示例#1
0
        /// <summary>
        /// Handle a SAY or COMMENT in a forum topic. The current topic must be set before this
        /// function is called or it does nothing. The replyNumber specifies whether this is a new
        /// thread (a SAY) or a reply to an existing thread (a COMMENT). A value of 0 starts a new
        /// thread otherwise it is the number of the message to which this is a reply.
        /// </summary>
        /// <param name="buffer">The I/O buffer</param>
        /// <param name="replyNumber">The message to which this is a reply</param>
        private void SayOrCommentCommand(LineBuffer buffer, int replyNumber)
        {
            if (_currentTopic != null)
            {
                PostMessage message = new PostMessage
                {
                    MsgID = replyNumber,
                    Forum = _currentTopic.Forum.Name,
                    Topic = _currentTopic.Name
                };

                buffer.WriteLine("Enter message. End with '.<CR>'");

                // The body of the message comprises multiple lines terminated by a line
                // that contains a single period character and nothing else.
                StringBuilder bodyMessage = new StringBuilder();

                string bodyLine = buffer.ReadLine();
                while (bodyLine != ".")
                {
                    bodyMessage.AppendLine(bodyLine.Trim());
                    bodyLine = buffer.ReadLine();
                }
                message.Body = bodyMessage.ToString();

                WebRequest wrPosturl = APIRequest.Post("forums/post", APIRequest.APIFormat.XML, message);

                buffer.WriteString("Adding..");

                try
                {
                    Stream objStream = wrPosturl.GetResponse().GetResponseStream();
                    if (objStream != null)
                    {
                        using (TextReader reader = new StreamReader(objStream))
                        {
                            XmlDocument doc = new XmlDocument {
                                InnerXml = reader.ReadLine()
                            };

                            if (doc.DocumentElement != null)
                            {
                                int newMessageNumber = Int32.Parse(doc.DocumentElement.InnerText);
                                buffer.WriteLine(string.Format("Message {0} added.", newMessageNumber));
                            }
                        }
                    }
                }
                catch (WebException e)
                {
                    if (e.Message.Contains("401"))
                    {
                        throw new AuthenticationException("Authentication Failed", e);
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Do a ZModem download of the scratchpad and optionally delete the scratchpad
        /// after a successful completion.
        /// </summary>
        /// <param name="buffer">Output buffer</param>
        private void DownloadCommand(LineBuffer buffer)
        {
            buffer.WriteLine("Zmodem download started... (to abort ^X^X^X^X^X)");
            buffer.WriteLine(string.Format("Filesize {0} bytes, estimated time at 2880 cps : 1 sec", _scratch.Length));

            string scratchFileName = Path.GetTempFileName();

            using (FileStream fileStream = new FileStream(scratchFileName, FileMode.Create))
            {
                ASCIIEncoding encoder       = new ASCIIEncoding();
                byte[]        rawScratchpad = encoder.GetBytes(_scratch.ToString());
                fileStream.Write(rawScratchpad, 0, rawScratchpad.Length);
            }

            ZModem.ZModem zModem = new ZModem.ZModem(buffer.Stream)
            {
                Filename = scratchFileName
            };
            bool success = zModem.Send();

            buffer.WriteLine(success ? "Download succeeded" : "Download failed");
            if (success)
            {
                buffer.WriteString("OK to delete the downloaded scratchpad-file? (y/n)? N\b");

                string yesNoResponse = buffer.ReadLine();
                if (yesNoResponse.Trim() == "Y")
                {
                    _scratch.Clear();
                }
            }

            File.Delete(scratchFileName);
        }
示例#3
0
 /// <summary>
 /// Handle the top-level Main commands.
 /// </summary>
 /// <param name="buffer">The telnet input stream</param>
 private void TopLevelCommand(LineBuffer buffer)
 {
     ChangeState(CoSyState.MAIN);
     do
     {
         if (!buffer.IsRunningScript)
         {
             buffer.Output = null;
             buffer.WriteString(PromptForState());
         }
     }while (!_endThread && !ActionCommand(buffer, buffer.ReadLine()));
 }
示例#4
0
 /// <summary>
 /// Handle the BYE command.
 /// </summary>
 /// <param name="buffer">Line buffer</param>
 /// <param name="parser">Parser</param>
 private bool ByeCommand(LineBuffer buffer, Parser parser)
 {
     if (parser.NextArgument() != "y" && _scratch.Length > 0)
     {
         buffer.WriteString("OK to delete your scratchpad? (y/n/q)? ");
         string yesNoQuit = buffer.ReadLine();
         if (yesNoQuit == "n")
         {
             SaveScratchpad();
         }
         if (yesNoQuit == "q")
         {
             return(false);
         }
     }
     return(true);
 }
示例#5
0
        /// <summary>
        /// Handle the RESIGN command.
        /// </summary>
        /// <param name="buffer">Input buffer</param>
        /// <param name="parser">Parser</param>
        private void ResignCommand(LineBuffer buffer, Parser parser)
        {
            string forumName = parser.NextArgument();
            string topicName = string.Empty;

            if (string.IsNullOrEmpty(forumName))
            {
                if (_currentTopic == null)
                {
                    buffer.WriteString("Conference name? ");
                    forumName = buffer.ReadLine();
                }
                else
                {
                    forumName = _currentTopic.Forum.Name;
                }
            }
            else
            {
                string[] joinParams = forumName.Split(new[] { '/' });
                if (joinParams.Length == 2)
                {
                    forumName = joinParams[0];
                    topicName = joinParams[1];
                }
            }

            if (!_forums.IsJoined(forumName))
            {
                buffer.WriteLine(string.Format("You are not a member of conference '{0}'.", forumName));
                return;
            }

            buffer.WriteLine(string.Format("Resigning from conference '{0}'.", forumName));
            _forums.Resign(forumName, topicName);

            ChangeState(CoSyState.MAIN);
        }
示例#6
0
        /// <summary>
        /// Display a prompt and request a Yes or No response.
        /// </summary>
        /// <param name="buffer">Line buffer</param>
        /// <param name="prompt">The prompt string</param>
        /// <returns>True if the user responded Yes, false if anything else</returns>
        private static bool Ask(LineBuffer buffer, string prompt)
        {
            while (true)
            {
                buffer.WriteString(prompt);
                buffer.WriteString("Y\b");

                string yesNo = buffer.ReadLine();

                if (string.IsNullOrEmpty(yesNo))
                {
                    continue;
                }
                if (yesNo.ToUpper().StartsWith("Y"))
                {
                    return(true);
                }
                if (yesNo.ToUpper().StartsWith("N"))
                {
                    return(false);
                }
            }
        }
示例#7
0
 /// <summary>
 /// Handle the top-level Main commands.
 /// </summary>
 /// <param name="buffer">The telnet input stream</param>
 private void TopLevelCommand(LineBuffer buffer)
 {
     ChangeState(CoSyState.MAIN);
     do
     {
         if (!buffer.IsRunningScript)
         {
             buffer.Output = null;
             buffer.WriteString(PromptForState());
         }
     }
     while (!_endThread && !ActionCommand(buffer, buffer.ReadLine()));
 }
示例#8
0
        /// <summary>
        /// Handle a SAY or COMMENT in a forum topic. The current topic must be set before this
        /// function is called or it does nothing. The replyNumber specifies whether this is a new
        /// thread (a SAY) or a reply to an existing thread (a COMMENT). A value of 0 starts a new
        /// thread otherwise it is the number of the message to which this is a reply.
        /// </summary>
        /// <param name="buffer">The I/O buffer</param>
        /// <param name="replyNumber">The message to which this is a reply</param>
        private void SayOrCommentCommand(LineBuffer buffer, int replyNumber)
        {
            if (_currentTopic != null)
            {
                PostMessage message = new PostMessage
                    {
                        MsgID = replyNumber,
                        Forum = _currentTopic.Forum.Name,
                        Topic = _currentTopic.Name
                    };

                buffer.WriteLine("Enter message. End with '.<CR>'");

                // The body of the message comprises multiple lines terminated by a line
                // that contains a single period character and nothing else.
                StringBuilder bodyMessage = new StringBuilder();

                string bodyLine = buffer.ReadLine();
                while (bodyLine != ".")
                {
                    bodyMessage.AppendLine(bodyLine.Trim());
                    bodyLine = buffer.ReadLine();
                }
                message.Body = bodyMessage.ToString();

                StringBuilder postMessageXml = new StringBuilder();

                using (XmlWriter writer = XmlWriter.Create(postMessageXml))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof (PostMessage));
                    serializer.Serialize(writer, message);
                }

                // Remove the header
                postMessageXml.Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "");

                // Messages are posted as 7-bit ASCII.
                UTF8Encoding encoder = new UTF8Encoding();
                byte[] postMessageBytes = encoder.GetBytes(postMessageXml.ToString());

                WebRequest wrPosturl = WebRequest.Create(CIXOAuth.PostUri(CoSyServer.CIXAPIServer + "cix.svc/forums/post.xml"));
                wrPosturl.Method = "POST";
                wrPosturl.ContentLength = encoder.GetByteCount(postMessageXml.ToString());
                wrPosturl.ContentType = "application/xml";

                Stream dataStream = wrPosturl.GetRequestStream();
                dataStream.Write(postMessageBytes, 0, postMessageBytes.Length);
                dataStream.Close();

                buffer.WriteString("Adding..");

                try
                {
                    Stream objStream = wrPosturl.GetResponse().GetResponseStream();
                    if (objStream != null)
                    {
                        using (TextReader reader = new StreamReader(objStream))
                        {
                            XmlDocument doc = new XmlDocument {InnerXml = reader.ReadLine()};

                            if (doc.DocumentElement != null)
                            {
                                int newMessageNumber = Int32.Parse(doc.DocumentElement.InnerText);
                                buffer.WriteLine(string.Format("Message {0} added.", newMessageNumber));
                            }
                        }
                    }
                }
                catch (WebException e)
                {
                    if (e.Message.Contains("401"))
                    {
                        throw new AuthenticationException("Authentication Failed", e);
                    }
                }
            }
        }
示例#9
0
        /// <summary>
        /// Handle the RESIGN command.
        /// 
        /// CAUTION: The API currently doesn't support resigning topics within a forum, although
        /// the web service apparently seems to. Until this is supported, the resign command will
        /// resign entire forums. For safety, if a topic name is specified in the argument we
        /// bail out and do nothing.
        /// </summary>
        /// <param name="buffer">Input buffer</param>
        /// <param name="parser">Parser</param>
        private void ResignCommand(LineBuffer buffer, Parser parser)
        {
            string forumName = parser.NextArgument();
            if (string.IsNullOrEmpty(forumName))
            {
                if (_currentTopic == null)
                {
                    buffer.WriteString("Conference name? ");
                    forumName = buffer.ReadLine();
                }
                else
                {
                    forumName = _currentTopic.Forum.Name;
                }
            }
            else
            {
                string[] joinParams = forumName.Split(new[] {'/'});
                if (joinParams.Length == 2)
                {
                    return; // Bail out if a topic name was specified.
                }
            }

            if (!_forums.IsJoined(forumName))
            {
                buffer.WriteLine(string.Format("You are not a member of conference '{0}'.", forumName));
                return;
            }

            buffer.WriteLine(string.Format("Resigning from conference '{0}'.", forumName));
            _forums.Resign(forumName);

            ChangeState(CoSyState.MAIN);
        }
示例#10
0
        /// <summary>
        /// Handle the JOIN command.
        /// </summary>
        /// <param name="buffer">Line buffer</param>
        /// <param name="parser">Parser</param>
        private void JoinCommand(LineBuffer buffer, Parser parser)
        {
            string forumName = parser.NextArgument();
            if (!string.IsNullOrEmpty(forumName))
            {
                string topicName = null;

                string[] joinParams = forumName.Split(new[] {'/'});
                if (joinParams.Length == 2)
                {
                    forumName = joinParams[0];
                    topicName = joinParams[1];
                }

                if (!_forums.IsJoined(forumName))
                {
                    buffer.WriteString(string.Format("You are not registered in '{0}'. ", forumName));
                    if (Ask(buffer, "Would you like to register  (y/n)? "))
                    {
                        if (!_forums.Join(forumName))
                        {
                            buffer.WriteRedirectableLine(string.Format("No conference '{0}'.", forumName));
                            return;
                        }
                    }
                }

                Forum thisForum = _forums[forumName];
                Topic thisTopic;

                do
                {
                    if (topicName != null && !thisForum.Topics.Contains(topicName))
                    {
                        buffer.WriteLine("Couldn't find topic: No such file or directory");
                        buffer.WriteLine(string.Format("Topic '{0}' not found.", topicName));

                        topicName = thisForum.Topics[0].Name;
                    }

                    if (topicName == null)
                    {
                        buffer.WriteString("Topics are:");
                        for (int c = 0; c < thisForum.Topics.Count; ++c)
                        {
                            string topicString = thisForum.Topics[c].Name;
                            if (c > 0)
                            {
                                buffer.WriteString(",");
                            }
                            buffer.WriteString(string.Format(" '{0}'", topicString));
                        }
                        buffer.WriteLine("");
                        buffer.WriteString("Topic? ");

                        topicName = buffer.ReadLine();
                        if (topicName == "quit")
                        {
                            return;
                        }
                    }

                    thisTopic = thisForum.Topics[topicName];
                } while (thisTopic == null);

                buffer.WriteRedirectableLine(string.Format("Joining conference '{0}', topic '{1}'. {2} new message(s).", forumName, topicName, thisTopic.Unread));
                _currentTopic = thisTopic;

                ChangeState(CoSyState.READ);
            }
        }
示例#11
0
        /// <summary>
        /// This is the main CoSy client communication thread.
        /// </summary>
        /// <param name="client">The handle of the TCP client connection</param>
        private void HandleClientComm(object client)
        {
            TcpClient tcpClient = (TcpClient)client;
            TelnetStream stream = new TelnetStream(tcpClient.GetStream());
            LineBuffer buffer = new LineBuffer(stream);

            try
            {
                DateTime loginTime = DateTime.Now;

                buffer.WriteLine("CIX Conferencing System");

                while (true)
                {
                    buffer.WriteString("login: "******"qix" || loginString == "cix")
                    {
                        break;
                    }
                    buffer.WriteLine("Unknown login");
                }

                Version ver = Assembly.GetEntryAssembly().GetName().Version;
                string versionString = string.Format("{0}.{1}.{2}", ver.Major, ver.Minor, ver.Build);
                buffer.WriteLine(string.Format("{0} {1}", Properties.Resources.CIXAPIProxyTitle, versionString));

                buffer.WriteString("Nickname? (Enter 'new' for new user) ");
                string userName = buffer.ReadLine();

                buffer.WriteString("Password: "******"");

                Console.WriteLine("Logged in as '{0}' with password '{1}'", userName, password);

                _forums = new Forums();

                buffer.WriteLine(string.Format("You are a member of {0} conference(s).", _forums.Count));
                buffer.WriteLine("Max scratchsize during file has been set to 20000000 bytes");

                TopLevelCommand(buffer);

                buffer.Output = null;

                // Round up login time to 1 minute.
                TimeSpan onlineTime = (DateTime.Now - loginTime).Add(new TimeSpan(0, 1, 0));

                buffer.WriteLine(string.Format("{0}, you have been online {1}:{2} on line 5", userName, onlineTime.Hours,
                                               onlineTime.Minutes));
                buffer.WriteLine("Goodbye from CIX     !!!HANGUP NOW!!!");
            }
            catch (IOException)
            {
                Console.WriteLine("Client terminated connection");
            }
            catch (IndexOutOfRangeException)
            {
                Console.WriteLine("Client terminated connection");
            }
            catch (AuthenticationException)
            {
                // Authentication failed. Likely the app has been revoked. Clear
                // the tokens and force re-authentication.
                Properties.Settings.Default.oauthToken = "";
                Properties.Settings.Default.oauthTokenSecret = "";

                Properties.Settings.Default.Save();
            }

            tcpClient.Close();
        }
示例#12
0
        /// <summary>
        /// Do a ZModem download of the scratchpad and optionally delete the scratchpad
        /// after a successful completion.
        /// </summary>
        /// <param name="buffer">Output buffer</param>
        private void DownloadCommand(LineBuffer buffer)
        {
            buffer.WriteLine("Zmodem download started... (to abort ^X^X^X^X^X)");
            buffer.WriteLine(string.Format("Filesize {0} bytes, estimated time at 2880 cps : 1 sec", _scratch.Length));

            string scratchFileName = Path.GetTempFileName();
            using (FileStream fileStream = new FileStream(scratchFileName, FileMode.Create))
            {
                ASCIIEncoding encoder = new ASCIIEncoding();
                byte[] rawScratchpad = encoder.GetBytes(_scratch.ToString());
                fileStream.Write(rawScratchpad, 0, rawScratchpad.Length);
            }

            ZModem.ZModem zModem = new ZModem.ZModem(buffer.Stream) {Filename = scratchFileName};
            bool success = zModem.Send();

            buffer.WriteLine(success ? "Download succeeded" : "Download failed");
            if (success)
            {
                buffer.WriteString("OK to delete the downloaded scratchpad-file? (y/n)? N\b");

                string yesNoResponse = buffer.ReadLine();
                if (yesNoResponse.Trim() == "Y")
                {
                    _scratch.Clear();
                }
            }

            File.Delete(scratchFileName);
        }
示例#13
0
 /// <summary>
 /// Handle the BYE command.
 /// </summary>
 /// <param name="buffer">Line buffer</param>
 /// <param name="parser">Parser</param>
 private bool ByeCommand(LineBuffer buffer, Parser parser)
 {
     if (parser.NextArgument() != "y" && _scratch.Length > 0)
     {
         buffer.WriteString("OK to delete your scratchpad? (y/n/q)? ");
         string yesNoQuit = buffer.ReadLine();
         if (yesNoQuit == "q")
         {
             return false;
         }
     }
     return true;
 }
示例#14
0
        /// <summary>
        /// Display a prompt and request a Yes or No response.
        /// </summary>
        /// <param name="buffer">Line buffer</param>
        /// <param name="prompt">The prompt string</param>
        /// <returns>True if the user responded Yes, false if anything else</returns>
        private static bool Ask(LineBuffer buffer, string prompt)
        {
            while (true)
            {
                buffer.WriteString(prompt);
                buffer.WriteString("Y\b");

                string yesNo = buffer.ReadLine();

                if (string.IsNullOrEmpty(yesNo))
                {
                    continue;
                }
                if (yesNo.ToUpper().StartsWith("Y"))
                {
                    return true;
                }
                if (yesNo.ToUpper().StartsWith("N"))
                {
                    return false;
                }
            }
        }
示例#15
0
        /// <summary>
        /// This is the main CoSy client communication thread.
        /// </summary>
        /// <param name="client">The handle of the TCP client connection</param>
        private void HandleClientComm(object client)
        {
            TcpClient    tcpClient = (TcpClient)client;
            TelnetStream stream    = new TelnetStream(tcpClient.GetStream());
            LineBuffer   buffer    = new LineBuffer(stream);

            try
            {
                DateTime loginTime = DateTime.Now;

                buffer.WriteLine("CIX Conferencing System");

                while (true)
                {
                    buffer.WriteString("login: "******"qix" || loginString == "cix")
                    {
                        break;
                    }
                    buffer.WriteLine("Unknown login");
                }

                Version ver           = Assembly.GetEntryAssembly().GetName().Version;
                string  versionString = string.Format("{0}.{1}.{2}", ver.Major, ver.Minor, ver.Build);
                buffer.WriteLine(string.Format("CIX API Proxy {0}", versionString));

                buffer.WriteString("Nickname? (Enter 'new' for new user) ");
                string userName = buffer.ReadLine();

                buffer.WriteString("Password: "******"");

                Console.WriteLine("Logged in as '{0}' with password '{1}'", userName, password);

                APIRequest.Username = userName;
                APIRequest.Password = password;

                LoadScratchpad();

                _forums = new Forums();

                buffer.WriteLine(string.Format("You are a member of {0} conference(s).", _forums.Count));
                buffer.WriteLine("Max scratchsize during file has been set to 20000000 bytes");

                TopLevelCommand(buffer);

                buffer.Output = null;

                // Round up login time to 1 minute.
                TimeSpan onlineTime = (DateTime.Now - loginTime).Add(new TimeSpan(0, 1, 0));

                buffer.WriteLine(string.Format("{0}, you have been online {1}:{2} on line 5", userName, onlineTime.Hours,
                                               onlineTime.Minutes));
                buffer.WriteLine("Goodbye from CIX     !!!HANGUP NOW!!!");
            }
            catch (IOException)
            {
                Console.WriteLine("Client terminated connection");
            }
            catch (IndexOutOfRangeException)
            {
                Console.WriteLine("Client terminated connection");
            }
            catch (AuthenticationException)
            {
                Console.WriteLine("Client not authorised");
            }

            tcpClient.Close();
        }
示例#16
0
        /// <summary>
        /// Handle the JOIN command.
        /// </summary>
        /// <param name="buffer">Line buffer</param>
        /// <param name="parser">Parser</param>
        private void JoinCommand(LineBuffer buffer, Parser parser)
        {
            string forumName = parser.NextArgument();

            if (!string.IsNullOrEmpty(forumName))
            {
                string topicName = null;

                string[] joinParams = forumName.Split(new[] { '/' });
                if (joinParams.Length == 2)
                {
                    forumName = joinParams[0];
                    topicName = joinParams[1];
                }

                if (!_forums.IsJoined(forumName))
                {
                    buffer.WriteString(string.Format("You are not registered in '{0}'. ", forumName));
                    if (Ask(buffer, "Would you like to register  (y/n)? "))
                    {
                        if (!_forums.Join(forumName))
                        {
                            buffer.WriteRedirectableLine(string.Format("No conference '{0}'.", forumName));
                            return;
                        }
                    }
                }

                Forum thisForum = _forums[forumName];
                Topic thisTopic;

                do
                {
                    if (topicName != null && !thisForum.Topics.Contains(topicName))
                    {
                        buffer.WriteLine("Couldn't find topic: No such file or directory");
                        buffer.WriteLine(string.Format("Topic '{0}' not found.", topicName));

                        topicName = thisForum.Topics[0].Name;
                    }

                    if (topicName == null)
                    {
                        buffer.WriteString("Topics are:");
                        for (int c = 0; c < thisForum.Topics.Count; ++c)
                        {
                            string topicString = thisForum.Topics[c].Name;
                            if (c > 0)
                            {
                                buffer.WriteString(",");
                            }
                            buffer.WriteString(string.Format(" '{0}'", topicString));
                        }
                        buffer.WriteLine("");
                        buffer.WriteString("Topic? ");

                        topicName = buffer.ReadLine();
                        if (topicName == "quit")
                        {
                            return;
                        }
                    }

                    thisTopic = thisForum.Topics[topicName];
                } while (thisTopic == null);

                buffer.WriteRedirectableLine(string.Format("Joining conference '{0}', topic '{1}'. {2} new message(s).", forumName, topicName, thisTopic.Unread));
                _currentTopic = thisTopic;

                ChangeState(CoSyState.READ);
            }
        }