*** motion-3.2.4_snap4-orig/netcam.c	Sun Oct 30 03:52:57 2005
--- motion-3.2.4_snap4/netcam.c	Sat Nov 19 01:09:59 2005
***************
*** 146,152 ****
  {
  	char *s;
  	int i;
! 	const char *re = "(http|ftp)://(((.*):(.*))@)?"
  	                 "([^/:]|[-.a-z0-9]+)(:([0-9]+))?($|(/[^:]*))";
  	regex_t pattbuf;
  	regmatch_t matches[10];
--- 146,152 ----
  {
  	char *s;
  	int i;
! 	const char *re = "(http|ftp|exec)://(((.*):(.*))@)?"
  	                 "([^/:]|[-.a-z0-9]+)(:([0-9]+))?($|(/[^:]*))";
  	regex_t pattbuf;
  	regmatch_t matches[10];
***************
*** 190,196 ****
  		}
  	}
  	if (!parse_url->port) {
! 		if (!strcmp(parse_url->service, "http"))
  			parse_url->port = 80;
  		else if (!strcmp(parse_url->service, "ftp"))
  			parse_url->port = 21;
--- 190,196 ----
  		}
  	}
  	if (!parse_url->port) {
! 		if (!strcmp(parse_url->service, "http") || !strcmp(parse_url->service, "exec"))
  			parse_url->port = 80;
  		else if (!strcmp(parse_url->service, "ftp"))
  			parse_url->port = 21;
***************
*** 599,604 ****
--- 599,659 ----
  	}
  }
  
+ 
+ /* 
+  * for cams that so not stream images in a html'ized mjpeg stream
+  * here instead of opening a socket to a HTTP server
+  * we instead "open" a sockep to a local binary that
+  * connectes to the nonconformist camera and feeds us the
+  * html'ized mjpeg stream we want
+  */
+ static int netcam_html_exec_proxy(netcam_context_ptr netcam) {
+ int sockets[2], child;
+ 
+ 
+     if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
+ 	motion_log(LOG_ERR, 1,
+ 		       "socketpair error %m");
+ 	return(-1);
+     }
+ 
+     /* create child process */
+     if ((child = fork()) == -1) {
+ 	printf("fork error %d\n", errno);
+ 	motion_log(LOG_ERR, 1, "fork error %m");
+ 	exit(1);
+     }
+ 
+     if (child != 0) { /* parent */
+ 	close(sockets[0]);	/* close child's socket side */
+ 	netcam->sock = sockets[1];
+     } else {
+ 	int i;
+ 
+ 			  
+ 	close(sockets[1]);
+ 	/* Close any superfluous file descripters */
+ 	for (i=getdtablesize(); i>2; --i) {
+ 	    if(i == sockets[0])
+ 		continue;
+ 	    close(i);
+ 	}
+ 
+ 
+ 	motion_log(LOG_INFO, 0, "connect_exec_path = %s\n", netcam->connect_exec_path);
+ 
+ 	dup2(sockets[0], STDOUT_FILENO);
+ 
+ 	execl(netcam->connect_exec_path, netcam->connect_exec_path,
+ 		netcam->cnt->conf.netcam_url,
+ 		NULL);
+ 
+ 	exit(1);
+     }
+ 
+     return(0);
+ }
+ 
  /**
   * netcam_connect
   *
***************
*** 624,629 ****
--- 679,693 ----
  
  	/* Assure any previous connection has been closed */
  	netcam_disconnect(netcam);
+ 	netcam->sock = -1;
+ 
+ 	if ( netcam->connect_exec_path ) {
+ 	    ret = netcam_html_exec_proxy(netcam);
+ 		motion_log(LOG_INFO, 0,
+ 		           "netcam_html_exec_proxy ret=%d sock=%d",
+ 				ret, netcam->sock);
+ 
+ 	} else {
  
  	/* create a new socket */
  	if ((netcam->sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
***************
*** 737,742 ****
--- 801,808 ----
  		return -1;
  	}
  
+ 	} // exec_proxy
+ 
  	/* The socket info is stored in the rbuf structure of our context */
  	rbuf_initialize(netcam);
  
***************
*** 1354,1359 ****
--- 1420,1426 ----
  
  	/*
  	 * We are now ready to set up the netcam's "connect request".  Most of
+ 	 url.path = NULL;
  	 * this comes from the (preset) string 'connect_req', but additional
  	 * characters are required if there is a proxy server, or if there is
  	 * a username / password for the camera.  The variable 'ix' currently
***************
*** 1480,1486 ****
  		if ((cptr = strchr(ptr, ':')) == NULL)
  			netcam->ftp->user = strdup(ptr);
  		else {
! 			netcam->ftp->user = strndup(ptr, (cptr - ptr));
  			netcam->ftp->passwd = strdup(cptr + 1);
  		}
  	}
--- 1547,1553 ----
  		if ((cptr = strchr(ptr, ':')) == NULL)
  			netcam->ftp->user = strdup(ptr);
  		else {
! 			netcam->ftp->user = (char *)strndup(ptr, (cptr - ptr));
  			netcam->ftp->passwd = strdup(cptr + 1);
  		}
  	}
***************
*** 1793,1798 ****
--- 1860,1866 ----
  	memset(cnt->netcam, 0, sizeof(struct netcam_context));
  	netcam = cnt->netcam;           /* Just for clarity in remaining code */
  	netcam->cnt = cnt;              /* Fill in the "parent" info */
+ 	netcam->sock = -1;		/* init to a non-connected state PS */
  
  	/*
  	 * Fill in our new netcam context with all known initial
***************
*** 1849,1855 ****
--- 1917,1931 ----
  		netcam->connect_host = url.host;
  		url.host = NULL;
  		netcam->connect_port = url.port;
+ 		if(url.path && strncmp("exec:", cnt->conf.netcam_proxy, 5) == 0) {
+ 		    netcam->connect_exec_path = url.path;
+ 		    url.path = NULL;
+ 		}
  		netcam_url_free(&url);  /* Finished with proxy */
+ 		motion_log(LOG_INFO, 0, "host=%s, path=%s", /* ### */
+ 			netcam->connect_host,
+ 			( netcam->connect_exec_path ? netcam->connect_exec_path : "NULL")
+ 			);
  	}
  
  	/*
***************
*** 1869,1875 ****
  		netcam->connect_port = url.port;
  	}
  
! 	if (!strcmp(url.service, "http")) {
  		retval = netcam_setup_html(netcam, &url);
  	} else if (!strcmp(url.service, "ftp")) {
  		retval = netcam_setup_ftp(netcam, &url);
--- 1945,1951 ----
  		netcam->connect_port = url.port;
  	}
  
! 	if (!strcmp(url.service, "http") || !strcmp(url.service, "exec")) {
  		retval = netcam_setup_html(netcam, &url);
  	} else if (!strcmp(url.service, "ftp")) {
  		retval = netcam_setup_ftp(netcam, &url);
