*** 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);