/*
* wire.c -- part of wire.mod
* An encrypted partyline communication.
* Compatible with wire.tcl.
* This module does not support wire usage in the files area.
*
* by ButchBub - Scott G. Taylor (staylor@mrynet.com)
*
* Version Date Req'd Eggver Notes Who
* ....... .......... ............ .................... ......
* 1.0 1997-07-17 1.2.0 Initial. BB
* 1.1 1997-07-28 1.2.0 Release version. BB
* 1.2 1997-08-19 1.2.1 Update and bugfixes. BB
* 1.3 1997-09-24 1.2.2.0 Reprogrammed for 1.2.2 BB
* 1.4 1997-11-25 1.2.2.0 Added language addition Kirk
* 1.5 1998-07-12 1.3.0.0 Fixed ;me and updated BB
*
* $Id: wire.c,v 1.37 2006-03-28 02:35:52 wcc Exp $
*/
/*
* Copyright (C) 1999 - 2006 Eggheads Development Team
*
* 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 the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define MODULE_NAME "wire"
#define MAKING_WIRE
#include "src/mod/module.h"
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include "src/users.h"
#include "src/chan.h"
#include "wire.h"
#undef global
static Function *global = NULL, *encryption_funcs = NULL;
typedef struct wire_t {
int sock;
char *crypt;
char *key;
struct wire_t *next;
} wire_list;
static wire_list *wirelist;
static cmd_t wire_bot[] = {
{0, 0, 0, 0}, /* Saves having to malloc :P */
{0, 0, 0, 0} /* add_builtin expects a terminating elem */
};
static void wire_leave();
static void wire_join();
static void wire_display();
static int wire_expmem()
{
wire_list *w = wirelist;
int size = 0;
while (w) {
size += sizeof(wire_list);
size += strlen(w->crypt) + 1;
size += strlen(w->key) + 1;
w = w->next;
}
return size;
}
static void nsplit(char *to, char *from)
{
char *x, *y = from;
x = newsplit(&y);
strcpy(to, x);
strcpy(from, y);
}
static void wire_filter(char *from, char *cmd, char *param)
{
char wirecrypt[512];
char wirewho[512];
char wiretmp2[512];
char wiretmp[512];
char wirereq[512];
wire_list *w = wirelist;
char reqsock;
time_t now2 = now;
char idle[20];
char *enctmp;
strcpy(wirecrypt, &cmd[5]);
strcpy(wiretmp, param);
nsplit(wirereq, param);
/*
* !wire<crypt"wire"> !wirereq <destbotsock> <crypt"destbotnick">
* ----- wirecrypt wirereq wirewho param
*/
if (!strcmp(wirereq, "!wirereq")) {
nsplit(wirewho, param);
while (w) {
if (!strcmp(w->crypt, wirecrypt)) {
int idx = findanyidx(w->sock);
reqsock = atoi(wirewho);
if (now2 - dcc[idx].timeval > 300) {
unsigned long Days, hrs, mins;
Days = (now2 - dcc[idx].timeval) / 86400;
hrs = ((now2 - dcc[idx].timeval) - (Days * 86400)) / 3600;
mins = ((now2 - dcc[idx].timeval) - (hrs * 3600)) / 60;
if (Days > 0)
sprintf(idle, " [%s %lud%luh]", WIRE_IDLE, Days, hrs);
else if (hrs > 0)
sprintf(idle, " [%s %luh%lum]", WIRE_IDLE, hrs, mins);
else
sprintf(idle, " [%s %lum]", WIRE_IDLE, mins);
} else
idle[0] = 0;
sprintf(wirereq, "----- %c%-9s %-9s %s%s",
geticon(idx), dcc[idx].nick, botnetnick, dcc[idx].host, idle);
enctmp = encrypt_string(w->key, wirereq);
strcpy(wiretmp, enctmp);
nfree(enctmp);
sprintf(wirereq, "zapf %s %s !wire%s !wireresp %s %s %s",
botnetnick, from, wirecrypt, wirewho, param, wiretmp);
dprintf(nextbot(from), "%s\n", wirereq);
if (dcc[idx].u.chat->away) {
sprintf(wirereq, "----- %s: %s\n", WIRE_AWAY,
dcc[idx].u.chat->away);
enctmp = encrypt_string(w->key, wirereq);
strcpy(wiretmp, enctmp);
nfree(enctmp);
sprintf(wirereq, "zapf %s %s !wire%s !wireresp %s %s %s",
botnetnick, from, wirecrypt, wirewho, param, wiretmp);
dprintf(nextbot(from), "%s\n", wirereq);
}
}
w = w->next;
}
return;
}
if (!strcmp(wirereq, "!wireresp")) {
nsplit(wirewho, param);
reqsock = atoi(wirewho);
w = wirelist;
nsplit(wiretmp2, param);
while (w) {
if (w->sock == reqsock) {
int idx = findanyidx(reqsock);
enctmp = decrypt_string(w->key, wiretmp2);
strcpy(wirewho, enctmp);
nfree(enctmp);
if (!strcmp(dcc[idx].nick, wirewho)) {
enctmp = decrypt_string(w->key, param);
dprintf(idx, "%s\n", enctmp);
nfree(enctmp);
return;
}
}
w = w->next;
}
return;
}
while (w) {
if (!strcmp(wirecrypt, w->crypt))
wire_display(findanyidx(w->sock), w->key, wirereq, param);
w = w->next;
}
}
static void wire_display(int idx, char *key, char *from, char *message)
{
char *enctmp;
enctmp = decrypt_string(key, message);
if (from[0] == '!')
dprintf(idx, "----- > %s %s\n", &from[1], enctmp + 1);
else
dprintf(idx, "----- <%s> %s\n", from, enctmp);
nfree(enctmp);
}
static int cmd_wirelist(struct userrec *u, int idx, char *par)
{
wire_list *w = wirelist;
int entry = 0;
dprintf(idx, "Current Wire table: (Base table address = %p)\n", w);
while (w) {
dprintf(idx, "entry %d: w=%p idx=%d sock=%d next=%p\n",
++entry, w, findanyidx(w->sock), w->sock, w->next);
w = w->next;
}
return 0;
}
static int cmd_onwire(struct userrec *u, int idx, char *par)
{
wire_list *w, *w2;
char wiretmp[512], wirecmd[512], idxtmp[512];
char idle[20], *enctmp;
time_t now2 = now;
w = wirelist;
while (w) {
if (w->sock == dcc[idx].sock)
break;
w = w->next;
}
if (!w) {
dprintf(idx, "%s\n", WIRE_NOTONWIRE);
return 0;
}
dprintf(idx, "----- %s '%s':\n", WIRE_CURRENTLYON, w->key);
dprintf(idx, "----- Nick Bot Host\n");
dprintf(idx, "----- ---------- ---------- ------------------------------\n");
enctmp = encrypt_string(w->key, "wire");
sprintf(wirecmd, "!wire%s", enctmp);
nfree(enctmp);
enctmp = encrypt_string(w->key, dcc[idx].nick);
strcpy(wiretmp, enctmp);
nfree(enctmp);
simple_sprintf(idxtmp, "!wirereq %d %s", dcc[idx].sock, wiretmp);
botnet_send_zapf_broad(-1, botnetnick, wirecmd, idxtmp);
w2 = wirelist;
while (w2) {
if (!strcmp(w2->key, w->key)) {
int idx2 = findanyidx(w2->sock);
if (now2 - dcc[idx2].timeval > 300) {
unsigned long Days, hrs, mins;
Days = (now2 - dcc[idx2].timeval) / 86400;
hrs = ((now2 - dcc[idx2].timeval) - (Days * 86400)) / 3600;
mins = ((now2 - dcc[idx2].timeval) - (hrs * 3600)) / 60;
if (Days > 0)
sprintf(idle, " [%s %lud%luh]", WIRE_IDLE, Days, hrs);
else if (hrs > 0)
sprintf(idle, " [%s %luh%lum]", WIRE_IDLE, hrs, mins);
else
sprintf(idle, " [%s %lum]", WIRE_IDLE, mins);
} else
idle[0] = 0;
dprintf(idx, "----- %c%-9s %-9s %s%s\n",
geticon(idx2), dcc[idx2].nick, botnetnick, dcc[idx2].host, idle);
if (dcc[idx2].u.chat->away)
dprintf(idx, "----- %s: %s\n", WIRE_AWAY, dcc[idx2].u.chat->away);
}
w2 = w2->next;
}
return 0;
}
static int cmd_wire(struct userrec *u, int idx, char *par)
{
wire_list *w = wirelist;
if (!par[0]) {
dprintf(idx, "%s: .wire [<encrypt-key>|OFF|info]\n", MISC_USAGE);
return 0;
}
while (w) {
if (w->sock == dcc[idx].sock)
break;
w = w->next;
}
if (!egg_strcasecmp(par, "off")) {
if (w) {
wire_leave(w->sock);
dprintf(idx, "%s\n", WIRE_NOLONGERWIRED);
return 0;
}
dprintf(idx, "%s\n", WIRE_NOTONWIRE);
return 0;
}
if (!egg_strcasecmp(par, "info")) {
if (w)
dprintf(idx, "%s '%s'.\n", WIRE_CURRENTLYON, w->key);
else
dprintf(idx, "%s\n", WIRE_NOTONWIRE);
return 0;
}
if (w) {
dprintf(idx, "%s %s...\n", WIRE_CHANGINGKEY, par);
wire_leave(w->sock);
} else {
dprintf(idx, "----- %s\n", WIRE_INFO1);
dprintf(idx, "----- %s\n", WIRE_INFO2);
dprintf(idx, "----- %s\n", WIRE_INFO3);
}
wire_join(idx, par);
cmd_onwire((struct userrec *) 0, idx, "");
return 0;
}
static char *chof_wire(char *from, int idx)
{
wire_leave(dcc[idx].sock);
return NULL;
}
static void wire_join(int idx, char *key)
{
char wirecmd[512];
char wiremsg[512];
char wiretmp[512];
char *enctmp;
wire_list *w = wirelist, *w2;
while (w) {
if (w->next == 0)
break;
w = w->next;
}
if (!wirelist) {
wirelist = nmalloc(sizeof *wirelist);
w = wirelist;
} else {
w->next = nmalloc(sizeof *w->next);
w = w->next;
}
w->sock = dcc[idx].sock;
w->key = nmalloc(strlen(key) + 1);
strcpy(w->key, key);
w->next = 0;
enctmp = encrypt_string(w->key, "wire");
strcpy(wiretmp, enctmp);
nfree(enctmp);
w->crypt = nmalloc(strlen(wiretmp) + 1);
strcpy(w->crypt, wiretmp);
sprintf(wirecmd, "!wire%s", wiretmp);
sprintf(wiremsg, "%s joined wire '%s'", dcc[idx].nick, key);
enctmp = encrypt_string(w->key, wiremsg);
strcpy(wiretmp, enctmp);
nfree(enctmp);
{
char x[1024];
simple_sprintf(x, "%s %s", botnetnick, wiretmp);
botnet_send_zapf_broad(-1, botnetnick, wirecmd, x);
}
w2 = wirelist;
while (w2) {
if (!strcmp(w2->key, w->key))
dprintf(findanyidx(w2->sock), "----- %s %s '%s'.\n",
dcc[findanyidx(w->sock)].nick, WIRE_JOINED, w2->key);
w2 = w2->next;
}
w2 = wirelist;
while (w2) { /* Is someone using this key here already? */
if (w2 != w)
if (!strcmp(w2->key, w->key))
break;
w2 = w2->next;
}
if (!w2) { /* Someone else is NOT using this key, so
* we add a bind */
wire_bot[0].name = wirecmd;
wire_bot[0].flags = "";
wire_bot[0].func = (Function) wire_filter;
add_builtins(H_bot, wire_bot);
}
}
static void wire_leave(int sock)
{
char wirecmd[513];
char wiremsg[513];
char wiretmp[513];
char *enctmp;
wire_list *w = wirelist;
wire_list *w2 = wirelist;
wire_list *wlast = wirelist;
while (w) {
if (w->sock == sock)
break;
w = w->next;
}
if (!w)
return;
enctmp = encrypt_string(w->key, "wire");
strcpy(wirecmd, enctmp);
nfree(enctmp);
sprintf(wiretmp, "%s left the wire.", dcc[findanyidx(w->sock)].nick);
enctmp = encrypt_string(w->key, wiretmp);
strcpy(wiremsg, enctmp);
nfree(enctmp);
{
char x[1024];
simple_sprintf(x, "!wire%s %s", wirecmd, botnetnick);
botnet_send_zapf_broad(-1, botnetnick, x, wiremsg);
}
w2 = wirelist;
while (w2) {
if (w2->sock != sock && !strcmp(w2->key, w->key)) {
dprintf(findanyidx(w2->sock), "----- %s %s\n",
dcc[findanyidx(w->sock)].nick, WIRE_LEFT);
}
w2 = w2->next;
}
/* Check to see if someone else is using this wire key.
* If so, then don't remove the wire filter binding.
*/
w2 = wirelist;
while (w2) {
if (w2 != w && !strcmp(w2->key, w->key))
break;
w2 = w2->next;
}
if (!w2) { /* Someone else is NOT using this key */
wire_bot[0].name = wirecmd;
wire_bot[0].flags = "";
wire_bot[0].func = (Function) wire_filter;
rem_builtins(H_bot, wire_bot);
}
w2 = wirelist;
wlast = 0;
while (w2) {
if (w2 == w)
break;
wlast = w2;
w2 = w2->next;
}
if (wlast) {
if (w->next)
wlast->next = w->next;
else
wlast->next = 0;
} else if (!w->next)
wirelist = 0;
else
wirelist = w->next;
nfree(w->crypt);
nfree(w->key);
nfree(w);
}
static char *cmd_putwire(int idx, char *message)
{
wire_list *w = wirelist;
wire_list *w2 = wirelist;
int wiretype;
char wirecmd[512];
char wiremsg[512];
char wiretmp[512];
char wiretmp2[512];
char *enctmp;
while (w) {
if (w->sock == dcc[idx].sock)
break;
w = w->next;
}
if (!w)
return "";
if (!message[1])
return "";
if ((strlen(message) > 3) && !strncmp(&message[1], "me", 2) &&
(message[3] == ' ')) {
sprintf(wiretmp2, "!%s@%s", dcc[idx].nick, botnetnick);
enctmp = encrypt_string(w->key, &message[3]);
wiretype = 1;
} else {
sprintf(wiretmp2, "%s@%s", dcc[idx].nick, botnetnick);
enctmp = encrypt_string(w->key, &message[1]);
wiretype = 0;
}
strcpy(wiremsg, enctmp);
nfree(enctmp);
enctmp = encrypt_string(w->key, "wire");
strcpy(wiretmp, enctmp);
nfree(enctmp);
sprintf(wirecmd, "!wire%s", wiretmp);
sprintf(wiretmp, "%s %s", wiretmp2, wiremsg);
botnet_send_zapf_broad(-1, botnetnick, wirecmd, wiretmp);
sprintf(wiretmp, "%s%s", wiretype ? "!" : "", dcc[findanyidx(w->sock)].nick);
while (w2) {
if (!strcmp(w2->key, w->key))
wire_display(findanyidx(w2->sock), w2->key, wiretmp, wiremsg);
w2 = w2->next;
}
return "";
}
/* a report on the module status */
static void wire_report(int idx, int details)
{
if (details) {
int count = 0, size = wire_expmem();
wire_list *w = wirelist;
while (w) {
count++;
w = w->next;
}
dprintf(idx, " %d wire%s\n", count, (count != 1) ? "s" : "");
dprintf(idx, " Using %d byte%s of memory\n", size,
(size != 1) ? "s" : "");
}
}
static cmd_t wire_dcc[] = {
{"wire", "", (Function) cmd_wire, NULL},
{"onwire", "", (Function) cmd_onwire, NULL},
{"wirelist", "n", (Function) cmd_wirelist, NULL},
{NULL, NULL, NULL, NULL}
};
static cmd_t wire_chof[] = {
{"*", "", (Function) chof_wire, "wire:chof"},
{NULL, NULL, NULL, NULL}
};
static cmd_t wire_filt[] = {
{";*", "", (Function) cmd_putwire, "wire:filt"},
{NULL, NULL, NULL, NULL}
};
static char *wire_close()
{
wire_list *w = wirelist;
char wiretmp[512];
char *enctmp;
p_tcl_bind_list H_temp;
/* Remove any current wire encrypt bindings for now, don't worry
* about duplicate unbinds.
*/
while (w) {
enctmp = encrypt_string(w->key, "wire");
sprintf(wiretmp, "!wire%s", enctmp);
nfree(enctmp);
wire_bot[0].name = wiretmp;
wire_bot[0].flags = "";
wire_bot[0].func = (Function) wire_filter;
rem_builtins(H_bot, wire_bot);
w = w->next;
}
w = wirelist;
while (w && w->sock) {
dprintf(findanyidx(w->sock), "----- %s\n", WIRE_UNLOAD);
dprintf(findanyidx(w->sock), "----- %s\n", WIRE_NOLONGERWIRED);
wire_leave(w->sock);
w = wirelist;
}
rem_help_reference("wire.help");
rem_builtins(H_dcc, wire_dcc);
H_temp = find_bind_table("filt");
rem_builtins(H_temp, wire_filt);
H_temp = find_bind_table("chof");
rem_builtins(H_temp, wire_chof);
del_lang_section("wire");
module_undepend(MODULE_NAME);
return NULL;
}
EXPORT_SCOPE char *wire_start();
static Function wire_table[] = {
(Function) wire_start,
(Function) wire_close,
(Function) wire_expmem,
(Function) wire_report,
};
char *wire_start(Function *global_funcs)
{
p_tcl_bind_list H_temp;
global = global_funcs;
module_register(MODULE_NAME, wire_table, 2, 0);
if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) {
module_undepend(MODULE_NAME);
return "This module requires Eggdrop 1.6.0 or later.";
}
if (!(encryption_funcs = module_depend(MODULE_NAME, "encryption", 2, 1))) {
module_undepend(MODULE_NAME);
return "This module requires an encryption module.";
}
add_help_reference("wire.help");
add_builtins(H_dcc, wire_dcc);
H_temp = find_bind_table("filt");
add_builtins(H_filt, wire_filt);
H_temp = find_bind_table("chof");
add_builtins(H_chof, wire_chof);
wirelist = NULL;
add_lang_section("wire");
return NULL;
}
syntax highlighted by Code2HTML, v. 0.9.1