static int ctcp_CHAT(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text) { if (!ischanhub()) return BIND_RET_LOG; if (u_pass_match(u, "-")) { strlcat(ctcp_reply, "\001ERROR no password set\001", sizeof(ctcp_reply)); return BIND_RET_BREAK; } int ix = -1, i = 0; for (i = 0; i < dcc_total; i++) { if (dcc[i].type && (dcc[i].type->flags & DCT_LISTEN) && (!strcmp(dcc[i].nick, "(telnet)"))) ix = i; } if (!iptolong(getmyip())) { simple_snprintf(&ctcp_reply[strlen(ctcp_reply)], sizeof(ctcp_reply) - strlen(ctcp_reply), "\001ERROR no ipv4 ip defined. Use /dcc chat %s\001", botname); } else if (dcc_total == max_dcc || (ix < 0 && (ix = listen_all(0, 0, 0)) < 0)) strlcat(ctcp_reply, "\001ERROR no telnet port\001", sizeof(ctcp_reply)); else { if (listen_time <= 2) listen_time++; /* do me a favour and don't change this back to a CTCP reply, * CTCP replies are NOTICE's this has to be a PRIVMSG * -poptix 5/1/1997 */ bd::String msg; msg = bd::String::printf("\001DCC CHAT chat %lu %u\001", iptolong(getmyip()), dcc[ix].port); privmsg(nick, msg.c_str(), DP_SERVER); } return BIND_RET_BREAK; }
static void remote_filereq(int idx, char *from, char *file) { char *p, what[256], dir[256], s[256], s1[256], *reject; FILE *f; filedb fdb; long i = 0; strcpy(what, file); p = strrchr(what, '/'); if (p == NULL) dir[0] = 0; else { *p = 0; strcpy(dir, what); strcpy(what, p + 1); } f = filedb_open(dir, 0); reject = NULL; if (f == NULL) { reject = FILES_DIRDNE; } else { if (!findmatch(f, what, &i, &fdb)) { reject = FILES_FILEDNE; filedb_close(f); } else { if ((!(fdb.stat & FILE_SHARE)) || (fdb.stat & (FILE_HIDDEN | FILE_DIR))) { reject = FILES_NOSHARE; filedb_close(f); } else { filedb_close(f); /* copy to /tmp if needed */ sprintf(s1, "%s%s%s%s", dccdir, dir, dir[0] ? "/" : "", what); if (copy_to_tmp) { sprintf(s, "%s%s", tempdir, what); copyfile(s1, s); } else strcpy(s, s1); i = raw_dcc_send(s, "*remote", FILES_REMOTE, s); if (i > 0) { wipe_tmp_filename(s, -1); reject = FILES_SENDERR; } } } } simple_sprintf(s1, "%s:%s/%s", botnetnick, dir, what); if (reject) { botnet_send_filereject(idx, s1, from, reject); return; } /* grab info from dcc struct and bounce real request across net */ i = dcc_total - 1; simple_sprintf(s, "%d %u %d", iptolong(getmyip()), dcc[i].port, dcc[i].u.xfer->length); botnet_send_filesend(idx, s1, from, s); putlog(LOG_FILES, "*", FILES_REMOTEREQ, dir, dir[0] ? "/" : "", what); }
void setup_HQ(int n) { dcc[n].addr = iptolong(getmyip()); dcc[n].sock = STDOUT; dcc[n].timeval = now; dcc[n].u.chat->con_flags = conmask | LOG_ALL; dcc[n].u.chat->strip_flags = STRIP_ALL; dcc[n].status = STAT_ECHO; strlcpy(dcc[n].nick, STR("HQ"), sizeof(dcc[n].nick)); strlcpy(dcc[n].host, STR("llama@console"), sizeof(dcc[n].host)); dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); /* Make sure there's an innocuous HQ user if needed */ if (!dcc[n].user) { userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_ADMIN | USER_OWNER | USER_MASTER | USER_VOICE | USER_OP | USER_PARTY | USER_CHUBA | USER_HUBA, 0); dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); } }
static void remote_filereq(int idx, char *from, char *file) { char *p = NULL, *what = NULL, *dir = NULL, *s1 = NULL, *reject = NULL, *s = NULL; FILE *fdb = NULL; int i = 0; filedb_entry *fdbe = NULL; malloc_strcpy(what, file); p = strrchr(what, '/'); if (p) { *p = 0; malloc_strcpy(dir, what); strcpy(what, p + 1); } else { malloc_strcpy(dir, ""); } fdb = filedb_open(dir, 0); if (!fdb) { reject = FILES_DIRDNE; } else { filedb_readtop(fdb, NULL); fdbe = filedb_matchfile(fdb, ftell(fdb), what); filedb_close(fdb); if (!fdbe) { reject = FILES_FILEDNE; } else { if ((!(fdbe->stat & FILE_SHARE)) || (fdbe->stat & (FILE_HIDDEN | FILE_DIR))) reject = FILES_NOSHARE; else { s1 = nmalloc(strlen(dccdir) + strlen(dir) + strlen(what) + 2); /* Copy to /tmp if needed */ sprintf(s1, "%s%s%s%s", dccdir, dir, dir[0] ? "/" : "", what); if (copy_to_tmp) { s = nmalloc(strlen(tempdir) + strlen(what) + 1); sprintf(s, "%s%s", tempdir, what); copyfile(s1, s); } else s = s1; i = raw_dcc_send(s, "*remote", FILES_REMOTE, s); if (i > 0) { wipe_tmp_filename(s, -1); reject = FILES_SENDERR; } if (s1 != s) my_free(s); my_free(s1); } free_fdbe(&fdbe); } } s1 = nmalloc(strlen(botnetnick) + strlen(dir) + strlen(what) + 3); simple_sprintf(s1, "%s:%s/%s", botnetnick, dir, what); if (reject) { botnet_send_filereject(idx, s1, from, reject); my_free(s1); my_free(what); my_free(dir); return; } /* Grab info from dcc struct and bounce real request across net */ i = dcc_total - 1; s = nmalloc(40); /* Enough? */ simple_sprintf(s, "%d %u %d", iptolong(getmyip()), dcc[i].port, dcc[i].u.xfer->length); botnet_send_filesend(idx, s1, from, s); putlog(LOG_FILES, "*", FILES_REMOTEREQ, dir, dir[0] ? "/" : "", what); my_free(s1); my_free(s); my_free(what); my_free(dir); }
int main(int argc, char **argv) { int xx, i; #ifdef STOP_UAC int nvpair[2]; #endif char buf[520], s[25]; FILE *f; #ifndef ENABLE_STRIP struct rlimit cdlim; #endif /* Don't allow Eggdrop to run as root. */ if (((int) getuid() == 0) || ((int) geteuid() == 0)) fatal("ERROR: Eggdrop will not run as root!", 0); #ifndef ENABLE_STRIP cdlim.rlim_cur = RLIM_INFINITY; cdlim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &cdlim); #endif #include "patch.h" /* Version info! */ egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version); egg_snprintf(version, sizeof version, "Eggdrop v%s (C) 1997 Robey Pointer (C) 2005 Eggheads", egg_version); /* Now add on the patchlevel (for Tcl) */ sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver); strcat(egg_version, egg_xtra); #ifdef STOP_UAC nvpair[0] = SSIN_UACPROC; nvpair[1] = UAC_NOPRINT; setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0); #endif /* Set up error / signal traps. */ setup_signal_traps(); /* Initialize a few variables before main loop. */ cache_miss = 0; cache_hit = 0; chanset = NULL; now = time(NULL); egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm)); lastmin = nowtm.tm_min; /* Initialize random number generator. */ srandom((unsigned int) (now % (getpid() + getppid()))); init_mem(); init_language(1); /* Process command line arguments. */ process_args(argc, argv); printf("\n%s\n", version); init_dcc_max(); init_userent(); logfile_init(0); init_bots(); init_net(); init_modules(); if (backgrd) bg_prepare_split(); init_tcl(argc, argv); init_language(0); help_init(); traffic_init(); logfile_init(1); #ifdef STATIC link_statics(); #endif strncpyz(s, ctime(&now), sizeof s); strcpy(&s[11], &s[20]); putlog(LOG_ALL, "*", "--- Loading %s (%s)", ver, s); /* Read configuration data. */ readconfig(); /* Check for encryption module. */ if (!encrypt_pass) { printf(MOD_NOCRYPT); bg_send_quit(BG_ABORT); exit(1); } putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.", botnetnick, count_channels(), count_users(userlist)); if (!pid_file[0]) egg_snprintf(pid_file, sizeof pid_file, "pid.%s", botnetnick); /* Check for pre-existing eggdrop! */ f = fopen(pid_file, "r"); if (f != NULL) { fgets(s, 10, f); xx = atoi(s); kill(xx, SIGCHLD); /* Meaningless kill to determine if PID is used. */ if (errno != ESRCH) { printf(EGG_RUNNING1, botnetnick); printf(EGG_RUNNING2, pid_file); bg_send_quit(BG_ABORT); exit(1); } } /* Move into background? */ if (backgrd) { #ifndef CYGWIN_HACKS bg_do_split(); } else { #endif xx = getpid(); if (xx != 0) { FILE *fp; /* Write PID to file. */ unlink(pid_file); fp = fopen(pid_file, "w"); if (fp != NULL) { fprintf(fp, "%u\n", xx); if (fflush(fp)) { /* Let the bot live since this doesn't appear to be a botchk. */ printf("Cannot not write to '%s' (PID file).\n", pid_file); fclose(fp); unlink(pid_file); } else fclose(fp); } else printf("Cannot not write to '%s' (PID file).\n", pid_file); #ifdef CYGWIN_HACKS printf("Launched into the background (PID: %d)\n\n", xx); #endif } } use_stderr = 0; /* Stop writing to stderr now */ if (backgrd) { /* Ok, try to disassociate from controlling terminal (finger cross) */ #if defined(HAVE_SETPGID) && !defined(CYGWIN_HACKS) setpgid(0, 0); #endif /* Tcl wants the stdin, stdout and stderr file handles kept open. */ freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); #ifdef CYGWIN_HACKS FreeConsole(); #endif } /* Terminal emulating dcc chat */ if (!backgrd && term_z) { int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info)); dcc[n].addr = iptolong(getmyip()); dcc[n].sock = STDOUT; dcc[n].timeval = now; dcc[n].u.chat->con_flags = conmask; dcc[n].u.chat->strip_flags = STRIP_ALL; dcc[n].status = STAT_ECHO; strcpy(dcc[n].nick, "HQ"); strcpy(dcc[n].host, "llama@console"); /* HACK: Workaround not to pass literal "HQ" as a non-const arg */ dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); /* Make sure there's an innocuous HQ user if needed */ if (!dcc[n].user) { userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_PARTY); dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); } setsock(STDOUT, 0); /* Entry in net table */ dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n"); dcc_chatter(n); } then = now; online_since = now; autolink_cycle(NULL); /* Hurry and connect to tandem bots. */ add_help_reference("cmds1.help"); add_help_reference("cmds2.help"); add_help_reference("core.help"); /* Create hooks. */ add_hook(HOOK_SECONDLY, (Function) core_secondly); add_hook(HOOK_MINUTELY, (Function) core_minutely); add_hook(HOOK_HOURLY, (Function) core_hourly); add_hook(HOOK_REHASH, (Function) event_rehash); add_hook(HOOK_PRE_REHASH, (Function) event_prerehash); add_hook(HOOK_USERFILE, (Function) event_save); add_hook(HOOK_BACKUP, (Function) backupuserfile); add_hook(HOOK_DAILY, (Function) event_logfile); add_hook(HOOK_DAILY, (Function) traffic_reset); add_hook(HOOK_LOADED, (Function) event_loaded); call_hook(HOOK_LOADED); debug0("main: entering loop"); while (1) { int socket_cleanup = 0; #ifdef USE_TCL_EVENTS /* Process a single Tcl event. */ Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT); #endif now = time(NULL); random(); /* Every second... */ if (now != then) { call_hook(HOOK_SECONDLY); then = now; } /* Only do this every so often. */ if (!socket_cleanup) { socket_cleanup = 5; /* Remove dead dcc entries. */ dcc_remove_lost(); /* Check for server or dcc activity. */ dequeue_sockets(); } else { socket_cleanup--; } /* Free unused structures. */ garbage_collect(); xx = sockgets(buf, &i); if (xx >= 0) { /* Non-error */ int idx; for (idx = 0; idx < dcc_total; idx++) { if (dcc[idx].sock != xx) continue; if (dcc[idx].type && dcc[idx].type->activity) { traffic_update_in(dcc[idx].type, (strlen(buf) + 1)); /* Traffic stats. */ dcc[idx].type->activity(idx, buf, i); } else { putlog(LOG_MISC, "*", "!!! untrapped dcc activity: type %s, sock %d", dcc[idx].type->name, dcc[idx].sock); } break; } } else if (xx == -1) { /* EOF */ int idx; if (i == STDOUT && !backgrd) fatal("END OF FILE ON TERMINAL", 0); for (idx = 0; idx < dcc_total; idx++) { if (dcc[idx].sock != i) continue; if (dcc[idx].type && dcc[idx].type->eof) { dcc[idx].type->eof(idx); } else { putlog(LOG_MISC, "*", "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED", i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*"); killsock(i); lostdcc(idx); } idx = dcc_total + 1; } if (idx == dcc_total) { putlog(LOG_MISC, "*", "(@) EOF socket %d, not a dcc socket, not anything.", i); close(i); killsock(i); } } else if (xx == -2 && errno != EINTR) { /* select() error */ putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno); for (i = 0; i < dcc_total; i++) { if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno == EBADF)) { putlog(LOG_MISC, "*", "DCC socket %d (type %d, name '%s') expired -- pfft", dcc[i].sock, dcc[i].type, dcc[i].nick); killsock(dcc[i].sock); lostdcc(i); i--; } } } else if (xx == -3) { call_hook(HOOK_IDLE); socket_cleanup = 0; /* If we've been idle, cleanup & flush */ } if (do_restart) { if (do_restart == -2) { rehash(); } else { int f = 1; module_entry *p; Function startfunc; char name[256]; check_tcl_event("prerestart"); /* Unload as many modules as possible */ while (f) { f = 0; for (p = module_list; p != NULL; p = p->next) { dependancy *d = dependancy_list; int ok = 1; while (ok && d) { if (d->needed == p) ok = 0; d = d->next; } if (ok) { strcpy(name, p->name); if (module_unload(name, botnetnick) == NULL) { f = 1; break; } } } } /* Make sure we don't have any modules left hanging around other than * "eggdrop" and the two that are supposed to be. */ for (f = 0, p = module_list; p; p = p->next) { if (strcmp(p->name, "eggdrop") && strcmp(p->name, "encryption") && strcmp(p->name, "uptime")) { f++; } } if (f != 0) { putlog(LOG_MISC, "*", MOD_STAGNANT); } /* Flush log files to disk. */ flushlogs(); /* Clean up Tcl stuff. */ kill_tcl(); /* Initialize stuff again. */ init_tcl(argc, argv); init_language(0); help_init(); traffic_init(); logfile_init(1); /* This resets our modules which we didn't unload (encryption and uptime). */ for (p = module_list; p; p = p->next) { if (p->funcs) { startfunc = p->funcs[MODCALL_START]; startfunc(NULL); } } rehash(); restart_chons(); call_hook(HOOK_LOADED); } do_restart = 0; } } }
int main(int arg_c, char **arg_v) { int i, xx; char s[25]; FILE *f; struct sigaction sv; struct chanset_t *chan; #ifdef DEBUG struct rlimit cdlim; #endif #ifdef STOP_UAC int nvpair[2]; #endif /* Make sure it can write core, if you make debug. Else it's pretty * useless (dw) * * Only allow unlimited size core files when compiled with DEBUG defined. * This is not a good idea for normal builds -- in these cases, use the * default system resource limits instead. */ #ifdef DEBUG cdlim.rlim_cur = RLIM_INFINITY; cdlim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &cdlim); #endif #ifdef DEBUG_CONTEXT /* Initialise context list */ for (i = 0; i < 16; i++) Context; #endif /* Include patch.h header for patch("...") */ #include "patch.h" argc = arg_c; argv = arg_v; /* Version info! */ egg_snprintf(ver, sizeof ver, "eggdrop v%s", egg_version); egg_snprintf(version, sizeof version, "Eggdrop v%s (C) 1997 Robey Pointer (C) 2011 Eggheads", egg_version); /* Now add on the patchlevel (for Tcl) */ sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver); strcat(egg_version, egg_xtra); /* For OSF/1 */ #ifdef STOP_UAC /* Don't print "unaligned access fixup" warning to the user */ nvpair[0] = SSIN_UACPROC; nvpair[1] = UAC_NOPRINT; setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0); #endif /* Set up error traps: */ sv.sa_handler = got_bus; sigemptyset(&sv.sa_mask); #ifdef SA_RESETHAND sv.sa_flags = SA_RESETHAND; #else sv.sa_flags = 0; #endif sigaction(SIGBUS, &sv, NULL); sv.sa_handler = got_segv; sigaction(SIGSEGV, &sv, NULL); #ifdef SA_RESETHAND sv.sa_flags = 0; #endif sv.sa_handler = got_fpe; sigaction(SIGFPE, &sv, NULL); sv.sa_handler = got_term; sigaction(SIGTERM, &sv, NULL); sv.sa_handler = got_hup; sigaction(SIGHUP, &sv, NULL); sv.sa_handler = got_quit; sigaction(SIGQUIT, &sv, NULL); sv.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sv, NULL); sv.sa_handler = got_ill; sigaction(SIGILL, &sv, NULL); sv.sa_handler = got_alarm; sigaction(SIGALRM, &sv, NULL); /* Initialize variables and stuff */ now = time(NULL); chanset = NULL; egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm)); lastmin = nowtm.tm_min; srandom((unsigned int) (now % (getpid() + getppid()))); init_mem(); init_language(1); if (argc > 1) for (i = 1; i < argc; i++) do_arg(argv[i]); printf("\n%s\n", version); #ifndef CYGWIN_HACKS /* Don't allow eggdrop to run as root * This check isn't useful under cygwin and has been * reported to cause trouble in some situations. */ if (((int) getuid() == 0) || ((int) geteuid() == 0)) fatal("ERROR: Eggdrop will not run as root!", 0); #endif #ifndef REPLACE_NOTIFIER init_threaddata(1); #endif init_userent(); init_misc(); init_bots(); init_modules(); if (backgrd) bg_prepare_split(); init_tcl(argc, argv); init_language(0); #ifdef STATIC link_statics(); #endif strncpyz(s, ctime(&now), sizeof s); strcpy(&s[11], &s[20]); putlog(LOG_ALL, "*", "--- Loading %s (%s)", ver, s); chanprog(); if (!encrypt_pass) { printf(MOD_NOCRYPT); bg_send_quit(BG_ABORT); exit(1); } i = 0; for (chan = chanset; chan; chan = chan->next) i++; putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.", botnetnick, i, count_users(userlist)); cache_miss = 0; cache_hit = 0; if (!pid_file[0]) egg_snprintf(pid_file, sizeof pid_file, "pid.%s", botnetnick); /* Check for pre-existing eggdrop! */ f = fopen(pid_file, "r"); if (f != NULL) { fgets(s, 10, f); xx = atoi(s); i = kill(xx, SIGCHLD); /* Meaningless kill to determine if pid * is used */ if (i == 0 || errno != ESRCH) { printf(EGG_RUNNING1, botnetnick); printf(EGG_RUNNING2, pid_file); bg_send_quit(BG_ABORT); exit(1); } } /* Move into background? */ if (backgrd) { bg_do_split(); } else { /* !backgrd */ xx = getpid(); if (xx != 0) { FILE *fp; /* Write pid to file */ unlink(pid_file); fp = fopen(pid_file, "w"); if (fp != NULL) { fprintf(fp, "%u\n", xx); if (fflush(fp)) { /* Let the bot live since this doesn't appear to be a botchk */ printf(EGG_NOWRITE, pid_file); fclose(fp); unlink(pid_file); } else fclose(fp); } else printf(EGG_NOWRITE, pid_file); } } use_stderr = 0; /* Stop writing to stderr now */ if (backgrd) { /* Ok, try to disassociate from controlling terminal (finger cross) */ #ifdef HAVE_SETPGID setpgid(0, 0); #endif /* Tcl wants the stdin, stdout and stderr file handles kept open. */ freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); #ifdef CYGWIN_HACKS FreeConsole(); #endif } /* Terminal emulating dcc chat */ if (!backgrd && term_z) { int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info)); dcc[n].addr = iptolong(getmyip()); dcc[n].sock = STDOUT; dcc[n].timeval = now; dcc[n].u.chat->con_flags = conmask; dcc[n].u.chat->strip_flags = STRIP_ALL; dcc[n].status = STAT_ECHO; strcpy(dcc[n].nick, "HQ"); strcpy(dcc[n].host, "llama@console"); /* HACK: Workaround not to pass literal "HQ" as a non-const arg */ dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); /* Make sure there's an innocuous HQ user if needed */ if (!dcc[n].user) { userlist = adduser(userlist, dcc[n].nick, "none", "-", USER_PARTY); dcc[n].user = get_user_by_handle(userlist, dcc[n].nick); } setsock(STDOUT, 0); /* Entry in net table */ dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n"); dcc_chatter(n); } then = now; online_since = now; autolink_cycle(NULL); /* Hurry and connect to tandem bots */ add_help_reference("cmds1.help"); add_help_reference("cmds2.help"); add_help_reference("core.help"); add_hook(HOOK_SECONDLY, (Function) core_secondly); add_hook(HOOK_MINUTELY, (Function) core_minutely); add_hook(HOOK_HOURLY, (Function) core_hourly); add_hook(HOOK_REHASH, (Function) event_rehash); add_hook(HOOK_PRE_REHASH, (Function) event_prerehash); add_hook(HOOK_USERFILE, (Function) event_save); add_hook(HOOK_BACKUP, (Function) backup_userfile); add_hook(HOOK_DAILY, (Function) event_logfile); add_hook(HOOK_DAILY, (Function) event_resettraffic); add_hook(HOOK_LOADED, (Function) event_loaded); call_hook(HOOK_LOADED); debug0("main: entering loop"); while (1) { mainloop(1); } }
/* Create a new listening port (or destroy one) * * listen <port> bots/all/users [mask] * listen <port> script <proc> [flag] * listen <port> off */ static int tcl_listen(ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { int i, j, idx = -1, port, realport; char s[11], msg[256]; struct portmap *pmap = NULL, *pold = NULL; BADARGS(3, 5, " port type ?mask?/?proc ?flag??"); port = realport = atoi(argv[1]); for (pmap = root; pmap; pold = pmap, pmap = pmap->next) if (pmap->realport == port) { port = pmap->mappedto; break; } for (i = 0; i < dcc_total; i++) if ((dcc[i].type == &DCC_TELNET) && (dcc[i].port == port)) idx = i; if (!egg_strcasecmp(argv[2], "off")) { if (pmap) { if (pold) pold->next = pmap->next; else root = pmap->next; nfree(pmap); } /* Remove */ if (idx < 0) { Tcl_AppendResult(irp, "no such listen port is open", NULL); return TCL_ERROR; } killsock(dcc[idx].sock); lostdcc(idx); return TCL_OK; } if (idx < 0) { /* Make new one */ if (dcc_total >= max_dcc) { Tcl_AppendResult(irp, "No more DCC slots available.", NULL); return TCL_ERROR; } /* Try to grab port */ j = port + 20; i = -1; while (port < j && i < 0) { i = open_listen(&port); if (i == -1) port++; else if (i == -2) break; } if (i == -1) { egg_snprintf(msg, sizeof msg, "Couldn't listen on port '%d' on the " "given address. Please make sure 'my-ip' is set correctly, " "or try a different port.", realport); Tcl_AppendResult(irp, msg, NULL); return TCL_ERROR; } else if (i == -2) { Tcl_AppendResult(irp, "Couldn't assign the requested IP. Please make " "sure 'my-ip' is set properly.", NULL); return TCL_ERROR; } idx = new_dcc(&DCC_TELNET, 0); dcc[idx].addr = iptolong(getmyip()); dcc[idx].port = port; dcc[idx].sock = i; dcc[idx].timeval = now; } /* script? */ if (!strcmp(argv[2], "script")) { strcpy(dcc[idx].nick, "(script)"); if (argc < 4) { Tcl_AppendResult(irp, "a proc name must be specified for a script listen", NULL); killsock(dcc[idx].sock); lostdcc(idx); return TCL_ERROR; } if (argc == 5) { if (strcmp(argv[4], "pub")) { Tcl_AppendResult(irp, "unknown flag: ", argv[4], ". allowed flags: pub", NULL); killsock(dcc[idx].sock); lostdcc(idx); return TCL_ERROR; } dcc[idx].status = LSTN_PUBLIC; } strncpyz(dcc[idx].host, argv[3], UHOSTMAX); egg_snprintf(s, sizeof s, "%d", port); Tcl_AppendResult(irp, s, NULL); return TCL_OK; } /* bots/users/all */ if (!strcmp(argv[2], "bots")) strcpy(dcc[idx].nick, "(bots)"); else if (!strcmp(argv[2], "users")) strcpy(dcc[idx].nick, "(users)"); else if (!strcmp(argv[2], "all")) strcpy(dcc[idx].nick, "(telnet)"); if (!dcc[idx].nick[0]) { Tcl_AppendResult(irp, "invalid listen type: must be one of ", "bots, users, all, off, script", NULL); killsock(dcc[idx].sock); dcc_total--; return TCL_ERROR; } if (argc == 4) strncpyz(dcc[idx].host, argv[3], UHOSTMAX); else strcpy(dcc[idx].host, "*"); egg_snprintf(s, sizeof s, "%d", port); Tcl_AppendResult(irp, s, NULL); if (!pmap) { pmap = nmalloc(sizeof(struct portmap)); pmap->next = root; root = pmap; } pmap->realport = realport; pmap->mappedto = port; putlog(LOG_MISC, "*", "Listening at telnet port %d (%s).", port, argv[2]); return TCL_OK; }
static void filesys_dcc_send_hostresolved(int i) { char *s1, *param, prt[100], ip[100], *tempf; int len = dcc[i].u.dns->ibuf, j; sprintf(prt, "%d", dcc[i].port); sprintf(ip, "%lu", iptolong(htonl(dcc[i].addr))); if (!hostsanitycheck_dcc(dcc[i].nick, dcc[i].u.dns->host, dcc[i].addr, dcc[i].u.dns->host, prt)) { lostdcc(i); return; } param = nmalloc(strlen(dcc[i].u.dns->cbuf) + 1); strcpy(param, dcc[i].u.dns->cbuf); changeover_dcc(i, &DCC_FORK_SEND, sizeof(struct xfer_info)); if (param[0] == '.') param[0] = '_'; /* Save the original filename */ dcc[i].u.xfer->origname = get_data_ptr(strlen(param) + 1); strcpy(dcc[i].u.xfer->origname, param); tempf = mktempfile(param); dcc[i].u.xfer->filename = get_data_ptr(strlen(tempf) + 1); strcpy(dcc[i].u.xfer->filename, tempf); /* We don't need the temporary buffers anymore */ my_free(tempf); my_free(param); if (upload_to_cd) { char *p = get_user(&USERENTRY_DCCDIR, dcc[i].user); if (p) sprintf(dcc[i].u.xfer->dir, "%s%s/", dccdir, p); else sprintf(dcc[i].u.xfer->dir, "%s", dccdir); } else strcpy(dcc[i].u.xfer->dir, dccin); dcc[i].u.xfer->length = len; s1 = nmalloc(strlen(dcc[i].u.xfer->dir) + strlen(dcc[i].u.xfer->origname) + 1); sprintf(s1, "%s%s", dcc[i].u.xfer->dir, dcc[i].u.xfer->origname); if (file_readable(s1)) { dprintf(DP_HELP, "NOTICE %s :File `%s' already exists.\n", dcc[i].nick, dcc[i].u.xfer->origname); lostdcc(i); my_free(s1); } else { my_free(s1); /* Check for dcc-sends in process with the same filename */ for (j = 0; j < dcc_total; j++) if (j != i) { if ((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND)) == (DCT_FILETRAN | DCT_FILESEND)) { if (!strcmp(dcc[i].u.xfer->origname, dcc[j].u.xfer->origname)) { dprintf(DP_HELP, "NOTICE %s :File `%s' is already being sent.\n", dcc[i].nick, dcc[i].u.xfer->origname); lostdcc(i); return; } } } /* Put uploads in /tmp first */ s1 = nmalloc(strlen(tempdir) + strlen(dcc[i].u.xfer->filename) + 1); sprintf(s1, "%s%s", tempdir, dcc[i].u.xfer->filename); dcc[i].u.xfer->f = fopen(s1, "w"); my_free(s1); if (dcc[i].u.xfer->f == NULL) { dprintf(DP_HELP, "NOTICE %s :Can't create file `%s' (temp dir error)\n", dcc[i].nick, dcc[i].u.xfer->origname); lostdcc(i); } else { dcc[i].timeval = now; dcc[i].sock = getsock(SOCK_BINARY); if (dcc[i].sock < 0 || open_telnet_dcc(dcc[i].sock, ip, prt) < 0) dcc[i].type->eof(i); } } }