@@ -476,7 +476,7 @@ void mystrftime_base(cls_camera *cam
476476
477477/* Old method for temporary use only. */
478478void mystrftime (cls_camera *cam, char *s, size_t mx_sz
479- , const char *usrfmt , const char *fname)
479+ , const char *usrcmd , const char *fname)
480480{
481481 std::string rslt, tmpnm;
482482 (void )mx_sz;
@@ -485,14 +485,14 @@ void mystrftime(cls_camera *cam, char *s, size_t mx_sz
485485 } else {
486486 tmpnm.assign (fname);
487487 }
488- mystrftime_base (cam, rslt, usrfmt , tmpnm);
488+ mystrftime_base (cam, rslt, usrcmd , tmpnm);
489489 sprintf (s, " %s" ,rslt.c_str ());
490490}
491491
492492void mystrftime (cls_camera *cam, std::string &rslt
493- , std::string usrfmt , std::string fname)
493+ , std::string usrcmd , std::string fname)
494494{
495- mystrftime_base (cam, rslt, usrfmt , fname);
495+ mystrftime_base (cam, rslt, usrcmd , fname);
496496}
497497
498498void mythreadname_set (const char *abbr, int threadnbr, const char *threadname)
@@ -666,66 +666,104 @@ AVPacket *mypacket_alloc(AVPacket *pkt)
666666
667667}
668668
669- void util_exec_command (cls_camera *cam, const char *command, const char *filename )
669+ void util_exec_command (cls_camera *cam, std::string usrcmd, std::string fname )
670670{
671- char stamp[PATH_MAX];
672- int pid;
673-
674- mystrftime (cam, stamp, sizeof (stamp), command, filename);
675-
676- pid = fork ();
677- if (!pid) {
678- /* Detach from parent */
679- setsid ();
680-
681- execl (" /bin/sh" , " sh" , " -c" , stamp, " &" ,(char *)NULL );
682-
683- /* if above function succeeds the program never reach here */
684- MOTION_LOG (ALR, TYPE_EVENTS, SHOW_ERRNO
685- ,_ (" Unable to start external command '%s'" ), stamp);
686-
687- exit (1 );
671+ std::string rslt, cmd_full, cmd_nm, tmp_parm;
672+ std::vector<std::string> parms;
673+ int pid, indx;
674+ size_t pos;
675+
676+ mystrftime (cam, rslt, usrcmd, fname);
677+ mytrim (rslt);
678+
679+ /* Parse the full command*/
680+ if (rslt[0 ] == ' "' ) {
681+ pos = rslt.find (' "' , 1 );
682+ cmd_full = rslt.substr (1 , pos-1 );
683+ pos++;
684+ } else if (rslt[0 ] == ' \' ' ) {
685+ pos = rslt.find (' \' ' , 1 );
686+ cmd_full = rslt.substr (1 , pos-1 );
687+ pos++;
688+ } else {
689+ pos = rslt.find (" " , 0 );
690+ cmd_full = rslt.substr (0 , pos);
688691 }
692+ mytrim (cmd_full);
689693
690- if (pid == 0 ) {
691- MOTION_LOG (ALR, TYPE_EVENTS, SHOW_ERRNO
692- , _ ( " Unable to start external command '%s' " ), stamp) ;
694+ /* Parse out the parameters */
695+ if (pos == std::string::npos) {
696+ tmp_parm = " " ;
693697 } else {
694- MOTION_LOG (DBG, TYPE_EVENTS, NO_ERRNO
695- ,_ (" Executing external command '%s'" ), stamp);
698+ tmp_parm = rslt.substr (pos+1 );
696699 }
697- }
700+ mytrim (tmp_parm);
698701
699- void util_exec_command (cls_camera *cam, std::string cmd)
700- {
701- std::string dst;
702- int pid;
702+ /* Parse out the command name to execute */
703+ pos = cmd_full.find_last_of (" /" );
704+ if (pos == std::string::npos) {
705+ cmd_nm = cmd_full;
706+ } else {
707+ cmd_nm = cmd_full.substr (pos+1 );
708+ }
709+ mytrim (cmd_nm);
710+
711+ /* The vector is being used for ease of programming
712+ and is likely not the most efficient way to get the
713+ values into the const char * array for execv
714+ */
715+ /* Parse the individual parameters into the vector*/
716+ parms.push_back (cmd_nm);
717+ while (tmp_parm != " " ) {
718+ if (tmp_parm[0 ] == ' "' ) {
719+ pos = tmp_parm.find (' "' , 1 )+1 ;
720+ } else if (tmp_parm[0 ] == ' \' ' ) {
721+ pos = tmp_parm.find (' \' ' , 1 )+1 ;
722+ } else {
723+ pos = tmp_parm.find (" " , 0 );
724+ }
725+ parms.push_back (tmp_parm.substr (0 , pos));
726+ if (pos == std::string::npos) {
727+ tmp_parm = " " ;
728+ } else {
729+ tmp_parm.erase (0 , pos+1 );
730+ }
731+ mytrim (tmp_parm);
732+ }
703733
704- mystrftime (cam, dst, cmd, " " );
734+ /* Put the vector into an array that can be processed by execv*/
735+ const char **parmv = new const char * [parms.size ()+1 ];
736+ for (indx = 0 ;indx<parms.size (); indx++) {
737+ parmv[indx] = parms[indx].c_str ();
738+ }
739+ parmv[indx]=nullptr ;
705740
706741 pid = fork ();
707742 if (!pid) {
708743 /* Detach from parent */
709744 setsid ();
710-
711- execl (" /bin/sh" , " sh" , " -c" , dst.c_str (), " &" ,(char *)NULL );
712-
713- /* if above function succeeds the program never reach here */
745+ execv (cmd_full.c_str (), (char **)parmv);
746+ /* if above function succeeds the program never reaches here */
714747 MOTION_LOG (ALR, TYPE_EVENTS, SHOW_ERRNO
715- ,_ (" Unable to start external command '%s' " ),dst .c_str ());
748+ ,_ (" Unable to start external command >%s< " ), rslt .c_str ());
716749
717750 exit (1 );
718751 }
719752
720- if (pid > 0 ) {
721- waitpid (pid, NULL , 0 );
722- } else {
753+ if (pid == 0 ) {
723754 MOTION_LOG (ALR, TYPE_EVENTS, SHOW_ERRNO
724- ,_ (" Unable to start external command '%s'" ), dst.c_str ());
755+ ,_ (" Unable to start external command >%s<" ), rslt.c_str ());
756+ } else {
757+ MOTION_LOG (DBG, TYPE_EVENTS, NO_ERRNO
758+ ,_ (" Executing external command >%s<" ), rslt.c_str ());
725759 }
726760
727- MOTION_LOG (DBG, TYPE_EVENTS, NO_ERRNO
728- ,_ (" Executing external command '%s'" ), dst.c_str ());
761+ }
762+
763+ /* Legacy format with chars */
764+ void util_exec_command (cls_camera *cam, const char *c_usrcmd, const char *c_fname)
765+ {
766+ util_exec_command (cam,std::string (c_usrcmd), std::string (c_fname));
729767}
730768
731769void util_exec_command (cls_sound *snd, std::string cmd)
@@ -742,7 +780,7 @@ void util_exec_command(cls_sound *snd, std::string cmd)
742780
743781 execl (" /bin/sh" , " sh" , " -c" , dst.c_str (), " &" ,(char *)NULL );
744782
745- /* if above function succeeds the program never reach here */
783+ /* if above function succeeds the program never reaches here */
746784 MOTION_LOG (ALR, TYPE_EVENTS, SHOW_ERRNO
747785 ,_ (" Unable to start external command '%s'" ),dst.c_str ());
748786
0 commit comments