]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/commands/DaemonCommand.java
6ee4f316cef9fd0b2b6efbb3a7d3fa1130f1b2bd
[signal-cli] / src / main / java / org / asamk / signal / commands / DaemonCommand.java
1 package org.asamk.signal.commands;
2
3 import net.sourceforge.argparse4j.impl.Arguments;
4 import net.sourceforge.argparse4j.inf.Namespace;
5 import net.sourceforge.argparse4j.inf.Subparser;
6
7 import org.asamk.signal.DbusConfig;
8 import org.asamk.signal.DbusReceiveMessageHandler;
9 import org.asamk.signal.JsonDbusReceiveMessageHandler;
10 import org.asamk.signal.OutputType;
11 import org.asamk.signal.dbus.DbusSignalImpl;
12 import org.asamk.signal.manager.Manager;
13 import org.freedesktop.dbus.connections.impl.DBusConnection;
14 import org.freedesktop.dbus.exceptions.DBusException;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18 import java.io.IOException;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Set;
22 import java.util.concurrent.TimeUnit;
23
24 public class DaemonCommand implements MultiLocalCommand {
25
26 private final static Logger logger = LoggerFactory.getLogger(DaemonCommand.class);
27
28 @Override
29 public void attachToSubparser(final Subparser subparser) {
30 subparser.addArgument("--system")
31 .action(Arguments.storeTrue())
32 .help("Use DBus system bus instead of user bus.");
33 subparser.addArgument("--ignore-attachments")
34 .help("Don’t download attachments of received messages.")
35 .action(Arguments.storeTrue());
36 subparser.addArgument("--json")
37 .help("WARNING: This parameter is now deprecated! Please use the global \"--output=json\" option instead.\n\nOutput received messages in json format, one json object per line.")
38 .action(Arguments.storeTrue());
39 }
40
41 @Override
42 public Set<OutputType> getSupportedOutputTypes() {
43 return Set.of(OutputType.PLAIN_TEXT, OutputType.JSON);
44 }
45
46 @Override
47 public int handleCommand(final Namespace ns, final Manager m) {
48 var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json");
49
50 // TODO delete later when "json" variable is removed
51 if (ns.getBoolean("json")) {
52 logger.warn("\"--json\" option has been deprecated, please use the global \"--output=json\" instead.");
53 }
54
55 boolean ignoreAttachments = ns.getBoolean("ignore_attachments");
56
57 DBusConnection.DBusBusType busType;
58 if (ns.getBoolean("system")) {
59 busType = DBusConnection.DBusBusType.SYSTEM;
60 } else {
61 busType = DBusConnection.DBusBusType.SESSION;
62 }
63
64 try (var conn = DBusConnection.getConnection(busType)) {
65 var objectPath = DbusConfig.getObjectPath();
66 var t = run(conn, objectPath, m, ignoreAttachments, inJson);
67
68 conn.requestBusName(DbusConfig.getBusname());
69
70 try {
71 t.join();
72 } catch (InterruptedException ignored) {
73 }
74 return 0;
75 } catch (DBusException | IOException e) {
76 logger.error("Dbus command failed", e);
77 return 2;
78 }
79 }
80
81 @Override
82 public int handleCommand(final Namespace ns, final List<Manager> managers) {
83 var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json");
84
85 // TODO delete later when "json" variable is removed
86 if (ns.getBoolean("json")) {
87 logger.warn("\"--json\" option has been deprecated, please use the global \"--output=json\" instead.");
88 }
89
90 boolean ignoreAttachments = ns.getBoolean("ignore_attachments");
91
92 DBusConnection.DBusBusType busType;
93 if (ns.getBoolean("system")) {
94 busType = DBusConnection.DBusBusType.SYSTEM;
95 } else {
96 busType = DBusConnection.DBusBusType.SESSION;
97 }
98
99 try (var conn = DBusConnection.getConnection(busType)) {
100 var receiveThreads = new ArrayList<Thread>();
101 for (var m : managers) {
102 var objectPath = DbusConfig.getObjectPath(m.getUsername());
103 var thread = run(conn, objectPath, m, ignoreAttachments, inJson);
104 receiveThreads.add(thread);
105 }
106
107 conn.requestBusName(DbusConfig.getBusname());
108
109 for (var t : receiveThreads) {
110 try {
111 t.join();
112 } catch (InterruptedException ignored) {
113 }
114 }
115 return 0;
116 } catch (DBusException | IOException e) {
117 logger.error("Dbus command failed", e);
118 return 2;
119 }
120 }
121
122 private Thread run(
123 DBusConnection conn, String objectPath, Manager m, boolean ignoreAttachments, boolean inJson
124 ) throws DBusException {
125 conn.exportObject(objectPath, new DbusSignalImpl(m));
126
127 final var thread = new Thread(() -> {
128 while (true) {
129 try {
130 m.receiveMessages(1,
131 TimeUnit.HOURS,
132 false,
133 ignoreAttachments,
134 inJson
135 ? new JsonDbusReceiveMessageHandler(m, conn, objectPath)
136 : new DbusReceiveMessageHandler(m, conn, objectPath));
137 } catch (IOException e) {
138 logger.warn("Receiving messages failed, retrying", e);
139 }
140 }
141 });
142
143 logger.info("Exported dbus object: " + objectPath);
144
145 thread.start();
146
147 return thread;
148 }
149 }