Release 26
git-svn-id: https://svn.code.sf.net/p/synalist/code/trunk@55 7c85be65-684b-0410-a082-b2ed4fbef004
This commit is contained in:
		
							
								
								
									
										575
									
								
								IMAPsend.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										575
									
								
								IMAPsend.pas
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,575 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 001.001.001 | | ||||
| |==============================================================================| | ||||
| | Content: IMAP4rev1 client                                                         | | ||||
| |==============================================================================| | ||||
| | The contents of this file are Subject to the Mozilla Public License Ver. 1.1 | | ||||
| | (the "License"); you may not use this file except in compliance with the     | | ||||
| | License. You may obtain a Copy of the License at http://www.mozilla.org/MPL/ | | ||||
| |                                                                              | | ||||
| | Software distributed under the License is distributed on an "AS IS" basis,   | | ||||
| | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for | | ||||
| | the specific language governing rights and limitations under the License.    | | ||||
| |==============================================================================| | ||||
| | The Original Code is Synapse Delphi Library.                                 | | ||||
| |==============================================================================| | ||||
| | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).| | ||||
| | Portions created by Lukas Gebauer are Copyright (c)2001.                     | | ||||
| | All Rights Reserved.                                                         | | ||||
| |==============================================================================| | ||||
| | Contributor(s):                                                              | | ||||
| |==============================================================================| | ||||
| | History: see HISTORY.HTM from distribution package                           | | ||||
| |          (Found at URL: http://www.ararat.cz/synapse/)                       | | ||||
| |==============================================================================} | ||||
|  | ||||
| {$WEAKPACKAGEUNIT ON} | ||||
|  | ||||
| //RFC-2060 | ||||
|  | ||||
| unit IMAPsend; | ||||
|  | ||||
| interface | ||||
|  | ||||
| uses | ||||
|   SysUtils, Classes, | ||||
|   blcksock, SynaUtil, SynaCode; | ||||
|  | ||||
| const | ||||
|   cIMAPProtocol = '143'; | ||||
|  | ||||
| type | ||||
|   TIMAPSend = class(TObject) | ||||
|   private | ||||
|     FSock: TTCPBlockSocket; | ||||
|     FTimeout: Integer; | ||||
|     FIMAPHost: string; | ||||
|     FIMAPPort: string; | ||||
|     FTagCommand: integer; | ||||
|     FResultString: string; | ||||
|     FFullResult: TStringList; | ||||
|     FIMAPcap: TStringList; | ||||
|     FUsername: string; | ||||
|     FPassword: string; | ||||
|     FAuthDone: Boolean; | ||||
|     FSelectedFolder: string; | ||||
|     FSelectedCount: integer; | ||||
|     FSelectedRecent: integer; | ||||
|     FSelectedUIDvalidity: integer; | ||||
|     FUID: Boolean; | ||||
|  | ||||
|     function ReadResult: string; | ||||
|     function AuthLogin: Boolean; | ||||
|     function Connect: Boolean; | ||||
|     procedure ParseMess(Value:TStrings); | ||||
|     procedure ParseFolderList(Value:TStrings); | ||||
|     procedure ParseSelect; | ||||
|     procedure ParseSearch(Value:TStrings); | ||||
|   public | ||||
|     constructor Create; | ||||
|     destructor Destroy; override; | ||||
|     function IMAPcommand(Value: string): string; | ||||
|     function IMAPuploadCommand(Value: string; const Data:TStrings): string; | ||||
|     function Login: Boolean; | ||||
|     procedure Logout; | ||||
|     function NoOp: Boolean; | ||||
|     function List(FromFolder: string; const FolderList: TStrings): Boolean; | ||||
|     function ListSubscribed(FromFolder: string; const FolderList: TStrings): Boolean; | ||||
|     function CreateFolder(FolderName: string): Boolean; | ||||
|     function DeleteFolder(FolderName: string): Boolean; | ||||
|     function RenameFolder(FolderName, NewFolderName: string): Boolean; | ||||
|     function SubscribeFolder(FolderName: string): Boolean; | ||||
|     function UnsubscribeFolder(FolderName: string): Boolean; | ||||
|     function SelectFolder(FolderName: string): Boolean; | ||||
|     function SelectROFolder(FolderName: string): Boolean; | ||||
|     function CloseFolder: Boolean; | ||||
|     function StatusFolder(FolderName, Value: string): integer; | ||||
|     function ExpungeFolder: Boolean; | ||||
|     function CheckFolder: Boolean; | ||||
|     function AppendMess(ToFolder: string; const Mess: TStrings): Boolean; | ||||
|     function DeleteMess(MessID: integer): boolean; | ||||
|     function FetchMess(MessID: integer; const Mess: TStrings): Boolean; | ||||
|     function FetchHeader(MessID: integer; const Headers: TStrings): Boolean; | ||||
|     function MessageSize(MessID: integer): integer; | ||||
|     function CopyMess(MessID: integer; ToFolder: string): Boolean; | ||||
|     function SearchMess(Criteria: string; const FoundMess: TStrings): Boolean; | ||||
|     function SetFlagsMess(MessID: integer; Flags: string): Boolean; | ||||
|     function GetFlagsMess(MessID: integer; var Flags: string): Boolean; | ||||
|  | ||||
|     function FindCap(const Value: string): string; | ||||
|   published | ||||
|     property Timeout: Integer read FTimeout Write FTimeout; | ||||
|     property IMAPHost: string read FIMAPHost Write FIMAPHost; | ||||
|     property IMAPPort: string read FIMAPPort Write FIMAPPort; | ||||
|     property ResultString: string read FResultString; | ||||
|     property FullResult: TStringList read FFullResult; | ||||
|     property IMAPcap: TStringList read FIMAPcap; | ||||
|     property Username: string read FUsername Write FUsername; | ||||
|     property Password: string read FPassword Write FPassword; | ||||
|     property AuthDone: Boolean read FAuthDone; | ||||
|     property UID: Boolean read FUID Write FUID; | ||||
|     property Sock: TTCPBlockSocket read FSock; | ||||
|     property SelectedFolder: string read FSelectedFolder; | ||||
|     property SelectedCount: integer read FSelectedCount; | ||||
|     property SelectedRecent: integer read FSelectedRecent; | ||||
|     property SelectedUIDvalidity: integer read FSelectedUIDvalidity; | ||||
|   end; | ||||
|  | ||||
| implementation | ||||
|  | ||||
| const | ||||
|   CRLF = #13#10; | ||||
|  | ||||
| constructor TIMAPSend.Create; | ||||
| begin | ||||
|   inherited Create; | ||||
|   FFullResult := TStringList.Create; | ||||
|   FIMAPcap := TStringList.Create; | ||||
|   FSock := TTCPBlockSocket.Create; | ||||
|   FSock.CreateSocket; | ||||
|   FSock.SizeRecvBuffer := 32768; | ||||
|   FSock.SizeSendBuffer := 32768; | ||||
|   FTimeout := 300000; | ||||
|   FIMAPhost := cLocalhost; | ||||
|   FIMAPPort := cIMAPProtocol; | ||||
|   FUsername := ''; | ||||
|   FPassword := ''; | ||||
|   FTagCommand := 0; | ||||
|   FSelectedFolder := ''; | ||||
|   FSelectedCount := 0; | ||||
|   FSelectedRecent := 0; | ||||
|   FSelectedUIDvalidity := 0; | ||||
|   FUID := False; | ||||
| end; | ||||
|  | ||||
| destructor TIMAPSend.Destroy; | ||||
| begin | ||||
|   FSock.Free; | ||||
|   FIMAPcap.Free; | ||||
|   FFullResult.Free; | ||||
|   inherited Destroy; | ||||
| end; | ||||
|  | ||||
|  | ||||
| function TIMAPSend.ReadResult: string; | ||||
| var | ||||
|   s: string; | ||||
|   x, l: integer; | ||||
| begin | ||||
|   Result := ''; | ||||
|   FFullResult.Clear; | ||||
|   FResultString := ''; | ||||
|   repeat | ||||
|     s := FSock.RecvString(FTimeout); | ||||
|     if Pos('S' + IntToStr(FTagCommand) + ' ', s) = 1 then | ||||
|     begin | ||||
|       FResultString := s; | ||||
|       break; | ||||
|     end | ||||
|     else | ||||
|       FFullResult.Add(s); | ||||
|     if (s <> '') and (s[Length(s)]='}') then | ||||
|     begin | ||||
|       s := Copy(s, 1, Length(s) - 1); | ||||
|       x := RPos('{', s); | ||||
|       s := Copy(s, x + 1, Length(s) - x); | ||||
|       l := StrToIntDef(s, -1); | ||||
|       if l <> -1 then | ||||
|       begin | ||||
|         setlength(s, l); | ||||
|         x := FSock.recvbufferex(PChar(s), l, FTimeout); | ||||
|         SetLength(s, x); | ||||
|         FFullResult.Add(s); | ||||
|       end; | ||||
|     end; | ||||
|   until FSock.LastError <> 0; | ||||
|   s := separateright(FResultString, ' '); | ||||
|   Result:=uppercase(separateleft(s, ' ')); | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.IMAPcommand(Value: string): string; | ||||
| begin | ||||
|   Inc(FTagCommand); | ||||
|   FSock.SendString('S' + IntToStr(FTagCommand) + ' ' + Value + CRLF); | ||||
|   Result := ReadResult; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.IMAPuploadCommand(Value: string; const Data:TStrings): string; | ||||
| var | ||||
|   l: integer; | ||||
| begin | ||||
|   Inc(FTagCommand); | ||||
|   l := Length(Data.Text); | ||||
|   FSock.SendString(IntToStr(FTagCommand) + ' ' + Value + ' {'+ IntToStr(l) + '}' + CRLF); | ||||
|   FSock.SendString(Data.Text + CRLF); | ||||
|   Result := ReadResult; | ||||
| end; | ||||
|  | ||||
| procedure TIMAPSend.ParseMess(Value:TStrings); | ||||
| var | ||||
|   n: integer; | ||||
| begin | ||||
|   Value.Clear; | ||||
|   for n := 0 to FFullResult.Count - 2 do | ||||
|     if FFullResult[n][Length(FFullResult[n])] = '}' then | ||||
|     begin | ||||
|       Value.Text := FFullResult[n + 1]; | ||||
|       Break; | ||||
|     end; | ||||
| end; | ||||
|  | ||||
| procedure TIMAPSend.ParseFolderList(Value:TStrings); | ||||
| var | ||||
|   n, x: integer; | ||||
|   s: string; | ||||
| begin | ||||
|   Value.Clear; | ||||
|   for n := 0 to FFullResult.Count - 1 do | ||||
|   begin | ||||
|     s := FFullResult[n]; | ||||
|     x := RPos(' ', s); | ||||
|     if (x > 0) and (Pos('NOSELECT', UpperCase(s)) = 0) then | ||||
|       Value.Add(Copy(s, x + 1, Length(s) - x)); | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| procedure TIMAPSend.ParseSelect; | ||||
| var | ||||
|   n: integer; | ||||
|   s, t: string; | ||||
| begin | ||||
|   FSelectedCount := 0; | ||||
|   FSelectedRecent := 0; | ||||
|   FSelectedUIDvalidity := 0; | ||||
|   for n := 0 to FFullResult.Count - 1 do | ||||
|   begin | ||||
|     s := uppercase(FFullResult[n]); | ||||
|     if Pos(' EXISTS', s) > 0 then | ||||
|     begin | ||||
|       t := separateleft(s, ' EXISTS'); | ||||
|       t := separateright(t, '* '); | ||||
|       FSelectedCount := StrToIntDef(t, 0); | ||||
|     end; | ||||
|     if Pos(' RECENT', s) > 0 then | ||||
|     begin | ||||
|       t := separateleft(s, ' RECENT'); | ||||
|       t := separateright(t, '* '); | ||||
|       FSelectedRecent := StrToIntDef(t, 0); | ||||
|     end; | ||||
|     if Pos('UIDVALIDITY', s) > 0 then | ||||
|     begin | ||||
|       t := separateright(s, 'UIDVALIDITY '); | ||||
|       t := separateleft(t, ']'); | ||||
|       FSelectedUIDvalidity := StrToIntDef(t, 0); | ||||
|     end; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| procedure TIMAPSend.ParseSearch(Value:TStrings); | ||||
| var | ||||
|   n: integer; | ||||
|   s: string; | ||||
| begin | ||||
|   Value.Clear; | ||||
|   for n := 0 to FFullResult.Count - 1 do | ||||
|   begin | ||||
|     s := uppercase(FFullResult[n]); | ||||
|     if Pos('* SEARCH', s) = 1 then | ||||
|     begin | ||||
|       s := SeparateRight(s, '* SEARCH'); | ||||
|       while s <> '' do | ||||
|         Value.Add(Fetch(s, ' ')); | ||||
|     end; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.FindCap(const Value: string): string; | ||||
| var | ||||
|   n: Integer; | ||||
|   s: string; | ||||
| begin | ||||
|   s := UpperCase(Value); | ||||
|   Result := ''; | ||||
|   for n := 0 to FIMAPcap.Count - 1 do | ||||
|     if Pos(s, UpperCase(FIMAPcap[n])) = 1 then | ||||
|     begin | ||||
|       Result := FIMAPcap[n]; | ||||
|       Break; | ||||
|     end; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.AuthLogin: Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('LOGIN ' + FUsername + ' ' + FPassword) = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.Connect: Boolean; | ||||
| begin | ||||
|   FSock.CloseSocket; | ||||
|   FSock.CreateSocket; | ||||
|   FSock.Connect(FIMAPHost, FIMAPPort); | ||||
|   Result := FSock.LastError = 0; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.Login: Boolean; | ||||
| var | ||||
|   n: Integer; | ||||
|   s, t: string; | ||||
| begin | ||||
|   FSelectedFolder := ''; | ||||
|   FSelectedCount := 0; | ||||
|   FSelectedRecent := 0; | ||||
|   FSelectedUIDvalidity := 0; | ||||
|   Result := False; | ||||
|   FAuthDone := False; | ||||
|   if not Connect then | ||||
|     Exit; | ||||
|   s := FSock.RecvString(FTimeout); | ||||
|   if Pos('* PREAUTH', s) = 1 then | ||||
|     FAuthDone := True | ||||
|   else | ||||
|     if Pos('* OK', s) = 1 then | ||||
|       FAuthDone := False | ||||
|     else | ||||
|       Exit; | ||||
|   FIMAPcap.Clear; | ||||
|   s := IMAPcommand('CAPABILITY'); | ||||
|   if s = 'OK' then | ||||
|   begin | ||||
|     for n := 0 to FFullResult.Count - 1 do | ||||
|       if Pos('* CAPABILITY ', FFullResult[n]) = 1 then | ||||
|       begin | ||||
|         s := SeparateRight(FFullResult[n], '* CAPABILITY '); | ||||
|         while not (s = '') do | ||||
|         begin | ||||
|           t := separateleft(s, ' '); | ||||
|           s := separateright(s, ' '); | ||||
|           if s = t then | ||||
|             s := ''; | ||||
|           FIMAPcap.Add(t); | ||||
|         end; | ||||
|       end; | ||||
|     if Findcap('IMAP4rev1') = '' then | ||||
|       Exit; | ||||
|   end; | ||||
|   Result := AuthLogin; | ||||
| end; | ||||
|  | ||||
| procedure TIMAPSend.Logout; | ||||
| begin | ||||
|   IMAPcommand('LOGOUT'); | ||||
|   FSelectedFolder := ''; | ||||
|   FSock.CloseSocket; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.NoOp: Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('NOOP') = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.List(FromFolder: string; const FolderList: TStrings): Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('LIST "' + FromFolder + '" *') = 'OK'; | ||||
|   ParseFolderList(FolderList); | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.ListSubscribed(FromFolder: string; const FolderList: TStrings): Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('LSUB "' + FromFolder + '" *') = 'OK'; | ||||
|   ParseFolderList(FolderList); | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.CreateFolder(FolderName: string): Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('CREATE "' + FolderName + '"') = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.DeleteFolder(FolderName: string): Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('DELETE "' + FolderName + '"') = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.RenameFolder(FolderName, NewFolderName: string): Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('RENAME "' + FolderName + '" "' + NewFolderName + '"') = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.SubscribeFolder(FolderName: string): Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('SUBSCRIBE "' + FolderName + '"') = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.UnsubscribeFolder(FolderName: string): Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('UNSUBSCRIBE "' + FolderName + '"') = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.SelectFolder(FolderName: string): Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('SELECT "' + FolderName + '"') = 'OK'; | ||||
|   FSelectedFolder := FolderName; | ||||
|   ParseSelect; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.SelectROFolder(FolderName: string): Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('EXAMINE "' + FolderName + '"') = 'OK'; | ||||
|   FSelectedFolder := FolderName; | ||||
|   ParseSelect; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.CloseFolder: Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('CLOSE') = 'OK'; | ||||
|   FSelectedFolder := ''; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.StatusFolder(FolderName, Value: string): integer; | ||||
| var | ||||
|   n: integer; | ||||
|   s, t: string; | ||||
| begin | ||||
|   Result := -1; | ||||
|   Value := Uppercase(Value); | ||||
|   if IMAPcommand('STATUS "' + FolderName + '" (' + Value + ')' ) = 'OK' then | ||||
|     for n := 0 to FFullResult.Count - 1 do | ||||
|     begin | ||||
|       s := UpperCase(FFullResult[n]); | ||||
|       if (Pos('* STATUS ', s) = 1) and (Pos(Value, s) > 0 ) then | ||||
|       begin | ||||
|         t := SeparateRight(s, Value); | ||||
|         t := SeparateLeft(t, ')'); | ||||
|         t := trim(t); | ||||
|         Result := StrToIntDef(t, -1); | ||||
|         Break; | ||||
|       end; | ||||
|     end; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.ExpungeFolder: Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('EXPUNGE') = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.CheckFolder: Boolean; | ||||
| begin | ||||
|   Result := IMAPcommand('CHECK') = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.AppendMess(ToFolder: string; const Mess: TStrings): Boolean; | ||||
| begin | ||||
|   Result := IMAPuploadCommand('APPEND "' + ToFolder + '"', Mess) = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.DeleteMess(MessID: integer): boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   s := 'STORE ' + IntToStr(MessID) + ' +FLAGS.SILENT (\Deleted)'; | ||||
|   if FUID then | ||||
|     s := 'UID ' + s; | ||||
|   Result := IMAPcommand(s) = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.FetchMess(MessID: integer; const Mess: TStrings): Boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   s := 'FETCH ' + IntToStr(MessID) + ' (RFC822)'; | ||||
|   if FUID then | ||||
|     s := 'UID ' + s; | ||||
|   Result := IMAPcommand(s) = 'OK'; | ||||
|   ParseMess(Mess); | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.FetchHeader(MessID: integer; const Headers: TStrings): Boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   s := 'FETCH ' + IntToStr(MessID) + ' (RFC822.HEADER)'; | ||||
|   if FUID then | ||||
|     s := 'UID ' + s; | ||||
|   Result := IMAPcommand(s) = 'OK'; | ||||
|   ParseMess(Headers); | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.MessageSize(MessID: integer): integer; | ||||
| var | ||||
|   n: integer; | ||||
|   s, t: string; | ||||
| begin | ||||
|   Result := -1; | ||||
|   s := 'FETCH ' + IntToStr(MessID) + ' (RFC822.SIZE)'; | ||||
|   if FUID then | ||||
|     s := 'UID ' + s; | ||||
|   if IMAPcommand(s) = 'OK' then | ||||
|     for n := 0 to FFullResult.Count - 1 do | ||||
|     begin | ||||
|       s := UpperCase(FFullResult[n]); | ||||
|       if (Pos('* ', s) = 1) and (Pos('RFC822.SIZE', s) > 0 ) then | ||||
|       begin | ||||
|         t := SeparateRight(s, 'RFC822.SIZE '); | ||||
|         t := SeparateLeft(t, ')'); | ||||
|         t := trim(t); | ||||
|         Result := StrToIntDef(t, -1); | ||||
|         Break; | ||||
|       end; | ||||
|     end; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.CopyMess(MessID: integer; ToFolder: string): Boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   s := 'COPY ' + IntToStr(MessID) + ' "' + ToFolder + '"'; | ||||
|   if FUID then | ||||
|     s := 'UID ' + s; | ||||
|   Result := IMAPcommand(s) = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.SearchMess(Criteria: string; const FoundMess: TStrings): Boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   s := 'SEARCH ' + Criteria; | ||||
|   if FUID then | ||||
|     s := 'UID ' + s; | ||||
|   Result := IMAPcommand(s) = 'OK'; | ||||
|   ParseSearch(FoundMess); | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.SetFlagsMess(MessID: integer; Flags: string): Boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   s := 'STORE ' + IntToStr(MessID) + ' FLAGS.SILENT (' + Flags + ')'; | ||||
|   if FUID then | ||||
|     s := 'UID ' + s; | ||||
|   Result := IMAPcommand(s) = 'OK'; | ||||
| end; | ||||
|  | ||||
| function TIMAPSend.GetFlagsMess(MessID: integer; var Flags: string): Boolean; | ||||
| var | ||||
|   s: string; | ||||
|   n: integer; | ||||
| begin | ||||
|   Flags := ''; | ||||
|   s := 'FETCH ' + IntToStr(MessID) + ' (FLAGS)'; | ||||
|   if FUID then | ||||
|     s := 'UID ' + s; | ||||
|   Result := IMAPcommand(s) = 'OK'; | ||||
|   for n := 0 to FFullResult.Count - 1 do | ||||
|   begin | ||||
|     s := uppercase(FFullResult[n]); | ||||
|     if Pos('* FETCH (FLAGS', s) = 1 then | ||||
|     begin | ||||
|       s := SeparateRight(s, 'FLAGS'); | ||||
|       s := Separateright(s, '('); | ||||
|       Flags := SeparateLeft(s, ')'); | ||||
|     end; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| end. | ||||
							
								
								
									
										310
									
								
								NNTPsend.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										310
									
								
								NNTPsend.pas
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,310 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 001.000.000 | | ||||
| |==============================================================================| | ||||
| | Content: NNTP client                                                         | | ||||
| |==============================================================================| | ||||
| | The contents of this file are Subject to the Mozilla Public License Ver. 1.1 | | ||||
| | (the "License"); you may not use this file except in compliance with the     | | ||||
| | License. You may obtain a Copy of the License at http://www.mozilla.org/MPL/ | | ||||
| |                                                                              | | ||||
| | Software distributed under the License is distributed on an "AS IS" basis,   | | ||||
| | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for | | ||||
| | the specific language governing rights and limitations under the License.    | | ||||
| |==============================================================================| | ||||
| | The Original Code is Synapse Delphi Library.                                 | | ||||
| |==============================================================================| | ||||
| | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).| | ||||
| | Portions created by Lukas Gebauer are Copyright (c) 1999,2000,2001.          | | ||||
| | All Rights Reserved.                                                         | | ||||
| |==============================================================================| | ||||
| | Contributor(s):                                                              | | ||||
| |==============================================================================| | ||||
| | History: see HISTORY.HTM from distribution package                           | | ||||
| |          (Found at URL: http://www.ararat.cz/synapse/)                       | | ||||
| |==============================================================================} | ||||
|  | ||||
| {$WEAKPACKAGEUNIT ON} | ||||
|  | ||||
| unit NNTPsend; | ||||
|  | ||||
| interface | ||||
|  | ||||
| uses | ||||
|   SysUtils, Classes, | ||||
|   blcksock, SynaUtil, SynaCode; | ||||
|  | ||||
| const | ||||
|   cNNTPProtocol = 'nntp'; | ||||
|  | ||||
| type | ||||
|   TNNTPSend = class(TObject) | ||||
|   private | ||||
|     FSock: TTCPBlockSocket; | ||||
|     FTimeout: Integer; | ||||
|     FNNTPHost: string; | ||||
|     FNNTPPort: string; | ||||
|     FResultCode: Integer; | ||||
|     FResultString: string; | ||||
|     FData: TStringList; | ||||
|     function ReadResult: Integer; | ||||
|     function ReadData: boolean; | ||||
|     function SendData: boolean; | ||||
|     function Connect: Boolean; | ||||
|   public | ||||
|     constructor Create; | ||||
|     destructor Destroy; override; | ||||
|     function Login: Boolean; | ||||
|     procedure Logout; | ||||
|     function GetArticle(const Value: string): Boolean; | ||||
|     function GetBody(const Value: string): Boolean; | ||||
|     function GetHead(const Value: string): Boolean; | ||||
|     function GetStat(const Value: string): Boolean; | ||||
|     function SelectGroup(const Value: string): Boolean; | ||||
|     function IHave(const MessID: string): Boolean; | ||||
|     function GotoLast: Boolean; | ||||
|     function GotoNext: Boolean; | ||||
|     function ListGroups: Boolean; | ||||
|     function ListNewGroups(Since: TDateTime): Boolean; | ||||
|     function NewArticles(const Group: string; Since: TDateTime): Boolean; | ||||
|     function PostArticle: Boolean; | ||||
|     function SwitchToSlave: Boolean; | ||||
|   published | ||||
|     property Timeout: Integer read FTimeout Write FTimeout; | ||||
|     property NNTPHost: string read FNNTPHost Write FNNTPHost; | ||||
|     property NNTPPort: string read FNNTPPort Write FNNTPPort; | ||||
|     property ResultCode: Integer read FResultCode; | ||||
|     property ResultString: string read FResultString; | ||||
|     property Data: TStringList read FData; | ||||
|     property Sock: TTCPBlockSocket read FSock; | ||||
|   end; | ||||
|  | ||||
| implementation | ||||
|  | ||||
| const | ||||
|   CRLF = #13#10; | ||||
|  | ||||
| constructor TNNTPSend.Create; | ||||
| begin | ||||
|   inherited Create; | ||||
|   FData := TStringList.Create; | ||||
|   FSock := TTCPBlockSocket.Create; | ||||
|   FSock.CreateSocket; | ||||
|   FTimeout := 300000; | ||||
|   FNNTPhost := cLocalhost; | ||||
|   FNNTPPort := cNNTPProtocol; | ||||
| end; | ||||
|  | ||||
| destructor TNNTPSend.Destroy; | ||||
| begin | ||||
|   FSock.Free; | ||||
|   FData.Free; | ||||
|   inherited Destroy; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.ReadResult: Integer; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   Result := 0; | ||||
|   FData.Clear; | ||||
|   s := FSock.RecvString(FTimeout); | ||||
|   FResultString := Copy(s, 5, Length(s) - 4); | ||||
|   if FSock.LastError <> 0 then | ||||
|     Exit; | ||||
|   if Length(s) >= 3 then | ||||
|     Result := StrToIntDef(Copy(s, 1, 3), 0); | ||||
|   FResultCode := Result; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.ReadData: boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   Result := False; | ||||
|   repeat | ||||
|     s := FSock.RecvString(FTimeout); | ||||
|     if s = '.' then | ||||
|       break; | ||||
|     if (s <> '') and (s[1] = '.') then | ||||
|       s := Copy(s, 2, Length(s) - 1); | ||||
|     FData.Add(s); | ||||
|   until FSock.LastError <> 0; | ||||
|   Result := FSock.LastError = 0; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.SendData: boolean; | ||||
| var | ||||
|   s: string; | ||||
|   n: integer; | ||||
| begin | ||||
|   Result := False; | ||||
|   for n := 0 to FData.Count -1 do | ||||
|   begin | ||||
|     s := FData[n]; | ||||
|     if (s <> '') and (s[1]='.') then | ||||
|       s := s + '.'; | ||||
|     FSock.SendString(s + CRLF); | ||||
|     if FSock.LastError <> 0 then | ||||
|       break; | ||||
|   end; | ||||
|   Result := FSock.LastError = 0; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.Connect: Boolean; | ||||
| begin | ||||
|   FSock.CloseSocket; | ||||
|   FSock.CreateSocket; | ||||
|   FSock.Connect(FNNTPHost, FNNTPPort); | ||||
|   Result := FSock.LastError = 0; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.Login: Boolean; | ||||
| begin | ||||
|   Result := False; | ||||
|   if not Connect then | ||||
|     Exit; | ||||
|   Result := (ReadResult div 100) = 2; | ||||
| end; | ||||
|  | ||||
| procedure TNNTPSend.Logout; | ||||
| begin | ||||
|   FSock.SendString('QUIT' + CRLF); | ||||
|   ReadResult; | ||||
|   FSock.CloseSocket; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.GetArticle(const Value: string): Boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   Result := False; | ||||
|   s := 'ARTICLE'; | ||||
|   if Value <> '' then | ||||
|     s := s + ' ' + Value; | ||||
|   FSock.SendString(s + CRLF); | ||||
|   if (ReadResult div 100) <> 2 then | ||||
|     Exit; | ||||
|   Result := ReadData; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.GetBody(const Value: string): Boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   Result := False; | ||||
|   s := 'BODY'; | ||||
|   if Value <> '' then | ||||
|     s := s + ' ' + Value; | ||||
|   FSock.SendString(s + CRLF); | ||||
|   if (ReadResult div 100) <> 2 then | ||||
|     Exit; | ||||
|   Result := ReadData; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.GetHead(const Value: string): Boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   Result := False; | ||||
|   s := 'HEAD'; | ||||
|   if Value <> '' then | ||||
|     s := s + ' ' + Value; | ||||
|   FSock.SendString(s + CRLF); | ||||
|   if (ReadResult div 100) <> 2 then | ||||
|     Exit; | ||||
|   Result := ReadData; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.GetStat(const Value: string): Boolean; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   Result := False; | ||||
|   s := 'STAT'; | ||||
|   if Value <> '' then | ||||
|     s := s + ' ' + Value; | ||||
|   FSock.SendString(s + CRLF); | ||||
|   if (ReadResult div 100) <> 2 then | ||||
|     Exit; | ||||
|   Result := FSock.LastError = 0; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.SelectGroup(const Value: string): Boolean; | ||||
| begin | ||||
|   FSock.SendString('GROUP ' + Value + CRLF); | ||||
|   Result := (ReadResult div 100) = 2; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.IHave(const MessID: string): Boolean; | ||||
| var | ||||
|   x: integer; | ||||
| begin | ||||
|   FSock.SendString('IHAVE ' + MessID + CRLF); | ||||
|   x := (ReadResult div 100); | ||||
|   if x = 3 then | ||||
|   begin | ||||
|     SendData; | ||||
|     x := (ReadResult div 100); | ||||
|   end; | ||||
|   Result := x = 2; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.GotoLast: Boolean; | ||||
| begin | ||||
|   FSock.SendString('LAST' + CRLF); | ||||
|   Result := (ReadResult div 100) = 2; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.GotoNext: Boolean; | ||||
| begin | ||||
|   FSock.SendString('NEXT' + CRLF); | ||||
|   Result := (ReadResult div 100) = 2; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.ListGroups: Boolean; | ||||
| begin | ||||
|   FSock.SendString('LIST' + CRLF); | ||||
|   Result := (ReadResult div 100) = 2; | ||||
|   if Result then | ||||
|     Result := ReadData; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.ListNewGroups(Since: TDateTime): Boolean; | ||||
| begin | ||||
|   FSock.SendString('NEWGROUPS ' + SimpleDateTime(Since) + ' GMT' + CRLF); | ||||
|   Result := (ReadResult div 100) = 2; | ||||
|   if Result then | ||||
|     Result := ReadData; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.NewArticles(const Group: string; Since: TDateTime): Boolean; | ||||
| begin | ||||
|   FSock.SendString('NEWNEWS ' + Group + ' ' + SimpleDateTime(Since) + ' GMT' + CRLF); | ||||
|   Result := (ReadResult div 100) = 2; | ||||
|   if Result then | ||||
|     Result := ReadData; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.PostArticle: Boolean; | ||||
| var | ||||
|   x: integer; | ||||
| begin | ||||
|   FSock.SendString('POST' + CRLF); | ||||
|   x := (ReadResult div 100); | ||||
|   if x = 3 then | ||||
|   begin | ||||
|     SendData; | ||||
|     x := (ReadResult div 100); | ||||
|   end; | ||||
|   Result := x = 2; | ||||
| end; | ||||
|  | ||||
| function TNNTPSend.SwitchToSlave: Boolean; | ||||
| begin | ||||
|   FSock.SendString('SLAVE' + CRLF); | ||||
|   Result := (ReadResult div 100) = 2; | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| end. | ||||
| @@ -1,7 +1,7 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 001.003.004 | | ||||
| |==============================================================================| | ||||
| | Content: support for ASN.1 coding and decoding                               | | ||||
| | Content: support for ASN.1 BER coding and decoding                           | | ||||
| |==============================================================================| | ||||
| | The contents of this file are subject to the Mozilla Public License Ver. 1.1 | | ||||
| | (the "License"); you may not use this file except in compliance with the     | | ||||
|   | ||||
							
								
								
									
										200
									
								
								blcksock.pas
									
									
									
									
									
								
							
							
						
						
									
										200
									
								
								blcksock.pas
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 004.000.000 | | ||||
| | Project : Delphree - Synapse                                   | 004.004.000 | | ||||
| |==============================================================================| | ||||
| | Content: Library base                                                        | | ||||
| |==============================================================================| | ||||
| @@ -23,6 +23,7 @@ | ||||
| |          (Found at URL: http://www.ararat.cz/synapse/)                       | | ||||
| |==============================================================================} | ||||
|  | ||||
| {$Q-} | ||||
| {$WEAKPACKAGEUNIT ON} | ||||
|  | ||||
| unit blcksock; | ||||
| @@ -76,10 +77,15 @@ type | ||||
|     FLastError: Integer; | ||||
|     FBuffer: string; | ||||
|     FRaiseExcept: Boolean; | ||||
|     FNonBlockMode: Boolean; | ||||
|     FMaxLineLength: Integer; | ||||
|     FMaxBandwidth: Integer; | ||||
|     FNextSend: Cardinal; | ||||
|     function GetSizeRecvBuffer: Integer; | ||||
|     procedure SetSizeRecvBuffer(Size: Integer); | ||||
|     function GetSizeSendBuffer: Integer; | ||||
|     procedure SetSizeSendBuffer(Size: Integer); | ||||
|     procedure SetNonBlockMode(Value: Boolean); | ||||
|   protected | ||||
|     FSocket: TSocket; | ||||
|     FProtocol: Integer; | ||||
| @@ -88,6 +94,7 @@ type | ||||
|     function GetSinIP(Sin: TSockAddrIn): string; | ||||
|     function GetSinPort(Sin: TSockAddrIn): Integer; | ||||
|     procedure DoStatus(Reason: THookSocketReason; const Value: string); | ||||
|     procedure LimitBandwidth(Length: Integer); | ||||
|   public | ||||
|     constructor Create; | ||||
|     constructor CreateAlternate(Stub: string); | ||||
| @@ -103,6 +110,7 @@ type | ||||
|       Timeout: Integer): Integer; virtual; | ||||
|     function RecvByte(Timeout: Integer): Byte; virtual; | ||||
|     function RecvString(Timeout: Integer): string; virtual; | ||||
|     function RecvTerminated(Timeout: Integer; const Terminator: string): string; virtual; | ||||
|     function RecvPacket(Timeout: Integer): string; virtual; | ||||
|     function PeekBuffer(Buffer: Pointer; Length: Integer): Integer; virtual; | ||||
|     function PeekByte(Timeout: Integer): Byte; virtual; | ||||
| @@ -126,6 +134,7 @@ type | ||||
|     function RecvBufferFrom(Buffer: Pointer; Length: Integer): Integer; virtual; | ||||
|     function GroupCanRead(const SocketList: TList; Timeout: Integer; | ||||
|       const CanReadList: TList): Boolean; | ||||
|     function EnableReuse(Value: Boolean): Boolean; | ||||
|  | ||||
|     //See 'winsock2.txt' file in distribute package! | ||||
|     function SetTimeout(Timeout: Integer): Boolean; | ||||
| @@ -145,6 +154,9 @@ type | ||||
|     property SizeSendBuffer: Integer read GetSizeSendBuffer write SetSizeSendBuffer; | ||||
|     property WSAData: TWSADATA read FWsaData; | ||||
|     property OnStatus: THookSocketStatus read FOnStatus write FOnStatus; | ||||
|     property NonBlockMode: Boolean read FNonBlockMode Write SetNonBlockMode; | ||||
|     property MaxLineLength: Integer read FMaxLineLength Write FMaxLineLength; | ||||
|     property MaxBandwidth: Integer read FMaxBandwidth Write FMaxBandwidth; | ||||
|   end; | ||||
|  | ||||
|   TSocksBlockSocket = class(TBlockSocket) | ||||
| @@ -206,6 +218,8 @@ type | ||||
|     function RecvBuffer(Buffer: Pointer; Length: Integer): Integer; override; | ||||
|     function SendBufferTo(Buffer: Pointer; Length: Integer): Integer; override; | ||||
|     function RecvBufferFrom(Buffer: Pointer; Length: Integer): Integer; override; | ||||
|     procedure AddMulticast(MCastIP:string); | ||||
|     procedure DropMulticast(MCastIP:string); | ||||
|   end; | ||||
|  | ||||
|   //See 'winsock2.txt' file in distribute package! | ||||
| @@ -236,6 +250,12 @@ type | ||||
|  | ||||
| implementation | ||||
|  | ||||
| type | ||||
|   TMulticast = record | ||||
|     MCastAddr : u_long; | ||||
|     MCastIfc : u_long; | ||||
|   end; | ||||
|  | ||||
| constructor TBlockSocket.Create; | ||||
| var | ||||
|   e: ESynapseError; | ||||
| @@ -245,6 +265,10 @@ begin | ||||
|   FSocket := INVALID_SOCKET; | ||||
|   FProtocol := IPPROTO_IP; | ||||
|   FBuffer := ''; | ||||
|   FNonBlockMode := False; | ||||
|   FMaxLineLength := 0; | ||||
|   FMaxBandwidth := 0; | ||||
|   FNextSend := 0; | ||||
|   if not InitSocketInterface('') then | ||||
|   begin | ||||
|     e := ESynapseError.Create('Error loading Winsock DLL!'); | ||||
| @@ -345,6 +369,7 @@ end; | ||||
|  | ||||
| procedure TBlockSocket.CloseSocket; | ||||
| begin | ||||
|   synsock.Shutdown(FSocket, 2); | ||||
|   synsock.CloseSocket(FSocket); | ||||
|   DoStatus(HR_SocketClose, ''); | ||||
| end; | ||||
| @@ -385,8 +410,22 @@ begin | ||||
|   synsock.GetPeerName(FSocket, FremoteSin, Len); | ||||
| end; | ||||
|  | ||||
| procedure TBlockSocket.LimitBandwidth(Length: Integer); | ||||
| var | ||||
|   x: Cardinal; | ||||
| begin | ||||
|   if FMaxBandwidth > 0 then | ||||
|   begin | ||||
|     x := FNextSend - GetTick; | ||||
|     if x > 0 then | ||||
|       Sleep(x); | ||||
|     FNextSend := GetTick + Trunc((FMaxBandwidth / 1000) * Length); | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| function TBlockSocket.SendBuffer(Buffer: Pointer; Length: Integer): Integer; | ||||
| begin | ||||
|   LimitBandwidth(Length); | ||||
|   Result := synsock.Send(FSocket, Buffer^, Length, 0); | ||||
|   SockCheck(Result); | ||||
|   ExceptCheck; | ||||
| @@ -454,14 +493,9 @@ begin | ||||
|         if (system.Length(ss) + l) > fs then | ||||
|           l := fs - system.Length(ss); | ||||
|         SetLength(st, l); | ||||
|         x := synsock.Recv(FSocket, Pointer(st)^, l, 0); | ||||
|         if x = 0 then | ||||
|           FLastError := WSAECONNRESET | ||||
|         else | ||||
|           SockCheck(x); | ||||
|         x := RecvBuffer(Pointer(st), l); | ||||
|         if FLastError <> 0 then | ||||
|           Break; | ||||
|         DoStatus(HR_ReadCount, IntToStr(x)); | ||||
|         lss := system.Length(ss); | ||||
|         SetLength(ss, lss + x); | ||||
|         Move(Pointer(st)^, Pointer(@ss[lss + 1])^, x); | ||||
| @@ -515,47 +549,44 @@ end; | ||||
|  | ||||
| function TBlockSocket.RecvByte(Timeout: Integer): Byte; | ||||
| var | ||||
|   y: Integer; | ||||
|   Data: Byte; | ||||
|   s: String; | ||||
| begin | ||||
|   Data := 0; | ||||
|   Result := 0; | ||||
|   if CanRead(Timeout) then | ||||
|   begin | ||||
|     y := synsock.Recv(FSocket, Data, 1, 0); | ||||
|     if y = 0 then | ||||
|       FLastError := WSAECONNRESET | ||||
|     else | ||||
|       SockCheck(y); | ||||
|     Result := Data; | ||||
|     DoStatus(HR_ReadCount, '1'); | ||||
|     SetLength(s, 1); | ||||
|     RecvBuffer(Pointer(s), 1); | ||||
|     if s <> '' then | ||||
|       Result := Ord(s[1]); | ||||
|   end | ||||
|   else | ||||
|     FLastError := WSAETIMEDOUT; | ||||
|   ExceptCheck; | ||||
| end; | ||||
|  | ||||
| function TBlockSocket.RecvString(Timeout: Integer): string; | ||||
| function TBlockSocket.RecvTerminated(Timeout: Integer; const Terminator: string): string; | ||||
| const | ||||
|   MaxBuf = 1024; | ||||
|   MaxSize = 1024; | ||||
| var | ||||
|   x: Integer; | ||||
|   s: string; | ||||
|   c: Char; | ||||
|   r: Integer; | ||||
|   r,l: Integer; | ||||
| begin | ||||
|   s := ''; | ||||
|   l := Length(Terminator); | ||||
|   Result := ''; | ||||
|   if l = 0 then | ||||
|     Exit; | ||||
|   FLastError := 0; | ||||
|   c := #0; | ||||
|   repeat | ||||
|     x := 0; | ||||
|     if FBuffer = '' then | ||||
|     begin | ||||
|       x := WaitingData; | ||||
|       if x = 0 then | ||||
|         x := 1; | ||||
|       if x > MaxBuf then | ||||
|         x := MaxBuf; | ||||
|       if x = 1 then | ||||
|       if x > MaxSize then | ||||
|         x := MaxSize; | ||||
|       if x <= 1 then | ||||
|       begin | ||||
|         c := Char(RecvByte(Timeout)); | ||||
|         if FLastError <> 0 then | ||||
| @@ -565,42 +596,44 @@ begin | ||||
|       else | ||||
|       begin | ||||
|         SetLength(FBuffer, x); | ||||
|         r := synsock.Recv(FSocket, Pointer(FBuffer)^, x, 0); | ||||
|         SockCheck(r); | ||||
|         if r = 0 then | ||||
|           FLastError := WSAECONNRESET; | ||||
|         r := RecvBuffer(Pointer(FBuffer), x); | ||||
|         if FLastError <> 0 then | ||||
|           Break; | ||||
|         DoStatus(HR_ReadCount, IntToStr(r)); | ||||
|         if r < x then | ||||
|           SetLength(FBuffer, r); | ||||
|       end; | ||||
|     end; | ||||
|     x := Pos(#10, FBuffer); | ||||
|     if x < 1 then x := Length(FBuffer); | ||||
|     s := s + Copy(FBuffer, 1, x - 1); | ||||
|     c := FBuffer[x]; | ||||
|     Delete(FBuffer, 1, x); | ||||
|     s := s + c; | ||||
|   until c = #10; | ||||
|  | ||||
|   if FLastError = 0 then | ||||
|   begin | ||||
| {$IFDEF LINUX} | ||||
|     s := AdjustLineBreaks(s, tlbsCRLF); | ||||
| {$ELSE} | ||||
|     s := AdjustLineBreaks(s); | ||||
| {$ENDIF} | ||||
|     x := Pos(#13 + #10, s); | ||||
|     s := s + FBuffer; | ||||
|     FBuffer := ''; | ||||
|     x := Pos(Terminator, s); | ||||
|     if x > 0 then | ||||
|     begin | ||||
|       FBuffer := Copy(s, x + l, Length(s) - x - l + 1); | ||||
|       s := Copy(s, 1, x - 1); | ||||
|     Result := s; | ||||
|   end | ||||
|     end; | ||||
|     if (FMaxLineLength <> 0) and (Length(s) > FMaxLineLength) then | ||||
|     begin | ||||
|       FLastError := WSAENOBUFS; | ||||
|       Break; | ||||
|     end; | ||||
|   until x > 0; | ||||
|   if FLastError = 0 then | ||||
|     Result := s | ||||
|   else | ||||
|     Result := ''; | ||||
|   ExceptCheck; | ||||
| end; | ||||
|  | ||||
| function TBlockSocket.RecvString(Timeout: Integer): string; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   Result := ''; | ||||
|   s := RecvTerminated(Timeout, #13 + #10); | ||||
|   if FLastError = 0 then | ||||
|     Result := s; | ||||
| end; | ||||
|  | ||||
| function TBlockSocket.PeekBuffer(Buffer: Pointer; Length: Integer): Integer; | ||||
| begin | ||||
|   Result := synsock.Recv(FSocket, Buffer^, Length, MSG_PEEK); | ||||
| @@ -610,18 +643,15 @@ end; | ||||
|  | ||||
| function TBlockSocket.PeekByte(Timeout: Integer): Byte; | ||||
| var | ||||
|   y: Integer; | ||||
|   Data: Byte; | ||||
|   s: string; | ||||
| begin | ||||
|   Data := 0; | ||||
|   Result := 0; | ||||
|   if CanRead(Timeout) then | ||||
|   begin | ||||
|     y := synsock.Recv(FSocket, Data, 1, MSG_PEEK); | ||||
|     if y = 0 then | ||||
|       FLastError := WSAECONNRESET; | ||||
|     SockCheck(y); | ||||
|     Result := Data; | ||||
|     SetLength(s, 1); | ||||
|     PeekBuffer(Pointer(s), 1); | ||||
|     if s <> '' then | ||||
|       Result := Ord(s[1]); | ||||
|   end | ||||
|   else | ||||
|     FLastError := WSAETIMEDOUT; | ||||
| @@ -642,7 +672,8 @@ var | ||||
|   e: ESynapseError; | ||||
|   s: string; | ||||
| begin | ||||
|   if FRaiseExcept and (LastError <> 0) then | ||||
|   if FRaiseExcept and (LastError <> 0) and (LastError <> WSAEINPROGRESS) | ||||
|     and (LastError <> WSAEWOULDBLOCK) then | ||||
|   begin | ||||
|     s := GetErrorDesc(LastError); | ||||
|     e := ESynapseError.CreateFmt('TCP/IP Socket error %d: %s', [LastError, s]); | ||||
| @@ -833,10 +864,12 @@ function TBlockSocket.SendBufferTo(Buffer: Pointer; Length: Integer): Integer; | ||||
| var | ||||
|   Len: Integer; | ||||
| begin | ||||
|   LimitBandwidth(Length); | ||||
|   Len := SizeOf(FRemoteSin); | ||||
|   Result := synsock.SendTo(FSocket, Buffer^, Length, 0, FRemoteSin, Len); | ||||
|   SockCheck(Result); | ||||
|   ExceptCheck; | ||||
|   DoStatus(HR_WriteCount, IntToStr(Result)); | ||||
| end; | ||||
|  | ||||
| function TBlockSocket.RecvBufferFrom(Buffer: Pointer; Length: Integer): Integer; | ||||
| @@ -847,6 +880,7 @@ begin | ||||
|   Result := synsock.RecvFrom(FSocket, Buffer^, Length, 0, FRemoteSin, Len); | ||||
|   SockCheck(Result); | ||||
|   ExceptCheck; | ||||
|   DoStatus(HR_ReadCount, IntToStr(Result)); | ||||
| end; | ||||
|  | ||||
| function TBlockSocket.GetSizeRecvBuffer: Integer; | ||||
| @@ -883,6 +917,18 @@ begin | ||||
|   ExceptCheck; | ||||
| end; | ||||
|  | ||||
| procedure TBlockSocket.SetNonBlockMode(Value: Boolean); | ||||
| var | ||||
|   x: integer; | ||||
| begin | ||||
|   FNonBlockMode := Value; | ||||
|   if Value then | ||||
|     x := 1 | ||||
|   else | ||||
|     x := 0; | ||||
|   synsock.IoctlSocket(FSocket, FIONBIO, u_long(x)); | ||||
| end; | ||||
|  | ||||
| //See 'winsock2.txt' file in distribute package! | ||||
| function TBlockSocket.SetTimeout(Timeout: Integer): Boolean; | ||||
| begin | ||||
| @@ -940,6 +986,18 @@ begin | ||||
|           CanReadList.Add(TBlockSocket(SocketList.Items[n])); | ||||
| end; | ||||
|  | ||||
| function TBlockSocket.EnableReuse(Value: Boolean): Boolean; | ||||
| var | ||||
|   Opt: Integer; | ||||
|   Res: Integer; | ||||
| begin | ||||
|   opt := Ord(Value); | ||||
|   Res := synsock.SetSockOpt(FSocket, SOL_SOCKET, SO_REUSEADDR, @Opt, SizeOf(opt)); | ||||
|   SockCheck(Res); | ||||
|   Result := res = 0; | ||||
|   ExceptCheck; | ||||
| end; | ||||
|  | ||||
| procedure TBlockSocket.DoStatus(Reason: THookSocketReason; const Value: string); | ||||
| begin | ||||
|   if assigned(OnStatus) then | ||||
| @@ -1044,7 +1102,7 @@ begin | ||||
|     WSANOTINITIALISED: {10093} | ||||
|       Result := 'Winsock not initialized'; | ||||
|     WSAEDISCON: {10101} | ||||
|       Result := 'WSAEDISCON-10101'; | ||||
|       Result := 'Disconnect'; | ||||
|     WSAHOST_NOT_FOUND: {11001} | ||||
|       Result := 'Host not found'; | ||||
|     WSATRY_AGAIN: {11002} | ||||
| @@ -1325,6 +1383,28 @@ begin | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| procedure TUDPBlockSocket.AddMulticast(MCastIP: string); | ||||
| var | ||||
|   Multicast: TMulticast; | ||||
| begin | ||||
|   Multicast.MCastAddr := synsock.inet_addr(PChar(MCastIP)); | ||||
|   Multicast.MCastIfc := u_long(INADDR_ANY); | ||||
|   SockCheck(synsock.SetSockOpt(FSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, | ||||
|     pchar(@Multicast), SizeOf(Multicast))); | ||||
|   ExceptCheck; | ||||
| end; | ||||
|  | ||||
| procedure TUDPBlockSocket.DropMulticast(MCastIP: string); | ||||
| var | ||||
|   Multicast: TMulticast; | ||||
| begin | ||||
|   Multicast.MCastAddr := synsock.inet_addr(PChar(MCastIP)); | ||||
|   Multicast.MCastIfc := u_long(INADDR_ANY); | ||||
|   SockCheck(synsock.SetSockOpt(FSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, | ||||
|     pchar(@Multicast), SizeOf(Multicast))); | ||||
|   ExceptCheck; | ||||
| end; | ||||
|  | ||||
| {======================================================================} | ||||
|  | ||||
| procedure TTCPBlockSocket.CreateSocket; | ||||
| @@ -1356,7 +1436,7 @@ begin | ||||
|     if Sip = '0.0.0.0' then | ||||
|       Sip := LocalName; | ||||
|     SPort := IntToStr(GetLocalSinPort); | ||||
|     Connect(FSocksIP, FSocksPort); | ||||
|     inherited Connect(FSocksIP, FSocksPort); | ||||
|     b := SocksOpen; | ||||
|     if b then | ||||
|       b := SocksRequest(2, Sip, SPort); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 001.000.002 | | ||||
| | Project : Delphree - Synapse                                   | 001.000.003 | | ||||
| |==============================================================================| | ||||
| | Content: Inline MIME support procedures and functions                        | | ||||
| |==============================================================================| | ||||
| @@ -72,7 +72,7 @@ begin | ||||
|   Result := Value; | ||||
|   x := Pos('=?', Result); | ||||
|   y := SearchEndInline(Result, x); | ||||
|   while y > x do | ||||
|   while (y > x) and (x > 0) do  //fix by Marcus Moennig (minibbjd@gmx.de) | ||||
|   begin | ||||
|     s := Copy(Result, x, y - x + 2); | ||||
|     su := Copy(s, 3, Length(s) - 4); | ||||
|   | ||||
							
								
								
									
										86
									
								
								mimemess.pas
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								mimemess.pas
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 001.005.000 | | ||||
| | Project : Delphree - Synapse                                   | 001.007.000 | | ||||
| |==============================================================================| | ||||
| | Content: MIME message object                                                 | | ||||
| |==============================================================================| | ||||
| @@ -38,21 +38,27 @@ type | ||||
|   private | ||||
|     FFrom: string; | ||||
|     FToList: TStringList; | ||||
|     FCCList: TStringList; | ||||
|     FSubject: string; | ||||
|     FOrganization: string; | ||||
|     FCustomHeaders: TStringList; | ||||
|     FDate: TDateTime; | ||||
|   public | ||||
|     constructor Create; | ||||
|     destructor Destroy; override; | ||||
|     procedure Clear; | ||||
|     procedure EncodeHeaders(Value: TStringList); | ||||
|     procedure DecodeHeaders(Value: TStringList); | ||||
|     procedure EncodeHeaders(const Value: TStringList); | ||||
|     procedure DecodeHeaders(const Value: TStringList); | ||||
|     function FindHeader(Value: string): string; | ||||
|     procedure FindHeaderList(Value: string; const HeaderList: TStringList); | ||||
|   published | ||||
|     property From: string read FFrom Write FFrom; | ||||
|     property ToList: TStringList read FToList; | ||||
|     property CCList: TStringList read FCCList; | ||||
|     property Subject: string read FSubject Write FSubject; | ||||
|     property Organization: string read FOrganization Write FOrganization; | ||||
|     property CustomHeaders: TStringList read FCustomHeaders; | ||||
|     property Date: TDateTime read FDate Write FDate; | ||||
|   end; | ||||
|  | ||||
|   TMimeMess = class(TObject) | ||||
| @@ -66,8 +72,8 @@ type | ||||
|     destructor Destroy; override; | ||||
|     procedure Clear; | ||||
|     function AddPart: Integer; | ||||
|     procedure AddPartText(Value: TStringList); | ||||
|     procedure AddPartHTML(Value: TStringList); | ||||
|     procedure AddPartText(const Value: TStringList); | ||||
|     procedure AddPartHTML(const Value: TStringList); | ||||
|     procedure AddPartHTMLBinary(Value, Cid: string); | ||||
|     procedure AddPartBinary(Value: string); | ||||
|     procedure EncodeMessage; | ||||
| @@ -89,12 +95,14 @@ constructor TMessHeader.Create; | ||||
| begin | ||||
|   inherited Create; | ||||
|   FToList := TStringList.Create; | ||||
|   FCCList := TStringList.Create; | ||||
|   FCustomHeaders := TStringList.Create; | ||||
| end; | ||||
|  | ||||
| destructor TMessHeader.Destroy; | ||||
| begin | ||||
|   FCustomHeaders.Free; | ||||
|   FCCList.Free; | ||||
|   FToList.Free; | ||||
|   inherited Destroy; | ||||
| end; | ||||
| @@ -105,23 +113,29 @@ procedure TMessHeader.Clear; | ||||
| begin | ||||
|   FFrom := ''; | ||||
|   FToList.Clear; | ||||
|   FCCList.Clear; | ||||
|   FSubject := ''; | ||||
|   FOrganization := ''; | ||||
|   FCustomHeaders.Clear; | ||||
|   FDate := 0; | ||||
| end; | ||||
|  | ||||
| procedure TMessHeader.EncodeHeaders(Value: TStringList); | ||||
| procedure TMessHeader.EncodeHeaders(const Value: TStringList); | ||||
| var | ||||
|   n: Integer; | ||||
| begin | ||||
|   if FDate = 0 then | ||||
|     FDate := Now; | ||||
|   for n := FCustomHeaders.Count - 1 downto 0 do | ||||
|     if FCustomHeaders[n] <> '' then | ||||
|       Value.Insert(0, FCustomHeaders[n]); | ||||
|   Value.Insert(0, 'x-mailer: Synapse - Delphi TCP/IP library by Lukas Gebauer'); | ||||
|   Value.Insert(0, 'x-mailer: Synapse - Delphi & Kylix TCP/IP library by Lukas Gebauer'); | ||||
|   Value.Insert(0, 'MIME-Version: 1.0 (produced by Synapse)'); | ||||
|   Value.Insert(0, 'date: ' + Rfc822DateTime(Now)); | ||||
|   if FOrganization <> '' then | ||||
|     Value.Insert(0, 'Organization: ' + InlineCode(FOrganization)); | ||||
|   for n := 0 to FCCList.Count - 1 do | ||||
|     Value.Insert(0, 'CC: ' + InlineEmail(FCCList[n])); | ||||
|   Value.Insert(0, 'Date: ' + Rfc822DateTime(FDate)); | ||||
|   if FSubject <> '' then | ||||
|     Value.Insert(0, 'Subject: ' + InlineCode(FSubject)); | ||||
|   for n := 0 to FToList.Count - 1 do | ||||
| @@ -129,9 +143,9 @@ begin | ||||
|   Value.Insert(0, 'From: ' + InlineEmail(FFrom)); | ||||
| end; | ||||
|  | ||||
| procedure TMessHeader.DecodeHeaders(Value: TStringList); | ||||
| procedure TMessHeader.DecodeHeaders(const Value: TStringList); | ||||
| var | ||||
|   s: string; | ||||
|   s, t: string; | ||||
|   x: Integer; | ||||
|   cp: TMimeChar; | ||||
| begin | ||||
| @@ -160,13 +174,58 @@ begin | ||||
|     end; | ||||
|     if Pos('TO:', UpperCase(s)) = 1 then | ||||
|     begin | ||||
|       FToList.Add(InlineDecode(SeparateRight(s, ':'), cp)); | ||||
|       s := SeparateRight(s, ':'); | ||||
|       repeat | ||||
|         t := InlineDecode(fetch(s, ','), cp); | ||||
|         if t <> '' then | ||||
|           FToList.Add(t); | ||||
|       until s = ''; | ||||
|       continue; | ||||
|     end; | ||||
|     if Pos('CC:', UpperCase(s)) = 1 then | ||||
|     begin | ||||
|       s := SeparateRight(s, ':'); | ||||
|       repeat | ||||
|         t := InlineDecode(fetch(s, ','), cp); | ||||
|         if t <> '' then | ||||
|           FCCList.Add(t); | ||||
|       until s = ''; | ||||
|       continue; | ||||
|     end; | ||||
|     if Pos('DATE:', UpperCase(s)) = 1 then | ||||
|     begin | ||||
|       FDate := DecodeRfcDateTime(SeparateRight(s, ':')); | ||||
|       continue; | ||||
|     end; | ||||
|     FCustomHeaders.Add(s); | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| function TMessHeader.FindHeader(Value: string): string; | ||||
| var | ||||
|   n: integer; | ||||
| begin | ||||
|   Result := ''; | ||||
|   for n := 0 to FCustomHeaders.Count - 1 do | ||||
|     if Pos(Value, FCustomHeaders[n]) = 1 then | ||||
|     begin | ||||
|       Result := SeparateRight(FCustomHeaders[n], ':'); | ||||
|       break; | ||||
|     end; | ||||
| end; | ||||
|  | ||||
| procedure TMessHeader.FindHeaderList(Value: string; const HeaderList: TStringList); | ||||
| var | ||||
|   n: integer; | ||||
| begin | ||||
|   HeaderList.Clear; | ||||
|   for n := 0 to FCustomHeaders.Count - 1 do | ||||
|     if Pos(Value, FCustomHeaders[n]) = 1 then | ||||
|     begin | ||||
|       HeaderList.Add(SeparateRight(FCustomHeaders[n], ':')); | ||||
|     end; | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| constructor TMimeMess.Create; | ||||
| @@ -180,6 +239,7 @@ end; | ||||
|  | ||||
| destructor TMimeMess.Destroy; | ||||
| begin | ||||
|   Clear; | ||||
|   FHeader.Free; | ||||
|   Lines.Free; | ||||
|   PartList.Free; | ||||
| @@ -209,7 +269,7 @@ end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| procedure TMimeMess.AddPartText(Value: TStringList); | ||||
| procedure TMimeMess.AddPartText(const Value: TStringList); | ||||
| begin | ||||
|   with TMimePart(FPartList[AddPart]) do | ||||
|   begin | ||||
| @@ -228,7 +288,7 @@ end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| procedure TMimeMess.AddPartHTML(Value: TStringList); | ||||
| procedure TMimeMess.AddPartHTML(const Value: TStringList); | ||||
| begin | ||||
|   with TMimePart(FPartList[AddPart]) do | ||||
|   begin | ||||
|   | ||||
							
								
								
									
										43
									
								
								mimepart.pas
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								mimepart.pas
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 001.005.002 | | ||||
| | Project : Delphree - Synapse                                   | 001.007.000 | | ||||
| |==============================================================================| | ||||
| | Content: MIME support procedures and functions                               | | ||||
| |==============================================================================| | ||||
| @@ -44,6 +44,7 @@ type | ||||
|     FPrimary: string; | ||||
|     FEncoding: string; | ||||
|     FCharset: string; | ||||
|     FDefaultCharset: string; | ||||
|     FPrimaryCode: TMimePrimary; | ||||
|     FEncodingCode: TMimeEncoding; | ||||
|     FCharsetCode: TMimeChar; | ||||
| @@ -71,6 +72,7 @@ type | ||||
|     property Primary: string read FPrimary write SetPrimary; | ||||
|     property Encoding: string read FEncoding write SetEncoding; | ||||
|     property Charset: string read FCharset write SetCharset; | ||||
|     property DefaultCharset: string read FDefaultCharset write FDefaultCharset; | ||||
|     property PrimaryCode: TMimePrimary read FPrimaryCode Write FPrimaryCode; | ||||
|     property EncodingCode: TMimeEncoding read FEncodingCode Write FEncodingCode; | ||||
|     property CharsetCode: TMimeChar read FCharsetCode Write FCharsetCode; | ||||
| @@ -157,6 +159,7 @@ begin | ||||
|   FLines := TStringList.Create; | ||||
|   FDecodedLines := TMemoryStream.Create; | ||||
|   FTargetCharset := GetCurCP; | ||||
|   FDefaultCharset := 'US-ASCII'; | ||||
| end; | ||||
|  | ||||
| destructor TMIMEPart.Destroy; | ||||
| @@ -205,7 +208,7 @@ begin | ||||
|     Primary := 'text'; | ||||
|     FSecondary := 'plain'; | ||||
|     FDescription := ''; | ||||
|     Charset := 'US-ASCII'; | ||||
|     Charset := FDefaultCharset; | ||||
|     FFileName := ''; | ||||
|     Encoding := '7BIT'; | ||||
|  | ||||
| @@ -337,10 +340,8 @@ begin | ||||
|         if Pos('--' + b, s) = 1 then | ||||
|         begin | ||||
|           s := TrimRight(s); | ||||
|           x := Length(s); | ||||
|           if x > 4 then | ||||
|             if (s[x] = '-') and (S[x-1] = '-') then | ||||
|               Result := Value.Count - 1; | ||||
|           if s = ('--' + b + '--') then | ||||
|             Result := Value.Count - 1; | ||||
|           Break; | ||||
|         end; | ||||
|       end; | ||||
| @@ -406,8 +407,10 @@ end; | ||||
| procedure TMIMEPart.EncodePart; | ||||
| var | ||||
|   l: TStringList; | ||||
|   s, buff: string; | ||||
|   s, t: string; | ||||
|   n, x: Integer; | ||||
| const | ||||
|   MaxLine = 75; | ||||
| begin | ||||
|   if (FEncodingCode = ME_UU) or (FEncodingCode = ME_XX) then | ||||
|     Encoding := 'base64'; | ||||
| @@ -423,11 +426,9 @@ begin | ||||
|         begin | ||||
|           while FDecodedLines.Position < FDecodedLines.Size do | ||||
|           begin | ||||
|             Setlength(Buff, 54); | ||||
|             s := ''; | ||||
|             x := FDecodedLines.Read(pointer(Buff)^, 54); | ||||
|             for n := 1 to x do | ||||
|               s := s + Buff[n]; | ||||
|             Setlength(s, 54); | ||||
|             x := FDecodedLines.Read(pointer(s)^, 54); | ||||
|             Setlength(s, x); | ||||
|             if FPrimaryCode = MP_TEXT then | ||||
|               s := CharsetConversion(s, FTargetCharset, FCharsetCode); | ||||
|             s := EncodeBase64(s); | ||||
| @@ -440,13 +441,23 @@ begin | ||||
|           for n := 0 to l.Count - 1 do | ||||
|           begin | ||||
|             s := l[n]; | ||||
|             if FPrimaryCode = MP_TEXT then | ||||
|             if (FPrimaryCode = MP_TEXT) and (FEncodingCode <> ME_7BIT) then | ||||
|               s := CharsetConversion(s, FTargetCharset, FCharsetCode); | ||||
|             s := EncodeQuotedPrintable(s); | ||||
|             FLines.Add(s); | ||||
|             if FEncodingCode = ME_QUOTED_PRINTABLE then | ||||
|             begin | ||||
|               s := EncodeQuotedPrintable(s); | ||||
|               repeat | ||||
|                 t := Copy(s, 1, MaxLine); | ||||
|                 s := Copy(s, MaxLine + 1, Length(s) - MaxLine); | ||||
|                 if s <> '' then | ||||
|                   t := t + '='; | ||||
|                 FLines.Add(t); | ||||
|               until s = ''; | ||||
|             end | ||||
|             else | ||||
|               FLines.Add(s); | ||||
|           end; | ||||
|         end; | ||||
|  | ||||
|     end; | ||||
|     FLines.Add(''); | ||||
|     FLines.Insert(0, ''); | ||||
|   | ||||
							
								
								
									
										22
									
								
								pingsend.pas
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								pingsend.pas
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 002.001.002 | | ||||
| | Project : Delphree - Synapse                                   | 002.002.000 | | ||||
| |==============================================================================| | ||||
| | Content: PING sender                                                         | | ||||
| |==============================================================================| | ||||
| @@ -69,7 +69,6 @@ type | ||||
|     FPacketSize: Integer; | ||||
|     FPingTime: Integer; | ||||
|     function Checksum: Integer; | ||||
|     function GetTick: Cardinal; | ||||
|     function ReadPacket: Boolean; | ||||
|   public | ||||
|     function Ping(const Host: string): Boolean; | ||||
| @@ -178,25 +177,6 @@ begin | ||||
|   Result := Word(not CkSum); | ||||
| end; | ||||
|  | ||||
| {$IFDEF LINUX} | ||||
|  | ||||
| function TPINGSend.GetTick: Cardinal; | ||||
| var | ||||
|   Stamp: TTimeStamp; | ||||
| begin | ||||
|   Stamp := DateTimeToTimeStamp(Now); | ||||
|   Result := Stamp.Time; | ||||
| end; | ||||
|  | ||||
| {$ELSE} | ||||
|  | ||||
| function TPINGSend.GetTick: Cardinal; | ||||
| begin | ||||
|   Result := Windows.GetTickCount; | ||||
| end; | ||||
|  | ||||
| {$ENDIF} | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function PingHost(const Host: string): Integer; | ||||
|   | ||||
							
								
								
									
										11
									
								
								pop3send.pas
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								pop3send.pas
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 001.001.002 | | ||||
| | Project : Delphree - Synapse                                   | 001.002.000 | | ||||
| |==============================================================================| | ||||
| | Content: POP3 client                                                         | | ||||
| |==============================================================================| | ||||
| @@ -185,7 +185,16 @@ begin | ||||
|   end; | ||||
|   Result := False; | ||||
|   if (FTimeStamp <> '') and not (FAuthType = POP3AuthLogin) then | ||||
|   begin | ||||
|     Result := AuthApop; | ||||
|     if not Result then | ||||
|     begin | ||||
|       if not Connect then | ||||
|         Exit; | ||||
|       if ReadResult(False) <> 1 then | ||||
|         Exit; | ||||
|     end; | ||||
|   end; | ||||
|   if not Result and not (FAuthType = POP3AuthAPOP) then | ||||
|     Result := AuthLogin; | ||||
| end; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 001.000.000 | | ||||
| | Project : Delphree - Synapse                                   | 001.000.001 | | ||||
| |==============================================================================| | ||||
| | Content: SysLog client                                                       | | ||||
| |==============================================================================| | ||||
| @@ -137,6 +137,8 @@ begin | ||||
|   Buf := Buf + Tag + ': ' + FMessage; | ||||
|   if Length(Buf) <= 1024 then | ||||
|   begin | ||||
|     if FSock.EnableReuse(True) then | ||||
|       Fsock.Bind('0.0.0.0', FSyslogPort); | ||||
|     FSock.Connect(FSyslogHost, FSyslogPort); | ||||
|     FSock.SendString(Buf); | ||||
|     Result := FSock.LastError = 0; | ||||
|   | ||||
							
								
								
									
										98
									
								
								snmpsend.pas
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								snmpsend.pas
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 002.003.005 | | ||||
| | Project : Delphree - Synapse                                   | 002.003.006 | | ||||
| |==============================================================================| | ||||
| | Content: SNMP client                                                         | | ||||
| |==============================================================================| | ||||
| @@ -18,7 +18,7 @@ | ||||
| | All Rights Reserved.                                                         | | ||||
| |==============================================================================| | ||||
| | Contributor(s):                                                              | | ||||
| |   Jean-Fabien Connault (jfconnault@mail.dotcom.fr)                           | | ||||
| |   Jean-Fabien Connault (cycocrew@worldnet.fr)                                | | ||||
| |==============================================================================| | ||||
| | History: see HISTORY.HTM from distribution package                           | | ||||
| |          (Found at URL: http://www.ararat.cz/synapse/)                       | | ||||
| @@ -38,14 +38,14 @@ uses | ||||
| const | ||||
|   cSnmpProtocol = '161'; | ||||
|  | ||||
| //PDU type | ||||
|   //PDU type | ||||
|   PDUGetRequest = $A0; | ||||
|   PDUGetNextRequest = $A1; | ||||
|   PDUGetResponse = $A2; | ||||
|   PDUSetRequest = $A3; | ||||
|   PDUTrap = $A4; | ||||
|  | ||||
| //errors | ||||
|   //errors | ||||
|   ENoError = 0; | ||||
|   ETooBig = 1; | ||||
|   ENoSuchName = 2; | ||||
| @@ -60,9 +60,9 @@ type | ||||
|     FValue: string; | ||||
|     FValueType: Integer; | ||||
|   published | ||||
|     property OID: string read FOID Write FOID; | ||||
|     property Value: string read FValue Write FValue; | ||||
|     property ValueType: Integer read FValueType Write FValueType; | ||||
|     property OID: string read FOID write FOID; | ||||
|     property Value: string read FValue write FValue; | ||||
|     property ValueType: Integer read FValueType write FValueType; | ||||
|   end; | ||||
|  | ||||
|   TSNMPRec = class(TObject) | ||||
| @@ -84,12 +84,12 @@ type | ||||
|     procedure MIBDelete(Index: Integer); | ||||
|     function MIBGet(const MIB: string): string; | ||||
|   published | ||||
|     property Version: Integer read FVersion Write FVersion; | ||||
|     property Community: string read FCommunity Write FCommunity; | ||||
|     property PDUType: Integer read FPDUType Write FPDUType; | ||||
|     property ID: Integer read FID Write FID; | ||||
|     property ErrorStatus: Integer read FErrorStatus Write FErrorStatus; | ||||
|     property ErrorIndex: Integer read FErrorIndex Write FErrorIndex; | ||||
|     property Version: Integer read FVersion write FVersion; | ||||
|     property Community: string read FCommunity write FCommunity; | ||||
|     property PDUType: Integer read FPDUType write FPDUType; | ||||
|     property ID: Integer read FID write FID; | ||||
|     property ErrorStatus: Integer read FErrorStatus write FErrorStatus; | ||||
|     property ErrorIndex: Integer read FErrorIndex write FErrorIndex; | ||||
|     property SNMPMibList: TList read FSNMPMibList; | ||||
|   end; | ||||
|  | ||||
| @@ -107,18 +107,16 @@ type | ||||
|     destructor Destroy; override; | ||||
|     function DoIt: Boolean; | ||||
|   published | ||||
|     property Timeout: Integer read FTimeout Write FTimeout; | ||||
|     property Host: string read FHost Write FHost; | ||||
|     property Timeout: Integer read FTimeout write FTimeout; | ||||
|     property Host: string read FHost write FHost; | ||||
|     property HostIP: string read FHostIP; | ||||
|     property Query: TSNMPRec read FQuery; | ||||
|     property Reply: TSNMPRec read FReply; | ||||
|     property Sock: TUDPBlockSocket read FSock; | ||||
|   end; | ||||
|  | ||||
| function SNMPGet(const Oid, Community, SNMPHost: string; | ||||
|   var Value: string): Boolean; | ||||
| function SNMPSet(const Oid, Community, SNMPHost, Value: string; | ||||
|   ValueType: Integer): Boolean; | ||||
| function SNMPGet(const OID, Community, SNMPHost: string; var Value: string): Boolean; | ||||
| function SNMPSet(const OID, Community, SNMPHost, Value: string; ValueType: Integer): Boolean; | ||||
|  | ||||
| implementation | ||||
|  | ||||
| @@ -128,7 +126,7 @@ constructor TSNMPRec.Create; | ||||
| begin | ||||
|   inherited Create; | ||||
|   FSNMPMibList := TList.Create; | ||||
|   id := 1; | ||||
|   FID := 1; | ||||
| end; | ||||
|  | ||||
| destructor TSNMPRec.Destroy; | ||||
| @@ -137,6 +135,7 @@ var | ||||
| begin | ||||
|   for i := 0 to FSNMPMibList.Count - 1 do | ||||
|     TSNMPMib(FSNMPMibList[i]).Free; | ||||
|   FSNMPMibList.Clear; | ||||
|   FSNMPMibList.Free; | ||||
|   inherited Destroy; | ||||
| end; | ||||
| @@ -292,12 +291,9 @@ begin | ||||
| end; | ||||
|  | ||||
| function TSNMPSend.DoIt: Boolean; | ||||
| var | ||||
|   x: Integer; | ||||
| begin | ||||
|   Result := False; | ||||
|   FReply.Clear; | ||||
|   FBuffer := Query.EncodeBuf; | ||||
|   FBuffer := FQuery.EncodeBuf; | ||||
|   FSock.Connect(FHost, cSnmpProtocol); | ||||
|   FHostIP := '0.0.0.0'; | ||||
|   FSock.SendString(FBuffer); | ||||
| @@ -305,43 +301,45 @@ begin | ||||
|   if FSock.LastError = 0 then | ||||
|   begin | ||||
|     FHostIP := FSock.GetRemoteSinIP; | ||||
|     Result := True; | ||||
|   end; | ||||
|   if Result then | ||||
|     Result := FReply.DecodeBuf(FBuffer); | ||||
|   end | ||||
|   else | ||||
|     Result := False; | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function SNMPGet(const Oid, Community, SNMPHost: string; | ||||
|   var Value: string): Boolean; | ||||
| var | ||||
|   SNMP: TSNMPSend; | ||||
| begin | ||||
|   SNMP := TSNMPSend.Create; | ||||
|   try | ||||
|     SNMP.Query.Community := Community; | ||||
|     SNMP.Query.PDUType := PDUGetRequest; | ||||
|     SNMP.Query.MIBAdd(Oid, '', ASN1_NULL); | ||||
|     SNMP.Host := SNMPHost; | ||||
|     Result := SNMP.DoIt; | ||||
|     if Result then | ||||
|       Value := SNMP.Reply.MIBGet(Oid); | ||||
|   finally | ||||
|     SNMP.Free; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| function SNMPSet(const Oid, Community, SNMPHost, Value: string; | ||||
|   ValueType: Integer): Boolean; | ||||
| function SNMPGet(const OID, Community, SNMPHost: string; var Value: string): Boolean; | ||||
| var | ||||
|   SNMPSend: TSNMPSend; | ||||
| begin | ||||
|   SNMPSend := TSNMPSend.Create; | ||||
|   try | ||||
|     SNMPSend.Query.Clear; | ||||
|     SNMPSend.Query.Community := Community; | ||||
|     SNMPSend.Query.PDUType := PDUGetRequest; | ||||
|     SNMPSend.Query.MIBAdd(OID, '', ASN1_NULL); | ||||
|     SNMPSend.Host := SNMPHost; | ||||
|     Result := SNMPSend.DoIt; | ||||
|     if Result then | ||||
|       Value := SNMPSend.Reply.MIBGet(OID) | ||||
|     else | ||||
|       Value := ''; | ||||
|   finally | ||||
|     SNMPSend.Free; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| function SNMPSet(const OID, Community, SNMPHost, Value: string; ValueType: Integer): Boolean; | ||||
| var | ||||
|   SNMPSend: TSNMPSend; | ||||
| begin | ||||
|   SNMPSend := TSNMPSend.Create; | ||||
|   try | ||||
|     SNMPSend.Query.Clear; | ||||
|     SNMPSend.Query.Community := Community; | ||||
|     SNMPSend.Query.PDUType := PDUSetRequest; | ||||
|     SNMPSend.Query.MIBAdd(Oid, Value, ValueType); | ||||
|     SNMPSend.Query.MIBAdd(OID, Value, ValueType); | ||||
|     SNMPSend.Host := SNMPHost; | ||||
|     Result := SNMPSend.DoIt = True; | ||||
|   finally | ||||
| @@ -350,3 +348,5 @@ begin | ||||
| end; | ||||
|  | ||||
| end. | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										113
									
								
								sntpsend.pas
									
									
									
									
									
								
							
							
						
						
									
										113
									
								
								sntpsend.pas
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 002.000.002 | | ||||
| | Project : Delphree - Synapse                                   | 002.001.000 | | ||||
| |==============================================================================| | ||||
| | Content: SNTP client                                                         | | ||||
| |==============================================================================| | ||||
| @@ -18,6 +18,7 @@ | ||||
| | All Rights Reserved.                                                         | | ||||
| |==============================================================================| | ||||
| | Contributor(s):                                                              | | ||||
| |   Patrick Chevalley                                                          | | ||||
| |==============================================================================| | ||||
| | History: see HISTORY.HTM from distribution package                           | | ||||
| |          (Found at URL: http://www.ararat.cz/synapse/)                       | | ||||
| @@ -32,7 +33,7 @@ interface | ||||
|  | ||||
| uses | ||||
|   SysUtils, | ||||
|   synsock, blcksock; | ||||
|   synsock, blcksock, SynaUtil; | ||||
|  | ||||
| const | ||||
|   cNtpProtocol = 'ntp'; | ||||
| @@ -61,19 +62,30 @@ type | ||||
|   private | ||||
|     FNTPReply: TNtp; | ||||
|     FNTPTime: TDateTime; | ||||
|     FNTPOffset: double; | ||||
|     FNTPDelay: double; | ||||
|     FMaxSyncDiff: double; | ||||
|     FSyncTime: Boolean; | ||||
|     FSntpHost: string; | ||||
|     FTimeout: Integer; | ||||
|     FSock: TUDPBlockSocket; | ||||
|     FBuffer: string; | ||||
|     FLi, FVn, Fmode : byte; | ||||
|   public | ||||
|     constructor Create; | ||||
|     destructor Destroy; override; | ||||
|     function DecodeTs(Nsec, Nfrac: Longint): TDateTime; | ||||
|     procedure EncodeTs(dt: TDateTime; var Nsec, Nfrac: Longint); | ||||
|     function GetSNTP: Boolean; | ||||
|     function GetNTP: Boolean; | ||||
|     function GetBroadcastNTP: Boolean; | ||||
|   published | ||||
|     property NTPReply: TNtp read FNTPReply; | ||||
|     property NTPTime: TDateTime read FNTPTime; | ||||
|     property NTPOffset: Double read FNTPOffset; | ||||
|     property NTPDelay: Double read FNTPDelay; | ||||
|     property MaxSyncDiff: double read FMaxSyncDiff write FMaxSyncDiff; | ||||
|     property SyncTime: Boolean read FSyncTime write FSyncTime; | ||||
|     property SntpHost: string read FSntpHost write FSntpHost; | ||||
|     property Timeout: Integer read FTimeout write FTimeout; | ||||
|     property Sock: TUDPBlockSocket read FSock; | ||||
| @@ -88,6 +100,8 @@ begin | ||||
|   FSock.CreateSocket; | ||||
|   FTimeout := 5000; | ||||
|   FSntpHost := cLocalhost; | ||||
|   FMaxSyncDiff := 3600; | ||||
|   FSyncTime := False; | ||||
| end; | ||||
|  | ||||
| destructor TSNTPSend.Destroy; | ||||
| @@ -98,7 +112,7 @@ end; | ||||
|  | ||||
| function TSNTPSend.DecodeTs(Nsec, Nfrac: Longint): TDateTime; | ||||
| const | ||||
|   maxi = 4294967296.0; | ||||
|   maxi = 4294967295.0; | ||||
| var | ||||
|   d, d1: Double; | ||||
| begin | ||||
| @@ -106,16 +120,38 @@ begin | ||||
|   Nfrac := synsock.htonl(Nfrac); | ||||
|   d := Nsec; | ||||
|   if d < 0 then | ||||
|     d := maxi + d - 1; | ||||
|     d := maxi + d + 1; | ||||
|   d1 := Nfrac; | ||||
|   if d1 < 0 then | ||||
|     d1 := maxi + d1 - 1; | ||||
|     d1 := maxi + d1 + 1; | ||||
|   d1 := d1 / maxi; | ||||
|   d1 := Trunc(d1 * 1000) / 1000; | ||||
|   d1 := Trunc(d1 * 10000) / 10000; | ||||
|   Result := (d + d1) / 86400; | ||||
|   Result := Result + 2; | ||||
| end; | ||||
|  | ||||
| procedure TSNTPSend.EncodeTs(dt: TDateTime; var Nsec, Nfrac: Longint); | ||||
| const | ||||
|   maxi = 4294967295.0; | ||||
|   maxilongint = 2147483647; | ||||
| var | ||||
|   d, d1: Double; | ||||
| begin | ||||
|   d  := (dt - 2) * 86400; | ||||
|   d1 := frac(d); | ||||
|   d  := trunc(d); | ||||
|   if d>maxilongint then | ||||
|      d := d - maxi - 1; | ||||
|   d1 := Trunc(d1 * 10000) / 10000; | ||||
|   d1 := d1 * maxi; | ||||
|   if d1>maxilongint then | ||||
|      d1 := d1 - maxi - 1; | ||||
|   Nsec:=trunc(d); | ||||
|   Nfrac:=trunc(d1); | ||||
|   Nsec := synsock.htonl(Nsec); | ||||
|   Nfrac := synsock.htonl(Nfrac); | ||||
| end; | ||||
|  | ||||
| function TSNTPSend.GetBroadcastNTP: Boolean; | ||||
| var | ||||
|   NtpPtr: PNtp; | ||||
| @@ -123,23 +159,24 @@ var | ||||
| begin | ||||
|   Result := False; | ||||
|   FSock.Bind('0.0.0.0', cNtpProtocol); | ||||
|   if FSock.CanRead(Timeout) then | ||||
|   FBuffer := FSock.RecvPacket(FTimeout); | ||||
|   if FSock.LastError = 0 then | ||||
|   begin | ||||
|     x := FSock.WaitingData; | ||||
|     SetLength(FBuffer, x); | ||||
|     FSock.RecvBufferFrom(Pointer(FBuffer), x); | ||||
|     x := Length(FBuffer); | ||||
|     if (SntpHost = '0.0.0.0') or (FSock.GetRemoteSinIP = SntpHost) then | ||||
|       if x >= SizeOf(NTPReply) then | ||||
|       begin | ||||
|         NtpPtr := Pointer(FBuffer); | ||||
|         FNTPReply := NtpPtr^; | ||||
|         FNTPTime := DecodeTs(NTPReply.Xmit1, NTPReply.Xmit2); | ||||
|         if FSyncTime and ((abs(FNTPTime - GetUTTime) * 86400) <= FMaxSyncDiff) then | ||||
|           SetUTTime(FNTPTime); | ||||
|         Result := True; | ||||
|       end; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| function TSNTPSend.GetNTP: Boolean; | ||||
| function TSNTPSend.GetSNTP: Boolean; | ||||
| var | ||||
|   q: TNtp; | ||||
|   NtpPtr: PNtp; | ||||
| @@ -150,19 +187,65 @@ begin | ||||
|   FillChar(q, SizeOf(q), 0); | ||||
|   q.mode := $1B; | ||||
|   FSock.SendBuffer(@q, SizeOf(q)); | ||||
|   if FSock.CanRead(Timeout) then | ||||
|   FBuffer := FSock.RecvPacket(FTimeout); | ||||
|   if FSock.LastError = 0 then | ||||
|   begin | ||||
|     x := FSock.WaitingData; | ||||
|     SetLength(FBuffer, x); | ||||
|     FSock.RecvBuffer(Pointer(FBuffer), x); | ||||
|     x := Length(FBuffer); | ||||
|     if x >= SizeOf(NTPReply) then | ||||
|     begin | ||||
|       NtpPtr := Pointer(FBuffer); | ||||
|       FNTPReply := NtpPtr^; | ||||
|       FNTPTime := DecodeTs(NTPReply.Xmit1, NTPReply.Xmit2); | ||||
|       if FSyncTime and ((abs(FNTPTime - GetUTTime) * 86400) <= FMaxSyncDiff) then | ||||
|         SetUTTime(FNTPTime); | ||||
|       Result := True; | ||||
|     end; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| function TSNTPSend.GetNTP: Boolean; | ||||
| var | ||||
|   q: TNtp; | ||||
|   NtpPtr: PNtp; | ||||
|   x: Integer; | ||||
|   t1, t2, t3, t4 : TDateTime; | ||||
| begin | ||||
|   Result := False; | ||||
|   FSock.Connect(sntphost, cNtpProtocol); | ||||
|   FillChar(q, SizeOf(q), 0); | ||||
|   q.mode := $1B; | ||||
|   t1 := GetUTTime; | ||||
|   EncodeTs(t1,q.org1,q.org2); | ||||
|   FSock.SendBuffer(@q, SizeOf(q)); | ||||
|   FBuffer := FSock.RecvPacket(FTimeout); | ||||
|   if FSock.LastError = 0 then | ||||
|   begin | ||||
|     x := Length(FBuffer); | ||||
|     t4 := GetUTTime; | ||||
|     if x >= SizeOf(NTPReply) then | ||||
|     begin | ||||
|       NtpPtr := Pointer(FBuffer); | ||||
|       FNTPReply := NtpPtr^; | ||||
|       FLi := (NTPReply.mode and $C0) shr 6; | ||||
|       FVn := (NTPReply.mode and $38) shr 3; | ||||
|       Fmode := NTPReply.mode and $07; | ||||
|       if (Fli < 3) and (Fmode = 4) and | ||||
|          (NTPReply.stratum >= 1) and (NTPReply.stratum <= 15) and | ||||
|          (NTPReply.Rcv1 <> 0) and (NTPReply.Xmit1 <> 0) | ||||
|          then begin | ||||
|            t2 := DecodeTs(NTPReply.Rcv1, NTPReply.Rcv2); | ||||
|            t3 := DecodeTs(NTPReply.Xmit1, NTPReply.Xmit2); | ||||
|            FNTPDelay := (T4 - T1) - (T2 - T3); | ||||
|            FNTPTime := t3 + FNTPDelay / 2; | ||||
|            FNTPOffset := (((T2 - T1) + (T3 - T4)) / 2) * 86400; | ||||
|            FNTPDelay := FNTPDelay * 86400; | ||||
|            if FSyncTime and ((abs(FNTPTime - t1) * 86400) <= FMaxSyncDiff) then | ||||
|              SetUTTime(FNTPTime); | ||||
|            Result := True; | ||||
|            end | ||||
|          else result:=false; | ||||
|     end; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| end. | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 004.000.000 | | ||||
| | Project : Delphree - Synapse                                   | 004.000.001 | | ||||
| |==============================================================================| | ||||
| | Content: Charset conversion support                                          | | ||||
| |==============================================================================| | ||||
| @@ -947,7 +947,7 @@ begin | ||||
|         s := s + c; | ||||
|       end; | ||||
|       if s = '' then | ||||
|         s := '+' | ||||
|         s := WriteMulti(Ord('+'), 0, 0, 0, 2) | ||||
|       else | ||||
|         s := DecodeBase64(s); | ||||
|       Result := Result + s; | ||||
|   | ||||
							
								
								
									
										156
									
								
								synacode.pas
									
									
									
									
									
								
							
							
						
						
									
										156
									
								
								synacode.pas
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 001.004.001 | | ||||
| | Project : Delphree - Synapse                                   | 001.005.002 | | ||||
| |==============================================================================| | ||||
| | Content: Coding and decoding support                                         | | ||||
| |==============================================================================| | ||||
| @@ -52,7 +52,33 @@ const | ||||
|     '`!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_'; | ||||
|   TableXX = | ||||
|     '+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_'; | ||||
|  | ||||
|   ReTablebase64 = | ||||
|     #$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$3E +#$40 | ||||
|     +#$40 +#$40 +#$3F +#$34 +#$35 +#$36 +#$37 +#$38 +#$39 +#$3A +#$3B +#$3C | ||||
|     +#$3D +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$00 +#$01 +#$02 +#$03 | ||||
|     +#$04 +#$05 +#$06 +#$07 +#$08 +#$09 +#$0A +#$0B +#$0C +#$0D +#$0E +#$0F | ||||
|     +#$10 +#$11 +#$12 +#$13 +#$14 +#$15 +#$16 +#$17 +#$18 +#$19 +#$40 +#$40 | ||||
|     +#$40 +#$40 +#$40 +#$40 +#$1A +#$1B +#$1C +#$1D +#$1E +#$1F +#$20 +#$21 | ||||
|     +#$22 +#$23 +#$24 +#$25 +#$26 +#$27 +#$28 +#$29 +#$2A +#$2B +#$2C +#$2D | ||||
|     +#$2E +#$2F +#$30 +#$31 +#$32 +#$33 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40; | ||||
|   ReTableUU = | ||||
|     #$01 +#$02 +#$03 +#$04 +#$05 +#$06 +#$07 +#$08 +#$09 +#$0A +#$0B +#$0C | ||||
|     +#$0D +#$0E +#$0F +#$10 +#$11 +#$12 +#$13 +#$14 +#$15 +#$16 +#$17 +#$18 | ||||
|     +#$19 +#$1A +#$1B +#$1C +#$1D +#$1E +#$1F +#$20 +#$21 +#$22 +#$23 +#$24 | ||||
|     +#$25 +#$26 +#$27 +#$28 +#$29 +#$2A +#$2B +#$2C +#$2D +#$2E +#$2F +#$30 | ||||
|     +#$31 +#$32 +#$33 +#$34 +#$35 +#$36 +#$37 +#$38 +#$39 +#$3A +#$3B +#$3C | ||||
|     +#$3D +#$3E +#$3F +#$00 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 | ||||
|     +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 | ||||
|     +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40; | ||||
|   ReTableXX = | ||||
|     #$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$00 +#$40 | ||||
|     +#$01 +#$40 +#$40 +#$02 +#$03 +#$04 +#$05 +#$06 +#$07 +#$08 +#$09 +#$0A | ||||
|     +#$0B +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$40 +#$0C +#$0D +#$0E +#$0F | ||||
|     +#$10 +#$11 +#$12 +#$13 +#$14 +#$15 +#$16 +#$17 +#$18 +#$19 +#$1A +#$1B | ||||
|     +#$1C +#$1D +#$1E +#$1F +#$20 +#$21 +#$22 +#$23 +#$24 +#$25 +#$40 +#$40 | ||||
|     +#$40 +#$40 +#$40 +#$40 +#$26 +#$27 +#$28 +#$29 +#$2A +#$2B +#$2C +#$2D | ||||
|     +#$2E +#$2F +#$30 +#$31 +#$32 +#$33 +#$34 +#$35 +#$36 +#$37 +#$38 +#$39 | ||||
|     +#$3A +#$3B +#$3C +#$3D +#$3E +#$3F +#$40 +#$40 +#$40 +#$40 +#$40 +#$40; | ||||
|  | ||||
| function DecodeTriplet(const Value: string; Delimiter: Char): string; | ||||
| function DecodeQuotedPrintable(const Value: string): string; | ||||
| @@ -63,6 +89,8 @@ function EncodeQuotedPrintable(const Value: string): string; | ||||
| function EncodeURLElement(const Value: string): string; | ||||
| function EncodeURL(const Value: string): string; | ||||
| function Decode4to3(const Value, Table: string): string; | ||||
| function Decode4to3Ex(const Value, Table: string): string; | ||||
| function Encode3to4(const Value, Table: string): string; | ||||
| function DecodeBase64(const Value: string): string; | ||||
| function EncodeBase64(const Value: string): string; | ||||
| function DecodeUU(const Value: string): string; | ||||
| @@ -193,27 +221,31 @@ type | ||||
|  | ||||
| function DecodeTriplet(const Value: string; Delimiter: Char): string; | ||||
| var | ||||
|   x: Integer; | ||||
|   x, l: Integer; | ||||
|   c: Char; | ||||
|   s: string; | ||||
| begin | ||||
|   Result := ''; | ||||
|   SetLength(Result, Length(Value)); | ||||
|   x := 1; | ||||
|   l := 1; | ||||
|   while x <= Length(Value) do | ||||
|   begin | ||||
|     c := Value[x]; | ||||
|     Inc(x); | ||||
|     if c <> Delimiter then | ||||
|       Result := Result + c | ||||
|       Result[l] := c | ||||
|     else | ||||
|       if x < Length(Value) then | ||||
|       begin | ||||
|         s := Copy(Value, x, 2); | ||||
|         Inc(x, 2); | ||||
|         if pos(#13, s) + pos(#10, s) = 0 then | ||||
|           Result := Result + Char(StrToIntDef('$' + s, 32)); | ||||
|           Result[l] := Char(StrToIntDef('$' + s, 32)); | ||||
|       end; | ||||
|     Inc(l); | ||||
|   end; | ||||
|   Dec(l); | ||||
|   SetLength(Result, l); | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
| @@ -235,17 +267,33 @@ end; | ||||
| function EncodeTriplet(const Value: string; Delimiter: Char; | ||||
|   Specials: TSpecials): string; | ||||
| var | ||||
|   n: Integer; | ||||
|   n, l: Integer; | ||||
|   s: string; | ||||
|   c: char; | ||||
| begin | ||||
|   Result := ''; | ||||
|   SetLength(Result, Length(Value) * 3); | ||||
|   l := 1; | ||||
|   for n := 1 to Length(Value) do | ||||
|   begin | ||||
|     s := Value[n]; | ||||
|     if s[1] in Specials then | ||||
|       s := Delimiter + IntToHex(Ord(s[1]), 2); | ||||
|     Result := Result + s; | ||||
|     c := Value[n]; | ||||
|     if c in Specials then | ||||
|     begin | ||||
|       Result[l] := Delimiter; | ||||
|       Inc(l); | ||||
|       s := IntToHex(Ord(c), 2); | ||||
|       Result[l] := s[1]; | ||||
|       Inc(l); | ||||
|       Result[l] := s[2]; | ||||
|       Inc(l); | ||||
|     end | ||||
|     else | ||||
|     begin | ||||
|       Result[l] := c; | ||||
|       Inc(l); | ||||
|     end; | ||||
|   end; | ||||
|   Dec(l); | ||||
|   SetLength(Result, l); | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
| @@ -274,11 +322,12 @@ end; | ||||
|  | ||||
| function Decode4to3(const Value, Table: string): string; | ||||
| var | ||||
|   x, y, n: Integer; | ||||
|   x, y, n, l: Integer; | ||||
|   d: array[0..3] of Byte; | ||||
| begin | ||||
|   Result := ''; | ||||
|   SetLength(Result, Length(Value)); | ||||
|   x := 1; | ||||
|   l := 1; | ||||
|   while x < Length(Value) do | ||||
|   begin | ||||
|     for n := 0 to 3 do | ||||
| @@ -294,33 +343,77 @@ begin | ||||
|       end; | ||||
|       Inc(x); | ||||
|     end; | ||||
|     Result := Result + Char((D[0] and $3F) shl 2 + (D[1] and $30) shr 4); | ||||
|     Result[l] := Char((D[0] and $3F) shl 2 + (D[1] and $30) shr 4); | ||||
|     Inc(l); | ||||
|     if d[2] <> 64 then | ||||
|     begin | ||||
|       Result := Result + Char((D[1] and $0F) shl 4 + (D[2] and $3C) shr 2); | ||||
|       Result[l] := Char((D[1] and $0F) shl 4 + (D[2] and $3C) shr 2); | ||||
|       Inc(l); | ||||
|       if d[3] <> 64 then | ||||
|         Result := Result + Char((D[2] and $03) shl 6 + (D[3] and $3F)); | ||||
|       begin | ||||
|         Result[l] := Char((D[2] and $03) shl 6 + (D[3] and $3F)); | ||||
|         Inc(l); | ||||
|       end; | ||||
|     end; | ||||
|   end; | ||||
|   Dec(l); | ||||
|   SetLength(Result, l); | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function DecodeBase64(const Value: string): string; | ||||
| function Decode4to3Ex(const Value, Table: string): string; | ||||
| var | ||||
|   x, y, n, l: Integer; | ||||
|   d: array[0..3] of Byte; | ||||
| begin | ||||
|   Result := Decode4to3(Value, TableBase64); | ||||
|   SetLength(Result, Length(Value)); | ||||
|   x := 1; | ||||
|   l := 1; | ||||
|   while x < Length(Value) do | ||||
|   begin | ||||
|     for n := 0 to 3 do | ||||
|     begin | ||||
|       if x > Length(Value) then | ||||
|         d[n] := 64 | ||||
|       else | ||||
|       begin | ||||
|         y := Ord(Value[x]); | ||||
|         if (y < 33) or (y > 127) then | ||||
|           d[n] := 64 | ||||
|         else | ||||
|           d[n] := Ord(Table[y - 32]); | ||||
|       end; | ||||
|       Inc(x); | ||||
|     end; | ||||
|     Result[l] := Char((D[0] and $3F) shl 2 + (D[1] and $30) shr 4); | ||||
|     Inc(l); | ||||
|     if d[2] <> 64 then | ||||
|     begin | ||||
|       Result[l] := Char((D[1] and $0F) shl 4 + (D[2] and $3C) shr 2); | ||||
|       Inc(l); | ||||
|       if d[3] <> 64 then | ||||
|       begin | ||||
|         Result[l] := Char((D[2] and $03) shl 6 + (D[3] and $3F)); | ||||
|         Inc(l); | ||||
|       end; | ||||
|     end; | ||||
|   end; | ||||
|   Dec(l); | ||||
|   SetLength(Result, l); | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function EncodeBase64(const Value: string): string; | ||||
| function Encode3to4(const Value, Table: string): string; | ||||
| var | ||||
|   c: Byte; | ||||
|   n: Integer; | ||||
|   n, l: Integer; | ||||
|   Count: Integer; | ||||
|   DOut: array[0..3] of Byte; | ||||
| begin | ||||
|   Result := ''; | ||||
|   setlength(Result, ((Length(Value) + 2) div 3) * 4); | ||||
|   l := 1; | ||||
|   Count := 1; | ||||
|   while Count <= Length(Value) do | ||||
|   begin | ||||
| @@ -352,12 +445,29 @@ begin | ||||
|       DOut[3] := $40; | ||||
|     end; | ||||
|     for n := 0 to 3 do | ||||
|       Result := Result + TableBase64[DOut[n] + 1]; | ||||
|     begin | ||||
|       Result[l] := Table[DOut[n] + 1]; | ||||
|       Inc(l); | ||||
|     end; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function DecodeBase64(const Value: string): string; | ||||
| begin | ||||
|   Result := Decode4to3Ex(Value, ReTableBase64); | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function EncodeBase64(const Value: string): string; | ||||
| begin | ||||
|   Result := Encode3to4(Value, TableBase64); | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function DecodeUU(const Value: string): string; | ||||
| var | ||||
|   s: string; | ||||
|   | ||||
							
								
								
									
										347
									
								
								synautil.pas
									
									
									
									
									
								
							
							
						
						
									
										347
									
								
								synautil.pas
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| {==============================================================================| | ||||
| | Project : Delphree - Synapse                                   | 002.003.000 | | ||||
| | Project : Delphree - Synapse                                   | 002.007.001 | | ||||
| |==============================================================================| | ||||
| | Content: support procedures and functions                                    | | ||||
| |==============================================================================| | ||||
| @@ -39,15 +39,22 @@ uses | ||||
|   Windows; | ||||
| {$ENDIF} | ||||
|  | ||||
| function Timezone: string; | ||||
| function TimeZoneBias: integer; | ||||
| function TimeZone: string; | ||||
| function Rfc822DateTime(t: TDateTime): string; | ||||
| function CDateTime(t: TDateTime): string; | ||||
| function SimpleDateTime(t: TDateTime): string; | ||||
| function DecodeRfcDateTime(Value: string): TDateTime; | ||||
| function GetUTTime: TDateTime; | ||||
| function SetUTTime(Newdt: TDateTime): Boolean; | ||||
| function GetTick: Cardinal; | ||||
| function CodeInt(Value: Word): string; | ||||
| function DecodeInt(const Value: string; Index: Integer): Word; | ||||
| function IsIP(const Value: string): Boolean; | ||||
| function ReverseIP(Value: string): string; | ||||
| function IPToID(Host: string): string; | ||||
| procedure Dump(const Buffer, DumpFile: string); | ||||
| procedure DumpEx(const Buffer, DumpFile: string); | ||||
| function SeparateLeft(const Value, Delimiter: string): string; | ||||
| function SeparateRight(const Value, Delimiter: string): string; | ||||
| function GetParameter(const Value, Parameter: string): string; | ||||
| @@ -102,26 +109,19 @@ begin | ||||
| end; | ||||
| {==============================================================================} | ||||
|  | ||||
| function Timezone: string; | ||||
| function TimeZoneBias: integer; | ||||
| {$IFDEF LINUX} | ||||
| var | ||||
|   t: TTime_T; | ||||
|   UT: TUnixTime; | ||||
|   bias: Integer; | ||||
|   h, m: Integer; | ||||
| begin | ||||
|   __time(@T); | ||||
|   localtime_r(@T, UT); | ||||
|   bias := ut.__tm_gmtoff div 60; | ||||
|   if bias >= 0 then | ||||
|     Result := '+' | ||||
|   else | ||||
|     Result := '-'; | ||||
|   Result := ut.__tm_gmtoff div 60; | ||||
| {$ELSE} | ||||
| var | ||||
|   zoneinfo: TTimeZoneInformation; | ||||
|   bias: Integer; | ||||
|   h, m: Integer; | ||||
| begin | ||||
|   case GetTimeZoneInformation(Zoneinfo) of | ||||
|     2: | ||||
| @@ -131,11 +131,22 @@ begin | ||||
|   else | ||||
|     bias := zoneinfo.Bias; | ||||
|   end; | ||||
|   if bias <= 0 then | ||||
|   Result := bias * (-1); | ||||
| {$ENDIF} | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function TimeZone: string; | ||||
| var | ||||
|   bias: Integer; | ||||
|   h, m: Integer; | ||||
| begin | ||||
|   bias := TimeZoneBias; | ||||
|   if bias >= 0 then | ||||
|     Result := '+' | ||||
|   else | ||||
|     Result := '-'; | ||||
| {$ENDIF} | ||||
|   bias := Abs(bias); | ||||
|   h := bias div 60; | ||||
|   m := bias mod 60; | ||||
| @@ -148,7 +159,7 @@ function Rfc822DateTime(t: TDateTime): string; | ||||
| begin | ||||
|   SaveNames; | ||||
|   try | ||||
|     Result := FormatDateTime('ddd, d mmm yyyy hh:mm:ss', t); | ||||
|     Result := FormatDateTime('ddd, d mmm yyyy hh:nn:ss', t); | ||||
|     Result := Result + ' ' + Timezone; | ||||
|   finally | ||||
|     RestoreNames; | ||||
| @@ -161,7 +172,7 @@ function CDateTime(t: TDateTime): string; | ||||
| begin | ||||
|   SaveNames; | ||||
|   try | ||||
|     Result := FormatDateTime('mmm dd hh:mm:ss', t); | ||||
|     Result := FormatDateTime('mmm dd hh:nn:ss', t); | ||||
|     if Result[5] = '0' then | ||||
|       Result[5] := ' '; | ||||
|   finally | ||||
| @@ -171,6 +182,260 @@ end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function SimpleDateTime(t: TDateTime): string; | ||||
| begin | ||||
|   SaveNames; | ||||
|   try | ||||
|     Result := FormatDateTime('yymmdd hhnnss', t); | ||||
|   finally | ||||
|     RestoreNames; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function DecodeTimeZone(Value: string; var Zone: integer): Boolean; | ||||
| var | ||||
|   x: integer; | ||||
|   zh, zm: integer; | ||||
|   s: string; | ||||
| begin | ||||
|   Result := false; | ||||
|   s := Value; | ||||
|   if (Pos('+', s) = 1) or (Pos('-',s) = 1) then | ||||
|   begin | ||||
|     if s = '-0000' then | ||||
|       Zone := TimeZoneBias | ||||
|     else | ||||
|       if Length(s) > 4 then | ||||
|       begin | ||||
|         zh := StrToIntdef(s[2] + s[3], 0); | ||||
|         zm := StrToIntdef(s[4] + s[5], 0); | ||||
|         zone := zh * 60 + zm; | ||||
|         if s[1] = '-' then | ||||
|           zone := zone * (-1); | ||||
|       end; | ||||
|     Result := True; | ||||
|   end | ||||
|   else | ||||
|   begin | ||||
|     x := 32767; | ||||
|     if s = 'NZDT' then x := 13; | ||||
|     if s = 'IDLE' then x := 12; | ||||
|     if s = 'NZST' then x := 12; | ||||
|     if s = 'NZT' then x := 12; | ||||
|     if s = 'EADT' then x := 11; | ||||
|     if s = 'GST' then x := 10; | ||||
|     if s = 'JST' then x := 9; | ||||
|     if s = 'CCT' then x := 8; | ||||
|     if s = 'WADT' then x := 8; | ||||
|     if s = 'WAST' then x := 7; | ||||
|     if s = 'ZP6' then x := 6; | ||||
|     if s = 'ZP5' then x := 5; | ||||
|     if s = 'ZP4' then x := 4; | ||||
|     if s = 'BT' then x := 3; | ||||
|     if s = 'EET' then x := 2; | ||||
|     if s = 'MEST' then x := 2; | ||||
|     if s = 'MESZ' then x := 2; | ||||
|     if s = 'SST' then x := 2; | ||||
|     if s = 'FST' then x := 2; | ||||
|     if s = 'CEST' then x := 2; | ||||
|     if s = 'CET' then x := 1; | ||||
|     if s = 'FWT' then x := 1; | ||||
|     if s = 'MET' then x := 1; | ||||
|     if s = 'MEWT' then x := 1; | ||||
|     if s = 'SWT' then x := 1; | ||||
|     if s = 'UT' then x := 0; | ||||
|     if s = 'UTC' then x := 0; | ||||
|     if s = 'GMT' then x := 0; | ||||
|     if s = 'WET' then x := 0; | ||||
|     if s = 'WAT' then x := -1; | ||||
|     if s = 'BST' then x := -1; | ||||
|     if s = 'AT' then x := -2; | ||||
|     if s = 'ADT' then x := -3; | ||||
|     if s = 'AST' then x := -4; | ||||
|     if s = 'EDT' then x := -4; | ||||
|     if s = 'EST' then x := -5; | ||||
|     if s = 'CDT' then x := -5; | ||||
|     if s = 'CST' then x := -6; | ||||
|     if s = 'MDT' then x := -6; | ||||
|     if s = 'MST' then x := -7; | ||||
|     if s = 'PDT' then x := -7; | ||||
|     if s = 'PST' then x := -8; | ||||
|     if s = 'YDT' then x := -8; | ||||
|     if s = 'YST' then x := -9; | ||||
|     if s = 'HDT' then x := -9; | ||||
|     if s = 'AHST' then x := -10; | ||||
|     if s = 'CAT' then x := -10; | ||||
|     if s = 'HST' then x := -10; | ||||
|     if s = 'EAST' then x := -10; | ||||
|     if s = 'NT' then x := -11; | ||||
|     if s = 'IDLW' then x := -12; | ||||
|     if x <> 32767 then | ||||
|     begin | ||||
|       zone := x * 60; | ||||
|       Result := True; | ||||
|     end; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function DecodeRfcDateTime(Value: string): TDateTime; | ||||
| var | ||||
|   day, month, year: Word; | ||||
|   zone: integer; | ||||
|   x: integer; | ||||
|   s: string; | ||||
|   SaveSeparator: char; | ||||
|   n: integer; | ||||
|   t: TDateTime; | ||||
| begin | ||||
| // ddd, d mmm yyyy hh:mm:ss | ||||
| // ddd, d mmm yy hh:mm:ss | ||||
| // ddd, mmm d yyyy hh:mm:ss | ||||
| // ddd mmm dd hh:mm:ss yyyy | ||||
| //       Sun, 06 Nov 1994 08:49:37 GMT    ; RFC 822, updated by RFC 1123 | ||||
| //       Sunday, 06-Nov-94 08:49:37 GMT   ; RFC 850, obsoleted by RFC 1036 | ||||
| //       Sun Nov  6 08:49:37 1994         ; ANSI C's asctime() Format | ||||
|  | ||||
|   Result := 0; | ||||
|   SaveSeparator := TimeSeparator; | ||||
|   try | ||||
|     TimeSeparator := ':'; | ||||
|     day := 0; | ||||
|     month := 0; | ||||
|     year := 0; | ||||
|     zone := 0; | ||||
|     Value := StringReplace(Value, ' -', ' #'); | ||||
|     Value := StringReplace(Value, '-', ' '); | ||||
|     Value := StringReplace(Value, ' #', ' -'); | ||||
|     while Value <> '' do | ||||
|     begin | ||||
|       s := Fetch(Value, ' '); | ||||
|       s := uppercase(s); | ||||
|       // timezone | ||||
|       if DecodetimeZone(s, x) then | ||||
|       begin | ||||
|         zone := x; | ||||
|         continue; | ||||
|       end; | ||||
|       x := StrToIntDef(s, 0); | ||||
|       // day or year | ||||
|       if x > 0 then | ||||
|         if (x < 32) and (day = 0) then | ||||
|         begin | ||||
|           day := x; | ||||
|           continue; | ||||
|         end | ||||
|         else | ||||
|         begin | ||||
|           year := x; | ||||
|           if year < 32 then | ||||
|             year := year + 2000; | ||||
|           if year < 1000 then | ||||
|            year := year + 1900; | ||||
|           continue; | ||||
|         end; | ||||
|       // time | ||||
|       if rpos(':', s) > Pos(':', s) then | ||||
|       begin | ||||
|         t := 0; | ||||
|         try | ||||
|           t := StrToTime(s); | ||||
|         except | ||||
|           on Exception do ; | ||||
|         end; | ||||
|         if t <> 0 then | ||||
|           Result := t; | ||||
|         continue; | ||||
|       end; | ||||
|       //timezone daylight saving time | ||||
|       if s = 'DST' then | ||||
|       begin | ||||
|         zone := zone + 60; | ||||
|         continue; | ||||
|       end; | ||||
|       // month | ||||
|       for n := 1 to 12 do | ||||
|         if s = uppercase(MyMonthNames[n]) then | ||||
|         begin | ||||
|           month := n; | ||||
|           break; | ||||
|         end; | ||||
|     end; | ||||
|     Result := Result + Encodedate(year, month, day); | ||||
|     zone := zone - TimeZoneBias; | ||||
|     t := EncodeTime(Abs(zone) div 60, Abs(zone) mod 60, 0, 0); | ||||
|     if zone < 0 then | ||||
|       t := 0 - t; | ||||
|     Result := Result - t; | ||||
|   finally | ||||
|     TimeSeparator := SaveSeparator; | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function GetUTTime: TDateTime; | ||||
| {$IFNDEF LINUX} | ||||
| var | ||||
|   st: TSystemTime; | ||||
| begin | ||||
|  GetSystemTime(st); | ||||
|  result:=SystemTimeToDateTime(st); | ||||
| {$ELSE} | ||||
| var | ||||
|   TV: TTimeVal; | ||||
| begin | ||||
|   gettimeofday(TV, nil); | ||||
|   Result:=UnixDateDelta + (TV.tv_sec + TV.tv_usec / 1000000) / 86400; | ||||
| {$ENDIF} | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function SetUTTime(Newdt: TDateTime): Boolean; | ||||
| {$IFNDEF LINUX} | ||||
| var | ||||
|   st: TSystemTime; | ||||
| begin | ||||
|  DateTimeToSystemTime(newdt,st); | ||||
|  Result:=SetSystemTime(st); | ||||
| {$ELSE} | ||||
| var | ||||
|   TV: TTimeVal; | ||||
|   d: double; | ||||
|   TZ: Ttimezone; | ||||
| begin | ||||
|   Result := false; | ||||
|   gettimeofday(TV, TZ); | ||||
|   d := (newdt - UnixDateDelta) * 86400; | ||||
|   TV.tv_sec := trunc(d); | ||||
|   TV.tv_usec := trunc(frac(d) * 1000000); | ||||
|   Result := settimeofday(TV, TZ) <> -1; | ||||
| {$ENDIF} | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| {$IFDEF LINUX} | ||||
| function GetTick: Cardinal; | ||||
| var | ||||
|   Stamp: TTimeStamp; | ||||
| begin | ||||
|   Stamp := DateTimeToTimeStamp(Now); | ||||
|   Result := Stamp.Time; | ||||
| end; | ||||
| {$ELSE} | ||||
| function GetTick: Cardinal; | ||||
| begin | ||||
|   Result := Windows.GetTickCount; | ||||
| end; | ||||
| {$ENDIF} | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function CodeInt(Value: Word): string; | ||||
| begin | ||||
|   Result := Chr(Hi(Value)) + Chr(Lo(Value)) | ||||
| @@ -278,6 +543,35 @@ end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| procedure DumpEx(const Buffer, DumpFile: string); | ||||
| var | ||||
|   n: Integer; | ||||
|   x: Byte; | ||||
|   s: string; | ||||
|   f: Text; | ||||
| begin | ||||
|   s := ''; | ||||
|   for n := 1 to Length(Buffer) do | ||||
|   begin | ||||
|     x := Ord(Buffer[n]); | ||||
|     if x in [65..90, 97..122] then | ||||
|       s := s + ' +''' + char(x) + '''' | ||||
|     else | ||||
|       s := s + ' +#$' + IntToHex(Ord(Buffer[n]), 2); | ||||
|   end; | ||||
|   AssignFile(f, DumpFile); | ||||
|   if FileExists(DumpFile) then | ||||
|     DeleteFile(PChar(DumpFile)); | ||||
|   Rewrite(f); | ||||
|   try | ||||
|     Writeln(f, s); | ||||
|   finally | ||||
|     CloseFile(f); | ||||
|   end; | ||||
| end; | ||||
|  | ||||
| {==============================================================================} | ||||
|  | ||||
| function SeparateLeft(const Value, Delimiter: string): string; | ||||
| var | ||||
|   x: Integer; | ||||
| @@ -359,13 +653,13 @@ begin | ||||
|     s := SeparateLeft(s, '"') | ||||
|   else | ||||
|   begin | ||||
|     s := SeparateRight(Value, '('); | ||||
|     if s <> Value then | ||||
|       s := SeparateLeft(s, ')') | ||||
|     else | ||||
|     s := SeparateLeft(Value, '<'); | ||||
|     if s = Value then | ||||
|     begin | ||||
|       s := SeparateLeft(Value, '<'); | ||||
|       if s = Value then | ||||
|       s := SeparateRight(Value, '('); | ||||
|       if s <> Value then | ||||
|         s := SeparateLeft(s, ')') | ||||
|       else | ||||
|         s := ''; | ||||
|     end; | ||||
|   end; | ||||
| @@ -449,7 +743,7 @@ begin | ||||
|   else | ||||
|     sURL := URL; | ||||
|   x := Pos('@', sURL); | ||||
|   if x > 0 then | ||||
|   if (x > 0) and (x < Pos('/', sURL)) then | ||||
|   begin | ||||
|     s := SeparateLeft(sURL, '@'); | ||||
|     sURL := SeparateRight(sURL, '@'); | ||||
| @@ -547,9 +841,16 @@ end; | ||||
| {==============================================================================} | ||||
|  | ||||
| function Fetch(var Value: string; const Delimiter: string): string; | ||||
| var | ||||
|   s: string; | ||||
| begin | ||||
|   Result := SeparateLeft(Value, Delimiter); | ||||
|   Value := SeparateRight(Value, Delimiter); | ||||
|   s := SeparateRight(Value, Delimiter); | ||||
|   if s = Value then | ||||
|     Value := '' | ||||
|   else | ||||
|     Value := Trim(s); | ||||
|   Result := Trim(Result); | ||||
| end; | ||||
|  | ||||
| end. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user