Rename Connection -> WvDbus.
[versaplex.git] / versaplexd / versaplexd.cs
blobafa3726286ed3ae0983b28a54f7ac4b8d16a7375
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Threading;
5 using System.Linq;
6 using Wv;
7 using Wv.Extensions;
8 using Wv.NDesk.Options;
10 public static class VersaMain
12 static WvLog log = new WvLog("Versaplex");
13 static VxDbusRouter msgrouter = new VxDbusRouter();
14 static WvDBusServer dbusserver;
15 static Thread dbusserver_thread = null;
16 static ManualResetEvent thread_ready = new ManualResetEvent(false);
17 public static bool want_to_die = false;
19 public static WvDbus conn;
20 static Queue<Action> action_queue = new Queue<Action>();
22 static bool WvDbusMsgReady(WvDbus conn, WvDbusMsg msg)
24 // FIXME: This should really queue things to be run from the thread
25 // pool and then the response would be sent back through the action
26 // queue
27 log.print(WvLog.L.Debug4, "WvDbusMsgReady\n");
29 switch (msg.type)
31 case Wv.Dbus.MType.MethodCall:
32 if (msg.ifc == "vx.db")
34 action_queue.Enqueue(() => {
35 WvDbusMsg reply;
36 if (msgrouter.route(conn, msg, out reply))
38 if (reply == null) {
39 // FIXME: Do something if this happens, maybe?
40 log.print("Empty reply from RouteWvDbusMsg\n");
41 } else {
42 // XXX: Should this be done further down rather than
43 // passing the reply out here?
44 conn.send(reply);
47 });
48 return true;
50 return false;
52 default:
53 log.print(WvLog.L.Warning,
54 "Unexpected DBus message received: #{0} {1}->{2} {3}:{4}.{5}\n",
55 msg.serial, msg.sender, msg.dest,
56 msg.path, msg.ifc, msg.method);
57 return false;
61 static void _StartDBusServerThread(string[] monikers)
63 using (dbusserver = new WvDBusServer())
65 foreach (string m in monikers)
66 dbusserver.listen(m);
67 thread_ready.Set();
68 while (!want_to_die)
69 dbusserver.runonce();
73 static void StartDBusServerThread(string[] monikers)
75 if (monikers.Length == 0) return;
76 thread_ready.Reset();
77 dbusserver_thread = new Thread(() => _StartDBusServerThread(monikers));
78 dbusserver_thread.Start();
79 thread_ready.WaitOne();
82 static void StopDBusServerThread()
84 want_to_die = true;
85 if (dbusserver_thread != null)
86 dbusserver_thread.Join();
89 static void ShowHelp()
91 Console.Error.WriteLine
92 ("Usage: versaplexd [-v] [-b dbus-moniker]\n" +
93 " [-l listen-moniker]\n" +
94 " [-c config-file]");
95 Environment.Exit(1);
98 public static int Main(string[] args)
100 WvLog.L verbose = WvLog.L.Info;
101 string bus = null;
102 string cfgfile = "versaplexd.ini";
103 var listeners = new List<string>();
104 new OptionSet()
105 .Add("v|verbose", delegate(string v) { ++verbose; })
106 .Add("b=|bus=", delegate(string v) { bus = v; })
107 .Add("c=|config=", delegate(string v) { cfgfile = v; })
108 .Add("l=|listen=", delegate(string v) { listeners.Add(v); })
109 .Add("?|h|help", delegate(string v) { ShowHelp(); })
110 .Parse(args);
112 WvLog.maxlevel = (WvLog.L)verbose;
114 StartDBusServerThread(listeners.ToArray());
116 bool cfgfound = false;
118 if (File.Exists(cfgfile))
119 cfgfound = true;
120 else if (File.Exists("/etc/versaplexd.ini"))
122 log.print("Using /etc/versaplexd.ini for configuration.\n");
123 cfgfound = true;
124 cfgfile = "/etc/versaplexd.ini";
127 if (cfgfound == true) {
128 VxSqlPool.SetIniFile(cfgfile);
129 } else {
130 throw new Exception(wv.fmt(
131 "Could not find config file '{0}',\n" +
132 "and /etc/versaplexd.ini does not exist",
133 cfgfile));
136 if (bus == null)
137 bus = WvDbus.session_bus_address;
139 if (bus == null)
141 log.print
142 ("DBUS_SESSION_BUS_ADDRESS not set and no -b option given.\n");
143 ShowHelp();
146 log.print("Connecting to '{0}'\n", bus);
147 conn = new WvDbus(bus);
149 string myNameReq = "vx.versaplexd";
150 RequestNameReply rnr = conn.RequestName(myNameReq,
151 NameFlag.DoNotQueue);
153 switch (rnr) {
154 case RequestNameReply.PrimaryOwner:
155 log.print("Name registered, ready\n");
156 break;
157 default:
158 log.print("Register name result: \n" + rnr.ToString());
159 StopDBusServerThread();
160 return 2;
163 conn.stream.onclose += () => {
164 log.print(
165 "***********************************************************\n"+
166 "************ D-bus connection closed by server ************\n"+
167 "***********************************************************\n");
168 want_to_die = true;
171 conn.handlers.Insert(0, (m) => WvDbusMsgReady(conn, m));
173 while (!want_to_die)
175 log.print(WvLog.L.Debug2, "Event loop.\n");
176 WvStream.runonce(-1);
177 while (action_queue.Count > 0)
178 action_queue.Dequeue()();
181 StopDBusServerThread();
182 log.print("Done!\n");
183 return 0;