コード例 #1
0
        public void Login(string username, string password)
        {
            fetcher.Username = username;
            fetcher.Password = password;

            try {
                bag = ContentCodeBag.ParseCodes(fetcher.Fetch("/content-codes"));

                ContentNode node = ContentParser.Parse(bag, fetcher.Fetch("/login"));
                ParseSessionId(node);

                FetchDatabases();
                Refresh();
                // FIXME - the update handling mechanism is currently disabled

                /* if (server_info.SupportsUpdate) {
                 *   update_running = true;
                 *   Thread thread = new Thread (UpdateLoop);
                 *   thread.IsBackground = true;
                 *   thread.Start ();
                 * }*/
            } catch (WebException e) {
                if (e.Response != null && (e.Response as HttpWebResponse).StatusCode == HttpStatusCode.Unauthorized)
                {
                    throw new AuthenticationException("Username or password incorrect");
                }
                else
                {
                    throw new LoginException("Failed to login", e);
                }
            } catch (Exception e) {
                throw new LoginException("Failed to login", e);
            }
        }
コード例 #2
0
        private static ContentNode [] ParseChildren(ContentCodeBag bag, byte [] buffer,
                                                    int offset, int length)
        {
            ArrayList children = new ArrayList();

            int position = offset;

            while (position < offset + length)
            {
                children.Add(Parse(bag, buffer, null, ref position));
            }

            return((ContentNode [])children.ToArray(typeof(ContentNode)));
        }
コード例 #3
0
        public static byte [] Write(ContentCodeBag bag, ContentNode node)
        {
            MemoryStream stream = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(stream);

            Write(bag, node, writer);
            writer.Flush();

            byte [] buf = stream.GetBuffer();
            long    len = stream.Length;

            writer.Close();

            byte [] ret = new byte [len];
            Array.Copy(buf, ret, len);
            return(ret);
        }
コード例 #4
0
 public static ContentNode Parse(ContentCodeBag bag, byte [] buffer)
 {
     return(Parse(bag, buffer, null));
 }
コード例 #5
0
        public static ContentNode Parse(ContentCodeBag bag, byte [] buffer, string root)
        {
            int offset = 0;

            return(Parse(bag, buffer, root, ref offset));
        }
コード例 #6
0
        public static ContentNode Parse(ContentCodeBag bag, byte [] buffer, string root,
                                        ref int offset)
        {
            ContentNode node = new ContentNode();
            int         num  = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, offset));
            ContentCode code;

            // This is a fix for iPhoto '08 which gives wrong content-type for dpap.databasecontainers (aply)
            if (num == 1634757753)
            {
                code      = new ContentCode();
                code.Name = "dpap.databasecontainers";
                code.Type = ContentType.Container;
            }
            else
            {
                code = bag.Lookup(num);
            }

            if (code.Name.Equals("dpap.filedata"))
            {
                code.Type = ContentType.FileData;
            }

            if (code.Equals(ContentCode.Zero))
            {
                // probably a buggy server.  fallback to our internal code bag
                Console.WriteLine("fallback to internal code bag");
                Console.WriteLine("Code number: " + num);
                throw new Exception("Content code not found!");
            }

            int length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, offset + 4));

            if (code.Equals(ContentCode.Zero))
            {
                throw new ContentException(String.Format("Failed to find content code for '{0}'.  Data length is {1}",
                                                         ContentCodeBag.GetStringFormat(num), length));
            }

            node.Name = code.Name;

            Console.WriteLine("name = " + node.Name + "Code=" + code.Type.ToString() + " num=" + num);

            switch (code.Type)
            {
            case ContentType.Char:
                node.Value = (byte)buffer [offset + 8];
                break;

            case ContentType.Short:
                node.Value = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, offset + 8));
                break;

            case ContentType.SignedLong:
            case ContentType.Long:
                node.Value = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, offset + 8));
                break;

            case ContentType.LongLong:
                node.Value = IPAddress.NetworkToHostOrder(BitConverter.ToInt64(buffer, offset + 8));
                break;

            case ContentType.String:
                node.Value = Encoding.UTF8.GetString(buffer, offset + 8, length);
                break;

            case ContentType.Date:
                node.Value = Utility.ToDateTime(IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, offset + 8)));
                break;

            case ContentType.Version:
                int major = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, offset + 8));
                int minor = (int)buffer [offset + 10];
                int micro = (int)buffer [offset + 11];

                node.Value = new Version(major, minor, micro);
                break;

            case ContentType.Container:
                node.Value = ParseChildren(bag, buffer, offset + 8, length);
                break;

            case ContentType.FileData:
                node.Value = offset + 8;
                break;

            default:
                throw new ContentException(String.Format("Unknown content type '{0}' for '{1}'",
                                                         code.Type, code.Name));
            }

            offset += length + 8;

            if (root != null)
            {
                ContentNode root_node = node.GetChild(root);

                if (root_node == null)
                {
                    throw new ContentException(String.Format("Could not find root node '{0}'", root));
                }

                return(root_node);
            }
            else
            {
                return(node);
            }
        }
コード例 #7
0
        private static void Write(ContentCodeBag bag, ContentNode node, BinaryWriter writer)
        {
            ContentCode code = bag.Lookup(node.Name);

            if (code.Equals(ContentCode.Zero))
            {
                throw new ContentException("Failed to get content code for: " + node.Name);
            }

            writer.Write(IPAddress.HostToNetworkOrder(code.Number));

            switch (code.Type)
            {
            case ContentType.Char:
                writer.Write(IPAddress.HostToNetworkOrder(1));
                writer.Write((byte)node.Value);
                break;

            case ContentType.Short:
                writer.Write(IPAddress.HostToNetworkOrder(2));
                writer.Write(IPAddress.HostToNetworkOrder((short)node.Value));
                break;

            case ContentType.SignedLong:
            case ContentType.Long:
                writer.Write(IPAddress.HostToNetworkOrder(4));
                writer.Write(IPAddress.HostToNetworkOrder((int)node.Value));
                break;

            case ContentType.LongLong:
                writer.Write(IPAddress.HostToNetworkOrder(8));
                writer.Write(IPAddress.HostToNetworkOrder((long)node.Value));
                break;

            case ContentType.String:
                byte [] data = Encoding.UTF8.GetBytes((string)node.Value);
                writer.Write(IPAddress.HostToNetworkOrder(data.Length));
                writer.Write(data);
                break;

            case ContentType.Date:
                writer.Write(IPAddress.HostToNetworkOrder(4));
                writer.Write(IPAddress.HostToNetworkOrder(Utility.FromDateTime((DateTime)node.Value)));
                break;

            case ContentType.Version:
                Version version = (Version)node.Value;
                writer.Write(IPAddress.HostToNetworkOrder(4));

                writer.Write((short)IPAddress.HostToNetworkOrder((short)version.Major));
                writer.Write((byte)version.Minor);
                writer.Write((byte)version.Build);
                break;

            case ContentType.FileData:
                // after "pfdt" we should send the file size and then immediately the file's contents
                // DEBUG
                //Console.WriteLine ("ContentWriter FileData!");
                ContentNode [] nodes = (ContentNode [])node.Value;

                //Console.WriteLine (nodes [0].Value);
                writer.Write(IPAddress.HostToNetworkOrder((int)nodes [0].Value));
                FileInfo info = new FileInfo((string)nodes [1].Value);
                //Console.WriteLine ("reading file " + nodes [1].Value + ", length=" +info.Length);


                FileStream stream = info.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
                int        offset = -1;
                using (BinaryReader reader = new BinaryReader(stream)) {
                    if (offset > 0)
                    {
                        reader.BaseStream.Seek(offset, SeekOrigin.Begin);
                    }

                    long count = 0;
                    long len   = info.Length;
                    while (count < len)
                    {
                        byte [] buf = reader.ReadBytes(Math.Min(8192, (int)len - (int)count));
                        if (buf.Length == 0)
                        {
                            break;
                        }

                        writer.Write(buf);
                        count += buf.Length;
                    }
                }
                break;

            case ContentType.Container:
                MemoryStream child_stream = new MemoryStream();
                BinaryWriter child_writer = new BinaryWriter(child_stream);

                foreach (ContentNode child in (ContentNode [])node.Value)
                {
                    Write(bag, child, child_writer);
                }

                child_writer.Flush();
                byte [] bytes = child_stream.GetBuffer();
                int     len   = (int)child_stream.Length;

                writer.Write(IPAddress.HostToNetworkOrder(len));
                writer.Write(bytes, 0, len);
                child_writer.Close();
                break;

            default:
                Console.Error.WriteLine("Cannot write node of type: " + code.Type);
                break;
            }
        }
コード例 #8
0
        public static ContentCodeBag ParseCodes(byte [] buffer)
        {
            ContentCodeBag bag = new ContentCodeBag();

            // add some codes to bootstrap us
            bag.AddCode("mccr", "dmap.contentcodesresponse", ContentType.Container);
            bag.AddCode("mdcl", "dmap.dictionary", ContentType.Container);
            bag.AddCode("mcnm", "dmap.contentcodesnumber", ContentType.Long);
            bag.AddCode("mcna", "dmap.contentcodesname", ContentType.String);
            bag.AddCode("mcty", "dmap.contentcodestype", ContentType.Short);
            bag.AddCode("mstt", "dmap.status", ContentType.Long);

            // some photo-specific codes
            // shouldn't be needed now
            bag.AddCode("ppro", "dpap.protocolversion", ContentType.Long);
            bag.AddCode("pret", "dpap.blah", ContentType.Container);
            bag.AddCode("avdb", "dpap.serverdatabases", ContentType.Container);
            bag.AddCode("aply", "dpap.databasecontainers", ContentType.Container);
            bag.AddCode("abpl", "dpap.baseplaylist", ContentType.Char);
            bag.AddCode("apso", "dpap.playlistsongs", ContentType.Container);
            bag.AddCode("pasp", "dpap.aspectratio", ContentType.String);
            bag.AddCode("adbs", "dpap.databasesongs", ContentType.Container);
            bag.AddCode("picd", "dpap.creationdate", ContentType.Long);
            bag.AddCode("pifs", "dpap.imagefilesize", ContentType.Long);
            bag.AddCode("pwth", "dpap.imagepixelwidth", ContentType.Long);
            bag.AddCode("phgt", "dpap.imagepixelheight", ContentType.Long);
            bag.AddCode("pcmt", "dpap.imagecomments", ContentType.String);
            bag.AddCode("prat", "dpap.imagerating", ContentType.Long);
            bag.AddCode("pimf", "dpap.imagefilename", ContentType.String);
            bag.AddCode("pfmt", "dpap.imageformat", ContentType.String);
            bag.AddCode("plsz", "dpap.imagelargefilesize", ContentType.Long);
            bag.AddCode("pfdt", "dpap.filedata", ContentType.FileData);



            ContentNode node = ContentParser.Parse(bag, buffer);

            foreach (ContentNode dictNode in (node.Value as ContentNode []))
            {
                if (dictNode.Name != "dmap.dictionary")
                {
                    continue;
                }

                ContentCode code = new ContentCode();

                foreach (ContentNode item in (dictNode.Value as ContentNode []))
                {
                    switch (item.Name)
                    {
                    case "dmap.contentcodesnumber":
                        code.Number = (int)item.Value;
                        break;

                    case "dmap.contentcodesname":
                        code.Name = (string)item.Value;
                        break;

                    case "dmap.contentcodestype":
                        code.Type = (ContentType)Enum.ToObject(typeof(ContentType), (short)item.Value);
                        break;
                    }
                }

                bag.codes [code.Number] = code;
            }
            return(bag);
        }