Initial commit
This commit is contained in:
commit
4902e0fb3f
|
@ -0,0 +1 @@
|
||||||
|
/.direnv
|
|
@ -0,0 +1,7 @@
|
||||||
|
include ../syndicate-nim/depends.tup
|
||||||
|
NIM_FLAGS += --path:$(TUP_CWD)/../getdns/src
|
||||||
|
NIM_FLAGS += --path:$(TUP_CWD)/../syndicate-nim/src
|
||||||
|
NIM_GROUPS += $(TUP_CWD)/<protocols>
|
||||||
|
|
||||||
|
NIM_FLAGS += --define:ssl
|
||||||
|
NIM_FLAGS += --define:traceSyndicate
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Package
|
||||||
|
|
||||||
|
version = "20230412"
|
||||||
|
author = "Emery Hemingway"
|
||||||
|
description = "Jabber Syndicate actor"
|
||||||
|
license = "Unlicense"
|
||||||
|
srcDir = "src"
|
||||||
|
bin = @["jabber_actor"]
|
||||||
|
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
requires "nim >= 1.6.10"
|
|
@ -0,0 +1,2 @@
|
||||||
|
version 1 .
|
||||||
|
XmppClient = <xmpp-client @jid string @password string @cap #!any> .
|
|
@ -0,0 +1,3 @@
|
||||||
|
include_rules
|
||||||
|
: foreach ../*.prs |> !preserves_schema_nim |> {schema}
|
||||||
|
: jabber_actor.nim | {schema} |> !nim_bin |>
|
|
@ -0,0 +1,72 @@
|
||||||
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||||
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
|
import std/asyncdispatch, asyncnet, net, strutils
|
||||||
|
import syndicate
|
||||||
|
import getdns
|
||||||
|
import ./protocol
|
||||||
|
|
||||||
|
when not defined(posix): {.error: "This utility requires POSIX".}
|
||||||
|
|
||||||
|
proc checkError(r: getdns_return_t) =
|
||||||
|
if r.isBad: quit($r, QuitFailure)
|
||||||
|
|
||||||
|
type Client = ref object
|
||||||
|
context: SslContext
|
||||||
|
socket: AsyncSocket
|
||||||
|
|
||||||
|
proc close(client: Client) =
|
||||||
|
try: close(client.socket)
|
||||||
|
except CatchableError: discard # stupid
|
||||||
|
destroyContext(client.context)
|
||||||
|
|
||||||
|
proc connect(client: Client; jid: string) {.async.} =
|
||||||
|
stderr.writeLine "connecting as ", jid
|
||||||
|
var domains = rsplit(jid, '@', 1)
|
||||||
|
stderr.writeLine "domains is ", $domains
|
||||||
|
if domains.len != 2:
|
||||||
|
stderr.writeLine "invalid JID ", jid
|
||||||
|
raise newException(ValueError, "invalid JID " & jid)
|
||||||
|
var serviceProtoName = "_xmpps-client._tcp." & domains[1]
|
||||||
|
stderr.writeLine "lookup ", serviceProtoName
|
||||||
|
let dns = getdns.newContext(true)
|
||||||
|
# defer: context_destroy(dns)
|
||||||
|
dns.setResolutionType(GETDNS_RESOLUTION_STUB)
|
||||||
|
var response: Dict
|
||||||
|
checkError service_sync(dns, serviceProtoName, nil, addr response)
|
||||||
|
if response["status"].int != RESPSTATUS_GOOD:
|
||||||
|
raise newException(IOError, $response)
|
||||||
|
for srvAddr in response["srv_addresses"]:
|
||||||
|
wrapSocket(client.context, client.socket)
|
||||||
|
try:
|
||||||
|
let
|
||||||
|
host = srvAddr["domain_name"].bindata.toFqdn
|
||||||
|
port = srvAddr["port"].int.Port
|
||||||
|
stderr.writeLine "connecting to ", host, ":", port
|
||||||
|
await connect(client.socket, host, port)
|
||||||
|
stderr.writeLine "successfully connected to ", host, ":", port
|
||||||
|
break
|
||||||
|
except CatchableError as e:
|
||||||
|
stderr.writeLine "failed to connect: ", e.msg
|
||||||
|
close(client)
|
||||||
|
|
||||||
|
proc bootClient(turn: var Turn; jid, password: string; ds: Ref): Client =
|
||||||
|
result = Client(
|
||||||
|
context: newContext(protTLSv1, CVerifyNone),
|
||||||
|
socket: newAsyncSocket(),
|
||||||
|
)
|
||||||
|
asyncCheck(turn, connect(result, jid))
|
||||||
|
|
||||||
|
bootDataspace("main") do (root: Ref; turn: var Turn):
|
||||||
|
stderr.writeLine "connectStdio…"
|
||||||
|
connectStdio(root, turn)
|
||||||
|
stderr.writeLine "stdio connected"
|
||||||
|
during(turn, root, ?XmppClient) do (jid: string, password: string, ds: Ref):
|
||||||
|
let client = bootClient(turn, jid, password, ds)
|
||||||
|
do:
|
||||||
|
stderr.writeLine "retracting client"
|
||||||
|
close(client)
|
||||||
|
|
||||||
|
runForever()
|
||||||
|
|
||||||
|
{.error: "during clause not active until retraction".}
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
import
|
||||||
|
std/typetraits, preserves
|
||||||
|
|
||||||
|
type
|
||||||
|
XmppClient* {.preservesRecord: "xmpp-client".} = object
|
||||||
|
`jid`*: string
|
||||||
|
`password`*: string
|
||||||
|
`cap`* {.preservesEmbedded.}: Preserve[void]
|
||||||
|
|
||||||
|
proc `$`*(x: XmppClient): string =
|
||||||
|
`$`(toPreserve(x))
|
||||||
|
|
||||||
|
proc encode*(x: XmppClient): seq[byte] =
|
||||||
|
encode(toPreserve(x))
|
Loading…
Reference in New Issue