-/* cmd_neonserv_extscript.c - NeonServ v5.1
+/* cmd_neonserv_extscript.c - NeonServ v5.3
* Copyright (C) 2011 Philipp Kreil (pk910)
*
* This program is free software: you can redistribute it and/or modify
*/
#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 UserNode *user;
+ struct ChanNode *chan;
+ int answere_channel;
+ FILE *pipe;
+};
+
CMD_BIND(neonserv_cmd_extscript) {
int i, j;
char *args[MAXNUMPARAMS];
int commandpos = 0;
char part[MAXLEN];
int partpos;
+ int escape_param;
int answere_channel = 0;
//check first arg
if(argc && !stricmp(argv[0], "toys")) {
commandpos = sprintf(command, "%s", argv[0]);
for(i = 1; i < argc-1; i++) {
partpos = 0;
+ escape_param = 1;
if(argv[i][0] == '$') {
argv[i]++;
if(argv[i][strlen(argv[i])-1] == '-') {
partpos = sprintf(part, "%s", ((user->flags & USERFLAG_ISAUTHED) ? user->auth : ""));
} else if(!strcmp(argv[i], "access")) {
if(chan)
- partpos = sprintf(part, "%d", getChannelAccess(user, chan, 0));
+ partpos = sprintf(part, "%d", getChannelAccess(user, chan));
}
} else {
partpos = sprintf(part, "%s", argv[i]);
+ escape_param = 0;
}
//escape shell argument
command[commandpos++] = ' ';
- command[commandpos++] = '\'';
- for(j = 0; j < partpos; j++) {
- if(part[j] == '\'') {
- command[commandpos++] = '\'';
- command[commandpos++] = '\\';
- command[commandpos++] = '\'';
- command[commandpos++] = '\'';
- } else
- command[commandpos++] = part[j];
- }
- command[commandpos++] = '\'';
+ if(escape_param) {
+ command[commandpos++] = '\'';
+ for(j = 0; j < partpos; j++) {
+ if(part[j] == '\'') {
+ command[commandpos++] = '\'';
+ command[commandpos++] = '\\';
+ command[commandpos++] = '\'';
+ command[commandpos++] = '\'';
+ } else
+ command[commandpos++] = part[j];
+ }
+ command[commandpos++] = '\'';
+ } else
+ commandpos += sprintf(command + commandpos, " %s", part);
}
command[commandpos] = '\0';
//we should now have a valid command
- 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(getTextBot(), user, "%s", command);
- }
- pclose(fp);
- } else {
- //error
- 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->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(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);
+}
+
+
+