CASA/c_micasad/init/Main.cs
2006-01-31 22:01:47 +00:00

225 lines
7.3 KiB
C#

/***********************************************************************
*
* Copyright (C) 2005-2006 Novell, Inc. 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.IO;
using System.Text;
using System.Threading;
using System.Diagnostics;
using sscs.communication;
using sscs.constants;
using sscs.common;
class SecretStoreClientService
{
private static Communication server = null;
private static Thread listeningThread = null;
public static void Main(string[] args)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
try
{
/* If getting a lock fails, just exit.
*/
if(!AcquireLock())
{
Console.WriteLine("Another instance of micasad is already running");
Mono.Unix.Native.Syscall.exit(-1);
}
RegisterSignals();
CSSSLogger.DbgLog("Client Side SecretStore Service has started.");
server = CommunicationFactory.CreateCommunicationEndPoint();
listeningThread = new Thread(new ThreadStart(StartServer));
listeningThread.Start();
listeningThread.Join();
}
catch(Exception e)
{
Terminate();
}
}
/* The thread which listens and spawns threads on every accept
* starts its execution from this method.
*/
private static void StartServer()
{
try
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
server.StartCommunicationEndPoint();
}
catch(ThreadAbortException exp)
{
CSSSLogger.DbgLog("Listening thread of miCASAd is going down.");
CSSSLogger.ExpLog(exp.ToString());
}
catch(Exception exp)
{
CSSSLogger.ExpLog(exp.ToString());
}
CSSSLogger.DbgLog("Listening thread of miCASAd is going down.");
}
/* This ensures that there is only one instance of
* SSCS at any point.
*/
private static bool AcquireLock()
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
int platform = (int)Environment.OSVersion.Platform;
if( (platform == 128) || (platform == 4) )
{
if(File.Exists(ConstStrings.SSCS_LINUX_PIDFILE))
{
if(CheckIfMiCASAdIsRunning())
{
CSSSLogger.DbgLog("Acquiring lock failed. Terminating miCASAd.");
return false;
}
else
{
File.Delete(ConstStrings.SSCS_LINUX_PIDFILE);
CreatePidFile();
return true;
}
}
else
{
CreatePidFile();
return true;
}
}
else
return false;
}
private static void RegisterSignals()
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
if(( (int)Environment.OSVersion.Platform) == 128)
{
//SIGTERM
Mono.Unix.Native.Stdlib.signal(Mono.Unix.Native.Signum.SIGTERM, new Mono.Unix.Native.SignalHandler(Terminate));
//SIGINT
Mono.Unix.Native.Stdlib.signal(Mono.Unix.Native.Signum.SIGINT, new Mono.Unix.Native.SignalHandler(Terminate));
//SIGHUP
Mono.Unix.Native.Stdlib.signal(Mono.Unix.Native.Signum.SIGHUP, new Mono.Unix.Native.SignalHandler(Terminate));
}
}
private static void Terminate(int sigNum)
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Terminate();
}
private static void Terminate()
{
CSSSLogger.ExecutionTrace(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
CSSSLogger.DbgLog("Client Side SecretStore Service is now exiting.");
if( listeningThread != null )
{
listeningThread.Abort("Aborting listening thread");
}
int platform = (int)Environment.OSVersion.Platform;
if( (platform == 128) || (platform == 4) )
{
if( File.Exists(ConstStrings.SSCS_LINUX_PIDFILE) )
{
File.Delete(ConstStrings.SSCS_LINUX_PIDFILE);
}
Mono.Unix.Native.Syscall.exit(0);
}
}
private static void CreatePidFile()
{
int pid = Mono.Unix.Native.Syscall.getpid();
string pidStr = String.Format("{0}",pid);
FileInfo fInfo = new FileInfo(ConstStrings.SSCS_LINUX_PIDFILE);
FileStream fs = fInfo.Open(System.IO.FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamWriter w = new StreamWriter(fs);
w.Write(pidStr);
w.Flush();
fs.Close();
}
private static bool CheckIfMiCASAdIsRunning()
{
try
{
StreamReader sr = new StreamReader(ConstStrings.SSCS_LINUX_PIDFILE);
string line = sr.ReadLine();
if( line == null )
{
sr.Close();
return false;
}
string procPath = "/proc/"+ line + "/cmdline";
/* If the file procPath itself does not exist,
* then another instance is surely not running.
*/
if( !File.Exists(procPath) )
{
return false;
}
/* There is a possibility that the pid stored in
* the pidfile has been reassigned to another process.
* So, if procPath exists, check if the process is
* micasad.exe.
*/
StreamReader procReader = new StreamReader(procPath);
string cmdline = procReader.ReadLine();
/*
string assemblyName = (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType).Assembly.FullName + ".exe\0";
*/
string assemblyName = "micasad.exe\0";
if(cmdline.EndsWith(assemblyName))
{
return true;
}
else
{
return false;
}
}
catch(Exception e)
{
return false;
}
}
}