Massively cleaned up #include's, so they're in a consistent
[freeradius.git] / src / main / exec.c
index f9094ba..aa982b0 100644 (file)
 #include <freeradius-devel/ident.h>
 RCSID("$Id$")
 
-#include <freeradius-devel/autoconf.h>
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/rad_assert.h>
 
 #include <sys/file.h>
 
-#include <stdlib.h>
-#include <string.h>
 #include <fcntl.h>
 #include <ctype.h>
 #include <signal.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 #ifdef HAVE_SYS_WAIT_H
 #      include <sys/wait.h>
 #endif
@@ -47,9 +42,6 @@ RCSID("$Id$")
 #      define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
 #endif
 
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/rad_assert.h>
-
 #define MAX_ARGV (256)
 /*
  *     Execute a program on successful authentication.
@@ -95,7 +87,7 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                return -1;
        }
 
-       strNcpy(mycmd, cmd, sizeof(mycmd));
+       strlcpy(mycmd, cmd, sizeof(mycmd));
 
        /*
         *      Split the string into argv's BEFORE doing radius_xlat...
@@ -226,7 +218,13 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                output_pairs = NULL;
        }
 
-       if ((pid = rad_fork(exec_wait)) == 0) {
+       if (exec_wait) {
+               pid = rad_fork();       /* remember PID */
+       } else {
+               pid = fork();           /* don't wait */
+       }
+
+       if (pid == 0) {
 #define MAX_ENVP 1024
                int devnull;
                char *envp[MAX_ENVP];
@@ -438,7 +436,7 @@ int radius_exec_program(const char *cmd, REQUEST *request,
                if (n == T_OP_INVALID) {
                        DEBUG("Exec-Program-Wait: plaintext: %s", answer);
                        if (user_msg) {
-                               strNcpy(user_msg, answer, msg_len);
+                               strlcpy(user_msg, answer, msg_len);
                        }
                } else {
                        /*
@@ -481,26 +479,21 @@ int radius_exec_program(const char *cmd, REQUEST *request,
         *      Call rad_waitpid (should map to waitpid on non-threaded
         *      or single-server systems).
         */
-       for (n = 0; n < 10; n++) {
-               child_pid = rad_waitpid(pid, &status, WNOHANG);
-               if (child_pid == pid) {
-                       if (WIFEXITED(status)) {
-                               status = WEXITSTATUS(status);
-                               radlog(L_DBG, "Exec-Program: returned: %d", status);
-                               return status;
-                       }
-               }
-               if (child_pid < 0) {
-                       radlog(L_ERR|L_CONS, "Exec-Program: Failed to catch child return code");
-                       return 2;
+       child_pid = rad_waitpid(pid, &status);
+       if (child_pid == 0) {
+               radlog(L_DBG, "Exec-Program: Timeout waiting for child");
+               return 2;
+       }
+
+       if (child_pid == pid) {
+               if (WIFEXITED(status)) {
+                       status = WEXITSTATUS(status);
+                       radlog(L_DBG, "Exec-Program: returned: %d", status);
+                       return status;
                }
-               /*
-                *      If we haven't returned yet, the chile hasn't finished,
-                *      so sleep for 1 second then try again.
-                */
-               sleep(1);
        }
 
-       radlog(L_ERR|L_CONS, "Exec-Program: Child execution is taking too long.  Giving up.");
-       return 2;
+       radlog(L_ERR|L_CONS, "Exec-Program: Abnormal child exit: %s",
+              strerror(errno));
+       return 1;
 }