#include <fcntl.h>
#include <sys/stat.h>
#include <sys/file.h>
#include "src/mod/module.h"
#include <time.h>
#include "filedb3.h"
#include "filesys.h"
#include "src/tandem.h"
#include "files.h"
#include "dbcompat.h"
#include "filelist.h"
#include "files.c"
#include "filedb3.c"
#include "tclfiles.c"
#include "dbcompat.c"
#include "filelist.c"
Go to the source code of this file.
Defines | |
#define | MODULE_NAME "filesys" |
#define | MAKING_FILESYS |
#define | dirent direct |
#define | NAMLEN(dirent) (dirent)->d_namlen |
#define | MKTEMPFILE_TOT (7 + 2 + 8) |
Functions | |
static int | is_valid () |
static void | eof_dcc_files (int idx) |
static void | dcc_files (int idx, char *buf, int i) |
static void | disp_dcc_files (int idx, char *buf) |
static int | expmem_dcc_files (void *x) |
static void | kill_dcc_files (int idx, void *x) |
static void | out_dcc_files (int idx, char *buf, void *x) |
static char * | mktempfile (char *filename) |
static int | check_tcl_fil (char *cmd, int idx, char *args) |
static void | dcc_files_pass (int idx, char *buf, int x) |
static int | got_files_cmd (int idx, char *msg) |
static void | tell_file_stats (int idx, char *hand) |
static int | cmd_files (struct userrec *u, int idx, char *par) |
static int | _dcc_send (int idx, char *filename, char *nick, char *dir, int resend) |
static int | do_dcc_send (int idx, char *dir, char *fn, char *nick, int resend) |
static void | filesys_dcc_send_hostresolved (int) |
static void | filesys_dcc_send (char *nick, char *from, struct userrec *u, char *text) |
static int | filesys_DCC_CHAT (char *nick, char *from, char *handle, char *object, char *keyword, char *text) |
static void | init_server_ctcps (char *module) |
static int | filesys_expmem () |
static void | filesys_report (int idx, int details) |
static char * | filesys_close () |
EXPORT_SCOPE char * | filesys_start () |
char * | filesys_start (Function *global_funcs) |
Variables | |
static p_tcl_bind_list | H_fil |
static Function * | transfer_funcs = 0 |
static Function * | global = 0 |
static char | dccdir [121] = "" |
static char | dccin [121] = "" |
static int | upload_to_cd = 0 |
static int | dcc_maxsize = 1024 |
static int | dcc_users = 0 |
static char | filedb_path [121] = "" |
static struct dcc_table | DCC_FILES |
static struct user_entry_type | USERENTRY_DCCDIR |
static tcl_strings | mystrings [] |
static tcl_ints | myints [] |
static struct dcc_table | DCC_FILES_PASS |
static cmd_t | myctcp [] |
static cmd_t | myload [] |
static Function | filesys_table [] |
#define MKTEMPFILE_TOT (7 + 2 + 8) |
Definition at line 727 of file filesys.c.
Referenced by mktempfile().
static int _dcc_send | ( | int | idx, | |
char * | filename, | |||
char * | nick, | |||
char * | dir, | |||
int | resend | |||
) | [static] |
Definition at line 360 of file filesys.c.
References dcc, DCCSEND_BADFN, DCCSEND_FEMPTY, DCCSEND_FULL, DCCSEND_NOSOCK, DP_HELP, dprintf, egg_strcasecmp, LOG_FILES, malloc_strcpy, my_free, NICKMAX, NULL, putlog, raw_dcc_resend(), raw_dcc_send(), and reserved_port_min.
Referenced by do_dcc_send().
00362 { 00363 int x; 00364 char *nfn, *buf = NULL; 00365 00366 if (strlen(nick) > NICKMAX) 00367 nick[NICKMAX] = 0; 00368 if (resend) 00369 x = raw_dcc_resend(filename, nick, dcc[idx].nick, dir); 00370 else 00371 x = raw_dcc_send(filename, nick, dcc[idx].nick, dir); 00372 if (x == DCCSEND_FULL) { 00373 dprintf(idx, "Sorry, too many DCC connections. (try again later)\n"); 00374 putlog(LOG_FILES, "*", "DCC connections full: %sGET %s [%s]", filename, 00375 resend ? "RE" : "", dcc[idx].nick); 00376 return 0; 00377 } 00378 if (x == DCCSEND_NOSOCK) { 00379 if (reserved_port_min) { 00380 dprintf(idx, "All my DCC SEND ports are in use. Try later.\n"); 00381 putlog(LOG_FILES, "*", "DCC port in use (can't open): %sGET %s [%s]", 00382 resend ? "RE" : "", filename, dcc[idx].nick); 00383 } else { 00384 dprintf(idx, "Unable to listen at a socket.\n"); 00385 putlog(LOG_FILES, "*", "DCC socket error: %sGET %s [%s]", filename, 00386 resend ? "RE" : "", dcc[idx].nick); 00387 } 00388 return 0; 00389 } 00390 if (x == DCCSEND_BADFN) { 00391 dprintf(idx, "File not found ?\n"); 00392 putlog(LOG_FILES, "*", "DCC file not found: %sGET %s [%s]", filename, 00393 resend ? "RE" : "", dcc[idx].nick); 00394 return 0; 00395 } 00396 if (x == DCCSEND_FEMPTY) { 00397 dprintf(idx, "The file is empty. Aborted transfer.\n"); 00398 putlog(LOG_FILES, "*", "DCC file is empty: %s [%s]", filename, 00399 dcc[idx].nick); 00400 return 0; 00401 } 00402 nfn = strrchr(dir, '/'); 00403 if (nfn == NULL) 00404 nfn = dir; 00405 else 00406 nfn++; 00407 00408 /* Eliminate any spaces in the filename. */ 00409 if (strchr(nfn, ' ')) { 00410 char *p; 00411 00412 malloc_strcpy(buf, nfn); 00413 p = nfn = buf; 00414 while ((p = strchr(p, ' ')) != NULL) 00415 *p = '_'; 00416 } 00417 00418 if (egg_strcasecmp(nick, dcc[idx].nick)) 00419 dprintf(DP_HELP, "NOTICE %s :Here is %s file from %s %s...\n", nick, 00420 resend ? "the" : "a", dcc[idx].nick, resend ? "again " : ""); 00421 dprintf(idx, "%sending: %s to %s\n", resend ? "Res" : "S", nfn, nick); 00422 my_free(buf); 00423 return 1; 00424 }
static int check_tcl_fil | ( | char * | cmd, | |
int | idx, | |||
char * | args | |||
) | [static] |
Definition at line 145 of file filesys.c.
References BIND_AMBIGUOUS, BIND_EXEC_LOG, BIND_HAS_BUILTINS, BIND_NOMATCH, BIND_QUIT, BIND_USE_ATTR, check_tcl_bind, dcc, dprintf, FR_CHAN, FR_GLOBAL, get_user_flagrec, interp, LOG_FILES, MATCH_PARTIAL, putlog, and user.
Referenced by got_files_cmd().
00146 { 00147 int x; 00148 char s[5]; 00149 struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 }; 00150 00151 get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.file->chat->con_chan); 00152 sprintf(s, "%ld", dcc[idx].sock); 00153 Tcl_SetVar(interp, "_fil1", dcc[idx].nick, 0); 00154 Tcl_SetVar(interp, "_fil2", s, 0); 00155 Tcl_SetVar(interp, "_fil3", args, 0); 00156 x = check_tcl_bind(H_fil, cmd, &fr, " $_fil1 $_fil2 $_fil3", 00157 MATCH_PARTIAL | BIND_USE_ATTR | BIND_HAS_BUILTINS); 00158 if (x == BIND_AMBIGUOUS) { 00159 dprintf(idx, "Ambiguous command.\n"); 00160 return 0; 00161 } 00162 if (x == BIND_NOMATCH) { 00163 dprintf(idx, "What? You need 'help'\n"); 00164 return 0; 00165 } 00166 00167 /* We return 1 to leave the filesys */ 00168 if (x == BIND_QUIT) /* CMD_LEAVE, 'quit' */ 00169 return 1; 00170 00171 if (x == BIND_EXEC_LOG) 00172 putlog(LOG_FILES, "*", "#%s# files: %s %s", dcc[idx].nick, cmd, args); 00173 return 0; 00174 }
static int cmd_files | ( | struct userrec * | u, | |
int | idx, | |||
char * | par | |||
) | [static] |
Definition at line 310 of file filesys.c.
References botnet_send_join_idx, botnet_send_part_idx, chanout_but, dcc, DCC_CHAT, dcc_users, dccdir, dprintf, userrec::flags, get_data_ptr, GLOBAL_CHANS, LOG_CMDS, LOG_FILES, my_free, now, putlog, STAT_CHAT, too_many_filers(), touch_laston, USER_MASTER, USER_XFER, and welcome_to_files().
00311 { 00312 int atr = u ? u->flags : 0; 00313 static struct chat_info *ci; 00314 00315 if (dccdir[0] == 0) 00316 dprintf(idx, "There is no file transfer area.\n"); 00317 else if (too_many_filers()) { 00318 dprintf(idx, "The maximum of %d %s in the file area right now.\n", 00319 dcc_users, (dcc_users != 1) ? "people are" : "person is"); 00320 dprintf(idx, "Please try again later.\n"); 00321 } else { 00322 if (!(atr & (USER_MASTER | USER_XFER))) 00323 dprintf(idx, "You don't have access to the file area.\n"); 00324 else { 00325 putlog(LOG_CMDS, "*", "#%s# files", dcc[idx].nick); 00326 dprintf(idx, "Entering file system...\n"); 00327 if (dcc[idx].u.chat->channel >= 0) { 00328 00329 chanout_but(-1, dcc[idx].u.chat->channel, 00330 "*** %s has left: file system\n", dcc[idx].nick); 00331 if (dcc[idx].u.chat->channel < GLOBAL_CHANS) 00332 botnet_send_part_idx(idx, "file system"); 00333 } 00334 ci = dcc[idx].u.chat; 00335 dcc[idx].u.file = get_data_ptr(sizeof(struct file_info)); 00336 00337 dcc[idx].u.file->chat = ci; 00338 dcc[idx].type = &DCC_FILES; 00339 dcc[idx].status |= STAT_CHAT; 00340 if (!welcome_to_files(idx)) { 00341 struct chat_info *ci = dcc[idx].u.file->chat; 00342 00343 my_free(dcc[idx].u.file); 00344 dcc[idx].u.chat = ci; 00345 dcc[idx].type = &DCC_CHAT; 00346 putlog(LOG_FILES, "*", "File system broken."); 00347 if (dcc[idx].u.chat->channel >= 0) { 00348 chanout_but(-1, dcc[idx].u.chat->channel, 00349 "*** %s has returned.\n", dcc[idx].nick); 00350 if (dcc[idx].u.chat->channel < GLOBAL_CHANS) 00351 botnet_send_join_idx(idx, -1); 00352 } 00353 } else 00354 touch_laston(u, "filearea", now); 00355 } 00356 } 00357 return 0; 00358 }
static void dcc_files | ( | int | idx, | |
char * | buf, | |||
int | i | |||
) | [static] |
Definition at line 230 of file filesys.c.
References botnet_send_join_idx, chanout_but, check_tcl_filt, dcc, DCC_CHAT, dcc_total, DCT_MASTER, detect_dcc_flood, dprintf, flush_lines, GLOBAL_CHANS, got_files_cmd(), killsock, LOG_FILES, lostdcc, my_free, now, putlog, set_user, STAT_CHAT, STAT_ECHO, STAT_PAGE, touch_laston, user, and USER_MASTER.
00231 { 00232 if (buf[0] && detect_dcc_flood(&dcc[idx].timeval, dcc[idx].u.file->chat, 00233 idx)) 00234 return; 00235 dcc[idx].timeval = now; 00236 strcpy(buf, check_tcl_filt(idx, buf)); 00237 if (!buf[0]) 00238 return; 00239 touch_laston(dcc[idx].user, "filearea", now); 00240 if (buf[0] == ',') { 00241 for (i = 0; i < dcc_total; i++) { 00242 if ((dcc[i].type->flags & DCT_MASTER) && dcc[idx].user && 00243 (dcc[idx].user->flags & USER_MASTER) && 00244 ((dcc[i].type == &DCC_FILES) || (dcc[i].u.chat->channel >= 0)) && 00245 ((i != idx) || (dcc[idx].status & STAT_ECHO))) 00246 dprintf(i, "-%s- %s\n", dcc[idx].nick, &buf[1]); 00247 } 00248 } else if (got_files_cmd(idx, buf)) { 00249 dprintf(idx, "*** Ja mata!\n"); 00250 flush_lines(idx, dcc[idx].u.file->chat); 00251 putlog(LOG_FILES, "*", "DCC user [%s]%s left file system", dcc[idx].nick, 00252 dcc[idx].host); 00253 set_user(&USERENTRY_DCCDIR, dcc[idx].user, dcc[idx].u.file->dir); 00254 if (dcc[idx].status & STAT_CHAT) { 00255 struct chat_info *ci; 00256 00257 dprintf(idx, "Returning you to command mode...\n"); 00258 ci = dcc[idx].u.file->chat; 00259 my_free(dcc[idx].u.file); 00260 dcc[idx].u.chat = ci; 00261 dcc[idx].status &= (~STAT_CHAT); 00262 dcc[idx].type = &DCC_CHAT; 00263 if (dcc[idx].u.chat->channel >= 0) { 00264 chanout_but(-1, dcc[idx].u.chat->channel, 00265 "*** %s has returned.\n", dcc[idx].nick); 00266 if (dcc[idx].u.chat->channel < GLOBAL_CHANS) 00267 botnet_send_join_idx(idx, -1); 00268 } 00269 } else { 00270 dprintf(idx, "Dropping connection now.\n"); 00271 putlog(LOG_FILES, "*", "Left files: [%s]%s/%d", dcc[idx].nick, 00272 dcc[idx].host, dcc[idx].port); 00273 killsock(dcc[idx].sock); 00274 lostdcc(idx); 00275 } 00276 } 00277 if (dcc[idx].status & STAT_PAGE) 00278 flush_lines(idx, dcc[idx].u.file->chat); 00279 }
static void dcc_files_pass | ( | int | idx, | |
char * | buf, | |||
int | x | |||
) | [static] |
Definition at line 176 of file filesys.c.
References dcc, dprintf, get_user_by_handle, killsock, LOG_FILES, LOG_MISC, lostdcc, now, putlog, STAT_TELNET, too_many_filers(), touch_laston, u_pass_match, userlist, and welcome_to_files().
00177 { 00178 struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick); 00179 00180 if (!x) 00181 return; 00182 if (u_pass_match(u, buf)) { 00183 if (too_many_filers()) { 00184 dprintf(idx, "Too many people are in the file system right now.\n"); 00185 dprintf(idx, "Please try again later.\n"); 00186 putlog(LOG_MISC, "*", "File area full: DCC chat [%s]%s", dcc[idx].nick, 00187 dcc[idx].host); 00188 killsock(dcc[idx].sock); 00189 lostdcc(idx); 00190 return; 00191 } 00192 dcc[idx].type = &DCC_FILES; 00193 if (dcc[idx].status & STAT_TELNET) 00194 dprintf(idx, "\377\374\001\n"); /* turn echo back on */ 00195 putlog(LOG_FILES, "*", "File system: [%s]%s/%d", dcc[idx].nick, 00196 dcc[idx].host, dcc[idx].port); 00197 if (!welcome_to_files(idx)) { 00198 putlog(LOG_FILES, "*", "File system broken."); 00199 killsock(dcc[idx].sock); 00200 lostdcc(idx); 00201 } else { 00202 struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick); 00203 00204 touch_laston(u, "filearea", now); 00205 } 00206 return; 00207 } 00208 dprintf(idx, "Negative on that, Houston.\n"); 00209 putlog(LOG_MISC, "*", "Bad password: DCC chat [%s]%s", dcc[idx].nick, 00210 dcc[idx].host); 00211 killsock(dcc[idx].sock); 00212 lostdcc(idx); 00213 }
static void disp_dcc_files | ( | int | idx, | |
char * | buf | |||
) | [static] |
static int do_dcc_send | ( | int | idx, | |
char * | dir, | |||
char * | fn, | |||
char * | nick, | |||
int | resend | |||
) | [static] |
Definition at line 426 of file filesys.c.
References _dcc_send(), at_limit(), copy_to_tmp, copyfile, dcc, dccdir, DCCSEND_OK, dprintf, file_readable, LOG_FILES, LOG_MISC, mktempfile(), my_free, NICKMAX, nmalloc, nrealloc, NULL, putlog, queue_file(), tempdir, and wipe_tmp_filename().
Referenced by cmd_reget_get(), and files_reget().
00427 { 00428 char *s = NULL, *s1 = NULL; 00429 int x; 00430 00431 if (nick && strlen(nick) > NICKMAX) 00432 nick[NICKMAX] = 0; 00433 if (dccdir[0] == 0) { 00434 dprintf(idx, "DCC file transfers not supported.\n"); 00435 putlog(LOG_FILES, "*", "Refused dcc %sget %s from [%s]", resend ? "re" : "", 00436 fn, dcc[idx].nick); 00437 return 0; 00438 } 00439 if (strchr(fn, '/') != NULL) { 00440 dprintf(idx, "Filename cannot have '/' in it...\n"); 00441 putlog(LOG_FILES, "*", "Refused dcc %sget %s from [%s]", resend ? "re" : "", 00442 fn, dcc[idx].nick); 00443 return 0; 00444 } 00445 if (dir[0]) { 00446 s = nmalloc(strlen(dccdir) + strlen(dir) + strlen(fn) + 2); 00447 sprintf(s, "%s%s/%s", dccdir, dir, fn); 00448 } else { 00449 s = nmalloc(strlen(dccdir) + strlen(fn) + 1); 00450 sprintf(s, "%s%s", dccdir, fn); 00451 } 00452 00453 if (!file_readable(s)) { 00454 dprintf(idx, "No such file.\n"); 00455 putlog(LOG_FILES, "*", "Refused dcc %sget %s from [%s]", resend ? "re" : 00456 "", fn, dcc[idx].nick); 00457 my_free(s); 00458 return 0; 00459 } 00460 00461 if (!nick || !nick[0]) 00462 nick = dcc[idx].nick; 00463 /* Already have too many transfers active for this user? queue it */ 00464 if (at_limit(nick)) { 00465 char xxx[1024]; 00466 00467 sprintf(xxx, "%d*%s%s", (int) strlen(dccdir), dccdir, dir); 00468 queue_file(xxx, fn, dcc[idx].nick, nick); 00469 dprintf(idx, "Queued: %s to %s\n", fn, nick); 00470 my_free(s); 00471 return 1; 00472 } 00473 if (copy_to_tmp) { 00474 char *tempfn = mktempfile(fn); 00475 00476 /* Copy this file to /tmp, add a random prefix to the filename. */ 00477 s = nrealloc(s, strlen(dccdir) + strlen(dir) + strlen(fn) + 2); 00478 sprintf(s, "%s%s%s%s", dccdir, dir, dir[0] ? "/" : "", fn); 00479 s1 = nrealloc(s1, strlen(tempdir) + strlen(tempfn) + 1); 00480 sprintf(s1, "%s%s", tempdir, tempfn); 00481 my_free(tempfn); 00482 if (copyfile(s, s1) != 0) { 00483 dprintf(idx, "Can't make temporary copy of file!\n"); 00484 putlog(LOG_FILES | LOG_MISC, "*", 00485 "Refused dcc %sget %s: copy to %s FAILED!", 00486 resend ? "re" : "", fn, tempdir); 00487 my_free(s); 00488 my_free(s1); 00489 return 0; 00490 } 00491 } else { 00492 s1 = nrealloc(s1, strlen(dccdir) + strlen(dir) + strlen(fn) + 2); 00493 sprintf(s1, "%s%s%s%s", dccdir, dir, dir[0] ? "/" : "", fn); 00494 } 00495 s = nrealloc(s, strlen(dir) + strlen(fn) + 2); 00496 sprintf(s, "%s%s%s", dir, dir[0] ? "/" : "", fn); 00497 x = _dcc_send(idx, s1, nick, s, resend); 00498 if (x != DCCSEND_OK) 00499 wipe_tmp_filename(s1, -1); 00500 my_free(s); 00501 my_free(s1); 00502 return x; 00503 }
static void eof_dcc_files | ( | int | idx | ) | [static] |
static int expmem_dcc_files | ( | void * | x | ) | [static] |
static char* filesys_close | ( | ) | [static] |
Definition at line 952 of file filesys.c.
References dcc, DCC_BOOTED1, dcc_total, del_bind_table, del_entry_type, del_lang_section, dprintf, find_bind_table, H_ctcp, H_dcc, H_load, killsock, LOG_MISC, lostdcc, MODULE_NAME, module_undepend, myfiles, NULL, putlog, rem_builtins, rem_help_reference, rem_tcl_commands, rem_tcl_ints, and rem_tcl_strings.
00953 { 00954 int i; 00955 p_tcl_bind_list H_ctcp; 00956 00957 putlog(LOG_MISC, "*", "Unloading filesystem; killing all filesystem " 00958 "connections."); 00959 for (i = 0; i < dcc_total; i++) 00960 if (dcc[i].type == &DCC_FILES) { 00961 dprintf(i, DCC_BOOTED1); 00962 dprintf(i, "You have been booted from the filesystem, module " 00963 "unloaded.\n"); 00964 killsock(dcc[i].sock); 00965 lostdcc(i); 00966 } else if (dcc[i].type == &DCC_FILES_PASS) { 00967 killsock(dcc[i].sock); 00968 lostdcc(i); 00969 } 00970 rem_tcl_commands(mytcls); 00971 rem_tcl_strings(mystrings); 00972 rem_tcl_ints(myints); 00973 rem_builtins(H_dcc, mydcc); 00974 rem_builtins(H_load, myload); 00975 rem_builtins(H_fil, myfiles); 00976 rem_help_reference("filesys.help"); 00977 if ((H_ctcp = find_bind_table("ctcp"))) 00978 rem_builtins(H_ctcp, myctcp); 00979 del_bind_table(H_fil); 00980 del_entry_type(&USERENTRY_DCCDIR); 00981 del_lang_section("filesys"); 00982 module_undepend(MODULE_NAME); 00983 return NULL; 00984 }
static int filesys_DCC_CHAT | ( | char * | nick, | |
char * | from, | |||
char * | handle, | |||
char * | object, | |||
char * | keyword, | |||
char * | text | |||
) | [static] |
Definition at line 832 of file filesys.c.
References botname, chan_op, dcc, DCC_CONNECTFAILED1, DCC_CONNECTFAILED2, DCC_ENTERPASS, DCC_REFUSED, DCC_REFUSED2, DCC_REFUSED3, DCC_REFUSED4, DCC_REFUSED5, DCC_REFUSED7, DCC_TOOMANYDCCS2, dcc_total, dccdir, DP_HELP, dprintf, egg_strcasecmp, egg_strncasecmp, filesys_dcc_send(), FR_ANYWH, FR_CHAN, FR_GLOBAL, get_data_ptr, get_user_by_handle, get_user_flagrec, getsock, glob_party, glob_xfer, userrec::handle, increase_socks_max, killsock, LOG_FILES, LOG_MISC, max_dcc, my_atoul, neterror, new_dcc, newsplit, now, open_telnet_dcc, putlog, quiet_reject, require_p, STAT_ECHO, u_pass_match, and userlist.
00834 { 00835 char *param, *ip, *prt, buf[512], *msg = buf; 00836 int i, sock; 00837 struct userrec *u = get_user_by_handle(userlist, handle); 00838 struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 }; 00839 00840 if (egg_strcasecmp(object, botname)) 00841 return 0; 00842 if (!egg_strncasecmp(text, "SEND ", 5)) { 00843 filesys_dcc_send(nick, from, u, text + 5); 00844 return 1; 00845 } 00846 if (egg_strncasecmp(text, "CHAT ", 5) || !u) 00847 return 0; 00848 strcpy(buf, text + 5); 00849 get_user_flagrec(u, &fr, 0); 00850 param = newsplit(&msg); 00851 if (dcc_total == max_dcc && increase_socks_max()) { 00852 putlog(LOG_MISC, "*", DCC_TOOMANYDCCS2, "CHAT(file)", param, nick, from); 00853 } else if (glob_party(fr) || (!require_p && chan_op(fr))) 00854 return 0; /* Allow ctcp.so to pick up the chat */ 00855 else if (!glob_xfer(fr)) { 00856 if (!quiet_reject) 00857 dprintf(DP_HELP, "NOTICE %s :%s\n", nick, DCC_REFUSED2); 00858 putlog(LOG_MISC, "*", "%s: %s!%s", DCC_REFUSED, nick, from); 00859 } else if (u_pass_match(u, "-")) { 00860 if (!quiet_reject) 00861 dprintf(DP_HELP, "NOTICE %s :%s\n", nick, DCC_REFUSED3); 00862 putlog(LOG_MISC, "*", "%s: %s!%s", DCC_REFUSED4, nick, from); 00863 } else if (!dccdir[0]) { 00864 putlog(LOG_MISC, "*", "%s: %s!%s", DCC_REFUSED5, nick, from); 00865 } else { 00866 ip = newsplit(&msg); 00867 prt = newsplit(&msg); 00868 sock = getsock(0); 00869 if (sock < 0 || open_telnet_dcc(sock, ip, prt) < 0) { 00870 neterror(buf); 00871 if (!quiet_reject) 00872 dprintf(DP_HELP, "NOTICE %s :%s (%s)\n", nick, DCC_CONNECTFAILED1, buf); 00873 putlog(LOG_MISC, "*", "%s: CHAT(file) (%s!%s)", DCC_CONNECTFAILED2, nick, 00874 from); 00875 putlog(LOG_MISC, "*", " (%s)", buf); 00876 killsock(sock); 00877 } else if (atoi(prt) < 1024 || atoi(prt) > 65535) { 00878 /* Invalid port */ 00879 if (!quiet_reject) 00880 dprintf(DP_HELP, "NOTICE %s :%s (invalid port)\n", nick, 00881 DCC_CONNECTFAILED1); 00882 putlog(LOG_FILES, "*", "%s: %s!%s", DCC_REFUSED7, nick, from); 00883 00884 } else { 00885 i = new_dcc(&DCC_FILES_PASS, sizeof(struct file_info)); 00886 dcc[i].addr = my_atoul(ip); 00887 dcc[i].port = atoi(prt); 00888 dcc[i].sock = sock; 00889 strcpy(dcc[i].nick, u->handle); 00890 strcpy(dcc[i].host, from); 00891 dcc[i].status = STAT_ECHO; 00892 dcc[i].timeval = now; 00893 dcc[i].u.file->chat = get_data_ptr(sizeof(struct chat_info)); 00894 strcpy(dcc[i].u.file->chat->con_chan, "*"); 00895 dcc[i].user = u; 00896 putlog(LOG_MISC, "*", "DCC connection: CHAT(file) (%s!%s)", nick, from); 00897 dprintf(i, "%s\n", DCC_ENTERPASS); 00898 } 00899 } 00900 return 1; 00901 }
static void filesys_dcc_send | ( | char * | nick, | |
char * | from, | |||
struct userrec * | u, | |||
char * | text | |||
) | [static] |
Definition at line 634 of file filesys.c.
References dcc, DCC_CONNECTFAILED1, dcc_dnshostbyip, DCC_DNSWAIT, DCC_FORK_SEND, dcc_maxsize, dccin, DP_HELP, dprintf, filesys_dcc_send_hostresolved(), userrec::flags, get_data_ptr, LOG_FILES, LOG_MISC, my_atoul, my_free, new_dcc, newsplit, nmalloc, NULL, putlog, quiet_reject, RES_HOSTBYIP, sanitycheck_dcc, upload_to_cd, and USER_XFER.
Referenced by filesys_DCC_CHAT().
00636 { 00637 char *param, *ip, *prt, *buf = NULL, *msg; 00638 int atr = u ? u->flags : 0, i, j = 0; 00639 00640 if (text[j] == '"') { 00641 text[j] = ' '; 00642 00643 for (j = 1; text[j] != '"' && text[j] != '\0'; j++) { 00644 if (text[j] == ' ') 00645 { 00646 text[j] = '_'; 00647 } 00648 } 00649 00650 text[j] = ' '; 00651 } 00652 00653 buf = nmalloc(strlen(text) + 1); 00654 msg = buf; 00655 strcpy(buf, text); 00656 param = newsplit(&msg); 00657 if (!(atr & USER_XFER)) { 00658 putlog(LOG_FILES, "*", "Refused DCC SEND %s (no access): %s!%s", param, 00659 nick, from); 00660 if (!quiet_reject) 00661 dprintf(DP_HELP, "NOTICE %s :No access\n", nick); 00662 } else if (!dccin[0] && !upload_to_cd) { 00663 dprintf(DP_HELP, "NOTICE %s :DCC file transfers not supported.\n", nick); 00664 putlog(LOG_FILES, "*", "Refused dcc send %s from %s!%s", param, nick, from); 00665 } else if (strchr(param, '/')) { 00666 dprintf(DP_HELP, "NOTICE %s :Filename cannot have '/' in it...\n", nick); 00667 putlog(LOG_FILES, "*", "Refused dcc send %s from %s!%s", param, nick, from); 00668 } else { 00669 ip = newsplit(&msg); 00670 prt = newsplit(&msg); 00671 if (atoi(prt) < 1024 || atoi(prt) > 65535) { 00672 /* Invalid port */ 00673 dprintf(DP_HELP, "NOTICE %s :%s (invalid port)\n", nick, 00674 DCC_CONNECTFAILED1); 00675 putlog(LOG_FILES, "*", "Refused dcc send %s (%s): invalid port", param, 00676 nick); 00677 } else if (atoi(msg) == 0) { 00678 dprintf(DP_HELP, "NOTICE %s :Sorry, file size info must be included.\n", 00679 nick); 00680 putlog(LOG_FILES, "*", "Refused dcc send %s (%s): no file size", 00681 param, nick); 00682 } else if (dcc_maxsize && (atoi(msg) > (dcc_maxsize * 1024))) { 00683 dprintf(DP_HELP, "NOTICE %s :Sorry, file too large.\n", nick); 00684 putlog(LOG_FILES, "*", "Refused dcc send %s (%s): file too large", param, 00685 nick); 00686 } else { 00687 /* This looks like a good place for a sanity check. */ 00688 if (!sanitycheck_dcc(nick, from, ip, prt)) { 00689 my_free(buf); 00690 return; 00691 } 00692 i = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info)); 00693 if (i < 0) { 00694 dprintf(DP_HELP, "NOTICE %s :Sorry, too many DCC connections.\n", nick); 00695 putlog(LOG_MISC, "*", "DCC connections full: SEND %s (%s!%s)", param, 00696 nick, from); 00697 return; 00698 } 00699 dcc[i].addr = my_atoul(ip); 00700 dcc[i].port = atoi(prt); 00701 dcc[i].sock = -1; 00702 dcc[i].user = u; 00703 strcpy(dcc[i].nick, nick); 00704 strcpy(dcc[i].host, from); 00705 dcc[i].u.dns->cbuf = get_data_ptr(strlen(param) + 1); 00706 strcpy(dcc[i].u.dns->cbuf, param); 00707 dcc[i].u.dns->ibuf = atoi(msg); 00708 dcc[i].u.dns->ip = dcc[i].addr; 00709 dcc[i].u.dns->dns_type = RES_HOSTBYIP; 00710 dcc[i].u.dns->dns_success = filesys_dcc_send_hostresolved; 00711 dcc[i].u.dns->dns_failure = filesys_dcc_send_hostresolved; 00712 dcc[i].u.dns->type = &DCC_FORK_SEND; 00713 dcc_dnshostbyip(dcc[i].addr); 00714 } 00715 } 00716 my_free(buf); 00717 }
static void filesys_dcc_send_hostresolved | ( | int | i | ) | [static] |
Definition at line 749 of file filesys.c.
References changeover_dcc, dcc, DCC_FORK_SEND, dcc_total, dccdir, dccin, DCT_FILESEND, DCT_FILETRAN, DP_HELP, dprintf, file_readable, get_data_ptr, get_user, getsock, hostsanitycheck_dcc, iptolong, lostdcc, mktempfile(), my_free, nmalloc, now, NULL, open_telnet_dcc, SOCK_BINARY, tempdir, upload_to_cd, and user.
Referenced by filesys_dcc_send().
00750 { 00751 char *s1, *param, prt[100], ip[100], *tempf; 00752 int len = dcc[i].u.dns->ibuf, j; 00753 00754 sprintf(prt, "%d", dcc[i].port); 00755 sprintf(ip, "%lu", iptolong(htonl(dcc[i].addr))); 00756 if (!hostsanitycheck_dcc(dcc[i].nick, dcc[i].u.dns->host, dcc[i].addr, 00757 dcc[i].u.dns->host, prt)) { 00758 lostdcc(i); 00759 return; 00760 } 00761 param = nmalloc(strlen(dcc[i].u.dns->cbuf) + 1); 00762 strcpy(param, dcc[i].u.dns->cbuf); 00763 00764 changeover_dcc(i, &DCC_FORK_SEND, sizeof(struct xfer_info)); 00765 if (param[0] == '.') 00766 param[0] = '_'; 00767 /* Save the original filename */ 00768 dcc[i].u.xfer->origname = get_data_ptr(strlen(param) + 1); 00769 strcpy(dcc[i].u.xfer->origname, param); 00770 tempf = mktempfile(param); 00771 dcc[i].u.xfer->filename = get_data_ptr(strlen(tempf) + 1); 00772 strcpy(dcc[i].u.xfer->filename, tempf); 00773 /* We don't need the temporary buffers anymore */ 00774 my_free(tempf); 00775 my_free(param); 00776 00777 if (upload_to_cd) { 00778 char *p = get_user(&USERENTRY_DCCDIR, dcc[i].user); 00779 00780 if (p) 00781 sprintf(dcc[i].u.xfer->dir, "%s%s/", dccdir, p); 00782 else 00783 sprintf(dcc[i].u.xfer->dir, "%s", dccdir); 00784 } else 00785 strcpy(dcc[i].u.xfer->dir, dccin); 00786 dcc[i].u.xfer->length = len; 00787 s1 = nmalloc(strlen(dcc[i].u.xfer->dir) + 00788 strlen(dcc[i].u.xfer->origname) + 1); 00789 sprintf(s1, "%s%s", dcc[i].u.xfer->dir, dcc[i].u.xfer->origname); 00790 00791 if (file_readable(s1)) { 00792 dprintf(DP_HELP, "NOTICE %s :File `%s' already exists.\n", dcc[i].nick, 00793 dcc[i].u.xfer->origname); 00794 lostdcc(i); 00795 my_free(s1); 00796 } else { 00797 my_free(s1); 00798 /* Check for dcc-sends in process with the same filename */ 00799 for (j = 0; j < dcc_total; j++) 00800 if (j != i) { 00801 if ((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND)) == 00802 (DCT_FILETRAN | DCT_FILESEND)) { 00803 if (!strcmp(dcc[i].u.xfer->origname, dcc[j].u.xfer->origname)) { 00804 dprintf(DP_HELP, "NOTICE %s :File `%s' is already being sent.\n", 00805 dcc[i].nick, dcc[i].u.xfer->origname); 00806 lostdcc(i); 00807 return; 00808 } 00809 } 00810 } 00811 /* Put uploads in /tmp first */ 00812 s1 = nmalloc(strlen(tempdir) + strlen(dcc[i].u.xfer->filename) + 1); 00813 sprintf(s1, "%s%s", tempdir, dcc[i].u.xfer->filename); 00814 dcc[i].u.xfer->f = fopen(s1, "w"); 00815 my_free(s1); 00816 if (dcc[i].u.xfer->f == NULL) { 00817 dprintf(DP_HELP, 00818 "NOTICE %s :Can't create file `%s' (temp dir error)\n", 00819 dcc[i].nick, dcc[i].u.xfer->origname); 00820 lostdcc(i); 00821 } else { 00822 dcc[i].timeval = now; 00823 dcc[i].sock = getsock(SOCK_BINARY); 00824 if (dcc[i].sock < 0 || open_telnet_dcc(dcc[i].sock, ip, prt) < 0) 00825 dcc[i].type->eof(i); 00826 } 00827 } 00828 }
static int filesys_expmem | ( | ) | [static] |
Definition at line 921 of file filesys.c.
Referenced by filesys_report().
static void filesys_report | ( | int | idx, | |
int | details | |||
) | [static] |
Definition at line 926 of file filesys.c.
References dcc_maxsize, dcc_users, dccdir, dccin, dprintf, filesys_expmem(), and upload_to_cd.
00927 { 00928 if (details) { 00929 int size = filesys_expmem(); 00930 00931 if (dccdir[0]) { 00932 dprintf(idx, " DCC file path: %s", dccdir); 00933 if (upload_to_cd) 00934 dprintf(idx, "\n Incoming: (user's current directory)\n"); 00935 else if (dccin[0]) 00936 dprintf(idx, "\n Incoming: %s\n", dccin); 00937 else 00938 dprintf(idx, " (no uploads)\n"); 00939 00940 if (dcc_users) 00941 dprintf(idx, " Max users: %d\n", dcc_users); 00942 if (upload_to_cd || dccin[0]) 00943 dprintf(idx, " Max upload file size: %dk\n", dcc_maxsize); 00944 } else 00945 dprintf(idx, " Filesystem module loaded, but no active dcc path " 00946 "exists.\n"); 00947 dprintf(idx, " Using %d byte%s of memory\n", size, 00948 (size != 1) ? "s" : ""); 00949 } 00950 }
char* filesys_start | ( | Function * | global_funcs | ) |
Definition at line 1003 of file filesys.c.
References add_bind_table, add_builtins, add_entry_type, add_help_reference, add_lang_section, add_tcl_commands, add_tcl_ints, add_tcl_strings, global, user_entry_type::got_share, H_dcc, H_load, init_server_ctcps(), module_depend, MODULE_NAME, module_register, module_undepend, my_memcpy, myfiles, NULL, password_timeout, dcc_table::timeout_val, transfer_funcs, and USERENTRY_INFO.
01004 { 01005 global = global_funcs; 01006 01007 module_register(MODULE_NAME, filesys_table, 2, 0); 01008 if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) { 01009 module_undepend(MODULE_NAME); 01010 return "This module requires Eggdrop 1.6.0 or later."; 01011 } 01012 if (!(transfer_funcs = module_depend(MODULE_NAME, "transfer", 2, 0))) { 01013 module_undepend(MODULE_NAME); 01014 return "This module requires transfer module 2.0 or later."; 01015 } 01016 add_tcl_commands(mytcls); 01017 add_tcl_strings(mystrings); 01018 add_tcl_ints(myints); 01019 H_fil = add_bind_table("fil", 0, builtin_fil); 01020 add_builtins(H_dcc, mydcc); 01021 add_builtins(H_fil, myfiles); 01022 add_builtins(H_load, myload); 01023 add_help_reference("filesys.help"); 01024 init_server_ctcps(0); 01025 my_memcpy(&USERENTRY_DCCDIR, &USERENTRY_INFO, 01026 sizeof(struct user_entry_type) - sizeof(char *)); 01027 01028 USERENTRY_DCCDIR.got_share = 0; /* We dont want it shared tho */ 01029 add_entry_type(&USERENTRY_DCCDIR); 01030 DCC_FILES_PASS.timeout_val = &password_timeout; 01031 add_lang_section("filesys"); 01032 return NULL; 01033 }
EXPORT_SCOPE char* filesys_start | ( | ) |
static int got_files_cmd | ( | int | idx, | |
char * | msg | |||
) | [static] |
Definition at line 217 of file filesys.c.
References check_tcl_fil(), check_tcl_filt, and newsplit.
Referenced by dcc_files().
00218 { 00219 char *code; 00220 00221 strcpy(msg, check_tcl_filt(idx, msg)); 00222 if (!msg[0]) 00223 return 1; 00224 if (msg[0] == '.') 00225 msg++; 00226 code = newsplit(&msg); 00227 return check_tcl_fil(code, idx, msg); 00228 }
static void init_server_ctcps | ( | char * | module | ) | [static] |
Definition at line 908 of file filesys.c.
References add_builtins, find_bind_table, and H_ctcp.
Referenced by filesys_start().
00909 { 00910 p_tcl_bind_list H_ctcp; 00911 00912 if ((H_ctcp = find_bind_table("ctcp"))) 00913 add_builtins(H_ctcp, myctcp); 00914 }
static int is_valid | ( | ) | [static] |
static void kill_dcc_files | ( | int | idx, | |
void * | x | |||
) | [static] |
static char * mktempfile | ( | char * | filename | ) | [static] |
Definition at line 728 of file filesys.c.
References make_rand_str, MKTEMPFILE_TOT, my_free, NAME_MAX, and nmalloc.
Referenced by do_dcc_send(), and filesys_dcc_send_hostresolved().
00729 { 00730 char rands[8], *tempname, *fn = filename; 00731 int l; 00732 00733 make_rand_str(rands, 7); 00734 l = strlen(filename); 00735 if ((l + MKTEMPFILE_TOT) > NAME_MAX) { 00736 fn[NAME_MAX - MKTEMPFILE_TOT] = 0; 00737 l = NAME_MAX - MKTEMPFILE_TOT; 00738 fn = nmalloc(l + 1); 00739 strncpy(fn, filename, l); 00740 fn[l] = 0; 00741 } 00742 tempname = nmalloc(l + MKTEMPFILE_TOT + 1); 00743 sprintf(tempname, "%u-%s-%s", getpid(), rands, fn); 00744 if (fn != filename) 00745 my_free(fn); 00746 return tempname; 00747 }
static void out_dcc_files | ( | int | idx, | |
char * | buf, | |||
void * | x | |||
) | [static] |
static void tell_file_stats | ( | int | idx, | |
char * | hand | |||
) | [static] |
Definition at line 281 of file filesys.c.
References filesys_stats::dnload_ks, filesys_stats::dnloads, dprintf, fr, get_user, get_user_by_handle, NULL, filesys_stats::upload_ks, filesys_stats::uploads, USERENTRY_FSTAT, and userlist.
00282 { 00283 struct userrec *u; 00284 struct filesys_stats *fs; 00285 float fr = (-1.0), kr = (-1.0); 00286 00287 u = get_user_by_handle(userlist, hand); 00288 if (u == NULL) 00289 return; 00290 if (!(fs = get_user(&USERENTRY_FSTAT, u))) { 00291 dprintf(idx, "No file statistics for %s.\n", hand); 00292 } else { 00293 dprintf(idx, " uploads: %4u / %6luk\n", fs->uploads, fs->upload_ks); 00294 dprintf(idx, "downloads: %4u / %6luk\n", fs->dnloads, fs->dnload_ks); 00295 if (fs->uploads) 00296 fr = ((float) fs->dnloads / (float) fs->uploads); 00297 if (fs->upload_ks) 00298 kr = ((float) fs->dnload_ks / (float) fs->upload_ks); 00299 if (fr < 0.0) 00300 dprintf(idx, "(infinite file leech)\n"); 00301 else 00302 dprintf(idx, "leech ratio (files): %6.2f\n", fr); 00303 if (kr < 0.0) 00304 dprintf(idx, "(infinite size leech)\n"); 00305 else 00306 dprintf(idx, "leech ratio (size) : %6.2f\n", kr); 00307 } 00308 }
{ "FILES", 0x00000002 | 0x00000010 | 0x00000004 | 0x00000020 | 0x00000040 | 0x00000080 , eof_dcc_files, dcc_files, 0 , 0 , disp_dcc_files, expmem_dcc_files, kill_dcc_files, out_dcc_files }
Definition at line 106 of file filesys.c.
Referenced by too_many_filers().
struct dcc_table DCC_FILES_PASS [static] |
{ "FILES_PASS", 0, eof_dcc_files, dcc_files_pass, 0 , tout_dcc_files_pass, disp_dcc_files_pass, expmem_dcc_files, kill_dcc_files, out_dcc_files }
int dcc_maxsize = 1024 [static] |
Definition at line 87 of file filesys.c.
Referenced by filesys_dcc_send(), and filesys_report().
int dcc_users = 0 [static] |
Definition at line 90 of file filesys.c.
Referenced by cmd_files(), filesys_report(), and too_many_filers().
char dccdir[121] = "" [static] |
Definition at line 77 of file filesys.c.
Referenced by add_file(), cmd_files(), cmd_mkdir(), cmd_mv_cp(), cmd_rm(), cmd_rmdir(), do_dcc_send(), filedb_open(), filesys_DCC_CHAT(), filesys_dcc_send_hostresolved(), filesys_report(), is_valid(), remote_filereq(), resolve_dir(), and welcome_to_files().
char dccin[121] = "" [static] |
Definition at line 80 of file filesys.c.
Referenced by filesys_dcc_send(), filesys_dcc_send_hostresolved(), and filesys_report().
char filedb_path[121] = "" [static] |
Definition at line 94 of file filesys.c.
Referenced by filedb_open().
Function filesys_table[] [static] |
{ (Function) filesys_start, (Function) filesys_close, (Function) filesys_expmem, (Function) filesys_report, (Function) remote_filereq, (Function) add_file, (Function) incr_file_gots, (Function) is_valid, (Function) & H_fil, }
p_tcl_bind_list H_fil [static] |
{ {"DCC", "", filesys_DCC_CHAT, "files:DCC"}, { 0 , 0 , 0 , 0 } }
{ {"max-filesize", &dcc_maxsize}, {"max-file-users", &dcc_users}, {"upload-to-pwd", &upload_to_cd}, { 0 , 0 } }
{ {"server", "", (IntFunc) init_server_ctcps, "filesys:server"}, { 0 , 0 , 0 , 0 } }
tcl_strings mystrings[] [static] |
{ {"files-path", dccdir, 120, 1 | 2 }, {"incoming-path", dccin, 120, 1 | 2 }, {"filedb-path", filedb_path, 120, 1 | 2 }, { 0 , 0 , 0, 0} }
Function* transfer_funcs = 0 [static] |
Definition at line 71 of file filesys.c.
Referenced by filesys_start().
int upload_to_cd = 0 [static] |
Definition at line 83 of file filesys.c.
Referenced by filesys_dcc_send(), filesys_dcc_send_hostresolved(), and filesys_report().
struct user_entry_type USERENTRY_DCCDIR [static] |
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
"DCCDIR"
}
Definition at line 119 of file filesys.c.
Referenced by cmd_chdir(), cmd_optimize(), files_setpwd(), and welcome_to_files().