/* dcc.c -- handles: activity on a dcc socket disconnect on a dcc socket ...and that's it! (but it's a LOT) dprintf'ized, 27oct95 */ /* This file is part of the eggdrop source code copyright (c) 1997 Robey Pointer and is distributed according to the GNU general public license. For full details, read the top of 'main.c' or the file called COPYING that was distributed with this code. */ #include "../module.h" #ifdef MODULES #define MODULE_NAME "filesys" #include #include #include #include "filesys.h" #else #include "../../tclegg.h" #endif /* root dcc directory */ char dccdir[121] = ""; /* directory to put incoming dcc's into */ char dccin[121] = ""; /* let all uploads go to the user's current directory? */ int upload_to_cd = 0; #ifndef NO_FILE_SYSTEM /* check for tcl-bound file command, return 1 if found */ /* fil: proc-name */ #ifdef MODULES static #endif int check_tcl_fil PROTO3(char *, cmd, int, idx, char *, args) { int atr, chatr, x; char s[5]; modcontext; atr = get_attr_handle(dcc[idx].nick); chatr = get_chanattr_handle(dcc[idx].nick, dcc[idx].u.file->chat->con_chan); if (chatr & CHANUSER_OP) atr |= USER_PSUEDOOP; if (chatr & CHANUSER_MASTER) atr |= USER_PSUMST; if (chatr & CHANUSER_OWNER) atr |= USER_PSUOWN; sprintf(s, "%d", dcc[idx].sock); Tcl_SetVar(interp, "_n", dcc[idx].nick, 0); Tcl_SetVar(interp, "_i", s, 0); Tcl_SetVar(interp, "_a", args, 0); modcontext; x = check_tcl_bind(&H_fil, cmd, atr, " $_n $_i $_a", MATCH_PARTIAL | BIND_USE_ATTR | BIND_HAS_BUILTINS); modcontext; if (x == BIND_AMBIGUOUS) { modprintf(idx, "Ambigious command.\n"); return 0; } if (x == BIND_NOMATCH) { modprintf(idx, "What? You need 'help'\n"); return 0; } if (x == BIND_EXEC_BRK) return 1; if (x == BIND_EXEC_LOG) putlog(LOG_FILES, "*", "#%s# files: %s %s", dcc[idx].nick, cmd, args); return 0; } #ifdef MODULES static #endif void dcc_files_pass PROTO2(int, idx, char *, buf) { if (pass_match_by_handle(buf, dcc[idx].nick)) { if (too_many_filers()) { modprintf(idx, "Too many people are in the file system right now.\n"); modprintf(idx, "Please try again later.\n"); putlog(LOG_MISC, "*", "File area full: DCC chat [%s]%s", dcc[idx].nick, dcc[idx].host); killsock(dcc[idx].sock); lostdcc(idx); return; } dcc[idx].type = DCC_FILES; if (dcc[idx].u.file->chat->status & STAT_TELNET) modprintf(idx, "\377\374\001\n"); /* turn echo back on */ putlog(LOG_FILES, "*", "File system: [%s]%s/%d", dcc[idx].nick, dcc[idx].host, dcc[idx].port); if (!welcome_to_files(idx)) { putlog(LOG_FILES, "*", "File system broken."); killsock(dcc[idx].sock); lostdcc(idx); } return; } modprintf(idx, "Negative on that, Houston.\n"); putlog(LOG_MISC, "*", "Bad password: DCC chat [%s]%s", dcc[idx].nick, dcc[idx].host); killsock(dcc[idx].sock); lostdcc(idx); } /* hash function for file area commands */ #ifdef MODULES static #endif int got_files_cmd PROTO2(int, idx, char *, msg) { char total[512], code[512]; modcontext; strcpy(msg, check_tcl_filt(idx, msg)); modcontext; if (!msg[0]) return 1; if (msg[0] == '.') strcpy(msg, &msg[1]); strcpy(total, msg); rmspace(msg); nsplit(code, msg); rmspace(msg); return check_tcl_fil(code, idx, msg); } #ifdef MODULES static #endif void dcc_files PROTO2(int, idx, char *, buf) { int i; modcontext; if (detect_dcc_flood(dcc[idx].u.file->chat, idx)) return; dcc[idx].u.file->chat->timer = time(NULL); modcontext; strcpy(buf, check_tcl_filt(idx, buf)); modcontext; if (!buf[0]) return; if (buf[0] == ',') { for (i = 0; i < dcc_total; i++) { if ((dcc[i].type == DCC_CHAT) && (get_attr_handle(dcc[i].nick) & USER_MASTER) && (dcc[i].u.chat->channel >= 0) && ((i != idx) || (dcc[idx].u.chat->status & STAT_ECHO))) modprintf(i, "-%s- %s\n", dcc[idx].nick, &buf[1]); if ((dcc[i].type == DCC_FILES) && (get_attr_handle(dcc[i].nick) & USER_MASTER) && ((i != idx) || (dcc[idx].u.file->chat->status & STAT_ECHO))) modprintf(i, "-%s- %s\n", dcc[idx].nick, &buf[1]); } } else if (got_files_cmd(idx, buf)) { modprintf(idx, "*** Ja mata!\n"); putlog(LOG_FILES, "*", "DCC user [%s]%s left file system", dcc[idx].nick, dcc[idx].host); set_handle_dccdir(userlist, dcc[idx].nick, dcc[idx].u.file->dir); if (dcc[idx].u.file->chat->status & STAT_CHAT) { struct chat_info *ci; modprintf(idx, "Returning you to command mode...\n"); ci = dcc[idx].u.file->chat; modfree(dcc[idx].u.file); dcc[idx].u.chat = ci; dcc[idx].u.chat->status &= (~STAT_CHAT); dcc[idx].type = DCC_CHAT; if (dcc[idx].u.chat->channel >= 0) { chanout2(dcc[idx].u.chat->channel, "%s has returned.\n", dcc[idx].nick); modcontext; if (dcc[idx].u.chat->channel < 100000) tandout("unaway %s %d\n", botnetnick, dcc[idx].sock); } } else { modprintf(idx, "Dropping connection now.\n"); putlog(LOG_FILES, "*", "Left files: [%s]%s/%d", dcc[idx].nick, dcc[idx].host, dcc[idx].port); killsock(dcc[idx].sock); lostdcc(idx); } } } #ifdef MODULES int filesys_activity_hook PROTO3(int, idx, char *, buf, int, len) { modcontext; switch (dcc[idx].type) { case DCC_FILES_PASS: modcontext; dcc_files_pass(idx, buf); return 1; case DCC_FILES: modcontext; dcc_files(idx, buf); return 1; } return 0; } #endif #endif /* !NO_FILE_SYSTEM */