Another year is about to end... So we have to update these damn copyright information :P
[NeonServV5.git] / src / cmd_neonserv_extscript.c
index 21aad8b9f0abb844d2fb26c9e50126906eb3f2bb..d060d57e1ddc2155ca34d9bd7538aed04a1b0bd2 100644 (file)
@@ -1,5 +1,5 @@
-/* cmd_neonserv_extscript.c - NeonServ v5.2
- * Copyright (C) 2011  Philipp Kreil (pk910)
+/* cmd_neonserv_extscript.c - NeonServ v5.3
+ * Copyright (C) 2011-2012  Philipp Kreil (pk910)
  * 
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
  */
 
 #include "cmd_neonserv.h"
+#include <fcntl.h>
 
 /*
 * argv[0]      'toys' if it's a toy command (check if toys are enabled)
 * argv[argc-1] all arguments passed to the command
 */
 
+static TIMEQ_CALLBACK(neonserv_cmd_extscript_callback);
+
+struct neonserv_cmd_extscript_cache {
+    struct ClientSocket *client, *textclient;
+    struct Event *event;
+    struct UserNode *user;
+    struct ChanNode *chan;
+    int answere_channel;
+    FILE *pipe;
+};
+
 CMD_BIND(neonserv_cmd_extscript) {
     int i, j;
     char *args[MAXNUMPARAMS];
@@ -111,34 +123,48 @@ CMD_BIND(neonserv_cmd_extscript) {
     }
     command[commandpos] = '\0';
     //we should now have a valid command
-    struct ClientSocket *textbot = getTextBot();
-    pid_t pID = fork();
-    if (pID == 0) { //We're the child process :D
-        pID = fork();
-        if(pID < 0) exit(EXIT_FAILURE);
-        if(pID != 0) exit(EXIT_SUCCESS);
-        FILE *fp;
-        fp = popen(command, "r");
-        if (fp) {
-            char *a;
-            while (fgets(command, 1024, fp) != NULL) {
-                if((a = strchr(command, '\n'))) 
-                    *a = '\0';
-                if(answere_channel)
-                    putsock(client, "PRIVMSG %s :%s", chan->name, command);
-                else
-                    reply(textbot, user, "%s", command);
-            }
-            pclose(fp);
-        } else {
-            reply(getTextBot(), user, "internal bot error - please contact an administrator!");
+    
+    struct neonserv_cmd_extscript_cache *cache = malloc(sizeof(*cache));
+    if (!cache) {
+        perror("malloc() failed");
+        return;
+    }
+    cache->client = client;
+    cache->textclient = getTextBot();
+    cache->event = event;
+    cache->user = user;
+    cache->chan = chan;
+    cache->answere_channel = answere_channel;
+    cache->pipe = popen(command, "r");
+    #ifndef WIN32
+    fcntl(fileno(cache->pipe), F_SETFL, O_NONBLOCK);
+    #endif
+    timeq_add(1, neonserv_cmd_extscript_callback, cache);
+}
+
+static TIMEQ_CALLBACK(neonserv_cmd_extscript_callback) {
+    struct neonserv_cmd_extscript_cache *cache = data;
+    char command[512];
+    char *a;
+    if(feof(cache->pipe)) {
+        pclose(cache->pipe);
+        free(cache);
+        return;
+    }
+    while (fgets(command, 512, cache->pipe) != NULL) {
+        if((a = strchr(command, '\n'))) 
+            *a = '\0';
+        if(!stricmp(command, "/log")) {
+            logEvent(cache->event);
+            continue;
         }
-        exit(EXIT_FAILURE);
-    } else if (pID < 0) {
-        reply(getTextBot(), user, "internal bot error - please contact an administrator!");
-    } else {
-        //parent bot - continue program
-        wait(NULL);
+        if(cache->answere_channel)
+            putsock(cache->client, "PRIVMSG %s :%s", cache->chan->name, command);
+        else
+            reply(cache->textclient, cache->user, "%s", command);
     }
+    timeq_add(1, neonserv_cmd_extscript_callback, cache);
 }
 
+
+