Files
duplicati/Duplicati/Scheduler/RunBackup/Pipe.cs
T
kenneth.skovhede@gmail.com 65b0ba40f5 Update namespace and assembly names for Duplicati.Scheduler components.
Fixed a bug with pipe access permissions on non-english OS.
Included Scheduler in Duplicati build, so it gets picked up by the installer.

git-svn-id: https://duplicati.googlecode.com/svn/trunk@861 59da171f-624f-0410-aa54-27559c288bec
2011-08-18 09:14:07 +00:00

132 lines
5.7 KiB
C#

#region Disclaimer / License
// Copyright (C) 2011, Kenneth Bergeron, IAP Worldwide Services, Inc
// NOAA :: National Marine Fisheries Service
//
// 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; either
// version 2.1 of the License, or (at your option) any later version.
//
// 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
// 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, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace Duplicati.Scheduler.RunBackup
{
public static class Pipe
{
// Use ETX as a seperator in the pipe, makes for easy parsing
public const char Separator = (char)3;
// This lock is probably not necessary... Locks the pipe
private static object Locker = new object();
// The Pipe
private static System.IO.Pipes.NamedPipeClientStream itsPipe = null;
// The Pipe's stream
private static System.IO.StreamWriter itsPipeWriter = null;
// Just pack up a PROGRESS command all ready for the service and send it out stdout.
// Try to connect to the named pipe server, if not, don't try again for 5 seconds.
public static void OperationProgress(Duplicati.Library.Main.Interface aCaller,
Duplicati.Library.Main.DuplicatiOperation aOperation,
Duplicati.Library.Main.DuplicatiOperationMode aSpecificOperation,
int aProgress, int aSubprogress, string aMessage, string aSubmessage)
{
// Progress has come, make sure the pipe is ready
if (itsPipe != null && itsPipeWriter != null && itsPipe.IsConnected)
{
try
{
lock (Locker)
{
// Package the event up into a null-terminated list for easy disassembly later
itsPipeWriter.WriteLine(string.Join(Separator.ToString(), new string[]
{
"PROGRESS", Program.Job, aOperation.ToString(), aSpecificOperation.ToString(),
aProgress.ToString(), aMessage, aSubprogress.ToString(), aSubmessage
}));
}
}
catch (Exception Ex)
{
Debug.WriteLine(Ex);
}
}
}
// A handy parser class
public class ProgressArguments
{
public bool OK = false;
public string Job { get; set; }
public string Operation { get; set; }
public string SpecificOperation { get; set; }
public string Caller { get; set; }
public int Progress { get; set; }
public int SubProgress { get; set; }
public string Message { get; set; }
public string SubMessage { get; set; }
public ProgressArguments(string aCommand)
{
string[] Parts = aCommand.Split(Separator);
if (Parts.Length != 8 && Parts[0] != "PROGRESS") return;
Job = Parts[1];
Operation = Parts[2];
SpecificOperation = Parts[3];
Progress = int.Parse(Parts[4]);
Message = Parts[5];
SubProgress = int.Parse(Parts[6]);
SubMessage = Parts[7];
OK = true;
}
}
// Just keep trying to connect (in the background).
public static void Connecter()
{
// I guess that makes this a "pipe thread".
new System.Threading.Thread(new System.Threading.ThreadStart(Thread)) { Name = Program.ClientThreadName, IsBackground = true }
.Start();
}
private static void Thread()
{
string PipeName = Duplicati.Scheduler.Utility.NamedPipeServerStream.MakePipeName(Program.PipeBaseName, Duplicati.Scheduler.Utility.User.UserName, System.IO.Pipes.PipeDirection.In);
while (true)
{
lock (Locker) itsPipe = new System.IO.Pipes.NamedPipeClientStream(".", PipeName, System.IO.Pipes.PipeDirection.Out);
Debug.WriteLine("Looking for out pipe: " + PipeName);
using (itsPipe)
{
try { itsPipe.Connect(5000); }
catch (Exception Ex)
{
Debug.WriteLine(Ex);
}
Debug.WriteLine("Connected = " + itsPipe.IsConnected.ToString());
if (itsPipe.IsConnected)
{
using (itsPipeWriter = new System.IO.StreamWriter(itsPipe) { AutoFlush = true })
{
try
{
while (itsPipe.IsConnected)
System.Threading.Thread.Sleep(1000);
}
catch { } // It's a broken pipe...
}
}
// itsPipe.Close();
}
}
}
}
}