New e-d-s backend which indexes all local addressbooks and calendars.
[beagle.git] / Util / UnixListener.cs
blob0d75949e5e857276dad0e4398a25d88ad5048c4e
1 //
2 // UnixListener.cs
3 //
4 // Authors:
5 // Joe Shaw (joeshaw@novell.com)
6 //
7 // Copyright (C) 2004-2005 Novell, Inc.
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining a
12 // copy of this software and associated documentation files (the "Software"),
13 // to deal in the Software without restriction, including without limitation
14 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 // and/or sell copies of the Software, and to permit persons to whom the
16 // Software is furnished to do so, subject to the following conditions:
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 // DEALINGS IN THE SOFTWARE.
31 using System;
32 using System.Net;
33 using System.Net.Sockets;
34 using System.IO;
36 using Mono.Posix;
38 namespace Beagle.Util {
40 public class UnixListener : IDisposable {
41 bool disposed;
42 bool listening;
43 Socket server;
44 EndPoint savedEP;
46 void Init (UnixEndPoint ep)
48 listening = false;
49 string filename = ep.Filename;
50 if (File.Exists (filename)) {
51 Socket conn = new Socket (AddressFamily.Unix, SocketType.Stream, 0);
52 try {
53 conn.Connect (ep);
54 conn.Close ();
55 throw new InvalidOperationException ("There's already a server listening on " + filename);
56 } catch (SocketException se) {
58 File.Delete (filename);
61 server = new Socket (AddressFamily.Unix, SocketType.Stream, 0);
62 server.Bind (ep);
63 savedEP = server.LocalEndPoint;
66 public UnixListener (string path)
68 if (!Directory.Exists (Path.GetDirectoryName (path)))
69 Directory.CreateDirectory (Path.GetDirectoryName (path));
71 Init (new UnixEndPoint (path));
74 public UnixListener (UnixEndPoint localEndPoint)
76 if (localEndPoint == null)
77 throw new ArgumentNullException ("localendPoint");
79 Init (localEndPoint);
82 public EndPoint LocalEndpoint {
83 get { return savedEP; }
86 protected Socket Server {
87 get { return server; }
90 public Socket AcceptSocket ()
92 CheckDisposed ();
93 if (!listening)
94 throw new InvalidOperationException ("Socket is not listening");
96 // FIXME: This is a hack to work around a mono bug.
97 // server.Accept() *should* throw a SocketException
98 // immediately if the listener's Stop() is called, but
99 // it doesn't. So once that mono bug is fixed and
100 // reasonably deployed, we should remove the Poll()
101 // here and unconditionally return server.Accept().
103 // It is fixed in SVN post-1.1.7
105 // Time out after one second
106 if (server.Poll (1000000, SelectMode.SelectRead)) // 1000000 microseconds = 1 second
107 return server.Accept ();
108 else
109 return null;
112 public UnixClient AcceptUnixClient ()
114 CheckDisposed ();
115 if (!listening)
116 throw new InvalidOperationException ("Socket is not listening");
118 // FIXME: This is a hack to work around a mono bug.
119 // We shouldn't need to check for null, we should only
120 // need to "return new UnixClient (socket)". Once the
121 // above FIXME is removed, fix this one too.
122 Socket socket = AcceptSocket ();
123 if (socket == null)
124 return null;
125 return new UnixClient (socket);
128 ~UnixListener ()
130 Dispose (false);
133 public bool Pending ()
135 CheckDisposed ();
136 if (!listening)
137 throw new InvalidOperationException ("Socket is not listening");
139 return server.Poll (1000, SelectMode.SelectRead);
142 public void Start ()
144 Start (5);
147 public void Start (int backlog)
149 CheckDisposed ();
150 if (listening)
151 return;
153 server.Listen (backlog);
154 listening = true;
157 public void Stop ()
159 CheckDisposed ();
160 Dispose (true);
163 public void Dispose ()
165 Dispose (true);
166 GC.SuppressFinalize (this);
169 protected void Dispose (bool disposing)
171 if (disposed)
172 return;
174 if (disposing) {
175 if (server != null)
176 server.Close ();
178 server = null;
181 disposed = true;
184 void CheckDisposed ()
186 if (disposed)
187 throw new ObjectDisposedException (GetType().FullName);