src/mod/filesys.mod/filesys.c File Reference

#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"
Include dependency graph for filesys.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 Functiontransfer_funcs = 0
static Functionglobal = 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 Documentation

#define dirent   direct

Definition at line 39 of file filesys.c.

#define MAKING_FILESYS

Definition at line 27 of file filesys.c.

#define MKTEMPFILE_TOT   (7 + 2 + 8)

Definition at line 727 of file filesys.c.

Referenced by mktempfile().

#define MODULE_NAME   "filesys"

Definition at line 26 of file filesys.c.

#define NAMLEN ( dirent   )     (dirent)->d_namlen

Definition at line 40 of file filesys.c.


Function Documentation

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int filesys_expmem (  )  [static]

Definition at line 921 of file filesys.c.

Referenced by filesys_report().

00922 {
00923   return 0;
00924 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

static int is_valid (  )  [static]

Definition at line 1035 of file filesys.c.

References dccdir.

01036 {
01037   return dccdir[0];
01038 }

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 }

Here is the caller graph for this function:

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 }


Variable Documentation

struct dcc_table DCC_FILES [static]
Initial value:
 {
  "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]
Initial value:
 {
  "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
}

Definition at line 616 of file filesys.c.

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]
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* global = 0 [static]

Definition at line 74 of file filesys.c.

Definition at line 70 of file filesys.c.

cmd_t myctcp[] [static]
Initial value:
 {
  {"DCC", "",   filesys_DCC_CHAT, "files:DCC"},
  { 0 ,   0 ,  0 ,                     0 }
}

Definition at line 903 of file filesys.c.

tcl_ints myints[] [static]
Initial value:
 {
  {"max-filesize",    &dcc_maxsize},
  {"max-file-users",    &dcc_users},
  {"upload-to-pwd",  &upload_to_cd},
  { 0 ,                       0 }
}

Definition at line 609 of file filesys.c.

cmd_t myload[] [static]
Initial value:
 {
  {"server", "",   (IntFunc) init_server_ctcps, "filesys:server"},
  { 0 ,      0 ,  0 ,                                      0 }
}

Definition at line 916 of file filesys.c.

tcl_strings mystrings[] [static]
Initial value:
 {
  {"files-path",    dccdir,      120,  1  |  2 },
  {"incoming-path", dccin,       120,  1  |  2 },
  {"filedb-path",   filedb_path, 120,  1  |  2 },
  { 0 ,             0 ,        0,                       0}
}

Definition at line 602 of file filesys.c.

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().

Initial value:
 {
   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().


Generated on 7 Sep 2016 for Eggdrop by  doxygen 1.6.1