FACT++  1.0
skypeclient.cc
Go to the documentation of this file.
1 #include <iostream>
2 
3 #include "EventImp.h"
4 #include "Configuration.h"
5 #include "StateMachineDim.h"
6 #include "LocalControl.h"
7 
8 #include <boost/tokenizer.hpp>
9 
10 #include <dbus/dbus-glib-lowlevel.h>
11 
12 using namespace std;
13 
15 {
16 private:
17  static const string fAuthorizationMsg;
18 
19  enum {
20  kStateDisconnected = 1,
21  kStateConnected = 2,
22  };
23 
25 
26  DBusConnection *fBus;
27  GMainLoop *fLoop;
28 
29  vector<string> fContacts;
30 
31  string fUser;
32 
33  bool fAllowRaw;
34 
35  uint64_t fLastReadMessage;
36 
37  string Contact(const string &id) const
38  {
39  if (id.size()==0)
40  return "";
41 
42  if (id[0]!='#')
43  return "";
44 
45  const size_t p = id.find_first_of('/');
46  if (p==string::npos)
47  return "";
48 
49  return id.substr(1, p-1);
50  }
51 
52 
53 
54  static DBusHandlerResult NotifyHandler(DBusConnection *, DBusMessage *dbus_msg, void *user_data)
55  {
56  static_cast<SkypeClient*>(user_data)->HandleDBusMessage(dbus_msg);
57  static_cast<SkypeClient*>(user_data)->Minimize();
58  return DBUS_HANDLER_RESULT_HANDLED;
59  }
60 
61  int HandleMsg(const EventImp &evt)
62  {
63  if (evt.GetSize()==0)
64  return GetCurrentState();
65 
66  for (auto it=fContacts.begin(); it!=fContacts.end(); it++)
67  SendSkypeMessage(*it, evt.GetString());
68 
69  ostringstream msg;
70  msg << evt.GetString() << " [" << fContacts.size() << "]";
71 
72  Info(msg);
73 
74  return GetCurrentState();
75  }
76 
77  int HandleRaw(const EventImp &evt)
78  {
79  if (evt.GetSize()==0 || !fAllowRaw)
80  return GetCurrentState();
81 
82  SendDBusMessage(evt.GetString());
83 
84  return GetCurrentState();
85  }
86 
87  int HandleCall()
88  {
89  int cnt = 0;
90  for (auto it=fContacts.begin(); it!=fContacts.end(); it++)
91  {
92  const string user = Contact(*it);
93  if (user.empty())
94  continue;
95 
96  SendDBusMessageNB("CALL "+user);
97 
98  cnt++;
99  }
100 
101  ostringstream msg;
102  msg << "CALLING [" << cnt << "/" << fContacts.size() << "]";
103 
104  Info(msg);
105 
106  return GetCurrentState();
107  }
108 
109  int HandleSMS(const EventImp &/*sms*/)
110  {
111  /*
112  -> CREATE SMS OUTGOING +0123456789
113  <- SMS 821 STATUS COMPOSING
114  <- SMS 821 PRICE 0
115  <- SMS 821 TIMESTAMP 0
116  <- SMS 821 PRICE_PRECISION 3
117  <- SMS 821 PRICE_CURRENCY EUR
118  <- SMS 821 STATUS COMPOSING
119  <- SMS 821 TARGET_NUMBERS +0123456789
120  <- SMS 821 PRICE -1
121  <- SMS 821 TARGET_STATUSES +0123456789=TARGET_ANALYZING
122  <- SMS 821 TARGET_STATUSES +0123456789=TARGET_ACCEPTABLE
123  <- SMS 821 PRICE 78
124 
125  //-------------------------------------------------------------------
126  // Now let's add two more target numbers (in addition to original)
127  -> SET SMS 1702 TARGET_NUMBERS +37259877305, +37259877306, +37259877307
128  <- SMS 1702 TARGET_NUMBERS +37259877305, +37259877306, +37259877307
129  <- SMS 1702 TARGET_NUMBERS +37259877305, +37259877306, +37259877307
130  <- SMS 1702 PRICE -1
131  <- SMS 1702 TARGET_STATUSES +37259877305=TARGET_ACCEPTABLE, +37259877306=TARGET_ANALYZING, +37259877307=TARGET_ANALYZING
132  <- SMS 1702 TARGET_STATUSES +37259877305=TARGET_ACCEPTABLE, +37259877306=TARGET_ACCEPTABLE, +37259877307=TARGET_ACCEPTABLE
133  <- SMS 1702 TARGET_STATUSES +37259877305=TARGET_ACCEPTABLE, +37259877306=TARGET_ACCEPTABLE, +37259877307=TARGET_ACCEPTABLE
134  <- SMS 1702 PRICE 234
135 
136  TARGET_ANALYZING
137  TARGET_UNDEFINED
138  TARGET_ACCEPTABLE
139  TARGET_NOT_ROUTABLE
140  TARGET_DELIVERY_PENDING
141  TARGET_DELIVERY_SUCCESSFUL
142  TARGET_DELIVERY_FAILED
143  UNKNOWN
144 
145  // ----------------------------------------------------------------
146  // This is how to set the message text property
147  // Note that you will get two identical lines in response
148  -> SET SMS 821 BODY "test 123 test 223 test 333"
149  <- SMS 821 BODY "test 123 test 223 test 333"
150  <- SMS 821 BODY "test 123 test 223 test 333"
151 
152  // ----------------------------------------------------------------
153  // Now lets try to send the message
154  -> ALTER SMS 821 SEND
155  <- ALTER SMS 821 SEND
156  <- SMS 821 STATUS SENDING_TO_SERVER
157  <- SMS 821 TIMESTAMP 1174058095
158  <- SMS 821 TARGET_STATUSES +0123456789=TARGET_ACCEPTABLE
159  <- SMS 821 TARGET_STATUSES +0123456789=TARGET_DELIVERY_FAILED
160  <- SMS 821 FAILUREREASON INSUFFICIENT_FUNDS
161  <- SMS 821 STATUS FAILED
162  <- SMS 821 IS_FAILED_UNSEEN TRUE
163 
164  STATUS
165  RECEIVED the message has been received (but not tagged as read)
166  READ the message has been tagged as read
167  COMPOSING the message has been created but not yet sent
168  SENDING_TO_SERVER the message is in process of being sent to server
169  SENT_TO_SERVER the message has been sent to server
170  DELIVERED server has confirmed that the message is sent out to recepient
171  SOME_TARGETS_FAILED server reports failure to deliver the message to one of the recepients within 24h
172  FAILED the message has failed, possible reason may be found in FAILUREREASON property
173  UNKNOWN message status is unknown
174 
175  FAILUREREASON
176  MISC_ERROR indicates failure to supply a meaningful error message
177  SERVER_CONNECT_FAILED unable to connect to SMS server
178  NO_SMS_CAPABILITY recepient is unable to receive SMS messages
179  INSUFFICIENT_FUNDS insufficient Skype Credit to send an SMS message
180  INVALID_CONFIRMATION_CODE set when an erroneous code was submitted in a CONFIRMATION_CODE_SUBMIT message
181  USER_BLOCKED user is blocked from the server
182  IP_BLOCKED user IP is blocked from the server
183  NODE_BLOCKED user p2p network node has been blocked from the server
184  UNKNOWN default failure code
185  NO_SENDERID_CAPABILITY Set when a CONFIRMATION_CODE_REQUEST SMS message is sent with a mobile phone number containing country code of either USA, Taiwan or China. Setting reply-to number from Skype SMS’s to your mobile number is not supported in these countries. Added in Skype version 3.5 (protocol 8).
186 
187  // ----------------------------------------------------------------
188  // As sending the message failed (not enough Skype credit),
189  // lets delete the message
190  -> DELETE SMS 821
191  <- DELETE SMS 821
192  */
193 
194  return GetCurrentState();
195  }
196 
197  string SendDBusMessage(const string &cmd, bool display=true)
198  {
199  DBusMessage *send = GetDBusMessage(cmd);
200  if (!send)
201  return "";
202 
203  DBusError error;
204  dbus_error_init(&error);
205 
206  // Send the message and wait for reply
207  if (display)
208  Info("TX: "+cmd);
209  DBusMessage *reply=
210  dbus_connection_send_with_reply_and_block(fBus, send,
211  -1,//DBUS_TIMEOUT_USE_DEFAULT,
212  &error);
213  /*
214  DBusPendingCall *pending = 0;
215  if (!dbus_connection_send_with_reply (fBus, send,
216  &pending, DBUS_TIMEOUT_USE_DEFAULT))
217  return "";
218 
219  if (!pending)
220  return "";
221 
222  bool = dbus_pending_call_get_completed(pending);
223  //dbus_pending_call_block(pending);
224  DBusMessage *reply = dbus_pending_call_steal_reply(pending);
225  dbus_pending_call_unref(pending);
226  */
227 
228  if (!reply)
229  {
230  Error("dbus_connection_send_with_reply_and_block: "+string(error.message));
231  dbus_error_free(&error);
232  return "";
233  }
234 
235  // Get Skype's reply string
236  const char *ack = 0;
237  dbus_message_get_args(reply, 0, DBUS_TYPE_STRING, &ack, DBUS_TYPE_INVALID);
238 
239  if (display)
240  Info("RX: "+string(ack));
241 
242  const string rc = ack;
243 
244  // Show no interest in the previously created messages.
245  // DBus will delete a message if reference count drops to zero.
246  dbus_message_unref(send);
247  dbus_message_unref(reply);
248 
249  return rc;
250  }
251 
252  DBusMessage *GetDBusMessage(const string &cmd)
253  {
254  // Create a message to be sent to Skype
255 
256  // Constructs a new message to invoke a method on a remote object.
257  // Sets the service the message should be sent to "com.Skype.API"
258  // Sets the object path the message should be sent to "/com/Skype"
259  // Sets the interface to invoke method on to "com.Skype.API"
260  // Sets the method to invoke to "Invoke"
261  DBusMessage *send=
262  dbus_message_new_method_call("com.Skype.API", "/com/Skype",
263  "com.Skype.API", "Invoke");
264  if (!send)
265  {
266  Error("dbus_message_new_method_call failed.");
267  return NULL;
268  }
269 
270  // Set the argument of the Invoke method
271  // Sets arg to be an argument to be passed to the Invoke method.
272  // It is an input argument. It has a type string.
273  // There are no output arguments.
274  const char *msg = cmd.c_str();
275  dbus_message_append_args(send,
276  DBUS_TYPE_STRING, &msg,
277  DBUS_TYPE_INVALID);
278 
279  return send;
280  }
281 
282  bool Minimize()
283  {
284  DBusMessage *send = GetDBusMessage("MINIMIZE");
285  if (!send)
286  return false;
287 
288  // Send the message and ignore the reply
289  const bool rc = dbus_connection_send(fBus, send, NULL);
290 
291  // Show no interest in the previously created messages.
292  // DBus will delete a message if reference count drops to zero.
293  dbus_message_unref(send);
294 
295  return rc;
296  }
297 
298  bool SendDBusMessageNB(const string &cmd)
299  {
300  DBusMessage *send = GetDBusMessage(cmd);
301  if (!send)
302  return false;
303 
304  // Send the message and ignore the reply
305  Info("TX: "+cmd);
306  const bool rc = dbus_connection_send(fBus, send, NULL);
307 
308  // Show no interest in the previously created messages.
309  // DBus will delete a message if reference count drops to zero.
310  dbus_message_unref(send);
311 
312  return rc;
313  }
314 
315  bool SendSkypeMessage(const string &chat, const string &msg)
316  {
317  return SendDBusMessageNB("CHATMESSAGE "+chat+" "+msg);
318 /*
319  // SendDBusMessage(bus, "CHAT CREATE "+user);
320 
321  const string rc = SendDBusMessage("CHATMESSAGE "+chat+" "+msg);
322 
323  const vector<string> vec = Split(rc);
324  if (vec[0]=="ERROR")
325  {
326  auto it = find(fContacts.begin(), fContacts.end(), chat);
327  if (it!=fContacts.end())
328  fContacts.erase(it);
329  return false;
330  }
331 
332  return true;
333  */
334  }
335  vector<string> Split(const string &msg)
336  {
337  using namespace boost;
338 
339  typedef char_separator<char> separator;
340  const tokenizer<separator> tok(msg, separator(" "));
341 
342  vector<string> vec;
343  for (auto it=tok.begin(); it!=tok.end(); it++)
344  vec.push_back((*it)[0]==0?it->substr(1):*it);
345 
346  return vec;
347  }
348 
349  void HandleDBusMessage(DBusMessage *dbus_msg)
350  {
351  if (GetCurrentState()!=kStateConnected)
352  return;
353 
354  // CALL target1, target2, target3
355  // SET CALL <id> STATUS FINISHED
356 
357  // Stores the argument passed to the Notify method
358  // into notify_argument.
359 
360  char *notify_argument=0;
361  dbus_message_get_args(dbus_msg, 0,
362  DBUS_TYPE_STRING, &notify_argument,
363  DBUS_TYPE_INVALID);
364 
365  Info("Notify: "+string(notify_argument));
366 
367  const vector<string> vec = Split(notify_argument);
368 
369  if (vec[0]=="CURRENTUSERHANDLE")
370  {
371  if (vec[1]!=fUser)
372  {
373  Error("Wrong user '"+vec[1]+"' logged in, '"+fUser+"' expected!");
374  fNewState = kStateDisconnected;
375  return;
376  }
377  }
378 
379  if (vec[0]=="CONNSTATUS")
380  {
381  // OFFLINE / CONNECTING / PAUSING / ONLINE
382  if (vec[1]!="ONLINE")
383  {
384  Error("Connection status '"+vec[1]+"'");
385  fNewState = kStateDisconnected;
386  return;
387  }
388  }
389 
390  if (vec[0]=="USERSTATUS")
391  {
392  if (vec[1]!="ONLINE")
393  {
394  Info("Skype user not visible... setting online.");
395  SendDBusMessageNB("SET USERSTATUS ONLINE");
396  }
397  }
398 
399  // USER rtlprmft RECEIVEDAUTHREQUEST Please allow me to see when you are online
400 
401  if (vec[0]=="USER")
402  {
403  if (vec[2]=="ONLINESTATUS")
404  {
405  if (vec[3]=="OFFLINE")
406  {
407  }
408  Info("User '"+vec[1]+"' changed status to '"+vec[3]+"'");
409  }
410 
411  // Answer authorization requests
412  if (vec[2]=="RECEIVEDAUTHREQUEST")
413  SendDBusMessageNB("SET USER "+vec[1]+" BUDDYSTATUS 2 "+fAuthorizationMsg);
414 
415  //if (vec[2]=="NROF_AUTHED_BUDDIES")
416  // cout << vec[1] << " --> " << vec[3];
417  }
418 
419  if (vec[0]=="GROUP")
420  {
421  // 1: gorup id
422  // 2: NROFUSERS
423  // 3: n
424  }
425 
426  if (vec[0]=="CHATMESSAGE")
427  {
428  if (vec[2]=="STATUS" && (vec[3]=="RECEIVED"|| vec[3]=="READ"))
429  {
430  const uint64_t last = stoll(vec[1]);
431 
432  // Check if message has already been processed: Sometimes
433  // some messages are received twice as READ/READ
434  if (last<=fLastReadMessage)
435  return;
436  fLastReadMessage = last;
437 
438  string rc;
439 
440  rc=SendDBusMessage("GET CHATMESSAGE "+vec[1]+" CHATNAME");
441 
442  const string id = Split(rc)[3];
443 
444  rc=SendDBusMessage("GET CHATMESSAGE "+vec[1]+" BODY");
445 
446  const size_t p = rc.find(" BODY ");
447  if (p==string::npos)
448  {
449  cout<< "BODY TAG NOT FOUND|" << rc << "|" << endl;
450  return;
451  }
452 
453  rc = Tools::Trim(rc.substr(rc.find(" BODY ")+6));
454 
455  if (rc=="start")
456  {
457  auto it = find(fContacts.begin(), fContacts.end(), id);
458  if (it==fContacts.end())
459  {
460  SendSkypeMessage(id, "Successfully subscribed.");
461  fContacts.push_back(id);
462  }
463  else
464  SendSkypeMessage(id, "You are already subscribed.");
465 
466  return;
467  }
468  if (rc=="stop")
469  {
470  auto it = find(fContacts.begin(), fContacts.end(), id);
471  if (it!=fContacts.end())
472  {
473  SendSkypeMessage(id, "Successfully un-subscribed.");
474  fContacts.erase(it);
475  }
476  else
477  SendSkypeMessage(id, "You were not subscribed.");
478 
479  return;
480  }
481 
482  if (rc=="status")
483  {
484  for (auto it=fContacts.begin(); it!=fContacts.end(); it++)
485  {
486  if (*it==vec[1])
487  {
488  SendSkypeMessage(id, "You are subscribed.");
489  return;
490  }
491  }
492  SendSkypeMessage(id, "You are not subscribed.");
493  return;
494  }
495 
496  SendSkypeMessage(id, "SYNTAX ERROR\n\nAvailable commands:\nPlease use either 'start', 'stop' or 'status'");
497 
498  }
499  }
500 
501  if (vec[0]=="CHAT")
502  {
503  const string id = vec[1];
504  if (vec[2]=="ACTIVITY_TIMESTAMP")
505  {
506  //SendDBusMessage("CHAT CREATE "+Contact(vec[1]));
507  //Info(vec[2]);
508  // ALTER CHAT DISBAND
509  }
510  if (vec[2]=="MYROLE")
511  {
512  }
513  if (vec[2]=="MEMBERS")
514  {
515  }
516  if (vec[2]=="ACTIVEMEMBERS")
517  {
518  }
519  if (vec[2]=="STATUS")
520  {
521  // vec[3]=="DIALOG")
522  }
523  if (vec[2]=="TIMESTAMP")
524  {
525  }
526  if (vec[2]=="DIALOG_PARTNER")
527  {
528  }
529  if (vec[2]=="FRIENDLYNAME")
530  {
531  // Notify: CHAT #maggiyy/$rtlprmft;da26ea52b3e70e65 FRIENDLYNAME Lamouette | noch ne message
532  }
533  }
534 
535  if (vec[0]=="CALL")
536  {
537  if (vec[2]=="STATUS" && vec[2]=="INPROGRESS")
538  SendDBusMessageNB("SET CALL "+vec[1]+ "STATUS FINISHED");
539 
540  // CALL 1501 STATUS UNPLACED
541  // CALL 1501 STATUS ROUTING
542  // CALL 1501 STATUS RINGING
543  }
544 
545  }
546 
548  {
549  return kStateDisconnected;
550  }
551 
553  {
554  fLastConnect = Time();
555 
556  // Enable client connection to Skype
557  if (SendDBusMessage("NAME FACT++")!="OK")
558  return kStateDisconnected;
559 
560  // Negotiate protocol version
561  if (SendDBusMessage("PROTOCOL 5")!="PROTOCOL 5")
562  return kStateDisconnected;
563 
564  // Now we are connected: Minimize the window...
565  SendDBusMessageNB("MINIMIZE");
566 
567  // ... and switch off the away message
568  SendDBusMessageNB("SET AUTOAWAY OFF");
569 
570  // Check for unauthorized users and...
571  const string rc = SendDBusMessage("SEARCH USERSWAITINGMYAUTHORIZATION");
572 
573  // ...authorize them
574  vector<string> users = Split(rc);
575 
576  if (users[0]!="USERS")
577  {
578  Error("Unexpected answer received '"+rc+"'");
579  return kStateDisconnected;
580  }
581 
582  for (auto it=users.begin()+1; it!=users.end(); it++)
583  {
584  const size_t p = it->length()-1;
585  if (it->at(p)==',')
586  it->erase(p);
587 
588  SendDBusMessageNB("SET USER "+*it+" BUDDYSTATUS 2 "+fAuthorizationMsg);
589  }
590 
591  return kStateConnected;
592  }
593 
596 
597  int Execute()
598  {
599  fNewState = -1;
600 
601  static GMainContext *context = g_main_loop_get_context(fLoop);
602  g_main_context_iteration(context, FALSE);
603 
604  if (fNewState>0)
605  return fNewState;
606 
607  const Time now;
608 
609  if (GetCurrentState()>kStateDisconnected)
610  {
611  if (now-fLastPing>boost::posix_time::seconds(15))
612  {
613  if (SendDBusMessage("PING", false)!="PONG")
614  return kStateDisconnected;
615 
616  fLastPing = now;
617  }
618 
619  return GetCurrentState();
620  }
621 
622  if (now-fLastConnect>boost::posix_time::minutes(1))
623  return HandleConnect();
624 
625  return GetCurrentState();
626  }
627 
628 public:
629  SkypeClient(ostream &lout) : StateMachineDim(lout, "SKYPE"),
630  fLastConnect(Time()-boost::posix_time::minutes(5)), fLoop(0),
631  fLastReadMessage(0)
632  {
633  AddStateName(kStateDisconnected, "Disonnected", "");
634  AddStateName(kStateConnected, "Connected", "");
635 
636  AddEvent("MSG", "C", kStateConnected)
637  (bind(&SkypeClient::HandleMsg, this, placeholders::_1))
638  ("|msg[string]:message to be distributed");
639 
640  AddEvent("RAW", "C")
641  (bind(&SkypeClient::HandleRaw, this, placeholders::_1))
642  ("|msg[string]:send a raw message to the Skype API");
643 
644  AddEvent("CALL", "", kStateConnected)
645  (bind(&SkypeClient::HandleCall, this))
646  ("");
647 
648  AddEvent("CONNECT", kStateDisconnected)
649  (bind(&SkypeClient::HandleConnect, this))
650  ("");
651 
652  AddEvent("DISCONNECT", kStateConnected)
653  (bind(&SkypeClient::HandleDisconnect, this))
654  ("");
655 
656  fLoop = g_main_loop_new(NULL, FALSE);
657  }
659  {
660  g_main_loop_unref(fLoop);
661  }
662 
664  {
665  fUser = conf.Get<string>("user");
666  fAllowRaw = conf.Get<bool>("allow-raw");
667 
668  // Get a connection to the session bus.
669  DBusError error;
670  dbus_error_init(&error);
671 
672  fBus = dbus_bus_get(DBUS_BUS_SESSION, &error);
673  if (!fBus)
674  {
675  Error("dbus_bus_get failed: "+string(error.message));
676  dbus_error_free(&error);
677  return 1;
678  }
679 
680  // Set up this connection to work in a GLib event loop.
681  dbus_connection_setup_with_g_main(fBus, NULL);
682 
683  // Install notify handler to process Skype's notifications.
684  // The Skype-to-client method call.
685  DBusObjectPathVTable vtable;
686  vtable.message_function = SkypeClient::NotifyHandler;
687 
688  // We will process messages with the object path "/com/Skype/Client".
689  const dbus_bool_t check =
690  dbus_connection_register_object_path(fBus, "/com/Skype/Client",
691  &vtable, this);
692  if (!check)
693  {
694  Error("dbus_connection_register_object_path failed.");
695  return 2;
696  }
697 
698  return -1;
699  }
700 
701  int Write(const Time &time, const string &txt, int severity=MessageImp::kMessage)
702  {
703  return MessageImp::Write(time, txt, severity);
704  }
705 };
706 
707 const string SkypeClient::fAuthorizationMsg =
708  "This is an automatic client of the FACT project (www.fact-project.org). "
709  "If you haven't tried to get in contact with this bot, feel free to block it. "
710  "In case of problems or questions please contact system@fact-project.org.";
711 
712 
713 // -------------------------------------------------------------------------------------
714 
716 {
717  const string n = conf.GetName()+".log";
718 
719  po::options_description config("Skype client options");
720  config.add_options()
721  ("user", var<string>("www.fact-project.org"), "If a user is given only connection to a skype with this user are accepted.")
722  ("allow-raw", po_bool(false), "This allows sending raw messages to the SKype API (for debugging)")
723  ;
724 
725  conf.AddOptions(config);
726 }
727 
728 /*
729  Extract usage clause(s) [if any] for SYNOPSIS.
730  Translators: "Usage" and "or" here are patterns (regular expressions) which
731  are used to match the usage synopsis in program output. An example from cp
732  (GNU coreutils) which contains both strings:
733  Usage: cp [OPTION]... [-T] SOURCE DEST
734  or: cp [OPTION]... SOURCE... DIRECTORY
735  or: cp [OPTION]... -t DIRECTORY SOURCE...
736  */
738 {
739  cout <<
740  "The skypeclient is a Dim to Skype interface.\n"
741  "\n"
742  "The default is that the program is started without user intercation. "
743  "All actions are supposed to arrive as DimCommands. Using the -c "
744  "option, a local shell can be initialized. With h or help a short "
745  "help message about the usuage can be brought to the screen.\n"
746  "\n"
747  "Usage: skypeclient [OPTIONS]\n"
748  " or: skypeclient [OPTIONS]\n";
749  cout << endl;
750 }
751 
752 void PrintHelp()
753 {
754  /* Additional help text which is printed after the configuration
755  options goes here */
756 }
757 
758 
759 #include "Main.h"
760 
761 int main(int argc, const char *argv[])
762 {
763  Configuration conf(argv[0]);
766  SetupConfiguration(conf);
767 
768  if (!conf.DoParse(argc, argv, PrintHelp))
769  return 127;
770 
771  // No console access at all
772  if (!conf.Has("console"))
773  return Main::execute<LocalStream, SkypeClient>(conf);
774 
775  if (conf.Get<int>("console")==0)
776  return Main::execute<LocalShell, SkypeClient>(conf);
777  else
778  return Main::execute<LocalConsole, SkypeClient>(conf);
779 
780  return 0;
781 }
A general base-class describing events issues in a state machine.
Definition: EventImp.h:11
int HandleCall()
Definition: skypeclient.cc:87
void HandleDBusMessage(DBusMessage *dbus_msg)
Definition: skypeclient.cc:349
int HandleRaw(const EventImp &evt)
Definition: skypeclient.cc:77
void SetupConfiguration(Configuration &conf)
Definition: Main.h:25
int main(int argc, const char *argv[])
Definition: skypeclient.cc:761
int EvalOptions(Configuration &conf)
Definition: skypeclient.cc:663
Adds some functionality to boost::posix_time::ptime for our needs.
Definition: Time.h:30
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
string SendDBusMessage(const string &cmd, bool display=true)
Definition: skypeclient.cc:197
#define FALSE
Definition: dim.h:136
STL namespace.
int Execute()
Is called continously to execute actions in the current state.
Definition: skypeclient.cc:597
char id[4]
Definition: FITS.h:71
std::string GetString() const
Definition: EventImp.cc:194
int Write(const Time &time, const string &txt, int severity=MessageImp::kMessage)
Definition: skypeclient.cc:701
uint64_t fLastReadMessage
Definition: skypeclient.cc:35
bool fAllowRaw
Definition: skypeclient.cc:33
DBusMessage * GetDBusMessage(const string &cmd)
Definition: skypeclient.cc:252
Just a message, usually obsolete.
Definition: MessageImp.h:16
virtual int Write(const Time &time, const std::string &txt, int qos=kMessage)
Definition: MessageImp.cc:133
bool Has(const std::string &var)
void PrintUsage()
Definition: skypeclient.cc:737
void SetupConfiguration(Configuration &conf)
Definition: skypeclient.cc:715
Display * display
Definition: did.h:37
vector< string > Split(const string &msg)
Definition: skypeclient.cc:335
void AddOptions(const po::options_description &opt, bool visible=true)
Definition: Configuration.h:92
string Contact(const string &id) const
Definition: skypeclient.cc:37
int HandleDisconnect()
Definition: skypeclient.cc:547
int HandleConnect()
Definition: skypeclient.cc:552
void PrintHelp()
Definition: skypeclient.cc:752
Warning because the service this data corrsponds to might have been last updated longer ago than Local time
Definition: smartfact.txt:92
std::map< std::string, std::string > Split(std::string &, bool=false)
Definition: tools.cc:230
int HandleMsg(const EventImp &evt)
Definition: skypeclient.cc:61
static const string fAuthorizationMsg
Definition: skypeclient.cc:17
string fUser
Definition: skypeclient.cc:31
GMainLoop * fLoop
Definition: skypeclient.cc:27
Commandline parsing, resource file parsing and database access.
Definition: Configuration.h:9
DBusConnection * fBus
Definition: skypeclient.cc:26
int size
Definition: db_dim_server.c:17
Class for a state machine implementation within a DIM network.
bool SendDBusMessageNB(const string &cmd)
Definition: skypeclient.cc:298
static DBusHandlerResult NotifyHandler(DBusConnection *, DBusMessage *dbus_msg, void *user_data)
Definition: skypeclient.cc:54
Error()
Definition: HeadersFTM.h:197
std::string Trim(const std::string &str)
Definition: tools.cc:68
po::typed_value< bool > * po_bool(bool def=false)
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
const std::string & GetName() const
SkypeClient(ostream &lout)
Definition: skypeclient.cc:629
bool Minimize()
Definition: skypeclient.cc:282
int HandleSMS(const EventImp &)
Definition: skypeclient.cc:109
Time fLastConnect
Definition: skypeclient.cc:24
bool SendSkypeMessage(const string &chat, const string &msg)
Definition: skypeclient.cc:315
vector< string > fContacts
Definition: skypeclient.cc:29
virtual size_t GetSize() const
Definition: EventImp.h:55