1 // Copyright 2006 Alp Toker <alp@atoker.com> 2 // This software is made available under the MIT License 3 // See COPYING for details 4 5 using System; 6 using System.Text; 7 using System.Collections.Generic; 8 9 namespace NDesk.DBus 10 { 11 public class BadAddressException : Exception 12 { BadAddressException(string reason)13 public BadAddressException (string reason) : base (reason) {} 14 } 15 16 class AddressEntry 17 { 18 public string Method; 19 public IDictionary<string,string> Properties = new Dictionary<string,string> (); 20 ToString()21 public override string ToString () 22 { 23 StringBuilder sb = new StringBuilder (); 24 sb.Append (Method); 25 sb.Append (':'); 26 27 bool first = true; 28 foreach (KeyValuePair<string,string> prop in Properties) { 29 if (first) 30 first = false; 31 else 32 sb.Append (','); 33 34 sb.Append (prop.Key); 35 sb.Append ('='); 36 sb.Append (Escape (prop.Value)); 37 } 38 39 return sb.ToString (); 40 } 41 Escape(string str)42 static string Escape (string str) 43 { 44 if (str == null) 45 return String.Empty; 46 47 StringBuilder sb = new StringBuilder (); 48 int len = str.Length; 49 50 for (int i = 0 ; i != len ; i++) { 51 char c = str[i]; 52 53 //everything other than the optionally escaped chars _must_ be escaped 54 if (Char.IsLetterOrDigit (c) || c == '-' || c == '_' || c == '/' || c == '\\' || c == '.') 55 sb.Append (c); 56 else 57 sb.Append (Uri.HexEscape (c)); 58 } 59 60 return sb.ToString (); 61 } 62 Unescape(string str)63 static string Unescape (string str) 64 { 65 if (str == null) 66 return String.Empty; 67 68 StringBuilder sb = new StringBuilder (); 69 int len = str.Length; 70 int i = 0; 71 while (i != len) { 72 if (Uri.IsHexEncoding (str, i)) 73 sb.Append (Uri.HexUnescape (str, ref i)); 74 else 75 sb.Append (str[i++]); 76 } 77 78 return sb.ToString (); 79 } 80 81 Parse(string s)82 public static AddressEntry Parse (string s) 83 { 84 AddressEntry entry = new AddressEntry (); 85 86 string[] parts = s.Split (':'); 87 88 if (parts.Length < 2) 89 throw new BadAddressException ("No colon found"); 90 if (parts.Length > 2) 91 throw new BadAddressException ("Too many colons found"); 92 93 entry.Method = parts[0]; 94 95 foreach (string propStr in parts[1].Split (',')) { 96 parts = propStr.Split ('='); 97 98 if (parts.Length < 2) 99 throw new BadAddressException ("No equals sign found"); 100 if (parts.Length > 2) 101 throw new BadAddressException ("Too many equals signs found"); 102 103 entry.Properties[parts[0]] = Unescape (parts[1]); 104 } 105 106 return entry; 107 } 108 } 109 110 static class Address 111 { 112 //(unix:(path|abstract)=.*,guid=.*|tcp:host=.*(,port=.*)?);? ... Parse(string addresses)113 public static AddressEntry[] Parse (string addresses) 114 { 115 if (addresses == null) 116 throw new ArgumentNullException (addresses); 117 118 List<AddressEntry> entries = new List<AddressEntry> (); 119 120 foreach (string entryStr in addresses.Split (';')) 121 entries.Add (AddressEntry.Parse (entryStr)); 122 123 return entries.ToArray (); 124 } 125 126 const string SYSTEM_BUS_ADDRESS = "unix:path=/var/run/dbus/system_bus_socket"; 127 public static string System 128 { 129 get { 130 string addr = Environment.GetEnvironmentVariable ("DBUS_SYSTEM_BUS_ADDRESS"); 131 132 if (String.IsNullOrEmpty (addr)) 133 addr = SYSTEM_BUS_ADDRESS; 134 135 return addr; 136 } 137 } 138 139 public static string Session 140 { 141 get { 142 return Environment.GetEnvironmentVariable ("DBUS_SESSION_BUS_ADDRESS"); 143 } 144 } 145 146 public static string Starter 147 { 148 get { 149 return Environment.GetEnvironmentVariable ("DBUS_STARTER_ADDRESS"); 150 } 151 } 152 153 public static string StarterBusType 154 { 155 get { 156 return Environment.GetEnvironmentVariable ("DBUS_STARTER_BUS_TYPE"); 157 } 158 } 159 } 160 } 161