0

In Windows, it is possible to shutdown a machine through a java program by natively(JNA) calling a ExitWindowsEx function in Windows API. I am looking for something similar in linux. I know this can be done by executing commands but then I cannot rely on parsing the human-readable text.

Is IPC(DBus) the only way to do this or is it possible to load some library natively and the call the shutdown method natively. If there is a simpler way to do it please do let me know.

Using JNA or similar to shutdown and restart computer in linux and mac

I looked at this question earlier but it does not provide an answer as to how to do it programmatically.

Community
  • 1
  • 1
vignesh
  • 37
  • 1
  • 8
  • Take a look at busybox [`halt.c`](https://git.busybox.net/busybox/tree/init/halt.c) – Elliott Frisch Oct 31 '16 at 22:49
  • Can you use SSH? That's probably the best human readable parse you'll get. It'll give you everything until the moment of shutdown. There are many flavors: [Python](http://stackoverflow.com/questions/3586106/perform-commands-over-ssh-with-python), [Java](http://stackoverflow.com/questions/995944/ssh-library-for-java), [C#](http://stackoverflow.com/questions/11169396/c-sharp-send-a-simple-ssh-command) – ThisClark Oct 31 '16 at 22:53
  • @ThisClark I am trying to automate managing my servers. The program exists so that I dont have to login. I will send commands through java sockets to shutdown the machine. I have an desktop app that connects to the socket through which I send the commands. – vignesh Oct 31 '16 at 22:56

2 Answers2

0

Can't your program just invoke sh and execute shutdown command? Like that (needs root):

system("shutdown");

Or if it's a desktop session:

system("dbus-send --system --print-reply --dest=org.freedesktop.login1 /org/freedesktop/login1 "org.freedesktop.login1.Manager.PowerOff" boolean:true");

Or you can instead include a DBus connector library and do a proper IPC call.

Velkan
  • 7,067
  • 6
  • 43
  • 87
  • Is there a doc which provides the various functions that I can access via dbus? – vignesh Nov 03 '16 at 14:07
  • DBus is a call mechanism. What is accessible depends on what services are installed. I usually look at what is available through the `d-feet` dbus GUI explorer program (or `gdbus introspect` if in command line), then figure out to what service the object corresponds. Services have their documentation somewhere (like https://www.freedesktop.org/wiki/Software/systemd/logind/). And every class in DBus is defined by an xml file ("org.freedesktop.login1.xml" for the `login1`). The bindings for the programming languages are generated from these xml files (like in SOAP). – Velkan Nov 03 '16 at 14:37
  • Unfortunately I couldn't find a ready to go java library that was able to connect with the DBus. Maybe in the next iteration of my product's SDLC I will build on the existing DBus Library to get it working. Manged to find a solution through POSIX. – vignesh Nov 04 '16 at 22:12
0

So I managed to find the solution on my own after I did some research online. There is a library called JNA(Java Native Access) that lets you load libraries natively and resolves and dependencies. Using JNA I loaded the POSIX library on java through an interface. Running your code as sudo will let you shut down or reboot the machine. Here is the code.

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.ptr.IntByReference;

public interface CLibrary extends Library {
public CLibrary INSTANCE = (CLibrary) Native.loadLibrary(Platform.isWindows()?"msvcrt":"c",CLibrary.class);

int kill(long pid, int sig);
int reboot(int magic, int magic2, int cmd, IntByReference arg);
int reboot(int cmd);

int LINUX_REBOOT_MAGIC1 = 0xfee1dead;
int LINUX_REBOOT_MAGIC2 = 672274793;
int LINUX_REBOOT_MAGIC2A = 85072278;
int LINUX_REBOOT_MAGIC2B = 369367448;
int LINUX_REBOOT_MAGIC2C = 537993216;

int LINUX_REBOOT_CMD_RESTART = 0x01234567;
int LINUX_REBOOT_CMD_HALT = 0xCDEF0123;
int LINUX_REBOOT_CMD_CAD_ON =0x89ABCDEF;
int LINUX_REBOOT_CMD_CAD_OFF = 0x00000000;
int LINUX_REBOOT_CMD_POWER_OFF = 0x4321FEDC;
int LINUX_REBOOT_CMD_RESTART2 = 0xA1B2C3D4;
int LINUX_REBOOT_CMD_SW_SUSPEND = 0xD000FCE2;
int LINUX_REBOOT_CMD_KEXEC = 0x45584543;

}

p s v main(){
   CLibrary.INSTANCE.reboot(Clibrary.LINUX_REBOOT_CMD_POWER_OFF);
}

Note: This works only on Linux and not on Windows. To shutdown a machine programmatically look for ExitWindowsEx. Built into the JNA library.

All C POSIX headers files can be found C POSIX Library - Wikipedia

vignesh
  • 37
  • 1
  • 8