diff --git a/RhinoReminds/Program.cs b/RhinoReminds/Program.cs index cd588da..9745541 100644 --- a/RhinoReminds/Program.cs +++ b/RhinoReminds/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Threading.Tasks; using S22.Xmpp; @@ -15,6 +16,7 @@ namespace RhinoReminds public string Jid = null; public string AvatarFilepath = string.Empty; + public string PidFile = null; public string Password = null; } @@ -47,7 +49,8 @@ namespace RhinoReminds Console.WriteLine(" -h --help Show this message"); Console.WriteLine($" -f --file Specify where to save reminders (default: {settings.Filepath})"); Console.WriteLine(" --domain {domain} Set the domain users are allowed to originate at. Defaults to any domain."); - Console.WriteLine(" --avatar Update the XMPP account's avatar to the specified image. By default the avatar is not updated."); + Console.WriteLine(" --avatar Update the XMPP account's avatar to the specified image. By default the avatar is not updated."); + Console.WriteLine(" --pidfile Save our process ID to the specified file, and delete it on exit"); Console.WriteLine(); Console.WriteLine("Environment Variables:"); Console.WriteLine(" XMPP_JID The JID to login to"); @@ -67,18 +70,53 @@ namespace RhinoReminds case "--avatar": settings.AvatarFilepath = args[++i]; break; + + case "--pidfile": + settings.PidFile = args[++i]; + break; } } settings.Jid = Environment.GetEnvironmentVariable("XMPP_JID"); settings.Password = Environment.GetEnvironmentVariable("XMPP_PASSWORD"); - Run(); + if (settings.Jid == null) { + Console.Error.WriteLine("Error: No JID specified to login with."); + Console.Error.WriteLine("Do so with the XMPP_JID environment variable!"); + return 15; + } + if (settings.Password == null) { + Console.Error.WriteLine("Error: No password specified to login with."); + Console.Error.WriteLine("Do so with the XMPP_PASSWORD environment variable!"); + return 16; + } + if (settings.PidFile != null) + setupPidFile(); + + run(); + // We shouldn't ever end up here, but just in case..... + cleanupPidFile(); return 0; } - public static void Run() + private static void setupPidFile() + { + File.WriteAllText(settings.PidFile, Process.GetCurrentProcess().Id.ToString()); + AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => cleanupPidFile(); + AppDomain.CurrentDomain.DomainUnload += (object sender, EventArgs e) => cleanupPidFile(); + } + + private static void cleanupPidFile() { + // Make sure we only do cleanup once + if (settings.PidFile == null) + return; + + File.Delete(settings.PidFile); + settings.PidFile = null; + } + + private static void run() { ClientListener client = new ClientListener(settings.Jid, settings.Password) { ReminderFilePath = settings.Filepath @@ -96,7 +134,16 @@ namespace RhinoReminds } // Connect to the server & start listening // Make sure the program doesn't exit whilst we're connected - client.Start().Wait(); + try + { + client.Start().Wait(); + } catch (Exception) { + // Ensure we tidy up after ourselves by deleting the PID file + if (settings.PidFile != null) + cleanupPidFile(); + // Re-throw the error + throw; + } } } }