{ example_outbound -- connect to a remote Comet peer and send one or more files using the library's reference TCP transport + filesystem provider. Build: fpc -Mobjfpc -Sh -Fu../src -Fu../../fpc-msgbase/src \ -Fu../../fpc-log/src example_outbound.pas Run: ./example_outbound host[:port] inbound-dir file [file ...] Example: ./example_outbound 192.0.2.5:24554 ./inbound /tmp/TEST.PKT inbound-dir is where files received during the bidir batch land (Comet sessions are bidirectional even when you call the peer just to send). UNIX only (Linux / FreeBSD) -- reference transport is UNIX-only for v0.1.x. Windows / OS2 / DOS consumers plug in their own IComTransport. } program example_outbound; {$mode objfpc}{$H+} uses SysUtils, log.types, log.console, mb.address, cm.types, cm.config, cm.transport, cm.provider, cm.driver, cm.xfer, cm.transport.tcp, cm.provider.fs; procedure Usage; begin WriteLn('usage: example_outbound host[:port] inbound-dir file [file ...]'); WriteLn(' set CM_PASSWORD env to authenticate (else session goes NOPWD)'); Halt(2); end; var HostArg, InboundDir, Host: string; Port: Word; ColonPos, I: Integer; Cfg: TCometSessionConfig; Transport: TComTcpTransport; Provider: TComFsProvider; Session: TComSession; Xfer: TCometXfer; Logger: TConsoleLogger; R: TCometSessionResult; begin if ParamCount < 2 then Usage; HostArg := ParamStr(1); InboundDir := ParamStr(2); Port := 24554; ColonPos := Pos(':', HostArg); if ColonPos > 0 then begin Port := StrToIntDef(Copy(HostArg, ColonPos + 1, Length(HostArg)), 24554); Host := Copy(HostArg, 1, ColonPos - 1); end else Host := HostArg; ForceDirectories(InboundDir); if GetEnvironmentVariable('CM_LOG') = 'trace' then Logger := TConsoleLogger.Create(llTrace) else Logger := TConsoleLogger.Create(llDebug); Provider := TComFsProvider.Create(InboundDir, IncludeTrailingPathDelimiter(InboundDir) + 'tmp'); for I := 3 to ParamCount do Provider.Enqueue(ParamStr(I), cmFsKeep); try Transport := TComTcpTransport.CreateClient(Host, Port); except on E: Exception do begin WriteLn('connect failed: ', E.Message); Halt(3); end; end; CMConfigDefaults(Cfg); SetLength(Cfg.LocalAddrs, 1); Cfg.LocalAddrs[0] := MakeFTNAddress(1, 218, 720, 0); if GetEnvironmentVariable('CM_AKA') <> '' then if not ParseFTNAddress(GetEnvironmentVariable('CM_AKA'), Cfg.LocalAddrs[0]) then begin WriteLn('CM_AKA: cannot parse "', GetEnvironmentVariable('CM_AKA'), '"'); Halt(2); end; Cfg.SystemName := 'fpc-comet example'; Cfg.MailerName := 'example_outbound/0.1'; Cfg.Transport := Transport; Cfg.Provider := Provider; Cfg.Log := @Logger.Log; Cfg.Password := GetEnvironmentVariable('CM_PASSWORD'); Cfg.PrivateKey := GetEnvironmentVariable('CM_PRIVKEY'); Session := TComSession.Create(cmDirOutbound, Cfg); Xfer := TCometXfer.Create(Session); try Session.SetTransferHooks(@Xfer.HandleFrame, @Xfer.Step, @Xfer.IsDone); Xfer.Start; if GetEnvironmentVariable('CM_REQUEST') <> '' then Xfer.RequestFiles(GetEnvironmentVariable('CM_REQUEST')); if GetEnvironmentVariable('CM_LIST') <> '' then Xfer.RequestListing(GetEnvironmentVariable('CM_LIST')); while Session.NextStep do Transport.WaitReady(True, False, 50); R := Session.Result_; if R.Success then begin WriteLn(Format('OK: sent %d files (%d bytes), received %d files (%d bytes)', [Xfer.FilesSent, Xfer.BytesSent, Xfer.FilesReceived, Xfer.BytesReceived])); WriteLn(Format(' wire: %d sent / %d recv', [R.WireBytesSent, R.WireBytesRecv])); case R.AuthMethod of cmAuthNoPwd: WriteLn(' auth: NOPWD'); cmAuthPlain: WriteLn(' auth: plain'); cmAuthCRAM: WriteLn(' auth: CRAM-MD5'); cmAuthED25519: WriteLn(' auth: ED25519'); else WriteLn(' auth: other ', Ord(R.AuthMethod)); end; Halt(0); end else begin WriteLn(Format('FAIL: %s (code %d)', [R.ErrorMessage, Ord(R.ErrorCode)])); Halt(1); end; finally Xfer.Free; Session.Free; Logger.Free; { Transport + Provider are TInterfacedObject; freed via ref-count when Cfg goes out of scope. } end; end.