Find D-Bus unique address using gdbus - c

I'm trying to find out the best way to acquire the unique D-Bus address of an object in the D-Bus system bus using the GDBus library on Linux.
Here are version numbers of the libraries I am using:
# ls /usr/lib |grep -e dbus -e glib -e gio
libdbus-1.so
libdbus-1.so.3
libdbus-1.so.3.14.11
libdbus-glib-1.so
libdbus-glib-1.so.2
libdbus-glib-1.so.2.3.3
libgio-2.0.so
libgio-2.0.so.0
libgio-2.0.so.0.5000.3
libglib-2.0.so
libglib-2.0.so.0
libglib-2.0.so.0.5000.3
Basically, I want to know the unique name/address of the object /org/bluez/hci0 located on the system bus using gdbus library. Does anyone have an example of how I would do this using the C library?
Right now I can use the command
# dbus-monitor --system
To figure out that the address I need is :1.22. I'm almost certain that there's a better way to find the address then parsing the text output of that command.
Thanks!

Why not use the well-known name of the service to find it (and if you want to keep track of the current unique owner, use g_bus_watch_name() to get it).
In fact, in the case of bluez I don't think there's ever a reason to search for "/org/bluez/hci0" as you should be using D-Bus ObjectManager API to find the objects/interfaces that the bluez service exports.

To clarify some of the concepts here:
D-Bus address: There is no such thing as an ‘address’ in D-Bus in the way you’re thinking. There are object paths, well-known names and unique names. The term ‘address’ is used to describe the socket path which clients use to connect to the dbus-daemon, but this is unrelated to what you’re asking.
Unique name: Like :1.22, this uniquely identifies a particular connection to the dbus-daemon. Typically, each application has one connection to the daemon, so this typically identifies a single application. (However, applications can have more than one connection to the bus if they want; if so, each connection would have a different unique address). A well-known name is a consistent name for a service’s connection to the dbus-daemon, which is used as an alias for its unique name. For example, org.bluez or org.freedesktop.FileManager1 are both well-known names.
Object address: Like /org/freedesktop/SomeService/blah, this is actually called an object path. Object paths are only unique within the context of a single D-Bus connection, so the path /a/b/c will typically refer to different objects for D-Bus connections :1.1 and :1.2. (Hence the question “how can I find the unique name of the object path /a/b/c?” is ill-formed, because there may be many unique names which export such an object.)

Related

Opening a named mutex by fully a qualified path

Is it possible to open or query a named mutex, using OpenMutex, by its full path qualification? For example:
HANDLE hHandleMutex = OpenMutex(READ_CONTROL, FALSE,
"\\Sessions\\1\\BaseNamedObjects\\SmartScreen_AppRepSettings_Mutex");
However, the function returns NULL and fails with error 161 (ERROR_BAD_PATHNAME: The specified path is invalid). Yes, the documentation says well about \\Global and \\Local prefixes and doesn't state anything about these full object names. However, MSDN doesn't state everything!
I am aware that we can query the same using NtQuerySystemInformation, NtQueryObject undocumented APIs. But that involves opening process, duplicating the token etc. I can very well use these APIs, but wanted a simple solution.
Let's assume that process is running as a SYSTEM account, so error 5 (access denied) won't be a problem. If that's the problem, I can handle it.
You are using the wrong path. It should be:
"Session\\1\\SmartScreen_AppRepSettings_Mutex"
The documentation says that the Session\ prefix is "reserved for system" use. Caveat emptor.

How to check if openssl or cryptopp is installed and use the library that actually exists in the system (is installed)?

I wrote function that encrypts/decrypts a buffer (2 versions of the same function - first, with cryptopp, second - with openssl).
I would like to make something like this:
#if defined OPENSSL
run_aes_openssl(...);
#elif defined CRYPTOPP
run_aes_crytopp(...);
#else
error(...);
#end
Is it possible?
It's not quite that simple. In order to find that a macro is defined, you have to include the header that defines that macro. And C doesn't have anything like "include foo.h iff it exists"; it has to exist otherwise there is a compilation error.
Normally this would be sorted out by a script that you run before compilation. Your script checks locations like /usr/include, /usr/local/include, etc., to see if the OpenSSL headers are there; and then it outputs a Makefile which contains in the CFLAGS -DHAVE_OPENSSL. Then your code can check for that macro.
This is quite a bit of hullabaloo, to keep things simple you could require the user to manually edit a file , e.g. distribute your project with something called user_config.h that the user is supposed to edit before compiling, to specify where they put OpenSSL and so on.
There is a preset system called GNU Autoconf which contains a script that checks your system for everything under the sun. This has its advantages and disadvantages; it makes things easier for plebs downloading your source code, but it is bloaty and can be hard work for yourself.
How to check if openssl or cryptopp is installed and use the library that actually exists in the system (is installed)?
If your application was built on the system it is running, then the code you have shown is OK. Presumably, the build system will detect both OpenSSL and Crypto++. In the case both are available, it looks like your code will favor OpenSSL.
If you application is built elsewhere and needs to check at runtime, then you will need dlopen, dlsym, dlclose and friends.
In the case of runtime checking, its probably best to build a dispatch table and call through it. For example, you might have a table with function pointers to your internal run_aes_openssl, run_aes_crytopp, etc.
Upon startup, you populate the table based on the results of dlopen. If you find OpenSSL, then you populate your table with the OpenSSL gear. If you find Crypto++, then you populate your table with the Crypto++ gear.
C++ can be painful to use with dlopen and friends because of name mangling. Worse, the mangling differs between distributions and runtime library versions. For example, here's a function to generate a private RSA key:
RSA::PrivateKey key;
key.GenerateRandomWithKeySize(prng, 1024);
And here's the corresponding function names on Mac OS X. Debian and Red Hat will likely be different.
$ nm cryptopp-test.exe | grep -i GenerateRandom | grep -i RSA
00000001000c7d80 T __ZN8CryptoPP21InvertibleRSAFunction14GenerateRandomERNS_21RandomNumberGeneratorERKNS_14NameValuePairsE
00000001000c8eb0 T __ZThn120_N8CryptoPP21InvertibleRSAFunction14GenerateRandomERNS_21RandomNumberGeneratorERKNS_14NameValuePairsE

How to know the active slave interface in a bonding pair

I am working under Linux, with two physical ethernet interfaces.
I have grouped the two interfaces to a bonding interface for backup... and it works.
I would like to know if there is any way to know, from my C user program, what is the active interface.
Thanks
Look at /sys/class/net/bond0/bonding/active_slave and read it using a program or code of your choice. (Replace path accordingly if using an interface name different from bond0.)
Another method to know it (tested on Debian) is looking at the file /proc/net/bonding/bondX. Replace bondX with the name of your interface.

Retrieving Mac Address for the given IP-Address

Is there any way to retrieve the mac-address for the given ip-address from the ARP table without providing the Interface name ??
I do know the procedure of retrieving the mac address using ioctl call but in that case I should provide the interface name .. :(
One Crude Solution: Read /proc/net/arp file ... :( .. other than that .. any system call or anything else where i can retrieve the mac-address without the need of interface name ??
NOTE: Simple C based solution not interested in scripting libraries.
NOTE: I am expecting a *NUX based solution rather than WINDOWS based one.
I do know the procedure of retrieving
the mac address using ioctl call but
in that case I should provide the
interface name
So all you need is a way to find the interface name associated with a given IP. The ioctl SIOCGIFCONF will give you that.

Distributing loadable builtin bash modules

I've written a built-in for bash which modifies the 'cd' command, a requirement for my software. Is there a way to actually distribute a loadable independently of bash itself? I'd ideally like to distribute just a drop in "additional feature" because I know people can be put off by patching and compiling their shell from source code.
I want to time how long a user is in a directory so I can determine where they want to be. It's this functionality: http://github.com/joelthelion/autojump/tree/master rewritten as a bash builtin, for performance issues. This implementation uses $PROMPT_COMMAND to work but I wanted something integrated.
It is unclear what you have modified but in any case, bash (like at least ksh93 which IIRC introduced the concept and zsh) supports, using the enable -f file name syntax, loading built-in functions as external dynamically loaded modules.
These modules being plain files can certainly be distributed independently, as long as you make sure they are compatible with the target version/architecture. This was already true 5 years ago when you asked this question.
One issue in your case is there seems to be no documented way to overload a internal built-in like cd by a dynamically loaded one while keeping the ability to access the former.
A simple workaround would be to implement your customized cd with a different name, say mycd, like this:
int mycd_builtin(list)
WORD_LIST *list;
{
int rv;
rv=cd_builtin(list);
if(rv == EXECUTION_SUCCESS) {
char wd[PATH_MAX+1];
getcwd(wd,sizeof(wd));
// do your custom stuff knowing the new working directory
...
}
return (rv);
}
then to use an alias, or better, a shell function for your customized version to be used instead of the regular one:
cd() {
mycd "$#"
}
As long as your customization doesn't affect the behavior of the standard command and thus doesn't risk breaking scripts using it, there is nothing wrong in your approach.
Changing the built-in cd is a support nightmare for any admin and unwelcome to foreign users. What is wrong with naming it 'smart-cd' and letting the USER decide if they want the functionality by including it in their .bashrc or .profile? Then they can setup things however they want.
Also, using how long you've been in a directory is a pretty poor indication of preference. How would you distinguish between idling (a forgotten shell hanging in /tmp overnight), long-running scripts (nightly cron jobs), and actual activity.
There are a multitude of other methods for creating shortcuts to favorite directories: aliases, softlinks, $VARIABLES, scripts. It is arrogant of you to assume that your usage patterns will be welcomed by other users of your system.

Resources