singrdk/base/Windows/SmtpClient/Session.cs

241 lines
6.9 KiB
C#
Raw Normal View History

2008-11-17 18:29:00 -05:00
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Microsoft.Singularity.Smtp
{
public class Session
{
private Socket socket;
private byte[] ibuf;
private int iend;
private int ibeg;
private byte[] obuf;
private int odata;
private int result;
private bool verbose;
public Session(Socket socket)
{
this.socket = socket;
this.ibuf = new byte [4096];
this.ibeg = 0;
this.iend = 0;
this.obuf = new byte [4096];
this.odata = 0;
this.result = 0;
this.verbose = true;
}
private int HaveLine()
{
int left = iend - ibeg;
for (int i = 0; i + 1< left; i++) {
if (ibuf[ibeg + i] == '\r' && ibuf[ibeg + i + 1] == '\n') {
// return the # of character (not \r\n) in line.
return i;
}
}
return -1;
}
private int ReadLine()
{
for (;;) {
if (ibeg < iend) {
// See if there is a line already in the buffer.
int line = HaveLine();
if (line >= 0) {
return line;
}
// Make sure the remaining data is at the start of buffer.
if (ibeg > 0) {
Array.Copy(ibuf, ibeg, ibuf, 0, iend - ibeg);
iend -= ibeg;
ibeg = 0;
}
}
else {
ibeg = 0;
iend = 0;
}
int read = socket.Receive(ibuf, iend, ibuf.Length - iend, SocketFlags.None);
if (read == 0) {
// Should probably throw an exception.
return -1;
}
iend += read;
}
}
public int Result
{
get { return result; }
}
public bool Verbose
{
get { return verbose; }
set { verbose = value; }
}
public string ReadLine7()
{
result = 0;
int line = ReadLine();
if (line >= 0) {
string data = Encoding.ASCII.GetString(ibuf, ibeg, line);
for (int i = 0; i < line && ibuf[ibeg + i] >= '0' && ibuf[ibeg + i] <= '9'; i++) {
result = result * 10 + (ibuf[ibeg + i] - '0');
}
ibeg += line + 2;
if (verbose) {
Console.WriteLine("S: {0}", data);
}
return data;
}
if (verbose) {
Console.WriteLine("S: <end>");
}
return null;
}
public int ReadLine8(byte[] buffer, int offset)
{
result = 0;
int line = ReadLine();
if (line >= 0) {
Array.Copy(ibuf, ibeg, buffer, offset, line);
ibeg += line + 2;
if (verbose) {
Console.WriteLine("S: <8bit>");
}
return line;
}
if (verbose) {
Console.WriteLine("S: <end>");
}
return -1;
}
public void WritePrefix(byte prefix)
{
obuf[odata++] = prefix;
}
public void WriteLine7(string line)
{
WriteLine7(line, null, null);
}
public void WriteLine7(string a, string b)
{
WriteLine7(a, b, null);
}
public void WriteLine7(string a, string b, string c)
{
if (verbose) {
Console.WriteLine("C: {0}", a + b + c);
}
if (a != null) {
odata += Encoding.ASCII.GetBytes(a, 0, a.Length, obuf, odata);
}
if (b != null) {
odata += Encoding.ASCII.GetBytes(b, 0, b.Length, obuf, odata);
}
if (c != null) {
odata += Encoding.ASCII.GetBytes(c, 0, c.Length, obuf, odata);
}
obuf[odata++] = (byte)'\r';
obuf[odata++] = (byte)'\n';
socket.Send(obuf, 0, odata, SocketFlags.None);
odata = 0;
}
public void WriteLine8(byte[] line)
{
if (verbose) {
Console.WriteLine("C: <8bit>");
}
if (odata > 0) {
socket.Send(obuf, 0, odata, SocketFlags.None);
odata = 0;
}
socket.Send(line);
obuf[odata++] = (byte)'\r';
obuf[odata++] = (byte)'\n';
socket.Send(obuf, 0, odata, SocketFlags.None);
odata = 0;
}
public int Quit()
{
int save = result;
WriteLine7("QUIT");
ReadLine7();
socket.Shutdown(SocketShutdown.Both);
if (save == 0) {
return 999;
}
return save;
}
public int Close()
{
int save = result;
socket.Shutdown(SocketShutdown.Both);
if (save == 0) {
return 999;
}
return save;
}
private void Dump(byte[] array, int beg, int end)
{
for (int i = beg; i < end; i += 16) {
Console.Write(" :: ");
for (int j = i; j < i + 16; j++) {
if (j < end) {
Console.Write("{0:x2}", array[j]);
}
else {
Console.Write(" ");
}
}
Console.Write(" :: ");
for (int j = i; j < i + 16; j++) {
if (j < end) {
if (array[j] >= 32 && array[j] < 127) {
Console.Write("{0}", (char)array[j]);
}
else {
Console.Write(".");
}
}
else {
Console.Write(" ");
}
}
Console.WriteLine();
}
}
public void Dump()
{
Console.WriteLine(":::: Input {0}..{1}", ibeg, iend);
Dump(ibuf, ibeg, iend);
Console.WriteLine(":::: Output {0}..{1}", 0, odata);
Dump(obuf, 0, odata);
Console.WriteLine(":::: Result {0}", result);
}
}
}