/* CDCC v2 1.00 (c) Copyright 1996 William Glozer */
/* ----------------------------------------------- */
/* Last revision 04.19.96 by Ananda */
/* New CDCC for BitchX and any other clients that deserve to run it :) */
/* Note that I did use a lot of code/ideas from a copy of CDCC written */
/* for BitchX by panasync, so thanks to him for alot of the code and */
/* ideas :) I would appreciate any bugs reported to me as soon as is */
/* possible, and cdcc.c + cdcc.h for any mods you do... if you modify */
/* it for your client, I can add those mods as #ifdefs so the next ver */
/* will work with your client and have all the new stuff. -Ananda '96 */
/* Modifed even more by panasync (edwards@bitchx.dimension6.com) to */
/* interface cleanly and nicely with BitchX. Blame all bugs on me */
/* instead of Ananda */
#define CDCC_FLUD
#include "irc.h"
static char cvsrevision[] = "$Id: cdcc.c,v 1.1.1.1 2003/04/11 01:09:07 dan Exp $";
CVS_REVISION(cdcc_c)
#include "ircaux.h"
#include "struct.h"
#include "commands.h"
#include "ignore.h"
#include "ctcp.h"
#include "hook.h"
#include "dcc.h"
#include "flood.h"
#include "screen.h"
#include "parse.h"
#include "output.h"
#include "input.h"
#include "server.h"
#include "vars.h"
#include "list.h"
#include "userlist.h"
#include "misc.h"
#include "who.h"
#include "cdcc.h"
#include "misc.h"
#define MAIN_SOURCE
#include "modval.h"
#ifdef WANT_CDCC
/* external ircII stuff */
static int l_timer (char *, char *);
static int r_info (char *, char *);
static int r_rmsend (char *, char *);
static int r_queue (char *, char *);
static int l_tsend (char *, char *);
static int l_tresend (char *, char *);
static int l_resume (char *, char *);
static int l_describe (char *, char *);
static int l_help(char *, char *);
/* add a pack to the offer list */
static int l_offer(char *, char *);
/* send a pack to someone */
static int l_send(char *, char *);
/* re-send a pack to someone */
static int l_resend(char *, char *);
/* remove a pack or all packs from the offer list */
static int l_doffer(char *, char *);
/* localy list offered packs */
static int l_list(char *, char *);
/* notify the channel that packs are offered */
static int l_notice(char *, char *);
/* view your queue */
static int l_queue(char *, char *);
/* save all offered packs to cdcc.save */
static int l_save(char *, char *);
/* load packs from cdcc.save */
static int l_load(char *, char *);
static int l_minspeed(char *, char *);
static int l_secure(char *, char *);
/* remote CDCC commands */
/* -------------------- */
/* show help to a remote user */
static int r_help(char *, char *);
/* list packs offered to remote user */
static int r_list(char *, char *);
/* send pack to remote user */
static int r_send(char *, char *);
/* re-send pack to remote user */
static int r_rsend(char *, char *);
#if 0
/* send pack to remote user */
static int r_tsend(char *, char *);
/* re-send pack to remote user */
static int r_trsend(char *, char *);
#endif
/* add files */
static void add_files(char *, char *);
/* add description */
static void add_desc(char *, char *);
/* remove pack/all packs */
static void del_pack(char *, char *);
/* add/remove public channel */
static int l_channel(char *, char *);
/* add note to a pack */
static int l_note(char *, char *);
static int l_echo(char *, char *);
static int l_stats(char *, char *);
static int l_type(char *, char *);
/* add a person to the dcc queue */
int BX_add_to_queue(char *, char *, pack *);
void dcc_getfile_resume (char *, char *);
/* local commands */
local_cmd local[] = {
{ "CHANNEL", l_channel, "public timer channel" },
{ "DESCRIBE", l_describe, "change description of pack" },
{ "DOFFER", l_doffer, "remove pack from the offer list" },
{ "LIST", l_list, "list the packs you have offered" },
{ "LOAD", l_load, "load packs saved to .cdcc.save or specified name" },
{ "HELP", l_help, "cdcc help" },
{ "MINSPEED", l_minspeed, "minspeed for cdcc ( #.##) [mintime in seconds]" },
{ "NOTICE", l_notice, "notify the channel of offered packs" },
{ "OFFER", l_offer, "add a pack to the offer list" },
{ "PLIST", l_plist, "publicly list your offered packs" },
{ "QUEUE", l_queue, "view entries in the send queue" },
{ "SAVE", l_save, "save your offerlist to .cdcc.save or specified name" },
{ "SEND", l_send, "send a pack to user" },
{ "RESEND", l_resend, "re-send a pack to user" },
{ "TSEND", l_tsend, "tdcc send a pack to user" },
{ "TRESEND", l_tresend, "tdcc resend a pack to user" },
#ifdef MIRC_BROKEN_DCC_RESUME
{ "RESUME", l_resume, "mirc resume" },
#endif
{ "TIMER", l_timer, "public list timer in minutes" },
{ "NOTE", l_note, "add note to pack number"},
{ "TYPE", l_type, "toggle between public and notice" },
{ "ECHO", l_echo, "toggle echo on/off" },
{ "STATS", l_stats, "display cdcc statistics" },
{ "SECURE", l_secure, "adds a password to a pack"},
{ "ON", NULL, "cdcc offers on" },
{ "OFF", NULL, "cdcc offers off" },
{ empty_string, NULL, empty_string }
};
#define NUM_LOCAL (sizeof(local) / sizeof(local_cmd))
/* remote commands */
remote_cmd remote[] = {
{ "HELP", r_help, "help on CDCC commands" },
{ "RESEND", r_rsend, "have CDCC resend pack #N"},
#ifdef MIRC_BROKEN_DCC_RESUME
{ "RESUME", r_rmsend, "have CDCC resume pack #N"},
#endif
{ "SEND", r_send, "have CDCC send pack #N" },
#if 0
{ "TRESEND", r_trsend, "have CDCC tresend pack #N"},
{ "TSEND", r_tsend, "have CDCC tsend pack #N" },
#endif
{ "LIST", r_list, "list of offered packs" },
{ "INFO", r_info, "info on pack #N" },
{ "QUEUE", r_queue, "queue status for us" },
{ empty_string, NULL, empty_string },
};
#define NUM_REMOTE (sizeof(remote) / sizeof(remote_cmd))
/* ahh yes, global variables :( well, interfacing with ircII is a pain in */
/* the ass, and I couldn't figure out a better way... more than one of my */
/* routines need these... the static will keep them from being used by any */
/* functions outside of cdcc.c */
unsigned int cdcc_numpacks = 0;
unsigned int send_numpacks = 0;
pack *offerlist = NULL;
static pack *newpack;
static queue *queuelist = NULL;
static unsigned long total_size_of_packs = 0;
static int numqueue = 0;
static int ptimer = 0;
static int do_notice_list = 0;
static int do_cdcc_echo = 1;
double cdcc_minspeed = 0.0;
static char *public_channel = NULL;
extern double dcc_max_rate_out, dcc_bytes_out, dcc_max_rate_in, dcc_bytes_in;
#define cparse(s) convert_output_format(s, NULL, NULL)
/* parse a users CDCC command */
BUILT_IN_COMMAND(cdcc)
{
int i;
char *cmd, *rest;
cmd = next_arg(args, &args);
rest = next_arg(args, &args);
if (!cmd)
{
l_list(NULL, NULL);
put_it("%s: CDCC is [\002%s\002]. Use \002/cdcc help\002 to get help with cdcc", cparse(get_string_var(CDCC_PROMPT_VAR)), on_off(get_int_var(CDCC_VAR)));
return;
}
if (!my_stricmp(cmd, "ON") || !my_stricmp(cmd, "OFF"))
{
set_int_var(CDCC_VAR, !my_stricmp(cmd, "ON") ? 1 : 0);
put_it("%s: offers \002%s\002", cparse(get_string_var(CDCC_PROMPT_VAR)), cmd);
return;
}
for (i = 0; *local[i].name; i++)
{
if (!my_stricmp(local[i].name, cmd) && local[i].function)
{
local[i].function(rest, args);
return;
}
}
put_it("%s: unknown command \002%s\002", cparse(get_string_var(CDCC_PROMPT_VAR)), cmd);
return;
}
static int l_help(char *cmd, char *args)
{
int i;
char buffer[BIG_BUFFER_SIZE+1];
if (!cmd)
{
int c = 0;
*buffer = 0;
for (i = 0; *local[i].name; i++)
{
strmcat(buffer, local[i].name, BIG_BUFFER_SIZE);
strmcat(buffer, space, BIG_BUFFER_SIZE);
if (++c == 5)
{
put_it("%s", convert_output_format("$G $[13]0 $[13]1 $[13]2 $[13]3 $[13]4", "%s", buffer));
*buffer = 0;
c = 0;
}
}
if (c)
put_it("%s", convert_output_format("$G $[13]0 $[13]1 $[13]2 $[13]3 $[13]4", "%s", buffer));
userage("CDCC help", "%R[%ncommand%R]%n to get help on specific commands");
}
else
{
int done = 0;
for (i = 0; *local[i].name; i++)
{
if (my_stricmp(local[i].name, cmd))
continue;
sprintf(buffer, "CDCC %s", cmd);
userage(buffer, local[i].help?local[i].help:" - No help available");
done++;
}
if (!done)
put_it("%s", convert_output_format("$G CDCC - No such command", NULL, NULL));
}
return 0;
}
/* parse a remote message CDCC command */
char *msgcdcc(char *from, char *to, char *args)
{
int i;
char *secure = NULL;
char *cdcc, *rest, *cmd, *temp = NULL;
temp = LOCAL_COPY(args);
cdcc = next_arg(temp, &temp);
if (!cdcc || (my_strnicmp(cdcc, "XDCC", 4) && my_strnicmp(cdcc, "CDCC", 4)))
return args;
if (!get_int_var(CDCC_VAR))
return args;
if ((check_ignore(from, FromUserHost, to, IGNORE_CDCC, NULL) == IGNORED))
return args;
if (!check_flooding(from, CDCC_FLOOD, args, NULL) || !offerlist)
return NULL;
if ((secure = get_string_var(CDCC_SECURITY_VAR)))
{
UserList *tmp;
char *pass = NULL;
if (*secure == '0' && strlen(secure) == 1)
goto got_good_pass;
if (temp && *temp)
pass = strrchr(temp, ' ');
if (pass && *pass)
{
pass++;
if (*pass && !my_stricmp(pass, secure))
{
*pass-- = 0;
goto got_good_pass;
}
}
#ifdef WANT_USERLIST
if (!(tmp = lookup_userlevelc("*", FromUserHost, "*", NULL)) || !(tmp->flags & ADD_DCC))
return args;
#else
return args;
#endif
}
got_good_pass:
cmd = next_arg(temp, &temp);
if (!cmd)
return args;
rest = temp;
for (i = 0; *remote[i].name; i++)
{
if (!my_stricmp(cmd, remote[i].name))
{
remote[i].function(from, rest);
return NULL;
}
}
queue_send_to_server(from_server, "NOTICE %s :try /ctcp %s cdcc help",from, get_server_nickname(from_server));
return args;
}
static int r_info(char *args, char *rest)
{
if (rest && *rest)
{
char *q;
pack *ptr = NULL;
q = next_arg(rest, &rest);
for (ptr = offerlist; ptr; ptr = ptr->next)
if (matchmcommand(q, ptr->num))
break;
if (ptr)
queue_send_to_server(from_server, "NOTICE %s :%d file%s %d gets %ld size %2.4f minspeed %ld time added",args, ptr->numfiles, plural(ptr->numfiles), ptr->gets, ptr->size, ptr->minspeed, ptr->timeadded);
else
queue_send_to_server(from_server, "NOTICE %s :Invalid info request", args);
}
return 0;
}
static int r_queue(char *args, char *rest)
{
queue *new = NULL;
int count;
int num = 0;
char buffer[BIG_BUFFER_SIZE+1];
if (queuelist && args)
{
*buffer = 0;
for (new = queuelist, count = 1; new; new = new->next)
{
if (!my_stricmp(new->nick, args))
{
num++;
strmopencat(buffer, BIG_BUFFER_SIZE, ltoa(count), ",", NULL);
count++;
}
}
if (num)
{
chop(buffer, 1);
queue_send_to_server(from_server, "NOTICE %s :You have %d packs queued at %s", args, num, buffer);
}
else
queue_send_to_server(from_server, "NOTICE %s :You have no packs queued.", args);
}
return 0;
}
static int do_local_send(char *command, char *args, char *rest)
{
pack *ptr = NULL;
char *temp = NULL, *file = NULL, *dccinfo = NULL, *q = NULL, *p;
int maxdcc, maxqueue;
int tdcc = 0;
int queued_files = 0;
int count = 0;
if (*command == 'T')
tdcc = 1;
if (!args || !*args)
return 0;
maxdcc = get_int_var(DCC_SEND_LIMIT_VAR);
maxqueue = get_int_var(DCC_QUEUE_LIMIT_VAR);
while (1)
{
if (!(temp = next_arg(rest, &rest)))
break;
if (isdigit((unsigned char)*temp) || (*(temp+1) && isdigit((unsigned char)*(temp+1))))
{
if (*temp == '#')
temp++;
for (ptr = offerlist; ptr; ptr = ptr->next)
if (matchmcommand(temp, ptr->num))
break;
}
if (ptr)
{
if (maxdcc && get_active_count() >= maxdcc)
{
if (maxqueue && (numqueue >= maxqueue))
{
put_it("%s: all dcc and queue slots full", cparse(get_string_var(CDCC_PROMPT_VAR)));
if (queued_files)
put_it("%s: Queued %d files", cparse(get_string_var(CDCC_PROMPT_VAR)), queued_files );
return count + queued_files;
}
queued_files += add_to_queue(args, command, ptr);
do_hook(CDCC_SEND_NICK_LIST, "%s %s %s %d %d %d %s %s", args, "unknown", command, ptr->num, ptr->numfiles, ptr->gets, ptr->file, ptr->desc);
continue;
}
put_it("%s: %s %s%s%s pack #\002%d\002 (\002%d\002 file%s)", cparse(get_string_var(CDCC_PROMPT_VAR)),
!my_stricmp(command, "SEND")||!my_stricmp(command,"TSEND")?"sending":"resending",
UND_TOG_STR, args, UND_TOG_STR, ptr->num, ptr->numfiles,
plural(ptr->numfiles));
malloc_strcpy(&file, ptr->file);
q = file;
for (p = new_next_arg(file, &file); p && *p; p = new_next_arg(file, &file))
{
malloc_sprintf(&dccinfo, "%s \"%s\"", args, p);
if (!my_stricmp(command, "SEND") || !my_stricmp(command, "TSEND"))
dcc_filesend(command, dccinfo);
else
dcc_resend(command, dccinfo);
}
send_numpacks++;
count++;
ptr->gets++;
do_hook(CDCC_SEND_NICK_LIST, "%s %s %s %d %d %d %s %s", args, "unknown", command, ptr->num, ptr->numfiles, ptr->gets, ptr->file, ptr->desc);
}
else
{
if (offerlist && (isdigit((unsigned char)*temp) || (*(temp+1) && (isdigit((unsigned char)*(temp+1))))))
put_it("%s: No such pack number", cparse(get_string_var(CDCC_PROMPT_VAR)));
else
{
malloc_sprintf(&dccinfo, "%s \"%s\"", args, temp);
if (!my_stricmp(command, "SEND") || !my_stricmp(command, "TSEND"))
dcc_filesend(command, dccinfo);
else
dcc_resend(command, dccinfo);
count++;
}
}
new_free(&q);
file = NULL;
}
if (queued_files)
put_it("%s: Queued %d files", cparse(get_string_var(CDCC_PROMPT_VAR)), queued_files);
new_free(&dccinfo);
new_free(&q);
return count + queued_files;
}
static int l_send(char *args, char *rest)
{
do_local_send("SEND", args, rest);
return 0;
}
static int l_resend(char *args, char *rest)
{
do_local_send("RESEND", args, rest);
return 0;
}
#ifdef MIRC_BROKEN_DCC_RESUME
static int l_resume(char *args, char *rest)
{
do_local_send("RESUME", args, rest);
return 0;
}
#endif
static int l_tsend(char *args, char *rest)
{
do_local_send("TSEND", args, rest);
return 0;
}
static int l_tresend(char *args, char *rest)
{
do_local_send("TRESEND", args, rest);
return 0;
}
/*resends a pack to the requestee*/
/*Added by Wicked Angel: wangel@wgrobez1.remote.louisville.edu*/
/*It wasn't hard ... but hey ... it seemed like a good idea :>*/
/* routine modified highly by Colten Edwards. */
static int do_dcc_sends(char *command, char *from, char *args)
{
pack *ptr;
char *temp = NULL, *file = NULL, *dccinfo = NULL, *q = NULL, *p;
char *password = NULL;
int maxdcc, maxqueue;
int count = 0;
int queued_files = 0;
maxdcc = get_int_var(DCC_SEND_LIMIT_VAR);
maxqueue = get_int_var(DCC_QUEUE_LIMIT_VAR);
while (1)
{
if (!(temp = next_arg(args, &args)))
break;
if (args && *args && (!my_isdigit(args)))
password = next_arg(args, &args);
for (ptr = offerlist; ptr; ptr = ptr->next)
if (matchmcommand(temp, ptr->num))
break;
if (ptr)
{
if (ptr->password && (!password || (password && strcmp(ptr->password, password))))
{
put_it("%s: Attempted get of secure pack %d from %s failed. [%s]", cparse(get_string_var(CDCC_PROMPT_VAR)), ptr->num, from, !password? "No Password": "Invalid Password");
queue_send_to_server(from_server, "NOTICE %s :\002CDCC\002: Failed attempt to get secure pack %d", from, ptr->num);
continue;
}
if (maxdcc && ((maxdcc - get_active_count()) < ptr->numfiles || get_active_count() >= maxdcc))
{
if (maxqueue && (numqueue >= maxqueue))
{
if (queued_files)
{
put_it("%s: Queued %d files for %s", cparse(get_string_var(CDCC_PROMPT_VAR)), queued_files, from);
queue_send_to_server(from_server, "NOTICE %s :\002CDCC\002: all slots full... Some requests ignored. Added to queue for %d requests", from, queued_files);
}
else
queue_send_to_server(from_server, "NOTICE %s :\002CDCC\002: all dcc and queue slots full... Try again later", from);
return 0;
}
queued_files += add_to_queue(from, command, ptr);
count++;
do_hook(CDCC_SEND_NICK_LIST, "%s %s %s %d %d %d %s %s", from, FromUserHost, command, ptr->num, ptr->numfiles, ptr->gets, ptr->file, ptr->desc);
continue;
}
put_it("%s: %s %s%s%s pack #\002%d\002 (\002%d\002 file%s)", cparse(get_string_var(CDCC_PROMPT_VAR)),
!my_stricmp(command, "SEND")||!my_stricmp(command, "TSEND")?"sending":!my_stricmp(command,"RESUME")?"resuming":"resending", UND_TOG_STR, from, UND_TOG_STR,
ptr->num, ptr->numfiles, plural(ptr->numfiles));
malloc_strcpy(&file, ptr->file);
q = file;
for (p = next_arg(file, &file); p && *p; p = next_arg(file, &file))
{
malloc_sprintf(&dccinfo, "%s %s", from, p);
if (!my_stricmp(command, "RESEND") || !my_stricmp(command, "TRESEND"))
dcc_resend(command, dccinfo);
#ifdef MIRC_BROKEN_DCC_RESUME
else if (!my_stricmp(command, "RESUME"))
dcc_resume(command, dccinfo);
#endif
else
dcc_filesend(command, dccinfo);
}
send_numpacks++;
ptr->gets++;
do_hook(CDCC_SEND_NICK_LIST, "%s %s %s %d %d %d %s %s", from, FromUserHost, command, ptr->num, ptr->numfiles, ptr->gets, ptr->file, ptr->desc);
}
else if (!count)
queue_send_to_server(from_server, "NOTICE %s :\002CDCC\002: invalid pack number", from);
count++;
new_free(&q);
file = NULL;
}
if (queued_files)
{
put_it("%s: Queued %d files for %s", cparse(get_string_var(CDCC_PROMPT_VAR)), queued_files, from);
queue_send_to_server(from_server, "NOTICE %s :\002CDCC\002: all slots full... Added to the queue for %d requests", from, queued_files);
}
new_free(&dccinfo);
new_free(&q);
return 0;
}
static int r_rsend(char *from, char *args)
{
do_dcc_sends("RESEND", from, args);
return 0;
}
#ifdef MIRC_BROKEN_DCC_RESUME
static int r_rmsend(char *from, char *args)
{
do_dcc_sends("RESUME", from, args);
return 0;
}
#endif
#if 0
static int r_trsend(char *from, char *args)
{
do_dcc_sends("TRESEND", from, args);
return 0;
}
static int r_tsend(char *from, char *args)
{
do_dcc_sends("TSEND", from, args);
return 0;
}
#endif
/* senD a pack to the remote user */
static int r_send(char *from, char *args)
{
do_dcc_sends("SEND", from, args);
return 0;
}
/* remote pack list */
static int r_list(char *from, char *args)
{
pack *ptr;
char size[30];
char mrate_out[30];
char mrate_in[30];
char bytes_out[30];
char bytes_in[30];
char speed_out[30];
char *type_msg;
int once = 0;
sprintf(mrate_out, "%1.3g", dcc_max_rate_out);
sprintf(mrate_in, "%1.3g", dcc_max_rate_in);
sprintf(bytes_out, "%1.3g", dcc_bytes_out);
sprintf(bytes_in, "%1.3g", dcc_bytes_in);
sprintf(speed_out, "%1.3g", cdcc_minspeed);
type_msg = (do_notice_list)? "NOTICE":"PRIVMSG";
for (ptr = offerlist; ptr; ptr = ptr->next)
{
if (!once && do_hook(CDCC_PREPACK_LIST, "%s %s %s %d %d %d %d %d %s %s %s %s %lu %s",
"NOTICE", from, get_server_nickname(from_server),
cdcc_numpacks,
get_int_var(DCC_SEND_LIMIT_VAR)-get_active_count(),
get_int_var(DCC_SEND_LIMIT_VAR), numqueue,
get_int_var(DCC_QUEUE_LIMIT_VAR),
mrate_out, bytes_out, mrate_in, bytes_in,
total_size_of_packs, speed_out))
{
queue_send_to_server(from_server,"NOTICE %s :Files Offered: /ctcp %s CDCC send #N for pack N", from, get_server_nickname(from_server));
if (get_int_var(DCC_SEND_LIMIT_VAR))
queue_send_to_server(from_server, "NOTICE %s : [%d pack%s %d/%d slots open]", from,
cdcc_numpacks, plural(cdcc_numpacks), get_int_var(DCC_SEND_LIMIT_VAR)-get_active_count(), get_int_var(DCC_SEND_LIMIT_VAR));
else
queue_send_to_server(from_server, "NOTICE %s : [%d pack%s]", from, cdcc_numpacks,plural(cdcc_numpacks));
}
if (ptr->size / 1024 > 999)
sprintf(size, "\002%4.1f\002mb",
(((double)ptr->size) / 1024) / 1024);
else
sprintf(size, "\002%4.1f\002kb", (((double)ptr->size) / 1024));
if (do_hook(CDCC_PACK_LIST, "%s %s %d %d %lu %d %s",
"NOTICE", from, ptr->num, ptr->numfiles, ptr->size, ptr->gets, ptr->desc))
{
queue_send_to_server(from_server, "NOTICE %s :#%d \037(\037%10s\037:\037\002%4d\002 get%s\037)\037 %s",
from, ptr->num, size, ptr->gets, plural(ptr->gets),
ptr->desc ? ptr->desc : "no description");
}
if (ptr->notes && do_hook(CDCC_NOTE_LIST, "%s %s %s", "NOTICE", from, ptr->notes))
queue_send_to_server(from_server, "NOTICE %s :\t%s", from, ptr->notes);
once++;
}
if (once)
do_hook(CDCC_POSTPACK_LIST, "%s %s %s %d %d %d %d %d %s %s %s %s %lu %s",
"NOTICE", from, get_server_nickname(from_server),
cdcc_numpacks, get_int_var(DCC_SEND_LIMIT_VAR)-get_active_count(),
get_int_var(DCC_SEND_LIMIT_VAR), numqueue, get_int_var(DCC_QUEUE_LIMIT_VAR),
mrate_out, bytes_out, mrate_in, bytes_in, total_size_of_packs, speed_out);
return 0;
}
/* remote help display */
static int r_help(char *from, char *args)
{
int i;
#ifdef CDCC_FLUD
if (args && *args)
{
char *q;
q = next_arg(args, &args);
for (i = 0; *remote[i].name; i++)
{
if (!my_stricmp(remote[i].name, q))
{
queue_send_to_server(from_server, "NOTICE %s :\002CDCC\002: %-6s - %s",
from, remote[i].name, remote[i].help);
break;
}
}
}
else
{
char buffer[BIG_BUFFER_SIZE+1];
char *q = buffer;
for (i = 0; *remote[i].name; i++)
{
snprintf(q, BIG_BUFFER_SIZE, "%s ", remote[i].name);
q = &buffer[strlen(buffer)];
}
queue_send_to_server(from_server, "NOTICE %s :\002CDCC\002: %s", from, buffer);
}
#endif
return 0;
}
/* remove a pack or all packs from the offerlist */
static int l_doffer(char *args, char *rest)
{
if (!cdcc_numpacks) {
put_it("%s: you have no packs offered", cparse(get_string_var(CDCC_PROMPT_VAR)));
return 0;
}
if (args && *args)
{
char * temp = NULL;
malloc_sprintf(&temp, "%s %s", args, rest ? rest : empty_string);
del_pack(NULL, temp);
new_free(&temp);
l_list(NULL, NULL);
}
else
{
l_list(NULL, NULL);
add_wait_prompt("Remove pack [* for all packs]: ", del_pack, empty_string, WAIT_PROMPT_LINE, 1);
}
return 0;
}
/* localy list the packs you have offered */
static int l_list(char *args, char *rest)
{
pack *ptr;
char temp[30];
if (!cdcc_numpacks)
{
put_it("%s: you have no packs offered", cparse(get_string_var(CDCC_PROMPT_VAR)));
return 0;
}
if (args)
{
char *num = next_arg(args, &args);
int it;
it = my_atol(num);
if (it <= 0)
return 0;
for (ptr = offerlist; ptr; ptr= ptr->next)
{
if (it == ptr->num)
{
char *temp = NULL;
char *p, *q;
int i = 1;
malloc_strcpy(&temp, ptr->file);
q = temp;
while (temp && *temp)
{
p = next_arg(temp, &temp);
put_it("#%-2d %-2d %-2d %s",
ptr->num, ptr->gets, i++, p);
}
new_free(&q);
break;
}
}
}
else
{
put_it("%s", convert_output_format("# files size gets minspeed description", NULL, NULL));
for (ptr = offerlist; ptr; ptr = ptr->next)
{
sprintf(temp, "%4.1f", _GMKv(ptr->size));
/* buggy SUNOS doesn't like this next line at all. Why?
sprintf(temp2, "%4.1f", (double)(ptr->minspeed));*/
put_it("%-2d \002%3d\002 %6s%-4s \002%4d\002 0.0 %s",
ptr->num, ptr->numfiles,
temp, _GMKs(ptr->size), /*temp2*/ptr->gets, ptr->desc);
}
}
return 0;
}
/* add a pack to the offer list */
static int l_offer(char *args, char *rest)
{
char *tmp = NULL;
if (args && *args)
{
tmp = m_sprintf("%s %s", args, rest?rest:empty_string);
add_files(NULL, tmp);
}
else
{
malloc_sprintf(&tmp, "Add file(s) to pack%s #%d : ", plural(cdcc_numpacks), cdcc_numpacks+1);
add_wait_prompt(tmp, add_files, empty_string, WAIT_PROMPT_LINE, 1);
}
new_free(&tmp);
return 0;
}
/* display the offerlist to current channel */
int l_plist(char *args, char *rest)
{
pack *ptr;
char *chan = NULL, *string = NULL;
char size[20];
char mrate_out[30];
char mrate_in[30];
char bytes_out[30];
char bytes_in[30];
char speed_out[30];
char *type_msg;
int maxdccs, blocksize, maxqueue;
if (!get_current_channel_by_refnum(0) || !cdcc_numpacks || (args && *args && !is_channel(args))) {
put_it("%s: you %s",cparse(get_string_var(CDCC_PROMPT_VAR)),
cdcc_numpacks ? "are not on a channel!" :
"have no packs offered!");
return 0;
}
type_msg = (do_notice_list)? "NOTICE":"PRIVMSG";
if (args && *args)
chan = LOCAL_COPY(args);
else
chan = LOCAL_COPY(get_current_channel_by_refnum(0));
maxdccs = get_int_var(DCC_SEND_LIMIT_VAR);
blocksize = get_int_var(DCC_BLOCK_SIZE_VAR);
maxqueue = get_int_var(DCC_QUEUE_LIMIT_VAR);
set_display_target(chan, LOG_CRAP);
sprintf(mrate_out, "%1.3g", dcc_max_rate_out);
sprintf(mrate_in, "%1.3g", dcc_max_rate_in);
sprintf(bytes_out, "%1.3g", dcc_bytes_out);
sprintf(bytes_in, "%1.3g", dcc_bytes_in);
sprintf(speed_out, "%1.3g", cdcc_minspeed);
if (do_hook(CDCC_PREPACK_LIST, "%s %s %s %d %d %d %d %d %s %s %s %s %lu %s", type_msg, chan, get_server_nickname(from_server), cdcc_numpacks, get_int_var(DCC_SEND_LIMIT_VAR)-get_active_count(), get_int_var(DCC_SEND_LIMIT_VAR), numqueue, get_int_var(DCC_QUEUE_LIMIT_VAR), mrate_out, bytes_out, mrate_in, bytes_in, total_size_of_packs, speed_out))
{
if (get_int_var(QUEUE_SENDS_VAR))
{
malloc_sprintf(&string, "\037[\037cdcc\037]\037 \002%d\002 file%s offered\037-\037 /ctcp \002%s\002 cdcc send #x for pack #x",
cdcc_numpacks, plural(cdcc_numpacks), get_server_nickname(from_server));
queue_send_to_server(from_server, "%s %s :%s",
do_notice_list?"NOTICE":"PRIVMSG", chan, string);
malloc_sprintf(&string, "\037[\037cdcc\037]\037 dcc block size\037:\037 \002%d\002, slots open\037:\037 \002%2d\002/\002%2d\002, dcc queue\037:\037 \002%2d\002/\002%2d\002",
(blocksize) ? blocksize : 1024, maxdccs - get_active_count(),
maxdccs, maxqueue - numqueue, maxqueue);
queue_send_to_server(from_server, "%s %s :%s",
do_notice_list?"NOTICE":"PRIVMSG", chan, string);
}
else
{
malloc_sprintf(&string, "\037[\037cdcc\037]\037 \002%d\002 file%s offered\037-\037 /ctcp \002%s\002 cdcc send #x for pack #x",
cdcc_numpacks, plural(cdcc_numpacks), get_server_nickname(from_server));
send_text(chan, string, do_notice_list?"NOTICE":NULL, do_cdcc_echo, 0);
malloc_sprintf(&string, "\037[\037cdcc\037]\037 dcc block size\037:\037 \002%d\002, slots open\037:\037 \002%2d\002/\002%2d\002, dcc queue\037:\037 \002%2d\002/\002%2d\002",
(blocksize) ? blocksize : 1024, maxdccs - get_active_count(),
maxdccs, maxqueue - numqueue, maxqueue);
send_text(chan, string, do_notice_list?"NOTICE":NULL, do_cdcc_echo, 0);
}
}
for (ptr = offerlist; ptr; ptr = ptr->next)
{
if (ptr->size / 1024 > 999)
sprintf(size, "\002%3.2f\002mb",
(float) (ptr->size / 1024) / 1024);
else
sprintf(size, "\002%3.2f\002kb", (float) ptr->size / 1024);
if (do_hook(CDCC_PACK_LIST, "%s %s %d %d %lu %d %s",
type_msg, chan, ptr->num, ptr->numfiles, ptr->size, ptr->gets, ptr->desc))
{
if (get_int_var(QUEUE_SENDS_VAR))
{
malloc_sprintf(&string, "\037%%\037 #%-2d \037(\037%10s\037:\037\002%4d\002 get%s\037)\037 %s",
ptr->num, size, ptr->gets, plural(ptr->gets),
ptr->desc ? ptr->desc : "no description");
queue_send_to_server(from_server, "%s %s :%s",
do_notice_list?"NOTICE":"PRIVMSG", chan, string);
}
else
{
malloc_sprintf(&string, "\037%%\037 #%-2d \037(\037%10s\037:\037\002%4d\002 get%s\037)\037 %s",
ptr->num, size, ptr->gets, plural(ptr->gets),
ptr->desc ? ptr->desc : "no description");
send_text(chan, string, do_notice_list?"NOTICE":NULL, do_cdcc_echo, 0);
}
}
if (ptr->notes && do_hook(CDCC_NOTE_LIST, "%s %s %s", type_msg, chan, ptr->notes))
{
malloc_sprintf(&string, "\t%s", ptr->notes);
if (get_int_var(QUEUE_SENDS_VAR))
queue_send_to_server(from_server, "%s %s :%s",
do_notice_list?"NOTICE":"PRIVMSG", chan, string);
else
send_text(chan, string, do_notice_list?"NOTICE":NULL, do_cdcc_echo, 0);
}
}
do_hook(CDCC_POSTPACK_LIST, "%s %s %s %d %d %d %d %d %s %s %s %s %lu %s",
type_msg, chan, get_server_nickname(from_server), cdcc_numpacks,
get_int_var(DCC_SEND_LIMIT_VAR)-get_active_count(),
get_int_var(DCC_SEND_LIMIT_VAR), numqueue,
get_int_var(DCC_QUEUE_LIMIT_VAR), mrate_out, bytes_out,
mrate_in, bytes_in, total_size_of_packs, speed_out);
reset_display_target();
return 0;
}
/* notify the current channel that packs are offered */
static int l_notice(char *args, char *rest)
{
char *string = NULL, *chan = NULL;
char mrate_out[30];
char mrate_in[30];
char bytes_out[30];
char bytes_in[30];
char speed_out[30];
if (!get_current_channel_by_refnum(0) || !cdcc_numpacks || (args && *args && !is_channel(args))) {
put_it("%s: you %s",cparse(get_string_var(CDCC_PROMPT_VAR)),
cdcc_numpacks ? "are not on a channel!" :
"have no packs offered!");
return 0;
}
if (args && *args)
malloc_strcpy(&chan, args);
else
malloc_strcpy(&chan, get_current_channel_by_refnum(0));
set_display_target(chan, LOG_CRAP);
sprintf(mrate_out, "%1.3g", dcc_max_rate_out);
sprintf(mrate_in, "%1.3g", dcc_max_rate_in);
sprintf(bytes_out, "%1.3g", dcc_bytes_out);
sprintf(bytes_in, "%1.3g", dcc_bytes_in);
sprintf(speed_out, "%1.3g", cdcc_minspeed);
if (do_hook(CDCC_PREPACK_LIST, "%s %s %s %d %d %d %d %d %s %s %s %s %lu %s", "NOTICE", chan, get_server_nickname(from_server), cdcc_numpacks, get_int_var(DCC_SEND_LIMIT_VAR)-get_active_count(), get_int_var(DCC_SEND_LIMIT_VAR), numqueue, get_int_var(DCC_QUEUE_LIMIT_VAR), mrate_out, bytes_out, mrate_in, bytes_in, total_size_of_packs, speed_out))
{
malloc_sprintf(&string, "\037[\037cdcc\037]\037 \002%d\002 file%s offered\037-\037 \037\"\037/ctcp \002%s\002 cdcc list\037\"\037 for pack list",
cdcc_numpacks, plural(cdcc_numpacks), get_server_nickname(from_server));
if (get_int_var(QUEUE_SENDS_VAR))
queue_send_to_server(from_server, "NOTICE %s :%s", chan, string);
else
send_text(chan, string, "NOTICE", do_cdcc_echo, 0);
}
do_hook(CDCC_POSTPACK_LIST, "%s %s %s %d %d %d %d %d %s %s %s %s %lu %s",
"NOTICE", chan, get_server_nickname(from_server), cdcc_numpacks,
get_int_var(DCC_SEND_LIMIT_VAR)-get_active_count(),
get_int_var(DCC_SEND_LIMIT_VAR), numqueue,
get_int_var(DCC_QUEUE_LIMIT_VAR), mrate_out, bytes_out, mrate_in,
bytes_in, total_size_of_packs, speed_out);
reset_display_target();
new_free(&chan);
new_free(&string);
return 0;
}
/* display entries in your send queue */
static int l_queue(char *args, char *rest)
{
queue *ptr, *del, *prev = NULL;
int num = 1;
char *command = NULL;
int count = 0;
if (!queuelist)
{
put_it("%s: there are no queue entries",cparse(get_string_var(CDCC_PROMPT_VAR)));
return 0;
}
if (args && *args)
command = next_arg(args, &args);
if ((command == NULL) || !my_stricmp(command, "LIST"))
{
for (ptr = queuelist; ptr; ptr = ptr->next, num++)
{
if (command && rest && *rest && !wild_match(rest, ptr->nick))
continue;
if (command)
{
if (do_hook(CDCC_QUEUE_LIST, "%s %s %d %d %s", ptr->nick, my_ctime(ptr->time), ptr->num, ptr->numfiles, ptr->desc))
put_it("#\002%2d\002 nick: \037%9s\037 (\002%d\002 file%s)",
num, ptr->nick, ptr->numfiles,
plural(ptr->numfiles));
} else
count++;
}
if (count && !command)
put_it("%s: %d entries in the queue", cparse(get_string_var(CDCC_PROMPT_VAR)), count);
return 0;
}
else if (!my_stricmp(command, "REMOVE"))
{
char *n;
int success = 0;
n = rest;
if (!n || !*n)
return 0;
for (ptr = queuelist; ptr;)
{
del = ptr;
ptr = ptr->next;
count++;
if (matchmcommand(n, count) || wild_match(n, del->nick))
{
if (prev)
prev->next=del->next;
else
queuelist=del->next;
new_free(&del->file);
new_free(&del->nick);
new_free(&del->desc);
new_free((char **)&del);
success++;
} else
prev = del;
}
put_it("%s: deleted %d of %d entries from the queue", cparse(get_string_var(CDCC_PROMPT_VAR)), success, count);
}
else
put_it("%s: /Cdcc queue remove #|nick /Cdcc queue list [nick]", cparse(get_string_var(CDCC_PROMPT_VAR)));
return 0;
}
/* save all of your offered packs */
static int l_save(char *args, char *rest)
{
#ifdef PUBLIC_ACCESS
bitchsay("This command has been disabled on a public access system");
return;
#else
FILE *file;
char *name = NULL, *expand = NULL;
pack *ptr;
int count = 0;
char *fn;
if (!offerlist)
{
put_it("%s: you have no packs offered", cparse(get_string_var(CDCC_PROMPT_VAR)));
return 0;
}
if (args)
fn = args;
else
#if defined(WINNT) || defined(__EMX__)
fn = "cdcc.save";
#else
fn = ".cdcc.save";
#endif
malloc_sprintf(&expand, "~/%s", fn);
name = expand_twiddle(expand);
new_free(&expand);
#if defined(WINNT) || defined(__EMX__)
if (!name || !(file = fopen(name, "wt")))
#else
if (!name || !(file = fopen(name, "w")))
#endif
{
put_it("%s: couldn't open \"%s\"", cparse(get_string_var(CDCC_PROMPT_VAR)),name?name:empty_string);
new_free(&name);
return 0;
}
fprintf(file, "#cdcc save file 1.0\n");
for (ptr = offerlist; ptr; ptr = ptr->next)
{
fprintf(file, "%s\n", ptr->file);
fprintf(file, "%s %d\n", ptr->desc, ptr->numfiles);
fprintf(file, "%s\n", ptr->notes?ptr->notes:empty_string);
fprintf(file, "%d %lu 0.00 %d %lu %s\n", ptr->gets, ptr->size, ptr->server, (unsigned long)ptr->timeadded, ptr->password?ptr->password:empty_string);
count++;
}
fclose(file);
put_it("%s: \002%d\002 pack%s saved to %s", cparse(get_string_var(CDCC_PROMPT_VAR)),
count, plural(count), name);
new_free(&name);
return 0;
#endif
}
/* load packs from cdcc.save */
static int l_load(char *args, char *rest)
{
FILE *file;
char *buffer = NULL, *expand = NULL, *temp;
pack *ptr, *last = NULL;
char *p, *q;
int count = 0;
int got_header = 0;
#if defined(WINNT) || defined(__EMX__)
malloc_sprintf(&expand, "~/%s", args ? args: "cdcc.save");
#else
malloc_sprintf(&expand, "~/%s", args ? args: ".cdcc.save");
#endif
buffer = expand_twiddle(expand);
new_free(&expand);
if (!buffer || !(file = fopen(buffer, "rt")))
{
put_it("%s: couldn't open \"%s\"", cparse(get_string_var(CDCC_PROMPT_VAR)), buffer ? buffer : expand);
new_free(&buffer);
return 0;
}
for (ptr = offerlist; ptr; ptr = ptr->next)
last = ptr;
new_free(&buffer);
buffer = new_malloc(BIG_BUFFER_SIZE+1);
while (fgets(buffer, BIG_BUFFER_SIZE, file)) {
p = buffer;
buffer[BIG_BUFFER_SIZE-1] = 0;
chop(buffer, 1);
if (!got_header)
{
if (my_strnicmp(p, "#cdcc save file 1.0", 16))
{
put_it("File is not a cdcc save file.");
break;
}
got_header++;
continue;
}
ptr = (pack *) new_malloc(sizeof(pack));
ptr->num = ++cdcc_numpacks;
malloc_strcpy(&ptr->file, buffer);
fgets(buffer, BIG_BUFFER_SIZE, file);
chop(buffer, 1);
temp = strrchr(buffer, ' ');
*temp = '\0';
temp++;
malloc_strcpy(&ptr->desc, buffer);
if (*temp && !isdigit((unsigned char)*temp))
{
put_it("%s: not a cdcc pack aborting", cparse(get_string_var(CDCC_PROMPT_VAR)));
new_free(&ptr->file);
new_free((char **)&ptr);
fclose(file);
return 0;
}
ptr->numfiles = atoi(temp);
fgets(buffer, BIG_BUFFER_SIZE, file);
chop(buffer, 1);
if (*buffer)
malloc_strcpy(&ptr->notes, buffer);
fgets(buffer, BIG_BUFFER_SIZE, file);
chop(buffer, 1);
if ((q = next_arg(p, &p)))
ptr->gets = my_atol(q);
if ((q = next_arg(p, &p)))
ptr->size = my_atol(q);
next_arg(p, &p); /* skip over min speed for now */
if ((q = next_arg(p, &p)))
ptr->server = my_atol(q);
if ((q = next_arg(p, &p)))
ptr->timeadded = my_atol(q);
if (p && *p)
ptr->password = m_strdup(q);
/* ptr->gets = atoi(strtok(buffer, space));*/
/* ptr->size = atol(strtok(NULL, space));*/
/* ptr->minspeed = atof(strtok(NULL,"\r")); */
total_size_of_packs += ptr->size;
ptr->next = NULL;
if (last) {
last->next = ptr;
last = ptr;
} else {
offerlist = ptr;
last = offerlist;
}
count++;
}
fclose(file);
put_it("%s: \002%d\002 pack%s loaded", cparse(get_string_var(CDCC_PROMPT_VAR)), count, plural(count));
set_int_var(_CDCC_PACKS_OFFERED_VAR, cdcc_numpacks);
new_free(&buffer);
return 0;
}
/* --- Misc functions --- */
/* add file/files to a pack */
static void add_files(char *args, char *rest)
{
char *thefile = NULL, *expand = NULL, *path = NULL;
char *temp = NULL, *filebuf = NULL;
char *fptr = NULL, *f_path = NULL;
DIR *dptr = NULL;
struct dirent *dir;
struct stat statbuf;
path = alloca(strlen(rest)+1);
strcpy(path, rest);
temp = alloca(BIG_BUFFER_SIZE + 1);
*temp = 0;
f_path = alloca(BIG_BUFFER_SIZE + 1);
*f_path = 0;
newpack = (pack *) new_malloc(sizeof(pack));
while((thefile = new_next_arg(path, &path)))
{
if (!thefile || !*thefile)
break;
if ((fptr = strrchr(thefile, '/')))
{
*fptr++ = 0;
strcpy(f_path, thefile);
}
else
{
fptr = thefile;
strcpy(f_path, "~");
}
if ((expand = expand_twiddle(f_path)))
dptr = opendir(expand);
if (!dptr)
{
put_it("%s: you cannot access dir %s. Attempting to continue", cparse(get_string_var(CDCC_PROMPT_VAR)),expand ? expand : thefile);
new_free(&expand);
new_free(&filebuf);
continue;
}
while ((dir = readdir(dptr)))
{
if (!dir->d_ino || !wild_match(fptr, dir->d_name))
continue;
sprintf(temp, "%s/%s", expand, dir->d_name);
stat(temp, &statbuf);
sprintf(temp, "\"%s/%s\"", expand, dir->d_name);
if (filebuf)
malloc_strcat(&filebuf, space);
malloc_strcat(&filebuf, temp);
if (S_ISDIR(statbuf.st_mode))
continue;
newpack->size += statbuf.st_size;
newpack->numfiles++;
total_size_of_packs += statbuf.st_size;
}
closedir(dptr);
}
if (!newpack->numfiles)
{
put_it("%s: no files found, aborting...", cparse(get_string_var(CDCC_PROMPT_VAR)));
new_free(&expand);
new_free(&filebuf);
new_free((char **) &newpack);
return;
}
newpack->timeadded = now;
newpack->num = ++cdcc_numpacks;
newpack->server = from_server;
set_int_var(_CDCC_PACKS_OFFERED_VAR, cdcc_numpacks);
malloc_strcpy(&newpack->file, filebuf);
sprintf(temp, "Description of pack #%d : ", cdcc_numpacks);
add_wait_prompt(temp, add_desc, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&expand);
new_free(&filebuf);
return;
}
/* add a notes type description to the pack */
static void add_note(char *args, char *rest)
{
if (rest && *rest)
{
malloc_strcpy(&newpack->notes, rest);
put_it("%s: added note to pack #\002%d\002 %s", cparse(get_string_var(CDCC_PROMPT_VAR)), newpack->num, newpack->notes);
}
}
/* add a description to the new pack, and add to list */
static void add_desc(char *args, char *rest)
{
pack *ptr, *last = NULL;
char size[20];
char *temp = NULL;
malloc_strcpy(&newpack->desc, rest);
for (ptr = offerlist; ptr; ptr = ptr->next)
last = ptr;
if (last)
last->next = newpack;
else
offerlist = newpack;
newpack->next = NULL;
if (newpack->size / 1024 > 999)
sprintf(size, "\002%3.2f\002mb", (double) (newpack->size / 1024) / 1024);
else
sprintf(size, "\002%3.2f\002kb", (double) newpack->size / 1024);
put_it("%s: added pack #\002%d\002, \002%d\002 file%s (%s)", cparse(get_string_var(CDCC_PROMPT_VAR)),
newpack->num, newpack->numfiles,
plural(newpack->numfiles == 1), size);
malloc_sprintf(&temp, "Notes for pack #%d : ", cdcc_numpacks);
add_wait_prompt(temp, add_note, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&temp);
return;
}
/* handle the actual removing of packs / all packs */
static void del_pack(char *args, char *rest)
{
pack *ptr, *last = offerlist;
int packnum;
int num = 0;
if (!rest || !*rest)
{
put_it("%s: No pack specified for removal", cparse(get_string_var(CDCC_PROMPT_VAR)));
return;
}
if (*rest == '*') {
cdcc_numpacks = 0;
for (ptr = last = offerlist; last;)
{
ptr = last->next;
new_free(&last->desc);
new_free(&last->notes);
new_free(&last->file);
new_free(&last->password);
new_free((char **) &last);
last = ptr;
}
offerlist = NULL;
total_size_of_packs = 0;
set_int_var(_CDCC_PACKS_OFFERED_VAR, 0);
put_it("%s: removed all packs from offer list", cparse(get_string_var(CDCC_PROMPT_VAR)));
return;
}
while (rest && *rest)
{
packnum = atoi(next_arg(rest, &rest));
if (packnum <= 0)
{
put_it("%s: invalid pack specification", cparse(get_string_var(CDCC_PROMPT_VAR)));
continue;
}
for (ptr = offerlist; ptr; ptr = ptr->next)
{
if (ptr->num == packnum)
{
if (ptr != offerlist)
last->next = ptr->next;
else
offerlist = ptr->next;
new_free(&ptr->desc);
new_free(&ptr->file);
new_free(&ptr->notes);
new_free(&ptr->password);
total_size_of_packs -= ptr->size;
new_free((char **) &ptr);
cdcc_numpacks--;
set_int_var(_CDCC_PACKS_OFFERED_VAR, cdcc_numpacks);
put_it("%s: removed pack \002%d\002 from offer list",cparse(get_string_var(CDCC_PROMPT_VAR)), packnum);
num++;
break;
}
last = ptr;
}
}
if (num)
{
for (ptr = offerlist,num = 1; ptr; ptr = ptr->next)
ptr->num = num++;
}
else
put_it("%s: pack \002%s\002 does not exist", cparse(get_string_var(CDCC_PROMPT_VAR)),rest);
return;
}
/* add a person to the dcc send queue */
int BX_add_to_queue(char *nick, char *command, pack *sendpack)
{
queue *ptr = NULL, *last = NULL, *new = NULL;
static char *lastnick = NULL;
int count;
if (!sendpack || !sendpack->file)
{
put_it("%s: ERROR occured in cdcc add to queue", cparse(get_string_var(CDCC_PROMPT_VAR)));
return 0;
}
if (queuelist)
{
for (new = queuelist, count = 1; new; new = new->next)
{
if (!my_stricmp(nick, new->nick) && !my_stricmp(sendpack->file, new->file))
{
if (!lastnick || my_stricmp(lastnick, nick))
queue_send_to_server(from_server, "NOTICE %s :\002CDCC\002: You're already Queued for %s at position %d", nick, new->desc, count);
put_it("%s: Already queued %d files for %s at %d", cparse(get_string_var(CDCC_PROMPT_VAR)), sendpack->numfiles, nick, count);
return 0;
}
}
}
new = (queue *) new_malloc(sizeof(queue));
malloc_strcpy(&new->nick, nick);
malloc_strcpy(&new->file, sendpack->file);
malloc_strcpy(&new->desc, sendpack->desc);
new->time = now;
new->numfiles = sendpack->numfiles;
new->server = from_server;
new->command = m_strdup(command);
new->next = NULL;
sendpack->gets++;
for (ptr = queuelist, count = 1; ptr; ptr = ptr->next, count++)
last = ptr;
if (last)
last->next = new;
else
queuelist = new;
numqueue++;
put_it("%s: Queue position %d queuing %d files for %s", cparse(get_string_var(CDCC_PROMPT_VAR)), numqueue, sendpack->numfiles, nick);
if (!lastnick || (lastnick && my_stricmp(lastnick, nick)))
malloc_strcpy(&lastnick, nick);
return 1;
}
/* check queue & send files... called by irc.c io() */
void dcc_sendfrom_queue(void)
{
queue *ptr = queuelist;
char *dccinfo = NULL, *file = NULL, *temp = NULL;
int old_server = from_server;
int active = 0;
if (!ptr)
return;
active = get_active_count();
if (active && active >= get_int_var(DCC_SEND_LIMIT_VAR))
return;
put_it("%s: sending \037%s\037 \002%d\002 file%s from queue", cparse(get_string_var(CDCC_PROMPT_VAR)),
ptr->nick, ptr->numfiles,
plural(ptr->numfiles));
file = LOCAL_COPY(ptr->file);
if (ptr->server < server_list_size() && is_server_connected(ptr->server))
from_server = ptr->server;
while ((temp = new_next_arg(file, &file)))
{
if (!temp || !*temp)
break;
malloc_sprintf(&dccinfo, "%s %s", ptr->nick, temp);
if (ptr->command)
{
if (!my_stricmp(ptr->command, "RESEND") || !my_stricmp(ptr->command, "TRESEND"))
dcc_resend(ptr->command, dccinfo);
#ifdef MIRC_BROKEN_DCC_RESUME
else if (!my_stricmp(ptr->command, "RESUME"))
dcc_resume(ptr->command, dccinfo);
#endif
else
dcc_filesend(NULL, dccinfo);
}
else
dcc_filesend(ptr->command, dccinfo);
}
new_free(&dccinfo);
queuelist = ptr->next;
new_free(&ptr->nick);
new_free(&ptr->file);
new_free(&ptr->command);
new_free((char **) &ptr);
numqueue--;
from_server = old_server;
return;
}
static time_t plist_last_time = 0;
static void get_minspeed(char *args, char *rest)
{
char *last = NULL;
unsigned long cdcc_mintime = 0;
if (rest && *rest)
cdcc_minspeed = strtod(rest, &last);
if (cdcc_minspeed)
{
put_it("%s: Minspeed value to %1.4g KB/s", cparse(get_string_var(CDCC_PROMPT_VAR)),cdcc_minspeed);
if (last && *last && isdigit((unsigned char)*last))
{
cdcc_mintime = strtod(last, NULL);
set_int_var(_CDCC_MINSPEED_TIME_VAR, cdcc_mintime);
put_it("%s: Minspeed time to %5d seconds", cparse(get_string_var(CDCC_PROMPT_VAR)), cdcc_mintime);
}
else if (!get_int_var(_CDCC_MINSPEED_TIME_VAR))
put_it("%s: Make sure and /set _CDCC_MINSPEED_TIME as well", cparse(get_string_var(CDCC_PROMPT_VAR)));
}
else
cdcc_minspeed = 0.0;
}
static int l_minspeed(char *args, char *rest)
{
char *temp = NULL;
malloc_sprintf(&temp, "%s min-speed (0 to disable): ", cparse(get_string_var(CDCC_PROMPT_VAR)));
if (args && *args)
get_minspeed(NULL, args);
else
add_wait_prompt(temp, get_minspeed, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&temp);
return 0;
}
static void get_ptimer(char *args, char *rest)
{
if (rest && *rest)
ptimer = strtoul(rest, NULL, 10);
ptimer *= 60;
if (ptimer)
put_it("%s: Ptimer interval %d minutes", cparse(get_string_var(CDCC_PROMPT_VAR)),ptimer/60);
else
plist_last_time = 0;
}
static int l_timer(char *args, char *rest)
{
char *temp = NULL;
malloc_sprintf(&temp, "%s p-timer interval(s) (0 to disable): ", cparse(get_string_var(CDCC_PROMPT_VAR)));
if (args && *args)
get_ptimer(NULL, args);
else
add_wait_prompt(temp, get_ptimer, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&temp);
return 0;
}
static void get_pchannel(char *args, char *rest)
{
if (rest && *rest && is_channel(rest))
malloc_strcpy(&public_channel, rest);
else if (rest && *rest && *rest == '*')
{
int i = get_window_server(0);
ChannelList *chan;
if (i != -1)
{
new_free(&public_channel);
for (chan = get_server_channels(i); chan; chan = chan->next)
m_s3cat(&public_channel, ",", chan->channel);
} else
new_free(&public_channel);
}
else
new_free(&public_channel);
if (public_channel)
put_it("%s: Public timer channel(s) are [%s]", cparse(get_string_var(CDCC_PROMPT_VAR)),public_channel);
else
put_it("%s: Disabled %s public timer channel(s)", cparse(get_string_var(CDCC_PROMPT_VAR)), cparse(get_string_var(CDCC_PROMPT_VAR)));
}
static int l_channel(char *args, char *rest)
{
if (args && *args)
get_pchannel(NULL, args);
else
if (public_channel)
put_it("%s: Public timer channel is [%s]", cparse(get_string_var(CDCC_PROMPT_VAR)),public_channel);
else
put_it("%s: Disabled %s public timer channel", cparse(get_string_var(CDCC_PROMPT_VAR)), cparse(get_string_var(CDCC_PROMPT_VAR)));
return 0;
}
void cdcc_timer_offer(void)
{
if (!offerlist || !ptimer)
return;
if (now - plist_last_time > ptimer)
{
plist_last_time = now;
if (do_notice_list)
l_notice(public_channel, NULL);
else
l_plist(public_channel, NULL);
}
}
static void add_note1(unsigned long pnum, char *note)
{
pack *this_pack = NULL;
int i;
if (pnum && note)
{
for (i = 1, this_pack = offerlist; this_pack; this_pack = this_pack->next, i++)
if (i == pnum)
break;
if (this_pack)
{
if (note && *note)
malloc_strcpy(&this_pack->notes, note);
else
new_free(&this_pack->notes);
}
else
put_it("%s: Invalid pack number %ld", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
}
else
put_it("%s: Invalid pack number %ld", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
}
static void add_describe(unsigned long pnum, char *describe)
{
pack *this_pack = NULL;
int i;
if (pnum && describe)
{
for (i = 1, this_pack = offerlist; this_pack; this_pack = this_pack->next, i++)
if (i == pnum)
break;
if (this_pack)
malloc_strcpy(&this_pack->desc, describe);
else
put_it("%s: Invalid pack number %ld", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
}
else
put_it("%s: Invalid pack number %ld", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
}
static unsigned long got_pnum = 0;
static unsigned long got_dnum = 0;
static void get_pnote1(char *args, char *rest)
{
if (got_pnum && rest)
add_note1(got_pnum, rest);
got_pnum = 0;
}
static void get_desc(char *args, char *rest)
{
if (got_dnum && rest)
add_describe(got_dnum, rest);
got_dnum = 0;
}
static void get_pnote(char *args, char *rest)
{
unsigned long pnum = 0;
char *temp = NULL;
char *p;
if ((p = next_arg(rest, &rest)))
pnum = strtoul(p, NULL, 10);
if (rest && *rest)
add_note1(pnum, rest);
else
{
got_pnum = pnum;
malloc_sprintf(&temp, "%s note to add to pack %ld ", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
add_wait_prompt(temp, get_pnote1, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&temp);
}
}
static void get_describe(char *args, char *rest)
{
unsigned long pnum = 0;
char *temp = NULL;
char *p;
if ((p = next_arg(rest, &rest)))
pnum = strtoul(p, NULL, 10);
if (rest && *rest)
add_describe(pnum, rest);
else
{
got_dnum = pnum;
malloc_sprintf(&temp, "%s description to add to pack %ld ", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
add_wait_prompt(temp, get_desc, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&temp);
}
}
static int l_note(char *args, char *rest)
{
char *temp = NULL;
if (!offerlist)
return 0;
malloc_sprintf(&temp, "%s add note to pack #: ", cparse(get_string_var(CDCC_PROMPT_VAR)));
if (args && *args)
get_pnote(NULL, args);
else
add_wait_prompt(temp, get_pnote, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&temp);
return 1;
}
static int l_describe(char *args, char *rest)
{
char *temp = NULL;
if (!offerlist)
return 0;
malloc_sprintf(&temp, "%s change description of pack #: ", cparse(get_string_var(CDCC_PROMPT_VAR)));
if (args && *args)
get_describe(NULL, args);
else
add_wait_prompt(temp, get_describe, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&temp);
return 1;
}
static int l_type(char *args, char *rest)
{
if (args && *args)
do_notice_list = do_notice_list ? 0 : 1;
put_it("%s: type of output for offer set to [%s]", cparse(get_string_var(CDCC_PROMPT_VAR)), do_notice_list? "Notice":"privmsg");
return 0;
}
static int l_echo(char *args, char *rest)
{
if (args && *args)
do_cdcc_echo = do_cdcc_echo ? 0 : 1;
put_it("%s: local echo set to [%s]", cparse(get_string_var(CDCC_PROMPT_VAR)), on_off(do_cdcc_echo));
return 0;
}
static int l_stats(char *args, char *rest)
{
char cdcc_minspeed_s[80];
sprintf(cdcc_minspeed_s, "%1.3f", cdcc_minspeed);
put_it("%s",convert_output_format(" %GÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ%K[%C cdcc stat %K]%GÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸", NULL));
put_it("%s",convert_output_format(" %G³ ³", NULL));
put_it("%s",convert_output_format(" %G³%gÖÄ%K[%Cp%ctimer %K]%gÄÖ-%K[%Ct%cype %K]%gÄ·Ä%K[%Ct%cotal %Cp%cacks%K]%gÄÖÄ%K[%Cs%cent %K]%gÄ·Ä[%Cq%cueue%K]%gÄ·%G³", NULL));
put_it("%s",convert_output_format(" %G³%gº %W$[-10]0 %gº %W$[-10]1 %gº %W$[-10]2 %gº %W$[-8]3 %gº %W$[-7]4 %gº%G³", "%d %s %d %d %d", ptimer, do_notice_list ?"notice":"privmsg", cdcc_numpacks, send_numpacks, numqueue));
put_it("%s",convert_output_format(" %G³%gÓÄÄÄÄÄÄÄÄÄÄÄĽÄÄÄÄÄÄÄÄÄÄÄÄÄÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽÄÄÄÄÄÄÄÄÄÄÓÄÄÄÄÄÄÄÄĽ%G³", NULL));
put_it("%s",convert_output_format(" %G³ CDCC channel ³", NULL));
put_it("%s",convert_output_format(" %G³ %W$[63]0-%G ³", "%s", !public_channel ? "current channel": public_channel));
put_it("%s",convert_output_format(" %gÖÄÄÄÄ%K[%C %c %C %c %K]%gÄÄÄÖÄÄÄ%K[%C %c %C %c %K]%gÄÄÄ·ÄÄÄÄÄÄÄÄÄÄ%K[%Ct%coggles%K]%gÄÄÄÄÄÄÄÄÄÄ·", NULL));
put_it("%s",convert_output_format(" %gº %C %n %W$[-6]0%n%R %gº %C %n %W$[-6]1%n%R %gº %Ct%nimer: %W$[-3]2%n %Ce%ncho: %W$[-3]3 %gº", "1 1 %s %s", on_off(ptimer), on_off(do_cdcc_echo)));
put_it("%s",convert_output_format(" %gº %C %n %W$[-6]0%n%R %gº %C %n %W$[-6]1%n%R %gº %Cm%ninspeed: %W$[-3]2%n %Cs%necure:%W$[-3]3 %gº", "1 1 %s %s", cdcc_minspeed == 0.0 ? "off":cdcc_minspeed_s, on_off(get_string_var(CDCC_SECURITY_VAR) ? 1 : 0)));
put_it("%s",convert_output_format(" %gÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ", NULL));
return 0;
}
/*
* TimeCawp needed this particular function so I coded it for him.
* personally I don't think it's needed, but then who am I to say.
*/
BUILT_IN_FUNCTION(function_cdcc)
{
pack *ptr;
char *p;
int it = 0;
if (!cdcc_numpacks)
return m_strdup(empty_string);
if (!(p = next_arg(input, &input)))
return m_strdup(empty_string);
if (!(it = my_atol(p)))
return m_sprintf("%d", cdcc_numpacks);
for (ptr = offerlist; ptr; ptr= ptr->next)
{
if (it == ptr->num)
return m_sprintf("%d %d %lu %d %s", ptr->num, ptr->numfiles, ptr->size, ptr->gets, ptr->desc);
}
return m_strdup(empty_string);
}
BUILT_IN_FUNCTION(function_sendcdcc)
{
char *nick = NULL;
int count = 0;
int old_window_display = window_display;
window_display = 0;
if ((nick = next_arg(input, &input)))
count = do_local_send("SEND", nick, input);
window_display = old_window_display;
return m_sprintf("%d", count);
}
static void add_password(unsigned long pnum, char *password)
{
pack *this_pack = NULL;
int i;
if (pnum && password)
{
for (i = 1, this_pack = offerlist; this_pack; this_pack = this_pack->next, i++)
if (i == pnum)
break;
if (this_pack)
{
if (password && *password)
malloc_strcpy(&this_pack->password, password);
else
{
new_free(&this_pack->password);
put_it("%s: Removed passwd from %ld", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
}
}
else
put_it("%s: Invalid pack number %ld", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
}
else
put_it("%s: Invalid pack number %ld", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
}
static void get_passwd(char *args, char *rest)
{
if (got_dnum && rest)
add_password(got_dnum, rest);
got_dnum = 0;
}
static void get_password(char *args, char *rest)
{
unsigned long pnum = 0;
char *temp = NULL;
char *p;
if ((p = next_arg(rest, &rest)))
pnum = strtoul(p, NULL, 10);
if (rest && *rest)
add_password(pnum, rest);
else
{
got_dnum = pnum;
malloc_sprintf(&temp, "%s password to add to pack %ld: ", cparse(get_string_var(CDCC_PROMPT_VAR)), pnum);
add_wait_prompt(temp, get_passwd, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&temp);
}
}
static int l_secure(char *args, char *rest)
{
char *temp = NULL;
if (!offerlist)
return 0;
malloc_sprintf(&temp, "%s change password of pack #: ", cparse(get_string_var(CDCC_PROMPT_VAR)));
if (args && *args)
get_password(NULL, args);
else
add_wait_prompt(temp, get_password, empty_string, WAIT_PROMPT_LINE, 1);
new_free(&temp);
return 0;
}
int BX_get_num_queue(void)
{
return numqueue;
}
#else /* WANT_CDCC */
/* this is required for functions.c to compile properly */
BUILD_IN_FUNCTION(function_cdcc)
{
return m_strdup(empty_string);
}
BUILT_IN_FUNCTION(function_sendcdcc)
{
return m_strdup(empty_string);
}
int get_num_queue(void)
{
return 0;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1