#include "../core/config.h"
#include "../core/events.h"
#include "../lib/version.h"
+#include "../core/schedule.h"
#include "nterfacer.h"
#include "logging.h"
continue;
}
- item->ihost = (*(struct in_addr *)host->h_addr).s_addr;
+ item->ihost = (*(struct in_addr *)host->h_addr_list[0]).s_addr;
for(j=0;j<loaded_lines;j++) {
if(new_permits[j].ihost == item->ihost) {
nterface_log(nrl, NL_WARNING, "Host with items %d and %d is identical, dropping item %d.", j + 1, i + 1, i + 1);
if(argcount) {
parsebuf = (char *)ntmalloc(strlen(pp) + 1);
MemCheckR(parsebuf, RE_MEM_ERROR);
- newp = parsebuf;
for(newp=args[0]=parsebuf,pp++;*pp;pp++) {
if((*pp == '\\') && *(pp + 1)) {
return ri_final(ri);
}
+struct sched_rline {
+ rline rl;
+ int argc;
+ handler *hl;
+ void *schedule;
+ char argv[];
+};
+
+static const int XMAXARGS = 50;
+
+static void execrline(void *arg) {
+ struct sched_rline *sr = arg;
+ int re, i;
+ char *argv[XMAXARGS], *buf;
+
+ sr->schedule = NULL;
+
+ buf = sr->argv;
+ for(i=0;i<sr->argc;i++) {
+ argv[i] = buf;
+ buf+=strlen(buf) + 1;
+ }
+
+ re = (sr->hl->function)(&sr->rl, sr->argc, argv);
+
+ if(re)
+ Error("nterfacer", ERR_WARNING, "sendline: error occured calling %p %d: %s", sr->hl->function, re, request_error(re));
+}
+
void *nterfacer_sendline(char *service, char *command, int argc, char **argv, rline_callback callback, void *tag) {
struct service_node *servicep;
struct rline *prequest;
+ struct sched_rline *sr;
struct handler *hl;
- int re;
+ int totallen, i;
+ char *buf;
for(servicep=tree;servicep;servicep=servicep->next)
if(!strcmp(servicep->name->content, service))
break;
+ if(argc > XMAXARGS)
+ Error("nterfacer", ERR_STOP, "Over maximum arguments.");
+
if(!servicep) {
Error("nterfacer", ERR_WARNING, "sendline: service not found: %s", service);
return NULL;
return NULL;
}
- prequest = (struct rline *)ntmalloc(sizeof(struct rline));
- if(!prequest) {
+ /* we have to create a copy of the arguments for reentrancy reasons, grr */
+ totallen = 0;
+ for(i=0;i<argc;i++)
+ totallen+=strlen(argv[i]) + 1;
+
+ /* HACKY but allows existing code to still work */
+ sr = (struct sched_rline *)ntmalloc(sizeof(struct sched_rline) + totallen);
+ if(!sr) {
MemError();
return NULL;
}
+ prequest = &sr->rl;
+
+ sr->argc = argc;
+ buf = sr->argv;
+ for(i=0;i<argc;i++) {
+ size_t len = strlen(argv[i]) + 1;
+ memcpy(buf, argv[i], len);
+ buf+=len;
+ }
+ sr->hl = hl;
prequest->service = servicep;
prequest->handler = hl;
prequest->curpos = prequest->buf;
prequest->tag = tag;
prequest->id = 0;
- prequest->next = rlines;
prequest->socket = NULL;
prequest->callback = callback;
+ prequest->next = rlines;
rlines = prequest;
- re = (hl->function)(prequest, argc, argv);
- if(re) {
- Error("nterfacer", ERR_WARNING, "sendline: error occured calling %s %d: %s", command, re, request_error(re));
- return NULL;
- }
+ scheduleoneshot(time(NULL), execrline, sr);
- return (void *)prequest;
+ return (void *)sr;
}
void nterfacer_freeline(void *tag) {
- struct rline *prequest = tag;
+ struct sched_rline *prequest = tag;
- prequest->callback = NULL;
+ prequest->rl.callback = NULL;
+ if(prequest->schedule)
+ deleteschedule(prequest->schedule, execrline, NULL);
}
#define MAX_LINES 8192
/* this bites */
static void nterfacer_sendcallback(struct rline *ri, int error, char *buf) {
char *lines[MAX_LINES+1];
- char newbuf[MAX_BUFSIZE+1];
+ char newbuf[MAX_BUFSIZE+5];
char *s, *d, *laststart;
int linec = 0;
- for(laststart=s=buf,d=newbuf;*s;s++) {
+ for(s=buf,laststart=d=newbuf;*s;s++) {
if((*s == '\\') && *(s + 1)) {
if(*(s + 1) == ',') {
*d++ = ',';
}
lines[linec++] = laststart;
- laststart = s + 1;
+ laststart = d;
} else {
*d++ = *s;
}
}
+ *d = '\0';
lines[linec++] = laststart;
ri->callback(error, linec, lines, ri->tag);