zmtrigger - connect through domain socket

Support and queries relating to all previous versions of ZoneMinder
Locked
desnaturado
Posts: 11
Joined: Wed Aug 04, 2004 7:02 pm
Location: Ilhabela, Brazil

zmtrigger - connect through domain socket

Post by desnaturado »

"Inspired" by this http://www.zoneminder.com/forums/viewtopic.php?t=4245 thread, I tried to connect to zmtrigger via domain sockets with a minimalistic client.

Code: Select all

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>

#define NOSTR		1
#define ADDRESS		"/tmp/zm.sock"

char *str_arr[NOSTR] ={
	"1|on+10|1|Snapshot|text"
};

main()
{
	char c;
	register int i, sh, len, ch;
	struct sockaddr_un saddr_un;
	if ((sh = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
	{
		perror("socket");
		exit(1);
	}
	saddr_un.sun_family = AF_UNIX;
	strcpy(saddr_un.sun_path, ADDRESS);

 	len = sizeof(saddr_un.sun_family) + strlen(saddr_un.sun_path);
	if ((ch = connect(sh, (struct sockaddr *) &saddr_un, len)) < 0)
	{
		perror("connect");
		exit(1);
	}
	for (i = 0; i < NOSTR; i++)
	{
		if (send(sh, str_arr[i], strlen(str_arr[i]), 0) < 0)
		{
			perror("send");
			exit(1);
		}
	}
	close(sh);
	exit(0);
}
No reaction from zmtrigger. Nothing in the zmtrigger.log. The client opens the socket, connects, seems to send the data (no error message) and exits cleanly.
"netstat -anp" shows this after the client exits:

Code: Select all

unix  2      [ ACC ]     STREAM     OUVINDO       16989    5778/perl           /tmp/zm.sock
unix  3      [ ]         STREAM     CONECTANDO    0        -                   /tmp/zm.sock
(ouvindo = listening, connectando = connecting, unix 2 = zmtrigger.pl, unix 3 = leftover of the client)
So the connection never passed from "connecting" to "connected". Strange enough, a minimalistic socket server I wrote accepts the connection like a charm and receives the data OK.

Could anybody push me in the right direction?

Thanks

Juergen
desnaturado
Posts: 11
Joined: Wed Aug 04, 2004 7:02 pm
Location: Ilhabela, Brazil

Problem solved - zmtrigger - connect through domain socket

Post by desnaturado »

I found what was wrong. I had initialized the @sources array in zmtrigger.pl with a new source like this

Code: Select all

{ name=>"S3", type=>"file", path=>"/tmp/zm.pipe", parser=>"", }
to try out pipes.
If I comment out this line, everything works perfectly. The client connects, writes the data and returns. zmtrigger accepts the connection, receives the data and does all of the messages handling.

There is only one question left:
Why doesn´t the whole shebang work with the pipe-source in the sources array although I don´t even use it?
My best guess is some sort of screw-up in the vec-bitmap that is used to query "select".

Regards

Juergen
desnaturado
Posts: 11
Joined: Wed Aug 04, 2004 7:02 pm
Location: Ilhabela, Brazil

Post by desnaturado »

Well, the last question is also answered:
I just learned that POSIX rules for select() require that you open named pipes r/w and not just r/o. If you change line 160 in zmtrigger.pl from :

Code: Select all

open( *sfh, "<".$source->{path} ) or die( "Can't open: $!" );
to:

Code: Select all

open( *sfh, "+<".$source->{path} ) or die( "Can't open: $!" );
everything works fine. I don´t know what the side effect for other file-based triggers are (ttys, devs, etc).

Regards

Juergen

PS: Does anybody hear me? :cry: Sort of a monologue ... I feel soo lonely ... Phil, you probably want to change that ...
User avatar
lazyleopard
Posts: 403
Joined: Tue Mar 02, 2004 6:12 pm
Location: Gloucestershire, UK

Post by lazyleopard »

Did you get the named-pipe one working?
Rick Hewett
desnaturado
Posts: 11
Joined: Wed Aug 04, 2004 7:02 pm
Location: Ilhabela, Brazil

Post by desnaturado »

name pipe one?? Don´t understand. Did you mean the INET and domain sockets?

My sources array looks like this:

Code: Select all

my @sources = (
	{ name=>"S1", type=>"inet", port=>"6802", parser=>"", },
	{ name=>"S2", type=>"unix", path=>"/tmp/zm.sock", parser=>"", },
	{ name=>"S3", type=>"file", path=>"/tmp/zm.pipe", parser=>"", }
);
My "homebrew" client connects ok to the inet socket and to the unix domain socket. And I can echo strings to the pipe. With the abovementioned change zmtrigger does what it´s supposed to do - trigger an alert.

Following a piece of the zmtrigger.log:

Code: Select all

Trigger daemon starting at 05/04/01 22:17:15
Opening source 'S1'
Opening source 'S2'
Opening source 'S3'
Got input from 1 sources
Got input from source S1 (5)
Added new connection (8), 1 connections
Got input from connection on S1 (8)
Got input from 1 sources
Got input from connection on S1 (8)
Got '1|on+5|255|Snapshot|text' (24 bytes)
Processing buffer '1|on+5|255|Snapshot|text'
Processing message '1|on+5|255|Snapshot|text'
Found monitor for id '1'
Handling action 'on+5'
Triggered event on 'Snapshot'
Added timed event '1|cancel|Snapshot|text', expires at 1112404662 (+5 secs)
Got input from 1 sources
Got input from connection on S1 (8)
Removed connection (8), 0 connections
Checking for timed actions at 1112404658
Checking for timed actions at 1112404659
Checking for timed actions at 1112404660
Checking for timed actions at 1112404661
Checking for timed actions at 1112404662
Checking for timed actions at 1112404663
Found actions expiring at 1112404662
Found action '1|cancel|Snapshot|text'
Processing buffer '1|cancel|Snapshot|text'
Processing message '1|cancel|Snapshot|text'
Found monitor for id '1'
Handling action 'cancel'
Cancelled event 'text'

Got input from 1 sources
Got input from connection on S2 (8)
Removed connection (8), 0 connections
Got input from 1 sources
Got input from source S2 (6)
Added new connection (8), 1 connections
Got input from connection on S2 (8)
Got input from 1 sources
Got input from connection on S2 (8)
Got '1|on+5|255|Snapshot|text' (24 bytes)
Processing buffer '1|on+5|255|Snapshot|text'
Processing message '1|on+5|255|Snapshot|text'
Found monitor for id '1'
Handling action 'on+5'
Triggered event on 'Snapshot'
Added timed event '1|cancel|Snapshot|text', expires at 1112404794 (+5 secs)
Got input from 1 sources
Got input from connection on S2 (8)
Removed connection (8), 0 connections
Checking for timed actions at 1112404790
Checking for timed actions at 1112404791
Checking for timed actions at 1112404792
Checking for timed actions at 1112404793
Checking for timed actions at 1112404794
Checking for timed actions at 1112404795
Found actions expiring at 1112404794
Found action '1|cancel|Snapshot|text'
Processing buffer '1|cancel|Snapshot|text'
Processing message '1|cancel|Snapshot|text'
Found monitor for id '1'
Handling action 'cancel'
Cancelled event 'text'

Got input from 1 sources
Got input from source S3 (7)
Got '1|on+5|255|Snapshot|text' (25 bytes)
Processing buffer '1|on+5|255|Snapshot|text'
Processing message '1|on+5|255|Snapshot|text'
Found monitor for id '1'
Handling action 'on+5'
Triggered event on 'Snapshot'
Added timed event '1|cancel|Snapshot|text', expires at 1112404821 (+5 secs)
Checking for timed actions at 1112404817
Checking for timed actions at 1112404818
Checking for timed actions at 1112404819
Checking for timed actions at 1112404820
Checking for timed actions at 1112404821
Checking for timed actions at 1112404822
Found actions expiring at 1112404821
Found action '1|cancel|Snapshot|text'
Processing buffer '1|cancel|Snapshot|text'
Processing message '1|cancel|Snapshot|text'
Found monitor for id '1'
Handling action 'cancel'
Cancelled event 'text'
Really nice this zmtrigger thingy. Currently I´m trying to daemonized it, but have my doubts that I will make it - I´m not that much of a programmer...

Regards

Juergen
User avatar
lazyleopard
Posts: 403
Joined: Tue Mar 02, 2004 6:12 pm
Location: Gloucestershire, UK

Post by lazyleopard »

desnaturado wrote:name pipe one??
Sorry. Old *nix terminology. I should have said "fifo". "man mkfifo" will tell more...
Rick Hewett
Locked