]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/Cli.java
Add --verbose flag to show extended logging
[signal-cli] / src / main / java / org / asamk / signal / Cli.java
1 package org.asamk.signal;
2
3 import net.sourceforge.argparse4j.inf.Namespace;
4
5 import org.asamk.Signal;
6 import org.asamk.signal.commands.Command;
7 import org.asamk.signal.commands.Commands;
8 import org.asamk.signal.commands.DbusCommand;
9 import org.asamk.signal.commands.ExtendedDbusCommand;
10 import org.asamk.signal.commands.LocalCommand;
11 import org.asamk.signal.commands.ProvisioningCommand;
12 import org.asamk.signal.commands.RegistrationCommand;
13 import org.asamk.signal.dbus.DbusSignalImpl;
14 import org.asamk.signal.manager.Manager;
15 import org.asamk.signal.manager.NotRegisteredException;
16 import org.asamk.signal.manager.ProvisioningManager;
17 import org.asamk.signal.manager.RegistrationManager;
18 import org.asamk.signal.manager.ServiceConfig;
19 import org.asamk.signal.util.IOUtils;
20 import org.freedesktop.dbus.connections.impl.DBusConnection;
21 import org.freedesktop.dbus.exceptions.DBusException;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
25
26 import java.io.File;
27 import java.io.IOException;
28
29 public class Cli {
30
31 private final static Logger logger = LoggerFactory.getLogger(Main.class);
32
33 private final Namespace ns;
34
35 public Cli(final Namespace ns) {
36 this.ns = ns;
37 }
38
39 public int init() {
40 Command command = getCommand();
41 if (command == null) {
42 logger.error("Command not implemented!");
43 return 2;
44 }
45
46 if (ns.getBoolean("dbus") || ns.getBoolean("dbus_system")) {
47 return initDbusClient(command, ns.getBoolean("dbus_system"));
48 }
49
50 final String username = ns.getString("username");
51
52 final File dataPath;
53 String config = ns.getString("config");
54 if (config != null) {
55 dataPath = new File(config);
56 } else {
57 dataPath = getDefaultDataPath();
58 }
59
60 final SignalServiceConfiguration serviceConfiguration = ServiceConfig.createDefaultServiceConfiguration(
61 BaseConfig.USER_AGENT);
62
63 if (!ServiceConfig.getCapabilities().isGv2()) {
64 logger.warn("WARNING: Support for new group V2 is disabled,"
65 + " because the required native library dependency is missing: libzkgroup");
66 }
67
68 if (username == null) {
69 ProvisioningManager pm = new ProvisioningManager(dataPath, serviceConfiguration, BaseConfig.USER_AGENT);
70 return handleCommand(command, pm);
71 }
72
73 if (command instanceof RegistrationCommand) {
74 final RegistrationManager manager;
75 try {
76 manager = RegistrationManager.init(username, dataPath, serviceConfiguration, BaseConfig.USER_AGENT);
77 } catch (Throwable e) {
78 logger.error("Error loading or creating state file: {}", e.getMessage());
79 return 1;
80 }
81 try (RegistrationManager m = manager) {
82 return handleCommand(command, m);
83 } catch (Exception e) {
84 logger.error("Cleanup failed", e);
85 return 2;
86 }
87 }
88
89 Manager manager;
90 try {
91 manager = Manager.init(username, dataPath, serviceConfiguration, BaseConfig.USER_AGENT);
92 } catch (NotRegisteredException e) {
93 System.err.println("User is not registered.");
94 return 0;
95 } catch (Throwable e) {
96 logger.error("Error loading state file: {}", e.getMessage());
97 return 1;
98 }
99
100 try (Manager m = manager) {
101 try {
102 m.checkAccountState();
103 } catch (IOException e) {
104 logger.error("Error while checking account: {}", e.getMessage());
105 return 1;
106 }
107
108 return handleCommand(command, m);
109 } catch (IOException e) {
110 logger.error("Cleanup failed", e);
111 return 2;
112 }
113 }
114
115 private Command getCommand() {
116 String commandKey = ns.getString("command");
117 return Commands.getCommand(commandKey);
118 }
119
120 private int initDbusClient(final Command command, final boolean systemBus) {
121 try {
122 DBusConnection.DBusBusType busType;
123 if (systemBus) {
124 busType = DBusConnection.DBusBusType.SYSTEM;
125 } else {
126 busType = DBusConnection.DBusBusType.SESSION;
127 }
128 try (DBusConnection dBusConn = DBusConnection.getConnection(busType)) {
129 Signal ts = dBusConn.getRemoteObject(DbusConfig.SIGNAL_BUSNAME,
130 DbusConfig.SIGNAL_OBJECTPATH,
131 Signal.class);
132
133 return handleCommand(command, ts, dBusConn);
134 }
135 } catch (DBusException | IOException e) {
136 logger.error("Dbus client failed", e);
137 return 2;
138 }
139 }
140
141 private int handleCommand(Command command, Signal ts, DBusConnection dBusConn) {
142 if (command instanceof ExtendedDbusCommand) {
143 return ((ExtendedDbusCommand) command).handleCommand(ns, ts, dBusConn);
144 } else if (command instanceof DbusCommand) {
145 return ((DbusCommand) command).handleCommand(ns, ts);
146 } else {
147 System.err.println("Command is not yet implemented via dbus");
148 return 1;
149 }
150 }
151
152 private int handleCommand(Command command, ProvisioningManager pm) {
153 if (command instanceof ProvisioningCommand) {
154 return ((ProvisioningCommand) command).handleCommand(ns, pm);
155 } else {
156 System.err.println("Command only works with a username");
157 return 1;
158 }
159 }
160
161 private int handleCommand(Command command, RegistrationManager m) {
162 if (command instanceof RegistrationCommand) {
163 return ((RegistrationCommand) command).handleCommand(ns, m);
164 }
165 return 1;
166 }
167
168 private int handleCommand(Command command, Manager m) {
169 if (command instanceof LocalCommand) {
170 return ((LocalCommand) command).handleCommand(ns, m);
171 } else if (command instanceof DbusCommand) {
172 return ((DbusCommand) command).handleCommand(ns, new DbusSignalImpl(m));
173 } else {
174 System.err.println("Command only works via dbus");
175 return 1;
176 }
177 }
178
179 /**
180 * Uses $XDG_DATA_HOME/signal-cli if it exists, or if none of the legacy directories exist:
181 * - $HOME/.config/signal
182 * - $HOME/.config/textsecure
183 *
184 * @return the data directory to be used by signal-cli.
185 */
186 private static File getDefaultDataPath() {
187 File dataPath = new File(IOUtils.getDataHomeDir(), "signal-cli");
188 if (dataPath.exists()) {
189 return dataPath;
190 }
191
192 File configPath = new File(System.getProperty("user.home"), ".config");
193
194 File legacySettingsPath = new File(configPath, "signal");
195 if (legacySettingsPath.exists()) {
196 return legacySettingsPath;
197 }
198
199 legacySettingsPath = new File(configPath, "textsecure");
200 if (legacySettingsPath.exists()) {
201 return legacySettingsPath;
202 }
203
204 return dataPath;
205 }
206 }