1 package org
.asamk
.signal
.commands
;
3 import net
.sourceforge
.argparse4j
.impl
.Arguments
;
4 import net
.sourceforge
.argparse4j
.inf
.Namespace
;
5 import net
.sourceforge
.argparse4j
.inf
.Subparser
;
7 import org
.asamk
.signal
.DbusConfig
;
8 import org
.asamk
.signal
.DbusReceiveMessageHandler
;
9 import org
.asamk
.signal
.JsonDbusReceiveMessageHandler
;
10 import org
.asamk
.signal
.JsonWriter
;
11 import org
.asamk
.signal
.OutputType
;
12 import org
.asamk
.signal
.OutputWriter
;
13 import org
.asamk
.signal
.PlainTextWriter
;
14 import org
.asamk
.signal
.commands
.exceptions
.CommandException
;
15 import org
.asamk
.signal
.commands
.exceptions
.UnexpectedErrorException
;
16 import org
.asamk
.signal
.dbus
.DbusSignalControlImpl
;
17 import org
.asamk
.signal
.dbus
.DbusSignalImpl
;
18 import org
.asamk
.signal
.manager
.Manager
;
19 import org
.freedesktop
.dbus
.connections
.impl
.DBusConnection
;
20 import org
.freedesktop
.dbus
.exceptions
.DBusException
;
21 import org
.slf4j
.Logger
;
22 import org
.slf4j
.LoggerFactory
;
24 import java
.io
.IOException
;
25 import java
.util
.List
;
27 import java
.util
.concurrent
.TimeUnit
;
29 public class DaemonCommand
implements MultiLocalCommand
{
31 private final static Logger logger
= LoggerFactory
.getLogger(DaemonCommand
.class);
32 private final OutputWriter outputWriter
;
34 public static void attachToSubparser(final Subparser subparser
) {
35 subparser
.help("Run in daemon mode and provide an experimental dbus interface.");
36 subparser
.addArgument("--system")
37 .action(Arguments
.storeTrue())
38 .help("Use DBus system bus instead of user bus.");
39 subparser
.addArgument("--ignore-attachments")
40 .help("Don’t download attachments of received messages.")
41 .action(Arguments
.storeTrue());
44 public DaemonCommand(final OutputWriter outputWriter
) {
45 this.outputWriter
= outputWriter
;
49 public Set
<OutputType
> getSupportedOutputTypes() {
50 return Set
.of(OutputType
.PLAIN_TEXT
, OutputType
.JSON
);
54 public void handleCommand(final Namespace ns
, final Manager m
) throws CommandException
{
55 boolean ignoreAttachments
= ns
.getBoolean("ignore-attachments");
57 DBusConnection
.DBusBusType busType
;
58 if (ns
.getBoolean("system")) {
59 busType
= DBusConnection
.DBusBusType
.SYSTEM
;
61 busType
= DBusConnection
.DBusBusType
.SESSION
;
64 try (var conn
= DBusConnection
.getConnection(busType
)) {
65 var objectPath
= DbusConfig
.getObjectPath();
66 var t
= run(conn
, objectPath
, m
, ignoreAttachments
);
68 conn
.requestBusName(DbusConfig
.getBusname());
72 } catch (InterruptedException ignored
) {
74 } catch (DBusException
| IOException e
) {
75 logger
.error("Dbus command failed", e
);
76 throw new UnexpectedErrorException("Dbus command failed");
81 public void handleCommand(
82 final Namespace ns
, final List
<Manager
> managers
, SignalCreator c
83 ) throws CommandException
{
84 boolean ignoreAttachments
= ns
.getBoolean("ignore-attachments");
86 DBusConnection
.DBusBusType busType
;
87 if (ns
.getBoolean("system")) {
88 busType
= DBusConnection
.DBusBusType
.SYSTEM
;
90 busType
= DBusConnection
.DBusBusType
.SESSION
;
93 try (var conn
= DBusConnection
.getConnection(busType
)) {
94 final var signalControl
= new DbusSignalControlImpl(c
, m
-> {
96 final var objectPath
= DbusConfig
.getObjectPath(m
.getUsername());
97 return run(conn
, objectPath
, m
, ignoreAttachments
);
98 } catch (DBusException e
) {
99 logger
.error("Failed to export object", e
);
102 }, DbusConfig
.getObjectPath());
103 conn
.exportObject(signalControl
);
105 for (var m
: managers
) {
106 signalControl
.addManager(m
);
109 conn
.requestBusName(DbusConfig
.getBusname());
112 } catch (DBusException
| IOException e
) {
113 logger
.error("Dbus command failed", e
);
114 throw new UnexpectedErrorException("Dbus command failed");
119 DBusConnection conn
, String objectPath
, Manager m
, boolean ignoreAttachments
120 ) throws DBusException
{
121 conn
.exportObject(new DbusSignalImpl(m
, objectPath
));
123 logger
.info("Exported dbus object: " + objectPath
);
125 final var thread
= new Thread(() -> {
126 while (!Thread
.interrupted()) {
128 final var receiveMessageHandler
= outputWriter
instanceof JsonWriter
129 ?
new JsonDbusReceiveMessageHandler(m
, (JsonWriter
) outputWriter
, conn
, objectPath
)
130 : new DbusReceiveMessageHandler(m
, (PlainTextWriter
) outputWriter
, conn
, objectPath
);
131 m
.receiveMessages(1, TimeUnit
.HOURS
, false, ignoreAttachments
, receiveMessageHandler
);
133 } catch (IOException e
) {
134 logger
.warn("Receiving messages failed, retrying", e
);
135 } catch (InterruptedException ignored
) {