Add --bus-name option to use different D-Bus bus name

This commit is contained in:
AsamK 2024-02-09 17:45:41 +01:00
parent a48fdaf8b7
commit 1bf703b012
8 changed files with 98 additions and 53 deletions

View file

@ -76,6 +76,10 @@ public class App {
.dest("global-dbus-system")
.help("Make request via system dbus.")
.action(Arguments.storeTrue());
parser.addArgument("--bus-name")
.dest("global-bus-name")
.setDefault(DbusConfig.getBusname())
.help("Specify the D-Bus bus name to connect to.");
parser.addArgument("-o", "--output")
.help("Choose to output in plain text or JSON")
@ -125,8 +129,9 @@ public class App {
final var useDbus = Boolean.TRUE.equals(ns.getBoolean("global-dbus"));
final var useDbusSystem = Boolean.TRUE.equals(ns.getBoolean("global-dbus-system"));
if (useDbus || useDbusSystem) {
final var busName = ns.getString("global-bus-name");
// If account is null, it will connect to the default object path
initDbusClient(command, account, useDbusSystem, commandHandler);
initDbusClient(command, account, useDbusSystem, busName, commandHandler);
return;
}

View file

@ -4,6 +4,7 @@ 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.OutputType;
import org.asamk.signal.ReceiveMessageHandler;
import org.asamk.signal.Shutdown;
@ -50,6 +51,9 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
subparser.addArgument("--dbus-system", "--system")
.action(Arguments.storeTrue())
.help("Expose a DBus interface on the system bus.");
subparser.addArgument("--bus-name")
.setDefault(DbusConfig.getBusname())
.help("Specify the D-Bus bus name to connect to.");
subparser.addArgument("--socket")
.nargs("?")
.type(File.class)
@ -177,20 +181,25 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
final var isDbusSystem = Boolean.TRUE.equals(ns.getBoolean("dbus-system"));
if (isDbusSystem) {
daemonHandler.runDbus(true);
final var busName = ns.getString("bus-name");
daemonHandler.runDbus(true, busName);
}
final var isDbusSession = Boolean.TRUE.equals(ns.getBoolean("dbus"));
if (isDbusSession || (
!isDbusSystem
&& socketFile == null
&& tcpAddress == null
&& httpAddress == null
&& inheritedChannel == null
)) {
if (isDbusSession) {
final var busName = ns.getString("bus-name");
daemonHandler.runDbus(false, busName);
}
if (!isDbusSystem
&& !isDbusSession
&& socketFile == null
&& tcpAddress == null
&& httpAddress == null
&& inheritedChannel == null) {
logger.warn(
"Running daemon command without explicit mode is deprecated. Use --dbus to use the dbus interface.");
daemonHandler.runDbus(false);
daemonHandler.runDbus(false, DbusConfig.getBusname());
}
}
@ -214,7 +223,7 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
public abstract void runSocket(ServerSocketChannel serverChannel) throws CommandException;
public abstract void runDbus(boolean isDbusSystem) throws CommandException;
public abstract void runDbus(boolean isDbusSystem, final String busname) throws CommandException;
public abstract void runHttp(InetSocketAddress address) throws CommandException;
@ -267,8 +276,8 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
}
@Override
public void runDbus(final boolean isDbusSystem) throws CommandException {
runDbus(new DbusHandler(isDbusSystem, m, receiveMode != ReceiveMode.ON_START));
public void runDbus(final boolean isDbusSystem, final String busname) throws CommandException {
runDbus(new DbusHandler(isDbusSystem, busname, m, receiveMode != ReceiveMode.ON_START));
}
@Override
@ -292,8 +301,8 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
}
@Override
public void runDbus(final boolean isDbusSystem) throws CommandException {
runDbus(new DbusHandler(isDbusSystem, c, receiveMode != ReceiveMode.ON_START));
public void runDbus(final boolean isDbusSystem, final String busname) throws CommandException {
runDbus(new DbusHandler(isDbusSystem, busname, c, receiveMode != ReceiveMode.ON_START));
}
@Override

View file

@ -24,12 +24,16 @@ import java.io.IOException;
public class DbusCommandHandler {
public static void initDbusClient(
final Command command, final String account, final boolean systemBus, final CommandHandler commandHandler
final Command command,
final String account,
final boolean systemBus,
final String busname,
final CommandHandler commandHandler
) throws CommandException {
try {
final var busType = systemBus ? DBusConnection.DBusBusType.SYSTEM : DBusConnection.DBusBusType.SESSION;
try (var dBusConn = DBusConnectionBuilder.forType(busType).build()) {
handleCommand(command, account, dBusConn, commandHandler);
handleCommand(command, account, dBusConn, busname, commandHandler);
}
} catch (ServiceUnknown e) {
throw new UserErrorException("signal-cli DBus daemon not running on "
@ -45,6 +49,7 @@ public class DbusCommandHandler {
final Command command,
final String account,
final DBusConnection dBusConn,
final String busname,
final CommandHandler commandHandler
) throws CommandException, DBusException {
try {
@ -53,27 +58,27 @@ public class DbusCommandHandler {
throw new UserErrorException("You cannot specify a account (phone number) when linking");
}
handleProvisioningCommand(c, dBusConn, commandHandler);
handleProvisioningCommand(c, dBusConn, busname, commandHandler);
return;
}
if (account == null && command instanceof MultiLocalCommand c) {
handleMultiLocalCommand(c, dBusConn, commandHandler);
handleMultiLocalCommand(c, dBusConn, busname, commandHandler);
return;
}
if (account != null && command instanceof RegistrationCommand c) {
handleRegistrationCommand(c, account, dBusConn, commandHandler);
handleRegistrationCommand(c, account, dBusConn, busname, commandHandler);
return;
}
if (!(command instanceof LocalCommand localCommand)) {
throw new UserErrorException("Command only works in multi-account mode");
}
var accountObjectPath = account == null ? tryGetSingleAccountObjectPath(dBusConn) : null;
var accountObjectPath = account == null ? tryGetSingleAccountObjectPath(dBusConn, busname) : null;
if (accountObjectPath == null) {
accountObjectPath = DbusConfig.getObjectPath(account);
}
handleLocalCommand(localCommand, accountObjectPath, dBusConn, commandHandler);
handleLocalCommand(localCommand, accountObjectPath, dBusConn, busname, commandHandler);
} catch (UnsupportedOperationException e) {
throw new UserErrorException("Command is not yet implemented via dbus", e);
} catch (DBusExecutionException e) {
@ -81,10 +86,10 @@ public class DbusCommandHandler {
}
}
private static String tryGetSingleAccountObjectPath(final DBusConnection dBusConn) throws DBusException, CommandException {
var control = dBusConn.getRemoteObject(DbusConfig.getBusname(),
DbusConfig.getObjectPath(),
SignalControl.class);
private static String tryGetSingleAccountObjectPath(
final DBusConnection dBusConn, final String busname
) throws DBusException, CommandException {
var control = dBusConn.getRemoteObject(busname, DbusConfig.getObjectPath(), SignalControl.class);
try {
final var accounts = control.listAccounts();
if (accounts.isEmpty()) {
@ -102,12 +107,13 @@ public class DbusCommandHandler {
}
private static void handleMultiLocalCommand(
final MultiLocalCommand c, final DBusConnection dBusConn, final CommandHandler commandHandler
final MultiLocalCommand c,
final DBusConnection dBusConn,
final String busname,
final CommandHandler commandHandler
) throws CommandException, DBusException {
final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(),
DbusConfig.getObjectPath(),
SignalControl.class);
try (final var multiAccountManager = new DbusMultiAccountManagerImpl(signalControl, dBusConn)) {
final var signalControl = dBusConn.getRemoteObject(busname, DbusConfig.getObjectPath(), SignalControl.class);
try (final var multiAccountManager = new DbusMultiAccountManagerImpl(signalControl, dBusConn, busname)) {
commandHandler.handleMultiLocalCommand(c, multiAccountManager);
}
}
@ -116,10 +122,11 @@ public class DbusCommandHandler {
final LocalCommand c,
String accountObjectPath,
final DBusConnection dBusConn,
final String busname,
final CommandHandler commandHandler
) throws CommandException, DBusException {
var signal = dBusConn.getRemoteObject(DbusConfig.getBusname(), accountObjectPath, Signal.class);
try (final var manager = new DbusManagerImpl(signal, dBusConn)) {
var signal = dBusConn.getRemoteObject(busname, accountObjectPath, Signal.class);
try (final var manager = new DbusManagerImpl(signal, dBusConn, busname)) {
commandHandler.handleLocalCommand(c, manager);
}
}
@ -128,24 +135,24 @@ public class DbusCommandHandler {
final RegistrationCommand c,
String account,
final DBusConnection dBusConn,
final String busname,
final CommandHandler commandHandler
) throws CommandException, DBusException {
final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(),
DbusConfig.getObjectPath(),
SignalControl.class);
final var signalControl = dBusConn.getRemoteObject(busname, DbusConfig.getObjectPath(), SignalControl.class);
try (final var registrationManager = new DbusRegistrationManagerImpl(account, signalControl, dBusConn)) {
commandHandler.handleRegistrationCommand(c, registrationManager);
}
}
private static void handleProvisioningCommand(
final ProvisioningCommand c, final DBusConnection dBusConn, final CommandHandler commandHandler
final ProvisioningCommand c,
final DBusConnection dBusConn,
final String busname,
final CommandHandler commandHandler
) throws CommandException, DBusException {
final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(),
DbusConfig.getObjectPath(),
SignalControl.class);
final var signalControl = dBusConn.getRemoteObject(busname, DbusConfig.getObjectPath(), SignalControl.class);
final var provisioningManager = new DbusProvisioningManagerImpl(signalControl, dBusConn);
commandHandler.handleProvisioningCommand(c, provisioningManager);
}

View file

@ -21,12 +21,15 @@ public class DbusHandler implements AutoCloseable {
private final boolean isDbusSystem;
private DBusConnection dBusConnection;
private final String busname;
private final List<AutoCloseable> closeables = new ArrayList<>();
private final DbusRunner dbusRunner;
private final boolean noReceiveOnStart;
public DbusHandler(final boolean isDbusSystem, final Manager m, final boolean noReceiveOnStart) {
public DbusHandler(
final boolean isDbusSystem, final String busname, final Manager m, final boolean noReceiveOnStart
) {
this.isDbusSystem = isDbusSystem;
this.dbusRunner = (connection) -> {
try {
@ -35,9 +38,15 @@ public class DbusHandler implements AutoCloseable {
}
};
this.noReceiveOnStart = noReceiveOnStart;
this.busname = busname;
}
public DbusHandler(final boolean isDbusSystem, final MultiAccountManager c, final boolean noReceiveOnStart) {
public DbusHandler(
final boolean isDbusSystem,
final String busname,
final MultiAccountManager c,
final boolean noReceiveOnStart
) {
this.isDbusSystem = isDbusSystem;
this.dbusRunner = (connection) -> {
final var signalControl = new DbusSignalControlImpl(c, DbusConfig.getObjectPath());
@ -72,6 +81,7 @@ public class DbusHandler implements AutoCloseable {
}
};
this.noReceiveOnStart = noReceiveOnStart;
this.busname = busname;
}
public void init() throws CommandException {
@ -79,7 +89,7 @@ public class DbusHandler implements AutoCloseable {
throw new AssertionError("DbusHandler already initialized");
}
final var busType = isDbusSystem ? DBusConnection.DBusBusType.SYSTEM : DBusConnection.DBusBusType.SESSION;
logger.debug("Starting DBus server on {} bus: {}", busType, DbusConfig.getBusname());
logger.debug("Starting DBus server on {} bus: {}", busType, busname);
try {
dBusConnection = DBusConnectionBuilder.forType(busType).build();
dbusRunner.run(dBusConnection);
@ -90,13 +100,13 @@ public class DbusHandler implements AutoCloseable {
}
try {
dBusConnection.requestBusName(DbusConfig.getBusname());
dBusConnection.requestBusName(busname);
} catch (DBusException e) {
throw new UnexpectedErrorException("Dbus command failed, maybe signal-cli dbus daemon is already running: "
+ e.getMessage(), e);
}
logger.info("Started DBus server on {} bus: {}", busType, DbusConfig.getBusname());
logger.info("Started DBus server on {} bus: {}", busType, busname);
}
@Override

View file

@ -1,7 +1,6 @@
package org.asamk.signal.dbus;
import org.asamk.Signal;
import org.asamk.signal.DbusConfig;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.manager.api.AlreadyReceivingException;
import org.asamk.signal.manager.api.AttachmentInvalidException;
@ -90,14 +89,16 @@ public class DbusManagerImpl implements Manager {
private final Set<ReceiveMessageHandler> weakHandlers = new HashSet<>();
private final Set<ReceiveMessageHandler> messageHandlers = new HashSet<>();
private final List<Runnable> closedListeners = new ArrayList<>();
private final String busname;
private DBusSigHandler<Signal.MessageReceivedV2> dbusMsgHandler;
private DBusSigHandler<Signal.EditMessageReceived> dbusEditMsgHandler;
private DBusSigHandler<Signal.ReceiptReceivedV2> dbusRcptHandler;
private DBusSigHandler<Signal.SyncMessageReceivedV2> dbusSyncHandler;
public DbusManagerImpl(final Signal signal, DBusConnection connection) {
public DbusManagerImpl(final Signal signal, DBusConnection connection, final String busname) {
this.signal = signal;
this.connection = connection;
this.busname = busname;
}
@Override
@ -820,7 +821,7 @@ public class DbusManagerImpl implements Manager {
private <T extends DBusInterface> T getRemoteObject(final DBusPath path, final Class<T> type) {
try {
return connection.getRemoteObject(DbusConfig.getBusname(), path.getPath(), type);
return connection.getRemoteObject(busname, path.getPath(), type);
} catch (DBusException e) {
throw new AssertionError(e);
}

View file

@ -2,7 +2,6 @@ package org.asamk.signal.dbus;
import org.asamk.Signal;
import org.asamk.SignalControl;
import org.asamk.signal.DbusConfig;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.manager.MultiAccountManager;
import org.asamk.signal.manager.ProvisioningManager;
@ -32,10 +31,14 @@ public class DbusMultiAccountManagerImpl implements MultiAccountManager {
// TODO add listeners for added/removed accounts
private final Set<Consumer<Manager>> onManagerAddedHandlers = new HashSet<>();
private final Set<Consumer<Manager>> onManagerRemovedHandlers = new HashSet<>();
private final String busname;
public DbusMultiAccountManagerImpl(final SignalControl signalControl, DBusConnection connection) {
public DbusMultiAccountManagerImpl(
final SignalControl signalControl, DBusConnection connection, final String busname
) {
this.signalControl = signalControl;
this.connection = connection;
this.busname = busname;
}
@Override
@ -50,7 +53,7 @@ public class DbusMultiAccountManagerImpl implements MultiAccountManager {
public List<Manager> getManagers() {
return signalControl.listAccounts()
.stream()
.map(a -> (Manager) new DbusManagerImpl(getRemoteObject(a, Signal.class), connection))
.map(a -> (Manager) new DbusManagerImpl(getRemoteObject(a, Signal.class), connection, busname))
.toList();
}
@ -70,7 +73,9 @@ public class DbusMultiAccountManagerImpl implements MultiAccountManager {
@Override
public Manager getManager(final String phoneNumber) {
return new DbusManagerImpl(getRemoteObject(signalControl.getAccount(phoneNumber), Signal.class), connection);
return new DbusManagerImpl(getRemoteObject(signalControl.getAccount(phoneNumber), Signal.class),
connection,
busname);
}
@Override
@ -98,7 +103,7 @@ public class DbusMultiAccountManagerImpl implements MultiAccountManager {
private <T extends DBusInterface> T getRemoteObject(final DBusPath path, final Class<T> type) {
try {
return connection.getRemoteObject(DbusConfig.getBusname(), path.getPath(), type);
return connection.getRemoteObject(busname, path.getPath(), type);
} catch (DBusException e) {
throw new AssertionError(e);
}