How to configure systemd *.service using XML file configuration - c++

I'm making a cross-platform background process. For Windows, I have a XML configuration file, which has a service name, load type etc. On windows, program during execution just parses this file and creates the service, easy. Linux, on other hand, has this *.service config file, which doesn't allow me to use my XML config, so I have to configure my daemon inside *.service.
So the question is, how to make *.service use my XML config to load preferences for daemon? I know this is possible, but have no idea how to do this.

I suspect you use the well-known technique of registering your Windows Service executable as a service, when you run it as a regular process. That is simply a matter of calling the right Service Control Manager API's. You know you're not a service if StartServiceCtrlDispatcher fails.
The same idea works for Linux. If you start your program normally, you register yourself as a service following the documented procedure. This procedure is of course different from Windows; it involves you dynamically writing a *.service file and registering it.
Not all API's in an OS need to be function calls, an API can also take the shape of a file format.

Related

Starting a Tomcat 8.5 localhost through C++? What is the best practice?

I am attempting to create a small C++ Visual Studio Forms (via CPPCLR_WinformsProjekt) application that is essentially a browser but it also starts a local Tomcat 8.5 server with a WAR file in its web apps folder and redirects you to the localhost page. I am working on Windows.
My question precisely is - what is the best way to start the Tomcat server through C++ libraries?
Edit: The way I started solving this is by simply having the tomcat folder with the WAR file zipped within the Visual Studio project. On execution, the file gets unzipped, and I am thinking of having a system(*start tomcat command*).
NB: I know I can start Tomcat through the cmd but I need to get it working via C++.
[I am assuming you are under Windows, but on Unix-es similar ways are available.]
In a C++ program you can execute all commands that a shell can, so the easiest way to start Tomcat would be to use CreateProcess to execute catalina.bat (or startup.bat). The is also the most easily configurable way: a user can adapt setenv.bat to its needs.
Of course, if you want to omit the *.bat files you can:
either instantiate a JVM using java.exe with the appropriate parameters: you need at least bin/bootstrap.jar in the system classpath (and usually bin/tomcat-juli.jar) and call the main method of org.apache.catalina.startup.Bootstrap with a parameter of start.
or instantiate a JVM using jvm.dll through the Invocation API in a similar way as it is done by procrun.
I don't believe these methods give you any advantage over the *.bat scripts. To stop a modern Tomcat just send the kill signal.
Edit: If you plan to start only one specific web application a full-fledged Tomcat might be overkill. You might instead:
either use Tomcat Embedded, which boils up to writing on class and calling its main method instead of Boostrap#start. The advantage is, you just need to distribute a bunch of jar files and your WAR and you don't need a traditional Tomcat installation directory structure,
or user use Spring Boot.

How to adapt an unmanaged C++ DLL to be used by Ruby

I need advice on converting a desktop C++ application to a web app. (This is my first web app.) The desktop app currently has a C# GUI, but the functionality I need to use all resides in an unmanaged, non-threadsafe C++ DLL.
The web-app uses Rails, and will run on a Linux server. Mostly, it needs to pass a list of strings to the DLL and get a winnowed-down list in return. The DLL will need to run on a Windows server. It has a significant load time, so I want it to run persistently. And I'll need multiple instances to handle simultaneous requests in a timely manner. I need it to scale reasonably well. (In case it's relevant: The Windows server will be on Amazon Web Services.)
So I have to determine: (1) How to interact between Ruby and C++, and (2) how to manage concurrent requests.
Ruby to C++
I could use Ruby Extensions (perhaps with Swig or Rb++ to make it easier) to call the library from Ruby. But is that an option when they're running on separate servers?
Regardless, with the relative simplicity of the interactions, I should probably just go with HTTP requests. Right?
From what I've read, it sounds like FastCGI is the way to go. I'll just have to wrap my DLL in a process with a FastCGI interface. Is there any other option I should consider?
Multiple Processes
First I should clarify: The C++ DLL is not threadsafe. So I need the server to spawn a configurable number of processes, and route requests to an idle process (or hold it in a queue till one becomes idle).
If I've understood correctly, FastCGI in general supports this, and IIS in particular does too. (Apparently IIS doesn't support multithreaded FastCGI applications, but that's fine for me.)
So will this just be a matter of configuring the FastCGI Process Manager?
Look up ISAPI for IIS, then go Rails -> 'net -> Windows Server -> IIS -> ISAPI -> your ISAPI DLL plugin -> your HTTP webservice -> this DLL.
But that's a heck of a lot of hoops to jump through. Don't you have the source to the DLL?
If not, I would write a Windows test script which calls this DLL. Then I would writes tests that cover every single one of its behaviors. Then I would start a new project (maybe in Ruby, maybe in Gnu C++), and I would pass each one of those tests on the new project. I like to call this "extract algorithm refactor"; the result should be fresh code that does the same thing, more portably.

Remote launching C++ apps

My problem is simple, I have 1 computer conected to many powerfull servers. I want to execute the app locally but run the process (heavy load) in the remote servers.
The app+settings vary a lot, and I want that this exactly version of the app+settings folder to be used by the remote instances.
My approach so far:
Launch the app locally
Use PSEXEC to remote launch the same executable as it is running in local -> in the servers (with a random port number passed by argument)
Contect to them via sockets
Send commands to execute remotely and get the results
My problem relies in the config files, wich are many(50+) and some of them +4MB. This config files are TXT files in a config folder.
What is the proper way to do it? Is it possible to use PSEXEC to copy remotely a whole folder? Can I do any good trick on the sockets to directly pass a copy of the local files to remote?
I would like all the process to be semi-transparent. Since many people will use it with different versions and settings at the same time. So manually copying the files to 20+servers is NOT an option.
Thank you!
Put the program/script that you want to execute by all machines on one common location on local network (put your configs there too). On all servers create a batch file say 'runme.bat' that will execute your program directly from network location.
This way you can use psexec to run runme.bat essentially executing your program/script on any server you want.
Since often - there are issues using psexec - you may invoke your scripts from Task Scheduler etc.
I do that for 500+ servers and it works. If working for me it will work for you.
You might want to look at HTCondor (http://research.cs.wisc.edu/htcondor/) which could perhaps manage all of this for you.

Viability of tracking user logins in C++

I want to write a C++ application that collects information about user logons/logoffs for Windows XP. I've done some searching around and have yet to find a viable way of doing this. There doesn't appear to be a system call I could use. I could export the log file from Event Viewer and use I/O operations but the code would be relying on the assumption that someone exported the log file. Is it realistically possible to write a C++ application to collect information about user logons? I'm using MinGW.
This could be done by using an application that starts before anyone logs into the system and runs all the time, regardless of users logging in and out. That is to say, a Windows service.
Windows services have the ability to detect and react to session changes via the OnSessionChange event handler.
Happy hunting!

Create folders on a remote Windows PC using C++?

How can I create folders on a remote Windows PC using C++?
Directly, you can't -- there would have to be a service on the remote machine which exposes that functionality for you.
If you're talking about a server message block scenario (i.e. "Windows Filesharing"), you can just call CreateDirectory with a network path, i.e. "\\\\computername\\share\\newFolder", but this requires the remote machine already be setup with an existing network share (I don't believe you can create said share remotely without A. admin rights on the target box, and B. some lessening of security settings to allow creation of shares remotely).
EDIT: (In response to the tag edit adding the MFC tag)
As far as how CreateDirectory is exposed in MFC, I'm not sure if there's an MFC wrapper around that function at all -- though there really doesn't need to be a wrapper because the function itself is self contained -- there'd be no benefit of putting it in a class.
The typical way is to start by calling NetShareAdd to create a share to a path on the remote machine. To support creating things there, you'll normally want to specify at least ACCESS_CREATE for the share.
Once you've done that, you'll have a local path to the remote disk, and you can create a directory in it, just like you would with a local disk.