diff --git a/.gitignore b/.gitignore
index 7f4c3fab..c59e1718 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,6 +27,7 @@ data/camera1-dist.conf
data/camera2-dist.conf
data/camera3-dist.conf
data/sound1-dist.conf
+data/webcontrol/samplepage.html
#src
src/*.o
diff --git a/Makefile.am b/Makefile.am
index 1ea3302a..237638e7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,6 +23,7 @@ SUBDIRS = src po
pkgsysconfdir = $(sysconfdir)/@PACKAGE@
libstatedir = @localstatedir@/lib/@PACKAGE@
+libwebdir = @localstatedir@/lib/@PACKAGE@/webcontrol
dist_libstate_DATA = \
data/motion-dist.conf \
@@ -31,6 +32,9 @@ dist_libstate_DATA = \
data/camera3-dist.conf \
data/sound1-dist.conf
+dist_libweb_DATA = \
+ data/webcontrol/samplepage.html
+
dist_man_MANS = man/motion.1
dist_doc_DATA = \
@@ -60,6 +64,7 @@ cleanall: distclean
@rm -f data/motion-dist.service data/motion-dist.conf
@rm -f data/camera1-dist.conf data/camera2-dist.conf
@rm -f data/camera3-dist.conf data/sound1-dist.conf
+ @rm -f data/webcontrol/samplepage.conf
###################################################################
## Testing options for maintainer
diff --git a/configure.ac b/configure.ac
index a85095e4..b47357a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -662,6 +662,7 @@ AC_CONFIG_FILES([
data/sound1-dist.conf
data/motion-dist.conf
data/motion-dist.service
+ data/webcontrol/samplepage.html
])
AC_OUTPUT
diff --git a/doc/samplepage.html b/data/webcontrol/samplepage.html.in
similarity index 100%
rename from doc/samplepage.html
rename to data/webcontrol/samplepage.html.in
diff --git a/doc/motion_config.html b/doc/motion_config.html
index e54830fe..fb82e546 100644
--- a/doc/motion_config.html
+++ b/doc/motion_config.html
@@ -2468,7 +2468,14 @@
webcontrol_html
- Values: String | Default: Not defined
- The full path and file name for a user specified html page to use as the webcontrol.
+ The file name for a user specified html page to use as the webcontrol. The file
+ must be placed in a subdirectory from the motion.conf file called webcontrol. e.g.
+ if the motion.conf file is located
+ at /var/lib/motion/motion.conf, the webcontrol
+ page must be located in the directory
+ /var/lib/motion/webcontrol. Additionally, any files
+ in the webcontrol directory with an extension of html, json, js or css will also
+ be available as resources to the user html page.
diff --git a/src/util.cpp b/src/util.cpp
index 2f16e408..d7244b25 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -62,6 +62,19 @@ int mystrne(const char* var1, const char* var2)
return (strcmp(var1,var2) ? 1: 0);
}
+/*Convert string to lower case*/
+void mylower(std::string &parm)
+{
+ if (parm.length() == 0 ) {
+ return;
+ }
+
+ std::transform(parm.begin(),parm.end(),parm.begin()
+ ,[](unsigned char c)
+ { return std::tolower(c); });
+
+}
+
/* Trim whitespace from left side */
void myltrim(std::string &parm)
{
diff --git a/src/util.hpp b/src/util.hpp
index 977e724a..8e710193 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -94,6 +94,7 @@ struct ctx_params {
int mystrcne(const char* var1, const char* var2);
int mystreq(const char* var1, const char* var2);
int mystrne(const char* var1, const char* var2);
+ void mylower(std::string &parm);
void myltrim(std::string &parm);
void myrtrim(std::string &parm);
void mytrim(std::string &parm);
diff --git a/src/webu_ans.cpp b/src/webu_ans.cpp
index 62fa0fa6..acf1a82d 100644
--- a/src/webu_ans.cpp
+++ b/src/webu_ans.cpp
@@ -102,7 +102,7 @@ int cls_webu_ans::parseurl()
size_t pos_slash1, pos_slash2, baselen;
/* Example: /camid/cmd1/cmd2/cmd3 */
- uri_camid = "";
+ uri_cmd0 = "";
uri_cmd1 = "";
uri_cmd2 = "";
uri_cmd3 = "";
@@ -149,9 +149,9 @@ int cls_webu_ans::parseurl()
pos_slash1 = url.find("/", baselen+1);
if (pos_slash1 != std::string::npos) {
- uri_camid = url.substr(baselen+1, pos_slash1-baselen- 1);
+ uri_cmd0 = url.substr(baselen+1, pos_slash1-baselen- 1);
} else {
- uri_camid = url.substr(baselen+1);
+ uri_cmd0 = url.substr(baselen+1);
return 0;
}
@@ -201,22 +201,22 @@ void cls_webu_ans::parms_edit()
int indx, is_nbr;
if (parseurl() != 0) {
- uri_camid = "";
+ uri_cmd0 = "";
uri_cmd1 = "";
uri_cmd2 = "";
uri_cmd3 = "";
url = "";
}
- if (uri_camid.length() > 0) {
+ if (uri_cmd0.length() > 0) {
is_nbr = true;
- for (indx=0; indx < (int)uri_camid.length(); indx++) {
- if ((uri_camid[(uint)indx] > '9') || (uri_camid[(uint)indx] < '0')) {
+ for (indx=0; indx < (int)uri_cmd0.length(); indx++) {
+ if ((uri_cmd0[(uint)indx] > '9') || (uri_cmd0[(uint)indx] < '0')) {
is_nbr = false;
}
}
if (is_nbr) {
- device_id = atoi(uri_camid.c_str());
+ device_id = atoi(uri_cmd0.c_str());
}
}
@@ -228,10 +228,10 @@ void cls_webu_ans::parms_edit()
}
MOTION_LOG(DBG, TYPE_STREAM, NO_ERRNO
- , "camid: >%s< camindx: >%d< cmd1: >%s< cmd2: >%s< cmd3: >%s<"
- , uri_camid.c_str(), camindx
- , uri_cmd1.c_str(), uri_cmd2.c_str()
- , uri_cmd3.c_str());
+ , "cmd0: >%s< cmd1: >%s< cmd2: >%s< cmd3: >%s< camindx: >%d< "
+ , uri_cmd0.c_str(), uri_cmd1.c_str()
+ , uri_cmd2.c_str(), uri_cmd3.c_str()
+ , camindx );
}
@@ -951,7 +951,7 @@ cls_webu_ans::cls_webu_ans(cls_motapp *p_app, const char *uri)
char *tmplang;
url = "";
- uri_camid = "";
+ uri_cmd0 = "";
uri_cmd1 = "";
uri_cmd2 = "";
uri_cmd3 = "";
diff --git a/src/webu_ans.hpp b/src/webu_ans.hpp
index 84ae70f8..0ec5c277 100644
--- a/src/webu_ans.hpp
+++ b/src/webu_ans.hpp
@@ -33,10 +33,10 @@
std::string lang; /* Two character abbreviation for locale language*/
std::string url; /* The URL sent from the client */
- std::string uri_camid; /* Parsed camera number from the url eg /camid/cmd1/cmd2/cmd3 */
- std::string uri_cmd1; /* Parsed command1 from the url eg /camid/cmd1/cmd2/cmd3 */
- std::string uri_cmd2; /* Parsed command2 from the url eg /camid/cmd1/cmd2/cmd3 */
- std::string uri_cmd3; /* Parsed command3 from the url eg /camid/cmd1/cmd2/cmd3 */
+ std::string uri_cmd0; /* Parsed command1 from the url eg /cmd0/cmd1/cmd2/cmd3 */
+ std::string uri_cmd1; /* Parsed command1 from the url eg /cmd0/cmd1/cmd2/cmd3 */
+ std::string uri_cmd2; /* Parsed command2 from the url eg /cmd0/cmd1/cmd2/cmd3 */
+ std::string uri_cmd3; /* Parsed command3 from the url eg /cmd0/cmd1/cmd2/cmd3 */
enum WEBUI_RESP resp_type; /* indicator for the type of response to provide. */
std::string resp_page; /* The response that will be sent */
diff --git a/src/webu_html.cpp b/src/webu_html.cpp
index fea996c1..eb393302 100644
--- a/src/webu_html.cpp
+++ b/src/webu_html.cpp
@@ -1596,20 +1596,66 @@ void cls_webu_html::default_page()
void cls_webu_html::user_page()
{
char response[PATH_MAX];
+ std::string fname, ext;
+ size_t pos;
FILE *fp = NULL;
webua->resp_page = "";
- fp = myfopen(app->cfg->webcontrol_html.c_str(), "re");
+ pos = app->cfg->conf_filename.find("/",0);
+ if (pos == std::string::npos) {
+ MOTION_LOG(ERR, TYPE_STREAM, NO_ERRNO
+ , _("Unable to determine base path for: %s")
+ , app->cfg->conf_filename.c_str());
+ return;
+ }
+ fname = app->cfg->conf_filename.substr(0,
+ app->cfg->conf_filename.find_last_of("/"));
+ fname += "/webcontrol";
+
+ if (webua->uri_cmd0 == "") {
+ fname += "/"+app->cfg->webcontrol_html;
+ } else {
+ fname += webua->url;
+ }
+
+ pos = fname.find(".", 0);
+ if (pos == std::string::npos) {
+ ext = "";
+ } else {
+ ext = fname.substr(fname.find_last_of(".")+1);
+ }
+ mylower(ext);
+ if (ext == "json") {
+ webua->resp_type = WEBUI_RESP_JSON;
+ } else if ((ext == "js") || (ext == "css")) {
+ webua->resp_type = WEBUI_RESP_TEXT;
+ } else if (ext == "html") {
+ webua->resp_type = WEBUI_RESP_HTML;
+ } else {
+ MOTION_LOG(ERR, TYPE_STREAM, NO_ERRNO
+ , _("Invalid file requested: %s")
+ , fname.c_str());
+ return;
+ }
+
+ MOTION_LOG(DBG, TYPE_STREAM, NO_ERRNO
+ , _("Retrieving file: %s type/extension: %d/%s")
+ , fname.c_str(), webua->resp_type, ext.c_str());
+
+ fp = myfopen(fname.c_str(), "re");
if (fp == NULL) {
MOTION_LOG(ERR, TYPE_STREAM, NO_ERRNO
- , _("Invalid user html file: %s")
- , app->cfg->webcontrol_html.c_str());
+ , _("Invalid user requested file: %s")
+ , fname.c_str());
+ return;
} else {
while (fgets(response, PATH_MAX-1, fp)) {
webua->resp_page += response;
}
myfclose(fp);
}
+
+
}
void cls_webu_html::main()