CASA/c_micasad/communication/UnixCommunication.cs
2006-04-07 21:46:16 +00:00

168 lines
4.9 KiB
C#

/***********************************************************************
*
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
*
* 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; version 2.1
* of the License.
*
* 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
* Library 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, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
***********************************************************************/
using System;
using System.Net;
using System.Net.Sockets;
using Mono.Unix;
using Mono.Unix.Native;
using System.IO;
using System.Text;
using System.Threading;
using sscs.common;
using sscs.constants;
namespace sscs.communication
{
/* Platform specific class which implements
* the 'Communication' interface.
*/
class UnixCommunication : Communication
{
private Socket listeningSocket;
private Socket connectedSocket;
private string socketFileName = "/tmp/.novellCASA";
private Mono.Unix.UnixEndPoint sockEndPoint;
private ManualResetEvent eventVar = null;
//Methods
internal UnixCommunication()
{
CSSSLogger.ExecutionTrace(this);
Syscall.umask(0);
if(File.Exists(socketFileName))
{
File.Delete(socketFileName);
}
listeningSocket = new Socket( AddressFamily.Unix,
SocketType.Stream,
ProtocolType.IP );
sockEndPoint = new Mono.Unix.UnixEndPoint(socketFileName);
eventVar = new ManualResetEvent(true);
}
~UnixCommunication()
{
CSSSLogger.ExecutionTrace(this);
eventVar.Close();
CloseCommunicationEndPoint();
}
// This code executes in the listening thread.
public void StartCommunicationEndPoint()
{
CSSSLogger.ExecutionTrace(this);
try
{
UnixFileSystemInfo sockFileInfo = new UnixFileInfo(socketFileName);
UnixUserInfo sockFileOwner = sockFileInfo.OwnerUser;
// check if ROOT is the owner of the file: /tmp/.novellCASA
if (sockFileOwner.UserId != 0)
{
File.Delete(socketFileName);
}
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
}
listeningSocket.Bind(sockEndPoint);
listeningSocket.Listen(50);
while(true)
{
try
{
eventVar.Reset();
listeningSocket.BeginAccept(new AsyncCallback(ListenCb),
listeningSocket);
eventVar.WaitOne();
}
catch(Exception e)
{
CSSSLogger.ExpLog(e.ToString());
throw e;
}
}
}
public void CloseCommunicationEndPoint()
{
CSSSLogger.ExecutionTrace(this);
listeningSocket.Close();
if(File.Exists( socketFileName ))
File.Delete(socketFileName);
}
// On receipt of a new client, this method is called.
private void ListenCb (IAsyncResult state)
{
try
{
CSSSLogger.ExecutionTrace(this);
connectedSocket = ((Socket)state.AsyncState).EndAccept (state);
eventVar.Set();
ServiceClient();
}
catch(Exception e)
{
/* All resources would have been cleaned up before reaching
* here.
*/
CSSSLogger.ExpLog(e.ToString());
}
/* End of thread function */
}
private void ServiceClient()
{
CSSSLogger.ExecutionTrace(this);
IPCChannel ipcChannel = IPCChannel.Create(connectedSocket);
AppHandler appHandler = new AppHandler(ipcChannel);
try
{
int retVal = appHandler.ServiceApp();
if( retVal != RetCodes.SUCCESS )
CSSSLogger.DbgLog("Servicing client failed.");
}
catch( Exception e )
{
CSSSLogger.ExpLog(e.ToString());
}
finally
{
ipcChannel.Close();
}
}
}
}