/*
* transferfstat.c -- part of transfer.mod
*
* $Id: transferfstat.c,v 1.8 2006-03-28 02:35:51 wcc Exp $
*
* Copyright (C) 2003 - 2006 Eggheads Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
static int fstat_unpack(struct userrec *u, struct user_entry *e)
{
char *par, *arg;
struct filesys_stats *fs;
fs = user_malloc(sizeof(struct filesys_stats));
egg_bzero(fs, sizeof(struct filesys_stats));
par = e->u.list->extra;
arg = newsplit(&par);
if (arg[0])
fs->uploads = atoi(arg);
arg = newsplit(&par);
if (arg[0])
fs->upload_ks = atoi(arg);
arg = newsplit(&par);
if (arg[0])
fs->dnloads = atoi(arg);
arg = newsplit(&par);
if (arg[0])
fs->dnload_ks = atoi(arg);
list_type_kill(e->u.list);
e->u.extra = fs;
return 1;
}
static int fstat_pack(struct userrec *u, struct user_entry *e)
{
register struct filesys_stats *fs;
struct list_type *l = user_malloc(sizeof(struct list_type));
fs = e->u.extra;
l->extra = user_malloc(41);
egg_snprintf(l->extra, 41, "%09u %09u %09u %09u", fs->uploads, fs->upload_ks,
fs->dnloads, fs->dnload_ks);
l->next = NULL;
e->u.list = l;
nfree(fs);
return 1;
}
static int fstat_write_userfile(FILE *f, struct userrec *u,
struct user_entry *e)
{
register struct filesys_stats *fs;
fs = e->u.extra;
if (fprintf(f, "--FSTAT %09u %09u %09u %09u\n", fs->uploads, fs->upload_ks,
fs->dnloads, fs->dnload_ks) == EOF)
return 0;
return 1;
}
static int fstat_set(struct userrec *u, struct user_entry *e, void *buf)
{
register struct filesys_stats *fs = buf;
if (e->u.extra != fs) {
if (e->u.extra)
nfree(e->u.extra);
e->u.extra = fs;
} else if (!fs) /* e->u.extra == NULL && fs == NULL */
return 1;
if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED))) {
if (fs)
/* Don't check here for something like:
* ofs->uploads != fs->uploads || ofs->upload_ks != fs->upload_ks ||
* ofs->dnloads != fs->dnloads || ofs->dnload_ks != fs->dnload_ks
*
* Someone could do:
* e->u.extra->uploads = 12345;
* fs = user_malloc(sizeof(struct filesys_stats));
* my_memcpy(...e->u.extra...fs...);
* set_user(&USERENTRY_FSTAT, u, fs);
*
* Then we wouldn't detect here that something's changed.
* --rtc
*/
shareout(NULL, "ch fstat %09u %09u %09u %09u\n", fs->uploads,
fs->upload_ks, fs->dnloads, fs->dnload_ks);
else
shareout(NULL, "ch fstat r\n");
}
return 1;
}
static int fstat_tcl_get(Tcl_Interp *irp, struct userrec *u,
struct user_entry *e, int argc, char **argv)
{
register struct filesys_stats *fs;
char d[50];
BADARGS(3, 4, " handle FSTAT ?u/d?");
fs = e->u.extra;
if (argc == 3)
egg_snprintf(d, sizeof d, "%u %u %u %u", fs->uploads, fs->upload_ks,
fs->dnloads, fs->dnload_ks);
else
switch (argv[3][0]) {
case 'u':
egg_snprintf(d, sizeof d, "%u %u", fs->uploads, fs->upload_ks);
break;
case 'd':
egg_snprintf(d, sizeof d, "%u %u", fs->dnloads, fs->dnload_ks);
break;
}
Tcl_AppendResult(irp, d, NULL);
return TCL_OK;
}
static int fstat_kill(struct user_entry *e)
{
if (e->u.extra)
nfree(e->u.extra);
nfree(e);
return 1;
}
static int fstat_expmem(struct user_entry *e)
{
return sizeof(struct filesys_stats);
}
static void fstat_display(int idx, struct user_entry *e)
{
struct filesys_stats *fs;
fs = e->u.extra;
dprintf(idx, " FILES: %u download%s (%luk), %u upload%s (%luk)\n",
fs->dnloads, (fs->dnloads == 1) ? "" : "s", fs->dnload_ks,
fs->uploads, (fs->uploads == 1) ? "" : "s", fs->upload_ks);
}
static struct user_entry_type USERENTRY_FSTAT = {
NULL,
fstat_gotshare,
fstat_dupuser,
fstat_unpack,
fstat_pack,
fstat_write_userfile,
fstat_kill,
NULL,
fstat_set,
fstat_tcl_get,
fstat_tcl_set,
fstat_expmem,
fstat_display,
"FSTAT"
};
static int fstat_gotshare(struct userrec *u, struct user_entry *e,
char *par, int idx)
{
char *p;
struct filesys_stats *fs;
noshare = 1;
switch (par[0]) {
case 'u':
case 'd':
break;
case 'r':
set_user(&USERENTRY_FSTAT, u, NULL);
break;
default:
if (!(fs = e->u.extra)) {
fs = user_malloc(sizeof(struct filesys_stats));
egg_bzero(fs, sizeof(struct filesys_stats));
}
p = newsplit(&par);
if (p[0])
fs->uploads = atoi(p);
p = newsplit(&par);
if (p[0])
fs->upload_ks = atoi(p);
p = newsplit(&par);
if (p[0])
fs->dnloads = atoi(p);
p = newsplit(&par);
if (p[0])
fs->dnload_ks = atoi(p);
set_user(&USERENTRY_FSTAT, u, fs);
break;
}
noshare = 0;
return 1;
}
static int fstat_dupuser(struct userrec *u, struct userrec *o,
struct user_entry *e)
{
struct filesys_stats *fs;
if (e->u.extra) {
fs = user_malloc(sizeof(struct filesys_stats));
my_memcpy(fs, e->u.extra, sizeof(struct filesys_stats));
return set_user(&USERENTRY_FSTAT, u, fs);
}
return 0;
}
static void stats_add_dnload(struct userrec *u, unsigned long bytes)
{
struct user_entry *ue;
register struct filesys_stats *fs;
if (u) {
if (!(ue = find_user_entry(&USERENTRY_FSTAT, u)) || !(fs = ue->u.extra)) {
fs = user_malloc(sizeof(struct filesys_stats));
egg_bzero(fs, sizeof(struct filesys_stats));
}
fs->dnloads++;
fs->dnload_ks += ((bytes + 512) / 1024);
set_user(&USERENTRY_FSTAT, u, fs);
/* No shareout here, set_user already sends info... --rtc */
}
}
static void stats_add_upload(struct userrec *u, unsigned long bytes)
{
struct user_entry *ue;
register struct filesys_stats *fs;
if (u) {
if (!(ue = find_user_entry(&USERENTRY_FSTAT, u)) || !(fs = ue->u.extra)) {
fs = user_malloc(sizeof(struct filesys_stats));
egg_bzero(fs, sizeof(struct filesys_stats));
}
fs->uploads++;
fs->upload_ks += ((bytes + 512) / 1024);
set_user(&USERENTRY_FSTAT, u, fs);
/* No shareout here, set_user already sends info... --rtc */
}
}
static int fstat_tcl_set(Tcl_Interp *irp, struct userrec *u,
struct user_entry *e, int argc, char **argv)
{
register struct filesys_stats *fs;
int f = 0, k = 0;
BADARGS(4, 6, " handle FSTAT u/d ?files ?ks??");
if (argc > 4)
f = atoi(argv[4]);
if (argc > 5)
k = atoi(argv[5]);
switch (argv[3][0]) {
case 'u':
case 'd':
if (!(fs = e->u.extra)) {
fs = user_malloc(sizeof(struct filesys_stats));
egg_bzero(fs, sizeof(struct filesys_stats));
}
switch (argv[3][0]) {
case 'u':
fs->uploads = f;
fs->upload_ks = k;
break;
case 'd':
fs->dnloads = f;
fs->dnload_ks = k;
break;
}
set_user(&USERENTRY_FSTAT, u, fs);
break;
case 'r':
set_user(&USERENTRY_FSTAT, u, NULL);
break;
}
return TCL_OK;
}
syntax highlighted by Code2HTML, v. 0.9.1