signal-cli/src/main/java/org/asamk/signal/commands/DaemonCommand.java
2021-08-08 17:32:55 +02:00

137 lines
5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package org.asamk.signal.commands;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.DbusConfig;
import org.asamk.signal.DbusReceiveMessageHandler;
import org.asamk.signal.JsonDbusReceiveMessageHandler;
import org.asamk.signal.JsonWriter;
import org.asamk.signal.OutputType;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.PlainTextWriter;
import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
import org.asamk.signal.dbus.DbusSignalImpl;
import org.asamk.signal.manager.Manager;
import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class DaemonCommand implements MultiLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(DaemonCommand.class);
private final OutputWriter outputWriter;
public static void attachToSubparser(final Subparser subparser) {
subparser.help("Run in daemon mode and provide an experimental dbus interface.");
subparser.addArgument("--system")
.action(Arguments.storeTrue())
.help("Use DBus system bus instead of user bus.");
subparser.addArgument("--ignore-attachments")
.help("Dont download attachments of received messages.")
.action(Arguments.storeTrue());
}
public DaemonCommand(final OutputWriter outputWriter) {
this.outputWriter = outputWriter;
}
@Override
public Set<OutputType> getSupportedOutputTypes() {
return Set.of(OutputType.PLAIN_TEXT, OutputType.JSON);
}
@Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
boolean ignoreAttachments = ns.getBoolean("ignore-attachments");
DBusConnection.DBusBusType busType;
if (ns.getBoolean("system")) {
busType = DBusConnection.DBusBusType.SYSTEM;
} else {
busType = DBusConnection.DBusBusType.SESSION;
}
try (var conn = DBusConnection.getConnection(busType)) {
var objectPath = DbusConfig.getObjectPath();
var t = run(conn, objectPath, m, ignoreAttachments);
conn.requestBusName(DbusConfig.getBusname());
try {
t.join();
} catch (InterruptedException ignored) {
}
} catch (DBusException | IOException e) {
logger.error("Dbus command failed", e);
throw new UnexpectedErrorException("Dbus command failed");
}
}
@Override
public void handleCommand(final Namespace ns, final List<Manager> managers) throws CommandException {
boolean ignoreAttachments = ns.getBoolean("ignore-attachments");
DBusConnection.DBusBusType busType;
if (ns.getBoolean("system")) {
busType = DBusConnection.DBusBusType.SYSTEM;
} else {
busType = DBusConnection.DBusBusType.SESSION;
}
try (var conn = DBusConnection.getConnection(busType)) {
var receiveThreads = new ArrayList<Thread>();
for (var m : managers) {
var objectPath = DbusConfig.getObjectPath(m.getUsername());
var thread = run(conn, objectPath, m, ignoreAttachments);
receiveThreads.add(thread);
}
conn.requestBusName(DbusConfig.getBusname());
for (var t : receiveThreads) {
try {
t.join();
} catch (InterruptedException ignored) {
}
}
} catch (DBusException | IOException e) {
logger.error("Dbus command failed", e);
throw new UnexpectedErrorException("Dbus command failed");
}
}
private Thread run(
DBusConnection conn, String objectPath, Manager m, boolean ignoreAttachments
) throws DBusException {
conn.exportObject(objectPath, new DbusSignalImpl(m));
final var thread = new Thread(() -> {
while (true) {
try {
final var receiveMessageHandler = outputWriter instanceof JsonWriter
? new JsonDbusReceiveMessageHandler(m, (JsonWriter) outputWriter, conn, objectPath)
: new DbusReceiveMessageHandler(m, (PlainTextWriter) outputWriter, conn, objectPath);
m.receiveMessages(1, TimeUnit.HOURS, false, ignoreAttachments, receiveMessageHandler);
} catch (IOException e) {
logger.warn("Receiving messages failed, retrying", e);
}
}
});
logger.info("Exported dbus object: " + objectPath);
thread.start();
return thread;
}
}