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

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()