How to prevent ipmi-sensors output to stdout using FreeIPMI API - c

I am trying to get some information from the output of ipmi-sensors, such as CPU_TEMP, CPU_FAN, ... and save the values for another API to use. A daemon will send command from remote to gather all the hosts' hardware status.
I'm tracing the code of ipmi-sensors.c and relative files, such as ipmi-sensors-simple-output.c and ipmi-sensors-detail-output.c. I find that the ipmi-sensors default output to stdout. In the main(), ipmi-sensors call ipmi_sensors_argp_parse first,
ipmi_sensors_argp_parse (/*argc, argv, */&cmd_args);
I'd like to get ipmi-sensors data from an API, I do not use the argc, argv, I mark out argc, argv and modify the content of function call for this purpose.
Then main() call another func pstdout_setup to setup the stdout for output
if ((hosts_count = pstdout_setup (&(prog_data.args->common_args.hostname),
&(prog_data.args->common_args))) < 0)
return (EXIT_FAILURE);
and launch it
if ((rv = pstdout_launch (prog_data.args->common_args.hostname,
_ipmi_sensors,
&prog_data)) < 0)
Does FreeIPMI have any API call in FreeIPMI to do ipmi-sensors's task? Or do I need to redirect the stdout to a stream or file using fork and dup2? Or do I need to rewrite the all part of ipmi-sensors?
Thanks for your help.

FreeIPMI maintainer here. I believe the API you are looking for is "libipmimonitoring", it does about 90% of what is in ipmi-sensors.

Related

How to initialize stdout/stderr in a subsystem=windows program WITHOUT calling AllocConsole()?

So when trying to use the stdin/stdout/stderr streams in a Windows GUI app, one typically has to call AllocConsole (or AttachConsole) in order to initialize those streams for use. There are lots of posts on here on what you need to do AFTER calling AllocConsole (i.e. use freopen_s on the respective streams, etc).
I have a program where I want to redirect stdout and stderr to an anonymous pipe. I have a working example where I call:
AllocConsole();
FILE* fout;
FILE* ferr;
freopen_s(&fout, "CONOUT$", "r+", stdout);
freopen_s(&ferr, "CONOUT$", "r+", stderr);
HANDLE hreadout;
HANDLE hwriteout;
HANDLE hreaderr;
HANDLE hwriteerr;
SECURITY_ATTRIBUTES sao = { sizeof(sao),NULL,TRUE };
SECURITY_ATTRIBUTES sae = { sizeof(sae),NULL,TRUE };
CreatePipe(&hreadout, &hwriteout, &sao, 0);
CreatePipe(&hreaderr, &hwriteerr, &sae, 0);
SetStdHandle(STD_OUTPUT_HANDLE, hwriteout);
SetStdHandle(STD_ERROR_HANDLE, hwriteerr);
This snippet successfully sets stdout and stderr to the write ends of the anonymous pipes and I can capture the data.
However calling AllocConsole will spawn a Conhost.exe - this is the actual black window that pops to the screen. I don't have a use for this and most importantly, I would like to avoid the process creation of a child conhost.exe under my program.
So the question is, how can I fool Windows into thinking it has a console attached/manually setup the initial stdout and stderr file streams so that I can then redirect them as I have done already? I have looked at the AllocConsole call in a debugger as well as GetStdHandle and SetStdHandle to try and get a sense of what is going on, but my RE skills are lacking.
Without AllocConsole, the freopen_s calls fail with error 6, Invalid Handle. GetStdHandle also returns a NULL handle. Calling SetStdHandle succeeds (based on it's return code and calling GetLastError), however this doesn't appear to actually get things set up where I need them as I don't receive any output in my pipe.
Any ideas?
Use the SetStdHandle function to assign your pipe HANDLE values to STD_INPUT_HANDLE and STD_OUTPUT_HANDLE.

Running cat /proc/cpuinfo in glib

I've been trying to look for questions on how to use g_spawn_sync() and they said that it is good to use when you want to execute a command in the terminal besides using pipes.
The only thing I can't figure out now is why the command cat /proc/cpuinfo doesn't work. error->message returns (No such file or directory)but if I use commands like ls or cat alone, it works. I also tried running cd /proc && cat cpuinfo but it gives me the same error.
I'm not an expert of glib but I read in the manual that I can use G_SPAWN_SEARCH_PATH so that it will check my PATH for the commands I can use without including the absolute path for the command.
I have the following code:
gchar *argv[] = { "cat /proc/cpuinfo", NULL };
char *output = NULL; // will contain command output
GError *error = NULL;
int exit_status = 0;
if (!g_spawn_sync(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
&output, NULL, &exit_status, &error))
{
printf("[getHardwareInfo] DEBUG: Error on g_spawn_sync %s.\n", error->message);
}
tl;dr: Do not use g_spawn_command_line_sync() unless you really know what you are doing.
Firstly, the actual problem you are hitting: John Szakmeister’s comment was correct: g_spawn_sync() takes an array of arguments, the first one of which is the path to the program to execute (or to look for in $PATH, if you’ve specified G_SPAWN_SEARCH_PATH). By passing the array { "cat /proc/cpuinfo", NULL }, you are saying that you want to run the program cat /proc/cpuinfo with no arguments, not the program cat with the argument /proc/cpuinfo.
However, there are many other problems here, and I think it’s important to mention them before people start cargo-culting this code, because they have security implications:
As LegalProgrammer says, why are you spawning cat when you could just call g_file_get_contents()?
Failing that, use GSubprocess instead of g_spawn_*(). It’s a more modern API, which allows you to monitor the lifecycle of the spawned process more easily, as well as getting streaming I/O in and out of the subprocess.
Do not ignore the warnings in the manual about the security implications of using g_spawn_command_line_sync(). There are several:
It will run the first matching program found in your $PATH, so if an attacker has control of your $PATH, or write access to any directory in that $PATH (such as ~/.local/bin), you will end up running an attacker-controlled program.
It’s a synchronous function, so will block on the subprocess completing, which could take unbounded time. Your program will be unresponsive for that time.
It returns the output in a single allocation, rather than as a stream, so if the subprocess returns many megabytes of output, you may hit allocation failures and abort.
The obvious next step from “g_spawn_command_line_sync() seems to do what I want” is “let’s use g_strdup_printf() to put together a command to run with it”, and then you have shell injection vulnerabilities, where an attacker who controls any of the parameters to that printf() can twist the entire shell command to execute their arbitrary code.
I'm answering my question here. After reading the manual again, I decided to use another function, g_spawn_command_line_sync, which is simpler to use than g_spawn_sync.
A simple version of g_spawn_sync() with little-used parameters removed, taking a command line instead of an argument vector. See g_spawn_sync() for full details. command_line will be parsed by g_shell_parse_argv(). Unlike g_spawn_sync(), the G_SPAWN_SEARCH_PATH flag is enabled. Note that G_SPAWN_SEARCH_PATH can have security implications, so consider using g_spawn_sync() directly if appropriate. Possible errors are those from g_spawn_sync() and those from g_shell_parse_argv().
Here is my new code:
char *output = NULL; // will contain command output
GError *error = NULL;
gint exit_status = 0;
if (!g_spawn_command_line_sync("cat /proc/cpuinfo", &output, NULL, &exit_status, &error))
{
printf("[getHardwareInfo] DEBUG: Error on g_spawn_command_line_sync %s.\n", error->message);

How to make c programe as daemon in ubuntu?

Hi I am new to the linux environment. I am trying to create daemon process.
#include<stdio.h>
int main()
{
int a=10,b=10,c;
c=sum(a,b);
printf("%d",c);
return (0);
}
int sum(int a,int b)
{
return a+b;
}
I want to create daemon process of it. May i know how can do this? Any help would be appreciated. Thank you.
A daemon generally doesn't use its standard input and output streams, so it is unclear how your program could be run as a daemon. And a daemon program usually don't have any terminal, so it cannot use clrscr. Read also the tty demystified page, and also daemon(7).
I recommend reading some good introduction to Linux programming, like the old freely downloadable ALP (or something newer). We can't explain all of it here, and you need to read an entire book. See also intro(2) and syscalls(2).
I also recommend reading more about OSes, e.g. the freely available Operating Systems: Three Easy Pieces textbook.
You could use the daemon(3) function in your C program to run it as a daemon (but then, you are likely to not have any input and output). You may want to log messages using syslog(3).
You might consider job control facilities of your shell. You could run your program in the background (e.g. type myprog myarg & in your interactive shell). You could use the batch command. However neither background processes nor batch jobs are technically daemons.
Perhaps you want to code some ONC-RPC or JSONRPC or Web API server and client. You'll find libraries for that. See also pipe(7), socket(7)
(take several days or several weeks to read much more)
First find what are the properties of daemon process, as of my knowledge a daemon process have these properties:
Should not have any parent (it itself should be parent)
Process itself is a session leader.
Environment change to root.
File mode creating mask should be zero.
No controlling terminal.
All terminal should be removed
Should not be un-mounted .
Implement the code by considering above properties which is
int i=0;
int main()
{
int pid;
pid=fork();
if(pid!=0) {
/** you can add your task here , whatever you want to run in background **/
exit(0);
}
else
{
setsid();//setting sessions
chdir("/");//root.. should'nt beunmounted
umask(0);
close(0);//all terminal are removed
close(1);
close(2);
while(1)
{
printf("i = %d \n",i);
i++;
}
}
return 0;
}
or you can go through man page of daemon()
int daemon(int nochdir, int noclose);
I hope it helps.
Instead of writing the code to make the C program a daemon I would go with an already mature tool like supervisor:
http://supervisord.org/
I think this below will work
screen cmd arg1 arg2
You can also try
nohup cmd arg1

Libssh remote commands not executing on server

Having read the relevant docs and tutorials and found a similar question, I am still unable to proceed. My aplogies in advance if this is a common question. I did searches but I wasn't really sure what I was looking for...
I am experimenting with the Libssh for C in Debian.
rc = ssh_channel_request_exec(channel, "ls -l");
if (rc != SSH_OK) {
ssh_channel_close(channel);
ssh_channel_free(channel);
return rc;
}
This returns SSH_OK to state that the command was sent successfully. As I understand from a similar question this is because the return listens for the successful 'sending' of the command. The return does not listen to see if it has been successfully executed.
My questions is, how can I:
Execute the command (which by the above function presently does not execute it merely sends the command)
Listen for it's execution
print the returning output?
I am aware of the ssh_channel_read() function but as the command never executes, I usually get the output
Read (256) buffered : 0 bytes. Window: 64000
Take a look at examples/exec.c in the libssh source code!

Two mains in program

here is the situation: I need to send a data to a neighbor(socket) and then switch to listening mode. Ive got a client part in client.c, which just listens, and server part in server.c - sends data. Using sockets I need to have a main() in both of them. How should I get them "cooperate" together, so both mainss are not going result in error?
Or any other ideas how to solve this issue with sending and listening?
Thanks in advance!
Lucas
You can always create two executables from the sources. Each of them will have its own main.
Or, you can create a single executable and let it fork another process or create another thread. When creating a new thread you'll specify the second "main" to be the thread function.
When fork-ing, you should create two functions main_server and main_client and let the actual main decide which of them to call, just after the fork. See snippet:
int main_server(int argc, int argv){
//TODO: complete
return 0;
}
int main_client(int argc, int argv){
//TODO: complete
return 0;
}
int main(int argc, int argv){
//TODO: parse args and get argv_server, argv_client, argc_server, argc_client
int pid = fork();
if (pid < 0) {
//TODO: handle error and leave
} else if (pid) {
// start client here for example
main_client(argc_client, argv_client);
} else {
main_server(argc_server, argv_server);
wait(pid);
}
return 0;
/* TODO: each of the above calls should be checked for errors */
}
Hope it helps.
Note: it's better to create a separate executable but if you are required to have only one, use the above snippet.
The thing to remember is that these programs will compile into separate binaries that become separate processes. You will start the "server" program (which will run its main) and then the client program (which will run its main). They communicate over the socket you're creating.
Another solution to do this is using "select()" method. This is only for the socket programming in Linux/Unix environment. Using this you can have both sending and listening task done in the same main(). Here's the tutorial for this method.
http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#selectman
What it does is that instead of using fork() it puts all the sockets in a read_set. and then it goes into an infinite do-while() loop. Now this is very useful for socket programming in Linux/Unix. What happens in Linus/Unix each socket is assigned a File Descriptor(FD) in which they write the data and then it is transferred. It treats I/O console as a FD. So it puts the console FD in read_set, then all the other listening ports in read_set and then waits for the data from any of the above FD. So if you have data in console it will select that FD and perform the task you've written. Or will be in the listening mode until you close the program.
Now this is better than the fork() one because while using fork(), if didn't handled properly it could create a fork-bomb which would create processes recursively and will bomb your main memory. So its better to create a single process and have both functionality in it.

Resources