Watching new entries on Linux Syslog from a C program - c

I want to write a program that monitors syslog and performs an action when PPP authentication fails.
I think "tail -f /var/log/syslog" could help, but I'm not sure how to use it... probably using pipes?
I have found something similar written in bash, but I'm not sure how to implement it in C.
This is the bash method:
First create a named pipe using mkfifo:
$ mkfifo -p /home/mezgani/syslog.pipe
Make syslog.conf to points to this file:
*.info |/home/mezgani/syslog.pipe
Restart syslog:
$ sudo pkill -HUP syslogd
Create processing script that read the pipe
$ cat > foo
#!/bin/bash
cat /home/mezgani/syslog.pipe | while read input
do
# some stuff
echo ${input}
# ….
done

Finally I could found the solution!!
The solution was using named pipes!
First, I need to create a named pipe:
mkfifo /pipe
Then, I feed the pipe with the log info:
tail -f /var/log/syslog > /pipe
And then, I read the pipe from the C program using OPEN
int pipefd;
pipefd = open("/tmp/myFIFO", O_WRONLY);

Try to use inotify function. Using it you can monitor if a file or directory has changed.

Related

Is it possible to redirect stdout to two places in C?

I've been stuck on this for a while now, is it possible to redirect stdout to two different places? I am writing my own shell for practice, and it can currently run commands like ps aux | wc -l or ps aux | wc -l > output.file. However, when I try to run ps aux > file.out | wc -l, the second command does not receive the input from the first.
In the last example, the first command would be run in a child process that would output to one end of the pipe. The logic is similar to what follows:
close(stdout);
dup2(fd[1], STDOUT_FILENO);
//If a file output is also found
filewriter = open(...);
dup2(filewriter, STDOUT_FILENO);
//Execute the command
Normal UNIX shells don't work with that syntax either. UNIX (and some other OSs) provides the tee[1] command to send output to a file and also stdout.
Example:
ps aux | tee file.out | wc -l
[1] See http://en.wikipedia.org/wiki/Tee_(command)
The tee command does just that in UNIX. To see how to do it in straight C, why not look at tee's source code?

Get the output of multiple strace calls in one file

I want to get the Output of multiple strace calls in one file,
but i do not know how.
At the moment i am using:
strace -o tmpfile, but this just puts the output of one file in and then overrites the file with the new output.
Has anyone an idea, how to do this?
I hope this is no dumb question.
Thanks in advance.
Under the bash shell use the following command
strace -o >(cat >>outputfile) command [args] ...
This will pass to the -o flag an argument that will appear like a file, but will be instead a file descriptor to the standard input of the
cat >>outputfile
process. This process will append its input to the specified output file.
Instead of strace -o somefile command, can you just do strace command >> somefile? Alternatively, assuming a similar version of strace, my manual for strace indicates this should work: strace -o "|tail -a somefile" command (the -o "|command" functionality is implemented by strace itself, not by the shell).
I could not manage to do this via the call itself (in the Android Shell).
I just read through all files and write them to one Log file.
This solution slows the whole process down, but was the only solution I found.
The strace output is on stderr, strace 2>> outfile did the trick for me. If you invoke strace as single command you have to call it like this: adb -e shell "strace -p pid 2>> file"

execute shell command with sudo in c program

What is the best way to execute this command: "sudo cat /var/log/auth.log | grep Accepted" inside my C program ?
I tried to use:
sprintf(command_result,"sudo cat /var/log/auth.log | grep Accepted");
But it didn't work obviously.
You cannot execute the command with sprintf() you need system() atleast
fix:
sprintf(command_result, "sudo cat /var/log/auth.log | grep Accepted");
system(command_result);
you can execute the command with pipe
FILE *fp;
fp=popen(command_result,"r");
and then you can read the command output from the pipe fp like you read from files with fgets() or fread()...
BTW you can not execute sudo command if the password is required in the sudo command

Executing shell script with system() returns 256. What does that mean?

I've written a shell script to soft-restart HAProxy (reverse proxy). Executing the script from the shell works. But I want a daemon to execute the script. That doesn't work. system() returns 256. I have no clue what that might mean.
#!/bin/sh
# save previous state
mv /home/haproxy/haproxy.cfg /home/haproxy/haproxy.cfg.old
mv /var/run/haproxy.pid /var/run/haproxy.pid.old
cp /tmp/haproxy.cfg.new /home/haproxy/haproxy.cfg
kill -TTOU $(cat /var/run/haproxy.pid.old)
if haproxy -p /var/run/haproxy.pid -f /home/haproxy/haproxy.cfg; then
kill -USR1 $(cat /var/run/haproxy.pid.old)
rm -f /var/run/haproxy.pid.old
exit 1
else
kill -TTIN $(cat /var/run/haproxy.pid.old)
rm -f /var/run/haproxy.pid
mv /var/run/haproxy.pid.old /var/run/haproxy.pid
mv /home/haproxy/haproxy.cfg /home/haproxy/haproxy.cfg.err
mv /home/haproxy/haproxy.cfg.old /home/haproxy/haproxy.cfg
exit 0
fi
HAProxy is executed with user haproxy. My daemon has it's own user too. Both run with sudo.
Any hints?
According to this and that, Perl's system() returns exit values multiplied by 256. So it's actually exiting with 1. It seems this happens in C too.
Unless system returns -1 its return value is of the same format as the status value from the wait family of system calls (man 2 wait). There are macros to help you interpret this status:
man 3 wait
Lists these macros and what they tell you.
A code of 256 probably means that the system command cannot locate the binary to run it. Remember that it may not be calling bash and that it may not have paths setup. Try again with full paths to the binaries!
I have the same problem when call script that contains `kill' command in a daemon.
The daemon must have closed the stdout, stderr...
Use something like system("scrips.sh > /dev/null") should work.

How to create special files that talk to BASH shell

I'm trying to use someone else's [c] code that controls a linux shell over a wireless usb device. It fopen-s files "IReadFromBash" and "IWriteToBash" in the current dir to communicate. It comes with no notes but obviously expects a special file to already exist to facilitate this, and segfaults without them. Is there some obvious way to create named in- and out-files that connect to a shell?
Really just a guess on my part but I suspect they'll be named pipes, created with mknod. That seems to me the best way to achieve the desired goal.
You can see this in operation here. From a terminal session:
pax> mknod infile p
pax> mknod outfile p
pax> bash <infile >outfile
Then, from another terminal:
pax> echo ls >infile
pax> cat outfile | sed 's/^/ /'
backup0.sh
backup1.sh
Desktop
Downloads
infile
Music
outfile
Pax
Pictures
Public
super_sekrit_porn
Templates
Videos
workspace
pax> _

Resources