/*
* cdcc.c xdcc in C. This file tries to recreate the script xdcc in C,
* this file contains all the functions needed to implement this.
*
* Written by Scott H Kilau
*
* Heavily modified by Flier
*
* Copyright(c) 1995
*
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
*
* $Id: cdcc.c,v 1.55 2006/04/30 14:15:43 f Exp $
*/
#include "irc.h"
#include "list.h"
#include "server.h"
#include "vars.h"
#include "ircaux.h"
#include "input.h"
#include "window.h"
#include "screen.h"
#include "output.h"
#include "edit.h"
#include "scandir.h"
#include "dcc.h"
#include "parse.h"
#if !defined(CELEHOOK) && !defined(LITE)
#include "hook.h"
#endif
#include "cdcc.h"
#include "myvars.h"
#define LIST_DELAY 4
void Cdcc _((char *, char *, char *));
void CheckAutoGet _((char *, char *, char *, char *));
void CheckCdccTimers _((void));
void RemoveFromQueue _((int));
int TotalSendDcc _((void));
int TotalQueue _((void));
void helpmcommand _((char *));
int matchmcommand _((char *, int));
static void formatstats _((char *, int));
static void sendmcommand _((char *));
static void send2mcommand _((char *, char *));
static void send3mcommand _((char *, char *));
#ifdef EXTRAS
static void fsendmcommand _((char *));
static void fsend2mcommand _((char *, char *));
static void fsend3mcommand _((char *, char *));
#endif
static void resendmcommand _((char *));
static void resend2mcommand _((char *, char *));
static void resend3mcommand _((char *, char *));
static void getmcommand _((char *));
static void get2mcommand _((char *, char *));
static void doffermcommand _((char *));
static void doffer2mcommand _((char *, char *));
static void offermcommand _((char *));
static void offer2mcommand _((char *, char *));
static void offer3mcommand _((char *, char *));
static void offer4mcommand _((char *, char *));
#ifdef EXTRAS
static void renamepackmcommand _((char *));
#endif
static void listmcommand _((char *));
static void plistmcommand _((char *));
static void noticemcommand _((char *));
static void listcommand _((char *, char *));
static void helpcommand _((char *, char *));
static void sendcommand _((char *, char *, int, int));
static void versioncommand _((char *, char *));
static void queuecommand _((char *, char *));
#ifndef LITE
static void psendmcommand _((char *));
static void psend2mcommand _((char *, char *));
static void psend3mcommand _((char *, char *));
#endif
static void autogetmcommand _((char *));
static void securemcommand _((char *));
static void closemcommand _((char *));
static void close2mcommand _((char *, char *));
#ifdef EXTRA_STUFF
static void emcommand _((char *));
static void mmcommand _((char *));
#endif
/****** Coded by Zakath ******/
#ifndef LITE
static void requestmcommand _((char *));
#endif
/*****************************/
static void idlemcommand _((char *));
static void limitmcommand _((char *));
static void channelsmcommand _((char *));
static void ptimemcommand _((char *));
static void ntimemcommand _((char *));
static void longstatusmcommand _((char *));
static void overwritemcommand _((char *));
static void uldirmcommand _((char *));
static void dldirmcommand _((char *));
static void showdccsmcommand _((int));
#ifndef LITE
static void loadmcommand _((char *));
static void savemcommand _((char *));
#endif
static void statusmcommand _((char *));
static void statsmcommand _((char *));
static void warningmcommand _((char *));
static void verbosemcommand _((char *));
void queuemcommand _((char *));
static void GetDir _((char *));
static void CleanList _((void));
static void AddFileToList _((char *, char *, int));
static int AddFiles2List _((char *));
static void AddToOfferList _((char *, char *));
static void ShowPacks _((char *));
static void DeleteSend _((void));
static int AddToQueue _((Files *, char *, int));
static int SeedFiles _((char *, int));
static int GetSize _((char *, char *));
static int compar _((struct dirent **, struct dirent **));
static int selectent _((struct dirent *));
extern void AwaySave _((char *, int));
extern void PrintSetting _((char *, char *, char *, char *));
extern void NoWindowChannel _((void));
extern void PrintUsage _((char *));
extern void NumberCommand _((char *, char *, char *));
extern void OnOffCommand _((char *, char *, char *));
extern int CheckChannel _((char *, char *));
extern char *OpenCreateFile _((char *, int));
extern struct friends *CheckUsers _((char *, char *));
extern void ColorUserHost _((char *, char *, char *, int));
extern int CheckServer _((int));
extern void dcc_close _((char *));
extern void dcc_getfile _((char *));
#ifdef BROKEN_MIRC_RESUME
extern void dcc_getfile_resume _((char *));
#endif /* BROKEN_MIRC_RESUME */
extern void dcc_regetfile _((char *));
extern void dcc_filesend _((char *));
extern void dcc_resend _((char *));
extern void timercmd _((char *, char *, char *));
static Packs *packs=(Packs *) 0;
static Files *files=(Files *) 0;
static FileQueue *queuelist=(FileQueue *) 0;
static struct dirent **CdccFileNames=NULL;
static struct stat CdccStatBuf;
static int CdccEntries;
static char *CdccString="[S+Z]";
static time_t LastIdleCheck=0;
static time_t LastList=0;
/****** Coded by Zakath ******/
#ifndef LITE
static int CdccReqTog=0;
static char *CdccRequest=(char *) 0;
#endif
/*****************************/
static CdccCom CdccCommands[]={
{ "HELP", helpmcommand },
{ "GET", getmcommand },
{ "SEND", sendmcommand },
#ifdef EXTRAS
{ "FSEND", fsendmcommand },
#endif
{ "CLOSE", closemcommand },
{ "RESEND", resendmcommand },
{ "OFFER", offermcommand },
{ "DOFFER", doffermcommand },
{ "PLIST", plistmcommand },
{ "LIST", listmcommand },
{ "NOTICE", noticemcommand },
#ifdef EXTRAS
{ "RENPACK", renamepackmcommand },
#endif
/****** Coded by Zakath ******/
#ifndef LITE
{ "REQUEST", requestmcommand },
#endif
/*****************************/
{ "QUEUE", queuemcommand },
#ifndef LITE
{ "LOAD", loadmcommand },
{ "SAVE", savemcommand },
#endif
{ "LIMIT", limitmcommand },
{ "CHANNELS", channelsmcommand },
{ "PTIME", ptimemcommand },
{ "NTIME", ntimemcommand },
{ "LONGSTATUS", longstatusmcommand },
{ "OVERWRITE", overwritemcommand },
#ifndef LITE
{ "PSEND", psendmcommand },
#endif
{ "IDLE", idlemcommand },
{ "AUTOGET", autogetmcommand },
{ "SECURE", securemcommand },
{ "STATUS", statusmcommand },
{ "STATS", statsmcommand },
{ "VERBOSE", verbosemcommand },
{ "WARNING", warningmcommand },
{ "ULDIR", uldirmcommand },
{ "DLDIR", dldirmcommand },
#ifdef EXTRA_STUFF
{ "E", emcommand },
{ "M", mmcommand },
#endif
{ NULL, NULL }
};
extern char *dcc_types[];
/************************************************************************
* Cdcc: parse cdcc command line, and send off to correct function *
************************************************************************/
void Cdcc(command, args, subargs)
char *command;
char *args;
char *subargs;
{
char *word=(char *) 0;
char *tmpstr;
int len=0;
int found=0;
int i;
int com=0;
if (!(word=new_next_arg(args,&args))) {
showdccsmcommand(15);
return;
}
len=strlen(word);
for (i=0;CdccCommands[i].command && CdccCommands[i].function;i++)
if (!my_strnicmp(CdccCommands[i].command,word,len)) {
found++;
if (found>1) break;
if (!com) com=i;
}
if (found>1) {
for (tmpstr=word;*tmpstr;tmpstr++)
if (*tmpstr>='a' && *tmpstr<='z') *tmpstr-=' ';
say("CDCC %s is ambiguous",word);
return;
}
if (found) CdccCommands[com].function(args);
else say("Try /CDCC HELP");
}
/*********************************************************************
* Gives user help *
*********************************************************************/
void helpmcommand(line)
char *line;
{
PrintUsage("CDCC command where command is one of :");
say("AUTOGET CHAN CLOSE DLDIR DOFFER FSEND GET IDLE LIMIT");
say("LIST LOAD LONGST OVERWR NOTICE OFFER PLIST PTIME NTIME");
say("PSEND QUEUE RENPACK RESEND REQUEST SAVE SECURE SEND STATUS");
say("ULDIR VERBOSE WARNING");
say("For more help on command do /HELP CDCC command");
}
/***********************************************************************
* listmcommand: List packs *
***********************************************************************/
static void listmcommand(line)
char *line;
{
ShowPacks(line);
}
/***********************************************************************
* Sets CDCC limit *
***********************************************************************/
static void limitmcommand(line)
char *line;
{
int number;
int isnumber=1;
char *word;
char *tmpstr;
char tmpbuf1[mybufsize/16];
char tmpbuf2[mybufsize/16];
if ((word=new_next_arg(line,&line))) {
for (tmpstr=word;*tmpstr;tmpstr++) isnumber&=isdigit(*tmpstr)?1:0;
number=atoi(word);
if (isnumber && number>-1) CdccLimit=number;
else {
PrintUsage("CDCC LIMIT limit [queue limit]");
return;
}
if ((word=new_next_arg(line,&line))) {
for (tmpstr=word;*tmpstr;tmpstr++) isnumber&=isdigit(*tmpstr)?1:0;
number=atoi(word);
if (isnumber && number>-1) CdccQueueLimit=number;
else {
PrintUsage("CDCC LIMIT limit [queue limit]");
return;
}
}
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%d",CdccLimit);
if (CdccQueueLimit) snprintf(tmpbuf2,sizeof(tmpbuf2),"%d",CdccQueueLimit);
else strcpy(tmpbuf2,"unlimited");
PrintSetting("Cdcc limit",tmpbuf1,", queue limit is",tmpbuf2);
RemoveFromQueue(0);
}
/***********************************************************************
* Sets idle seconds before auto-close *
***********************************************************************/
static void idlemcommand(line)
char *line;
{
NumberCommand("IDLE",line,NULL);
}
/***********************************************************************
* Sets CDCC autoget on or off *
***********************************************************************/
static void autogetmcommand(line)
char *line;
{
OnOffCommand("AUTOGET",line,NULL);
update_all_status();
}
/***********************************************************************
* Sets CDCC security on or off *
***********************************************************************/
static void securemcommand(line)
char *line;
{
OnOffCommand("SECURE",line,NULL);
update_all_status();
}
#ifdef EXTRA_STUFF
/**********************************************************************
* Sets CDCC encode string *
***********************************************************************/
static void emcommand(line)
char *line;
{
if (*line) malloc_strcpy(&EString,line);
PrintSetting("Cdcc E",EString,empty_string,empty_string);
}
/**********************************************************************
* Sets CDCC renaming on or off *
***********************************************************************/
static void mmcommand(line)
char *line;
{
OnOffCommand("M",line,NULL);
}
#endif
/**********************************************************************
* Sets CDCC channels for PLIST *
***********************************************************************/
static void channelsmcommand(line)
char *line;
{
char *channels;
if ((channels=new_next_arg(line,&line))) malloc_strcpy(&CdccChannels,channels);
if (CdccChannels) {
if (!my_stricmp(CdccChannels,"current"))
PrintSetting("Cdcc channels","current channel",empty_string,empty_string);
else PrintSetting("Cdcc channels",CdccChannels,empty_string,empty_string);
}
else PrintSetting("Cdcc channels","none",empty_string,empty_string);
}
/***********************************************************************
* Sets seconds to pass before repeating PLIST *
***********************************************************************/
static void ptimemcommand(line)
char *line;
{
NumberCommand("PTIME",line,NULL);
}
/***********************************************************************
* Sets seconds to pass before repeating NOTICE *
***********************************************************************/
static void ntimemcommand(line)
char *line;
{
NumberCommand("NTIME",line,NULL);
}
/***********************************************************************
* Sets CDCC long status bar on or off *
***********************************************************************/
static void longstatusmcommand(line)
char *line;
{
OnOffCommand("LONGSTATUS",line,NULL);
}
/***********************************************************************
* Sets CDCC overwrite on or off *
***********************************************************************/
static void overwritemcommand(line)
char *line;
{
OnOffCommand("OVERWRITE",line,NULL);
}
/***********************************************************************
* Sets showing DCC status on status bar on or off *
***********************************************************************/
static void statusmcommand(line)
char *line;
{
OnOffCommand("STATUS",line,NULL);
DCCDone=0;
new_free(&CurrentDCC);
update_all_status();
}
/***********************************************************************
* Sets showing received/sent kB in PLIST on or off *
***********************************************************************/
static void statsmcommand(line)
char *line;
{
OnOffCommand("STATS",line,NULL);
}
/***********************************************************************
* Sets check on incoming DCCs on or off *
***********************************************************************/
static void warningmcommand(line)
char *line;
{
OnOffCommand("WARNING",line,NULL);
}
/***********************************************************************
* Sets verbose mode on or off *
***********************************************************************/
static void verbosemcommand(line)
char *line;
{
OnOffCommand("VERBOSE",line,NULL);
}
/***********************************************************************
* Sets CDCC upload dir *
***********************************************************************/
static void uldirmcommand(line)
char *line;
{
char *newdir;
char *fullname=(char *) 0;
char tmpbuf[mybufsize/4];
getcwd(tmpbuf,mybufsize);
if ((newdir=new_next_arg(line,&line))) {
fullname=expand_twiddle(newdir);
if (!chdir(fullname)) malloc_strcpy(&CdccUlDir,fullname);
else {
#ifdef WANTANSI
say("%sError%s, can't cd into %s%s%s",
CmdsColors[COLWARNING].color1,Colors[COLOFF],
CmdsColors[COLSETTING].color2,fullname,Colors[COLOFF]);
#else
say("Error, can't cd into %s",fullname);
#endif
}
new_free(&fullname);
chdir(tmpbuf);
}
if (CdccUlDir) PrintSetting("Cdcc upload dir",CdccUlDir,empty_string,empty_string);
else PrintSetting("Cdcc upload dir",tmpbuf," - your current dir",empty_string);
}
/***********************************************************************
* Sets CDCC download dir *
***********************************************************************/
static void dldirmcommand(line)
char *line;
{
char *newdir;
char *fullname=(char *) 0;
char tmpbuf[mybufsize/4];
getcwd(tmpbuf,mybufsize);
if ((newdir=new_next_arg(line,&line))) {
fullname=expand_twiddle(newdir);
if (!chdir(fullname)) malloc_strcpy(&CdccDlDir,fullname);
else {
#ifdef WANTANSI
say("%sError%s, can't cd into %s%s%s",
CmdsColors[COLWARNING].color1,Colors[COLOFF],
CmdsColors[COLSETTING].color2,fullname,Colors[COLOFF]);
#else
say("Error, can't cd into %s",fullname);
#endif
}
new_free(&fullname);
chdir(tmpbuf);
}
if (CdccDlDir) PrintSetting("Cdcc download dir",CdccDlDir,empty_string,empty_string);
else PrintSetting("Cdcc download dir",tmpbuf," - your current dir",empty_string);
}
/* returns DCC status as one character */
static char dccstatus(flags)
int flags;
{
return(flags&DCC_OFFER?'O' :
flags&DCC_DELETE?'D' :
flags&DCC_ACTIVE?'A' :
flags&DCC_WAIT?'W' :
#ifdef DCC_CNCT_PEND
flags&DCC_CNCT_PEND?'C' :
#endif
'U');
}
/***********************************************************************
* showdccscommand: Lists all dccs *
***********************************************************************/
static void showdccsmcommand(type)
int type;
{
int fills;
int count=1,i,j;
int highascii=get_int_var(HIGH_ASCII_VAR);
long completed;
char *filename;
char *format;
char tmpbuf1[mybufsize/4];
char tmpbuf2[mybufsize/4];
char tmpbuf3[mybufsize/4];
char tmpbuf4[mybufsize/32];
float rate;
time_t timenow;
time_t etatime;
unsigned flags;
DCC_list *Client;
if (LongStatus) format="%s %-6.6s %-9.9s %c %7.7s %s %s";
else format="%-2s %-6.6s %-9.9s %c %7.7s %s %s %s";
#if !defined(CELEHOOK) && !defined(LITE)
if (do_hook(DCC_LIST_HEADER,"%d",LongStatus))
#endif
{
if (LongStatus) say(format,"# ","Type","Nick",'S',"kb/s"," ETA ","Arguments");
else say(format,"# ","Type","Nick",'S',"kb/s","Completed "," ETA ","Arguments");
}
for (Client=ClientList;Client;Client=Client->next) {
flags=Client->flags;
if (type==15 || (flags&type)==type) {
*tmpbuf1='\0';
*tmpbuf2='\0';
timenow=time((time_t *) 0);
completed=0;
flags&=DCC_TYPES;
if (flags==DCC_FILEREAD) completed=Client->bytes_read;
else if (flags==DCC_FILEREGET)
completed=Client->bytes_read+Client->resendoffset;
else if (flags==DCC_FILEOFFER) completed=Client->bytes_sent;
else if (flags==DCC_RESENDOFFER)
completed=Client->bytes_sent+Client->resendoffset;
filename=rindex(Client->description,'/');
if (!filename) filename=Client->description;
else filename++;
if (completed && Client->filesize>0) {
if (Client->filesize>=10000000) fills=completed/(Client->filesize/100);
else fills=completed*100/Client->filesize;
}
else fills=0;
if (completed && (Client->flags)&DCC_ACTIVE && timenow-Client->starttime>0) {
rate = (float)(completed - Client->resendoffset) / (float)(timenow - Client->starttime);
if (rate>0.0 && completed<=Client->filesize)
etatime=(float) (((float) (Client->filesize)-(float) completed)/(float) rate);
else etatime=0;
}
else {
rate=0.0;
etatime=0;
}
#if !defined(CELEHOOK) && !defined(LITE)
snprintf(tmpbuf1,sizeof(tmpbuf1),"%.2f",rate);
if (do_hook(DCC_LIST,"%d %s %s %c %s %ld %s %d %ld",count,
dcc_types[flags],Client->user,dccstatus(Client->flags),
tmpbuf1,etatime,filename,fills,(long) Client->filesize))
#endif
{
if (completed) {
if (LongStatus) {
strmcpy(tmpbuf1,"\026 ",sizeof(tmpbuf1));
for (i=1;i<7;i++) strmcat(tmpbuf1," ",sizeof(tmpbuf1));
snprintf(tmpbuf2,sizeof(tmpbuf2),"%3d%% (%ld of %ld bytes)",fills,completed,
(long) Client->filesize);
fills=(fills+1)*63/100;
for (i=0,j=0;i<=fills;i++)
if (tmpbuf2[j] && i>14) {
tmpbuf1[i+1]=tmpbuf2[j];
j++;
}
else tmpbuf1[i+1]=' ';
if (!i) i++;
if (tmpbuf1[i]!=' ') tmpbuf1[i+1]=tmpbuf1[i];
tmpbuf1[i]='\026';
i++;
if (i<16) i=16;
while (tmpbuf2[j]) {
tmpbuf1[i+1]=tmpbuf2[j];
i++;
j++;
}
}
else {
#define BARSIZE 10
#ifdef HAVE_ICONV_H
char *fillchar=highascii?"\342\226\223":" ";
char *emptychar=highascii?"\342\226\221":"_";
#else
char *fillchar=highascii?"²":" ";
char *emptychar=highascii?"°":"_";
#endif /* HAVE_ICONV_H */
snprintf(tmpbuf2,sizeof(tmpbuf2)," %3d%%",fills);
fills=((fills+3)*BARSIZE)/100;
if (highascii) *tmpbuf1='\0';
else strmcpy(tmpbuf1,"\026",sizeof(tmpbuf1));
for (i=0;i<fills;i++) strmcat(tmpbuf1,fillchar,sizeof(tmpbuf1));
if (!highascii) strmcat(tmpbuf1,"\026",sizeof(tmpbuf1));
for (;i<BARSIZE;i++) strmcat(tmpbuf1,emptychar,sizeof(tmpbuf1));
strmcat(tmpbuf1,tmpbuf2,sizeof(tmpbuf1));
}
strmcpy(tmpbuf2," N/A",sizeof(tmpbuf2));
flags=Client->flags;
if (flags&DCC_ACTIVE && timenow-Client->starttime>0) {
flags&=DCC_TYPES;
rate = (float)(completed - Client->resendoffset) / (float)(timenow - Client->starttime);
snprintf(tmpbuf2,sizeof(tmpbuf2),"%6.2f",rate/1024.0);
if (rate>0.01 && completed<=Client->filesize) {
etatime=(float) (((float) (Client->filesize)-(float) completed)/(float) rate);
snprintf(tmpbuf3,sizeof(tmpbuf3),"%3ld:%02ld ",etatime/60,etatime%60);
}
else strmcpy(tmpbuf3," N/A ",sizeof(tmpbuf3));
}
else strmcpy(tmpbuf3," N/A ",sizeof(tmpbuf3));
}
else {
if (LongStatus) {
strmcpy(tmpbuf2," N/A",sizeof(tmpbuf2));
strmcpy(tmpbuf3," N/A ",sizeof(tmpbuf3));
}
else {
strmcpy(tmpbuf1," N/A ",sizeof(tmpbuf1));
strmcpy(tmpbuf2," N/A",sizeof(tmpbuf2));
strmcpy(tmpbuf3," N/A ",sizeof(tmpbuf3));
}
}
snprintf(tmpbuf4,sizeof(tmpbuf4),"%-2d",count);
if (!(*tmpbuf2)) strmcpy(tmpbuf2," ",sizeof(tmpbuf2));
if (LongStatus) {
flags=Client->flags;
say(format,tmpbuf4,dcc_types[flags&DCC_TYPES],Client->user,
dccstatus(flags),tmpbuf2,tmpbuf3,filename);
flags&=DCC_TYPES;
if (completed &&
(flags==DCC_FILEREAD || flags==DCC_FILEREGET ||
flags==DCC_FILEOFFER || flags==DCC_RESENDOFFER))
say("[%s]",tmpbuf1);
}
else {
flags=Client->flags;
say(format,tmpbuf4,dcc_types[flags&DCC_TYPES],Client->user,
dccstatus(flags),tmpbuf2,tmpbuf1,tmpbuf3,filename);
}
}
count++;
}
}
#if !defined(CELEHOOK) && !defined(LITE)
do_hook(DCC_LIST_FOOTER,"%d",count-1);
#endif
}
/***********************************************************************
* matchmcommand: Returns true if count matches line *
***********************************************************************/
int matchmcommand(origline,count)
char *origline;
int count;
{
int startnum=0;
int endnum=0;
register char *tmpstr;
tmpstr=origline;
if (!tmpstr) return(0);
if (*tmpstr=='#') tmpstr++;
if (*tmpstr=='*') return(1);
while (*tmpstr) {
startnum=0;
endnum=0;
if (*tmpstr=='-') {
while (*tmpstr && !isdigit(*tmpstr)) tmpstr++;
endnum=atoi(tmpstr);
startnum=1;
while (*tmpstr && isdigit(*tmpstr)) tmpstr++;
}
else {
while (*tmpstr && !isdigit(*tmpstr)) tmpstr++;
startnum=atoi(tmpstr);
while (*tmpstr && isdigit(*tmpstr)) tmpstr++;
if (*tmpstr=='-') {
while (*tmpstr && !isdigit(*tmpstr)) tmpstr++;
endnum=atoi(tmpstr);
if (!endnum) endnum=1000;
while (*tmpstr && isdigit(*tmpstr)) tmpstr++;
}
}
if (count==startnum || (count>=startnum && count<=endnum)) return(1);
}
if (count==startnum || (count>=startnum && count<=endnum)) return(1);
return(0);
}
/**********************************************************************
* closemcommand: Prompt User for type of dccs he wants to close *
***********************************************************************/
static void closemcommand(line)
char *line;
{
char *word;
if (!ClientList) {
say("No dccs to close");
return;
}
if ((word=new_next_arg(line,&line))) close2mcommand(NULL,word);
else {
showdccsmcommand(15);
add_wait_prompt("What to close (1-6,3 or *) ? ",
close2mcommand,line,WAIT_PROMPT_LINE);
}
}
/**********************************************************************
* close2mcommand This closes all user specified dccs *
***********************************************************************/
static void close2mcommand(blah,line)
char *blah;
char *line;
{
int count=0;
int packcount=0;
char tmpbuf[mybufsize];
DCC_list *Client;
unsigned flags;
if (line && *line) {
for (Client=ClientList;Client;Client=Client->next) {
packcount++;
flags=Client->flags;
if (matchmcommand(line,packcount)) {
count++;
snprintf(tmpbuf,sizeof(tmpbuf),"%s %s \"%s\"",dcc_types[flags&DCC_TYPES],Client->user,
Client->description);
dcc_close(tmpbuf);
}
}
say("Total of %d dccs closed",count);
RemoveFromQueue(0);
}
else say("You must specify what to close");
}
/**********************************************************************
* doffermcommand: Prompt User for removing pack *
***********************************************************************/
static void doffermcommand(line)
char *line;
{
char *word;
if (packs) {
if ((word=new_next_arg(line,&line))) doffer2mcommand(NULL,word);
else {
ShowPacks(NULL);
add_wait_prompt("Doffer what pack (1-6,3 or * for all) ? ",
doffer2mcommand,line,WAIT_PROMPT_LINE);
}
}
else say("No packs created");
}
/**********************************************************************
* doffer2mcommand This parses offer file list *
* And puts in Files Linked List *
***********************************************************************/
static void doffer2mcommand(blah,line)
char *blah;
char *line;
{
int packcount=0;
Files *tmp2;
Files *next;
Packs *tmp;
Packs *tmp1;
Packs *tmp3;
char *tmpstr=(char *) 0;
if ((tmpstr=new_next_arg(line,&line))) {
for (tmp=packs;tmp;tmp=tmp3) {
tmp3=tmp->next;
packcount++;
if (matchmcommand(tmpstr,packcount)) {
if ((tmp1=(Packs *) list_lookup((List **) &packs,tmp->description,
!USE_WILDCARDS,REMOVE_FROM_LIST))!=NULL) {
say("Removing pack %-2d : %s",packcount,tmp1->description);
for (tmp2=tmp1->files;tmp2;tmp2=next) {
next=tmp2->next;
new_free(&(tmp2->file));
new_free(&(tmp2->path));
new_free(&tmp2);
}
tmp1->files=NULL;
new_free(&(tmp1->description));
new_free(&tmp1);
/****** Coded by Zakath ******/
CdccPackNum--;
update_all_status();
/*****************************/
}
else say("DOH ERROR !");
}
}
}
else say("You must specify what packs to remove");
}
/* Formats Received/Sent */
static void formatstats(buffer,cdccstuff)
char *buffer;
int cdccstuff;
{
char byteschar='k';
char tmpbuf[mybufsize/4];
double mult=1.0;
if (BytesReceived>1073741823.0) {
byteschar='G';
mult=1048576.0;
}
else if (BytesReceived>1048575.0) {
byteschar='M';
mult=1024.0;
}
if (cdccstuff) snprintf(tmpbuf,sizeof(tmpbuf),"%s Received %.2f %cB",CdccString,
BytesReceived/(1024.0*mult),byteschar);
else snprintf(tmpbuf,sizeof(tmpbuf),"Received %.2f %cB",BytesReceived/(1024.0*mult),byteschar);
if (BytesSent>1073741823.0) {
byteschar='G';
mult=1048576.0;
}
else if (BytesSent>1048575.0) {
byteschar='M';
mult=1024.0;
}
else {
byteschar='k';
mult=1.0;
}
sprintf(buffer,"%s Sent %.2f %cB",tmpbuf,BytesSent/(1024.0*mult),byteschar);
}
/* Like CheckChannel but + before channel has special meaning */
static int CheckCdccChannel(channels,chanlist)
char *channels;
char *chanlist;
{
int found=0;
int minus=0;
char *tmpstr1;
char *tmpstr2;
char *tmpchan1;
char *tmpchan2;
char tmpbuf1[mybufsize];
char tmpbuf2[mybufsize];
if (!channels || !chanlist) return(0);
tmpchan2=chanlist;
while (*tmpchan2) {
tmpstr2=tmpbuf2;
while (*tmpchan2 && *tmpchan2!=',') *tmpstr2++=*tmpchan2++;
*tmpstr2='\0';
if (*tmpchan2==',') tmpchan2++;
tmpchan1=channels;
while (*tmpchan1) {
tmpstr1=tmpbuf1;
while (*tmpchan1 && *tmpchan1!=',') *tmpstr1++=*tmpchan1++;
*tmpstr1='\0';
if (*tmpbuf2=='-') {
tmpstr2=&tmpbuf2[1];
minus=1;
}
else if (*tmpbuf2=='+') {
tmpstr2=&tmpbuf2[1];
minus=2;
}
else {
tmpstr2=tmpbuf2;
minus=0;
}
if (*tmpbuf1=='-') {
tmpstr1=&tmpbuf1[1];
minus=1;
}
else tmpstr1=tmpbuf1;
if (wild_match(tmpstr2,tmpstr1) || wild_match(tmpstr1,tmpstr2)) {
if (minus==1) found=0;
else if (minus==2) found=2;
else found=1;
}
if (*tmpchan1==',') tmpchan1++;
}
}
return(found);
}
/* Sends output from plist to server (when called by timer) */
static void sendplist(text)
char *text;
{
char *msg;
char *channel;
channel=index(text,' ');
channel++;
msg=index(channel,' ');
*msg++='\0';
msg++;
send_text(channel,msg,"PRIVMSG");
}
/* Does actual plist */
static void doplist(tmpchan,current,chan)
char *tmpchan;
int current;
ChannelList *chan;
{
int count;
int delay=-1;
int number;
int donlist;
int oldserver;
char byteschar;
char *mynick=get_server_nickname(from_server);
char tmpbuf1[mybufsize];
char tmpbuf2[mybufsize/2];
float mult;
Packs *tmp;
void (*func)()=(void(*)()) sendplist;
for (tmp=packs,count=0;tmp;tmp=tmp->next) count++;
oldserver=from_server;
for (;chan;chan=chan->next) {
donlist=0;
if (current || (donlist=CheckCdccChannel(chan->channel,tmpchan))) {
from_server=chan->server;
#if !defined(CELEHOOK) && !defined(LITE)
if (do_hook(CDCC_PLIST_HEADER,"%s %d %s",chan->channel,count,mynick))
#endif
{
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s %d PACK%s OFFERED /CTCP %s CDCC SEND N for pack N",
CdccString,count,count==1?empty_string:"S",mynick);
send_text(chan->channel,tmpbuf1,"PRIVMSG");
}
if (donlist==2) continue;
number=1;
for (tmp=packs;tmp;tmp=tmp->next) {
#if !defined(CELEHOOK) && !defined(LITE)
snprintf(tmpbuf2,sizeof(tmpbuf2),"%.2f",tmp->minspeed);
if (do_hook(CDCC_PLIST,"%d %d %d %s %d %s",number,tmp->totalfiles,
tmp->totalbytes,tmpbuf2,tmp->gets,tmp->description))
#endif
{
if (delay==-1) delay=0;
snprintf(tmpbuf2,sizeof(tmpbuf2),"%d/%dx",number,tmp->gets);
if (tmp->totalbytes>1048575) {
byteschar='M';
mult=1024.0;
}
else {
byteschar='k';
mult=1.0;
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"-INV %d PRIVMSG %s :#%-6s %s [%d file%s/%.2f %cB",
delay,chan->channel,tmpbuf2,tmp->description,tmp->totalfiles,
tmp->totalfiles==1?"":"s",
(float) (tmp->totalbytes)/(1024.0*mult),byteschar);
if (tmp->minspeed>0.0) {
snprintf(tmpbuf2,sizeof(tmpbuf2),"/min %.2f kB/s",tmp->minspeed);
strmcat(tmpbuf1,tmpbuf2,sizeof(tmpbuf1));
}
strmcat(tmpbuf1,"]",sizeof(tmpbuf1));
timercmd("FTIMER",tmpbuf1,(char *) func);
if ((tmp->next || chan->next) && !(number%3)) delay+=LIST_DELAY;
}
number++;
}
#if !defined(CELEHOOK) && !defined(LITE)
snprintf(tmpbuf2,sizeof(tmpbuf2),"%.0f %.0f",BytesReceived,BytesSent);
if (do_hook(CDCC_PLIST_FOOTER,"%d %d %s",count,CdccStats,tmpbuf2))
#endif
{
if (CdccStats) {
formatstats(tmpbuf2,1);
if (delay==-1) send_text(chan->channel,tmpbuf2,"PRIVMSG");
else {
snprintf(tmpbuf1,sizeof(tmpbuf1),"-INV %d PRIVMSG %s :%s",delay,chan->channel,
tmpbuf2);
timercmd("FTIMER",tmpbuf1,(char *) func);
}
}
}
from_server=oldserver;
}
if (current) break;
}
LastPlist=time((time_t *) 0);
}
/**********************************************************************
* plistmcommand: Puts list to current channel *
***********************************************************************/
static void plistmcommand(line)
char *line;
{
int current=0;
char *tmpchan;
ChannelList *chan=server_list[curr_scr_win->server].chan_list;
if (packs) {
if (!(tmpchan=new_next_arg(line,&line))) tmpchan=CdccChannels;
if (!tmpchan) {
say("You must set CDCC CHANNELS first");
return;
}
if (!my_stricmp(tmpchan,"current")) {
tmpchan=get_channel_by_refnum(0);
if (!tmpchan) {
NoWindowChannel();
return;
}
current=1;
chan=lookup_channel(tmpchan,from_server,0);
}
doplist(tmpchan,current,chan);
}
else say("No packs created");
}
/* Does actual notice */
static void donotice(tmpchan,current,chan)
char *tmpchan;
int current;
ChannelList *chan;
{
int count;
int oldserver;
char *mynick=get_server_nickname(from_server);
char tmpbuf[mybufsize/4];
Packs *tmp;
for (tmp=packs,count=0;tmp;tmp=tmp->next) count++;
oldserver=from_server;
for (;chan;chan=chan->next) {
if (current || CheckCdccChannel(chan->channel,tmpchan)) {
snprintf(tmpbuf,sizeof(tmpbuf),"%s %d PACK%s OFFERED /CTCP %s CDCC LIST",
CdccString,count,count==1?empty_string:"S",mynick);
from_server=chan->server;
send_text(chan->channel,tmpbuf,"PRIVMSG");
from_server=oldserver;
}
if (current) break;
}
LastNlist=time((time_t *) 0);
}
/**********************************************************************
* noticemcommand: yells about offer to current channel *
***********************************************************************/
static void noticemcommand(line)
char *line;
{
int current=0;
char *tmpchan;
ChannelList *chan=server_list[curr_scr_win->server].chan_list;
if (packs) {
if (!(tmpchan=new_next_arg(line,&line))) tmpchan=CdccChannels;
if (!tmpchan) {
say("You must set CDCC CHANNELS first");
return;
}
if (!my_stricmp(tmpchan,"current")) {
tmpchan=get_channel_by_refnum(0);
if (!tmpchan) {
NoWindowChannel();
return;
}
current=1;
chan=lookup_channel(tmpchan,from_server,0);
}
donotice(tmpchan,current,chan);
}
else say("No packs created");
}
/***********************************************************************
* Sets new pack description *
***********************************************************************/
#ifdef EXTRAS
static void renamepackmcommand(line)
char *line;
{
int number;
int i;
char *pack;
char *desc;
Packs *tmp;
if (packs) {
if ((pack=new_next_arg(line,&line))) {
if (pack && *pack=='#') pack++;
number=atoi(pack);
desc=line;
for (tmp=packs,i=1;tmp;tmp=tmp->next,i++) {
if (i==number) {
say("Renamed pack #%d from %s to %s",number,tmp->description,desc);
malloc_strcpy(&tmp->description,desc);
return;
}
}
say("Invalid pack number %d",number);
}
else PrintUsage("CDCC RENPACK #packno new description");
}
else say("No packs created");
}
#endif
/***********************************************************************
* Lists files in queue *
***********************************************************************/
void queuemcommand(line)
char *line;
{
int count=0;
int countdel=0;
char *tmpstr;
char *files=(char *) 0;
char *file=(char *) 0;
char *nick=(char *) 0;
FileQueue *tmp;
FileQueue *prev=(FileQueue *) 0;
FileQueue *tmpdel;
tmpstr=new_next_arg(line,&line);
if (!queuelist) {
if (!tmpstr || my_stricmp(tmpstr,"FLUSH"))
say("No files in queue");
return;
}
if (tmpstr && !my_stricmp(tmpstr,"LIST")) {
tmpstr=new_next_arg(line,&line);
if (tmpstr && *tmpstr) nick=tmpstr;
if (nick) say("Listing all files in queue for %s",nick);
else say("Listing all files in queue");
for (tmp=queuelist;tmp;tmp=tmp->next)
if (!nick || wild_match(nick,tmp->nick)) {
count++;
if (nick) {
if (!(file=rindex(tmp->file,'/'))) file=tmp->file;
else file++;
if (files) malloc_strcat(&files," ");
malloc_strcat(&files,file);
if (count && (count%70)==0) {
say("%s",files);
new_free(&files);
}
}
else say("#%-2d %s to %s",count,tmp->file,tmp->nick);
}
if (nick) {
if (files) {
say("%s",files);
new_free(&files);
}
say("Total of %d file%s in queue for %s",count,count==1?"":"s",nick);
}
else say("Total of %d file%s in queue",count,count==1?"":"s");
}
else if (tmpstr && !my_stricmp(tmpstr,"REMOVE")) {
tmpstr=new_next_arg(line,&line);
if (tmpstr && *tmpstr) {
for (tmp=queuelist;tmp;) {
count++;
tmpdel=tmp;
tmp=tmp->next;
if (matchmcommand(tmpstr,count)) {
if (prev) prev->next=tmpdel->next;
else queuelist=tmpdel->next;
new_free(&(tmpdel->file));
new_free(&(tmpdel->nick));
new_free(&tmpdel);
countdel++;
}
else prev=tmpdel;
}
say("Total of %d files removed from queue",countdel);
}
else PrintUsage("CDCC QUEUE REMOVE filter");
}
else if (tmpstr && !my_stricmp(tmpstr,"FLUSH"))
RemoveFromQueue(0);
else {
for (tmp=queuelist;tmp;tmp=tmp->next) count++;
say("Total of %d file%s in queue",count,count==1?"":"s");
}
}
/**********************************************************************
* loadmcommand: loads packs from file *
***********************************************************************/
#ifndef LITE
static void loadmcommand(line)
char *line;
{
int count=0;
int lineno=0;
char *file;
char *filepath;
char *tmpstr;
char *tmpstr1;
char tmpbuf[mybufsize/2];
FILE *fp;
Packs *tmp=NULL;
Packs *last;
Files *tmpfile;
Files *lastfile;
file=new_next_arg(line,&line);
if (!file) file="ScrollZ.offer";
if (!(filepath=OpenCreateFile(file,1)) || (fp=fopen(filepath,"r"))==NULL) {
#ifdef WANTANSI
say("%sError%s: Can't open file %s !",
CmdsColors[COLWARNING].color1,Colors[COLOFF],file);
#else
say("Can't open file %s",file);
#endif
return;
}
last=packs;
while (last && last->next) last=last->next;
while (fgets(tmpbuf,mybufsize/2,fp)) {
lineno++;
if (tmpbuf[0]=='#') continue;
if (tmpbuf[strlen(tmpbuf)-1]=='\n') tmpbuf[strlen(tmpbuf)-1]='\0';
tmpstr=tmpbuf;
tmpstr1=new_next_arg(tmpstr,&tmpstr);
if (tmpstr1 && *tmpstr1 && !my_strnicmp(tmpstr1,"PACK",4)) {
tmp=(Packs *) new_malloc(sizeof(Packs));
tmp->description=NULL;
while (tmpstr && *tmpstr && isspace(*tmpstr)) tmpstr++;
malloc_strcpy(&tmp->description,tmpstr);
tmp->totalfiles=0;
tmp->totalbytes=0;
tmp->gets=0;
tmp->minspeed=0.0;
tmp->files=NULL;
tmp->next=NULL;
if (last) last->next=tmp;
else packs=tmp;
last=tmp;
count++;
}
else if (tmpstr1 && *tmpstr1 && !my_strnicmp(tmpstr1,"SPEED",5)) {
if (tmp) tmp->minspeed=atof(tmpstr);
else {
#ifdef WANTANSI
say("%sError%s in %s, %sline %d%s (SPEED should follow PACK)",
CmdsColors[COLWARNING].color1,Colors[COLOFF],file,
CmdsColors[COLWARNING].color3,lineno,Colors[COLOFF]);
#else
say("Error in %s, line %d (SPEED should follow PACK)",file,lineno);
#endif
continue;
}
}
else if (tmpstr1 && *tmpstr1 && !my_strnicmp(tmpstr1,"GETS",4)) {
if (tmp) tmp->gets=atoi(tmpstr);
else {
#ifdef WANTANSI
say("%sError%s in %s, %sline %d%s (GETS should follow PACK)",
CmdsColors[COLWARNING].color1,Colors[COLOFF],file,
CmdsColors[COLWARNING].color3,lineno,Colors[COLOFF]);
#else
say("Error in %s, line %d (GETS should follow PACK)",file,lineno);
#endif
continue;
}
}
else if (tmpstr1 && *tmpstr1 && !my_strnicmp(tmpstr1,"FILE",4)) {
if (tmp) {
for (tmpstr1=new_next_arg(tmpstr,&tmpstr);tmpstr1;tmpstr1=new_next_arg(tmpstr,&tmpstr))
if (SeedFiles(tmpstr1,0)) {
lastfile=tmp->files;
while (lastfile && lastfile->next) lastfile=lastfile->next;
if (lastfile) lastfile->next=files;
else tmp->files=files;
files=NULL;
}
else {
#ifdef WANTANSI
say("%sError%s in %s, %sline %d%s (can't stat %s)",
CmdsColors[COLWARNING].color1,Colors[COLOFF],file,
CmdsColors[COLWARNING].color3,lineno,Colors[COLOFF],tmpstr1);
#else
say("Error in %s, line %d (can't stat %s)",file,lineno,tmpstr1);
#endif
continue;
}
}
else {
#ifdef WANTANSI
say("%sError%s in %s, %sline %d%s (FILE should follow PACK)",
CmdsColors[COLWARNING].color1,Colors[COLOFF],file,
CmdsColors[COLWARNING].color3,lineno,Colors[COLOFF]);
#else
say("Error in %s, line %d (FILE should follow PACK)",file,lineno);
#endif
continue;
}
}
}
fclose(fp);
for (tmp=packs;tmp;tmp=tmp->next) {
tmp->totalbytes=0;
tmp->totalfiles=0;
for (tmpfile=tmp->files;tmpfile;tmpfile=tmpfile->next) {
tmp->totalbytes+=tmpfile->size;
tmp->totalfiles++;
}
}
tmp=packs;
last=packs;
while (tmp) {
if (!(tmp->totalfiles)) {
count--;
if (tmp==packs) {
packs=tmp->next;
last=packs;
}
else last->next=tmp->next;
say("No files in pack %s, deleting...",tmp->description);
new_free(&tmp->description);
for (tmpfile=tmp->files;tmpfile;tmpfile=lastfile) {
lastfile=tmpfile->next;
new_free(&tmpfile->path);
new_free(&tmpfile->file);
new_free(&tmpfile);
}
new_free(&tmp);
tmp=last;
}
else {
last=tmp;
tmp=tmp->next;
}
}
say("Loaded %d pack%s from %s",count,count==1?empty_string:"s",file);
CdccPackNum+=count;
}
/**********************************************************************
* savemcommand: saves packs to file *
***********************************************************************/
static void savemcommand(line)
char *line;
{
int count=0;
int oldumask=umask(0177);
char *file;
char *filepath;
FILE *fp;
Packs *tmp;
Files *tmpfile;
if (packs) {
file=new_next_arg(line,&line);
if (!file) file="ScrollZ.offer";
if (!(filepath=OpenCreateFile(file,1)) || (fp=fopen(filepath,"w"))==NULL) {
#ifdef WANTANSI
say("%sError%s: Can't open file %s !",
CmdsColors[COLWARNING].color1,Colors[COLOFF],file);
#else
say("Can't open file %s",file);
#endif
umask(oldumask);
return;
}
for (tmp=packs;tmp;tmp=tmp->next) {
fprintf(fp,"PACK %s\n",tmp->description);
if (tmp->minspeed>0.0) fprintf(fp,"SPEED %.2f\n",tmp->minspeed);
fprintf(fp,"GETS %d\n",tmp->gets);
for (tmpfile=tmp->files;tmpfile;tmpfile=tmpfile->next)
fprintf(fp,"FILE \"%s/%s\"\n",tmpfile->path,tmpfile->file);
count++;
}
fclose(fp);
say("Saved %d pack%s to %s",count,count==1?empty_string:"s",file);
}
else say("No packs created");
umask(oldumask);
}
/***********************************************************************
* requestmcommand: Lets User tell leechers what he needs. By Zakath *
***********************************************************************/
static void requestmcommand(line)
char *line;
{
if (line && *line) {
CdccReqTog=1; /* Assume request will be turned on, unless "OFF" */
if (!my_stricmp(line,"OFF")) {
CdccReqTog=0;
new_free(&CdccRequest); /* Not sure if new_free() is correct */
}
else malloc_strcpy(&CdccRequest,line); /* It works */
}
if (!CdccReqTog) PrintSetting("Cdcc request","OFF",empty_string,
empty_string);
else if (CdccRequest && CdccReqTog) PrintSetting("Cdcc request",CdccRequest,
empty_string,empty_string);
}
#endif /* LITE */
/**********************************************************************
* offermcommand: Prompt User for files *
***********************************************************************/
static void offermcommand(line)
char *line;
{
char *speed;
char *desc;
if (line && *line) {
speed=index(line,',');
if (!speed) {
PrintUsage("CDCC OFFER pattern1 pattern2 , speed , description");
return;
}
*speed='\0';
speed++;
while (isspace(*speed)) speed++;
desc=index(speed,',');
if (!desc) {
PrintUsage("CDCC OFFER pattern1 pattern2 , speed , description");
return;
}
*desc='\0';
desc++;
if (!(*desc)) {
PrintUsage("CDCC OFFER pattern1 pattern2 , speed , description");
return;
}
if (AddFiles2List(line)) offer4mcommand(speed,desc);
}
else add_wait_prompt("Add what files to pack ? ",offer2mcommand,line,WAIT_PROMPT_LINE);
}
/**********************************************************************
* offer2mcommand This parses offer file list *
* And puts in Files Linked List *
***********************************************************************/
static void offer2mcommand(blah,line)
char *blah;
char *line;
{
if (line && *line) {
if (AddFiles2List(line))
add_wait_prompt("Min speed for pack ? ",offer3mcommand,line,WAIT_PROMPT_LINE);
}
else say("You must specify file(s) to add to pack");
}
/**********************************************************************
* offer3mcommand This asks for description *
***********************************************************************/
static void offer3mcommand(blah,line)
char *blah;
char *line;
{
add_wait_prompt("Pack description ? ",offer4mcommand,line,WAIT_PROMPT_LINE);
}
/**********************************************************************
* offer4mcommand Final part of pack creation *
***********************************************************************/
static void offer4mcommand(blah,line)
char *blah;
char *line;
{
if (line && *line) AddToOfferList(blah,line);
else say("You must specify pack description");
DeleteSend();
}
/**********************************************************************
* AddToOfferList: Adds Files to offer List *
***********************************************************************/
static void AddToOfferList(speed,desc)
char *speed;
char *desc;
{
int totalfiles=0;
int totalbytes=0;
char byteschar;
char tmpbuf1[mybufsize/4];
#ifdef WANTANSI
char tmpbuf2[mybufsize/8];
#endif
float mult;
Packs *new=(Packs *) 0;
Packs *tmppack;
Files *tmp=(Files *) 0;
Files *tmp2=(Files *) 0;
Files *tmp3=(Files *) 0;
new=(Packs *) new_malloc(sizeof(Packs));
new->description=(char *) 0;
new->minspeed=(speed && *speed)?atof(speed):0.0;
new->gets=0;
malloc_strcpy(&(new->description),desc);
new->files=NULL;
new->next=NULL;
for (tmppack=packs;tmppack && tmppack->next;tmppack=tmppack->next);
if (tmppack) tmppack->next=new;
else packs=new;
if (files) {
tmp=files;
for (;;) {
tmp2=tmp->next;
for (tmp3=new->files;tmp3 && tmp3->next;) tmp3=tmp3->next;
if (tmp3) tmp3->next=tmp;
else new->files=tmp;
tmp->next=(Files *) 0;
totalfiles++;
totalbytes=totalbytes+tmp->size;
if (!tmp2) break;
tmp=tmp2;
}
files=(Files *) 0;
}
else files=(Files *) 0;
new->totalbytes=totalbytes;
new->totalfiles=totalfiles;
if (totalbytes>1048575) {
byteschar='M';
mult=1024.0;
}
else {
byteschar='k';
mult=1.0;
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%.2f %cB/%d file%s",(float) (totalbytes)/(1024.0*mult),byteschar,
totalfiles,totalfiles==1?empty_string:"s");
#ifdef WANTANSI
if (new->minspeed>0.0)
snprintf(tmpbuf2,sizeof(tmpbuf2),"%s/min %.2f kB/s%s",
CmdsColors[COLCDCC].color5,new->minspeed,Colors[COLOFF]);
else *tmpbuf2='\0';
say("%sCdcc%s %screated new pack%s : [%s%s%s%s] ",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF],
CmdsColors[COLCDCC].color5,tmpbuf1,Colors[COLOFF],tmpbuf2);
#else
if (new->minspeed>0.0)
say("Cdcc created new pack : [%s/min %.2f kB/s]",tmpbuf1,new->minspeed);
else say("Cdcc created new pack : [%s]",tmpbuf1);
#endif
/****** Coded by Zakath ******/
CdccPackNum++;
update_all_status();
/*****************************/
}
/**********************************************************************
* sendmcommand: Prompt User for files *
***********************************************************************/
static void sendmcommand(line)
char *line;
{
char *x = line, *comma = NULL;
if (line && *line) {
while (x) {
x = strchr(x, ',');
if (x) {
comma = x;
x++;
}
}
if (!comma) {
PrintUsage("CDCC SEND pattern1 pattern2 , nick1 nick2");
return;
}
*comma = '\0';
comma++;
if (AddFiles2List(line)) send3mcommand(NULL, comma);
}
else add_wait_prompt("Files to send ? ", send2mcommand, line, WAIT_PROMPT_LINE);
}
/**********************************************************************
* send2mcommand This parses file send list *
* Files Linked list *
***********************************************************************/
static void send2mcommand(blah,line)
char *blah;
char *line;
{
if (line && *line) {
if (AddFiles2List(line))
add_wait_prompt("Send to whom ? (ie. nick1 nick2 nick3) ",send3mcommand,line,WAIT_PROMPT_LINE);
}
else say("You must specify file(s) to send");
}
/**********************************************************************
* send3mcommand This parses nick send list, and sends all files in *
* Files Linked list *
***********************************************************************/
static void send3mcommand(blah,line)
char *blah;
char *line;
{
int count;
int total;
int queue=0;
int queueret;
int queuesay=0;
int queuesent=0;
char byteschar;
char *nick=(char *) 0;
char tmpbuf1[mybufsize/4];
char tmpbuf2[mybufsize/8];
float mult;
Files *tmp;
unsigned int display;
if (line && *line) {
for (nick=new_next_arg(line,&line);nick;nick=new_next_arg(line,&line)) {
total=0;
count=0;
display=window_display;
window_display=0;
for (tmp=files;tmp;tmp=tmp->next) {
if (TotalSendDcc()<CdccLimit) {
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s \"%s/%s\"",nick,tmp->path,tmp->file);
dcc_filesend(tmpbuf1);
count++;
total+=tmp->size;
}
else {
if ((queueret=AddToQueue(tmp,nick,1))>0) {
queue++;
count++;
total+=tmp->size;
}
else if (!queuesent && queueret==0) {
queuesent=1;
if (!CTCPCloaking)
send_to_server("NOTICE %s :Sorry, my Cdcc queue is full",nick);
}
if (!queuesay && queueret==-1) queuesay=1;
}
}
window_display=display;
if (total>1048575) {
byteschar='M';
mult=1024.0;
}
else {
byteschar='k';
mult=1.0;
}
snprintf(tmpbuf2,sizeof(tmpbuf2),"%.2f %cB/%d file%s",(float) (total)/(1024.0*mult),byteschar,
count,count==1?empty_string:"s");
if (queue) snprintf(tmpbuf1,sizeof(tmpbuf1),", %d file%s in queue",queue,
queue==1?"":"s");
else *tmpbuf1='\0';
if (count || queue) {
if (!CTCPCloaking)
send_to_server("NOTICE %s :Sent : [%s]%s",nick,tmpbuf2,tmpbuf1);
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"%sCdcc%s %ssending%s %s%s%s : ",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF],
CmdsColors[COLCDCC].color1,nick,Colors[COLOFF]);
if (!queue) say("%s[%s%s%s]",tmpbuf1,
CmdsColors[COLCDCC].color5,tmpbuf2,Colors[COLOFF]);
else say("%s[%s%s%s], %d file%s in queue",tmpbuf1,
CmdsColors[COLCDCC].color5,tmpbuf2,Colors[COLOFF],queue,
queue==1?"":"s");
if (queuesent) say("%sCdcc%s %squeue%s is full",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF]);
#else
if (!queue) say("Cdcc sending %s : [%s]",nick,tmpbuf2);
else say("Cdcc sending %s : [%s], %d file%s in queue",nick,tmpbuf2,queue,
queue==1?"":"s");
if (queuesent) say("Cdcc queue is full");
#endif
}
if (queuesay) say("Duplicate files were not put in queue");
}
}
else say("You must specify nick(s) to send file(s) to");
DeleteSend();
}
/**********************************************************************
* fsendmcommand: Prompt User for files *
***********************************************************************/
#ifdef EXTRAS
static void fsendmcommand(line)
char *line;
{
char *x = line, *comma = NULL;
if (line && *line) {
while (x) {
x = strchr(x, ',');
if (x) {
comma = x;
x++;
}
}
if (!comma) {
PrintUsage("CDCC FSEND pattern1 pattern2 , nick1 nick2");
return;
}
*comma='\0';
comma++;
if (AddFiles2List(line)) fsend3mcommand(NULL,comma);
}
else add_wait_prompt("Files to send ? ",fsend2mcommand,line,WAIT_PROMPT_LINE);
}
/**********************************************************************
* fsend2mcommand This parses file send list *
* Files Linked list *
***********************************************************************/
static void fsend2mcommand(blah,line)
char *blah;
char *line;
{
if (line && *line) {
if (AddFiles2List(line))
add_wait_prompt("Send to whom ? (ie. nick1 nick2 nick3) ",fsend3mcommand,line,WAIT_PROMPT_LINE);
}
else say("You must specify file(s) to send");
}
/**********************************************************************
* fsend3mcommand This parses nick send list, and sends all files in *
* Files Linked list *
***********************************************************************/
static void fsend3mcommand(blah,line)
char *blah;
char *line;
{
int count;
int total;
char byteschar;
char *nick=(char *) 0;
char tmpbuf1[mybufsize/4];
char tmpbuf2[mybufsize/8];
float mult;
Files *tmp;
unsigned int display;
if (line && *line) {
for (nick=new_next_arg(line,&line);nick;nick=new_next_arg(line,&line)) {
total=0;
count=0;
display=window_display;
window_display=0;
for (tmp=files;tmp;tmp=tmp->next) {
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s \"%s/%s\"",nick,tmp->path,tmp->file);
dcc_filesend(tmpbuf1);
count++;
total+=tmp->size;
}
window_display=display;
if (total>1048575) {
byteschar='M';
mult=1024.0;
}
else {
byteschar='k';
mult=1.0;
}
snprintf(tmpbuf2,sizeof(tmpbuf2),"%.2f %cB/%d file%s",(float) (total)/(1024.0*mult),byteschar,
count,count==1?empty_string:"s");
if (count) {
if (!CTCPCloaking)
send_to_server("NOTICE %s :Sent : [%s]",nick,tmpbuf2);
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"%sCdcc%s %ssending%s %s%s%s : ",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF],
CmdsColors[COLCDCC].color1,nick,Colors[COLOFF]);
say("%s[%s%s%s]",tmpbuf1,CmdsColors[COLCDCC].color5,tmpbuf2,Colors[COLOFF]);
#else
say("Cdcc sending %s : [%s]",nick,tmpbuf2);
#endif
}
}
}
else say("You must specify nick(s) to send file(s) to");
DeleteSend();
}
#endif /* EXTRAS */
/**********************************************************************
* resendmcommand: Prompt User for files *
***********************************************************************/
static void resendmcommand(line)
char *line;
{
char *x = line, *comma = NULL;
if (line && *line) {
while (x) {
x = strchr(x, ',');
if (x) {
comma = x;
x++;
}
}
if (!comma) {
PrintUsage("CDCC RESEND pattern1 pattern2 , nick1 nick2");
return;
}
*comma='\0';
comma++;
while (*comma==' ') comma++;
if (AddFiles2List(line)) resend3mcommand(NULL,comma);
}
else add_wait_prompt("Files to resend ? ",resend2mcommand,line,WAIT_PROMPT_LINE);
}
/**********************************************************************
* resend2mcommand This parses file resend list *
* Files Linked list *
***********************************************************************/
static void resend2mcommand(blah,line)
char *blah;
char *line;
{
if (line && *line) {
if (AddFiles2List(line))
add_wait_prompt("Resend to whom ? (ie. nick1 nick2 nick3) ",resend3mcommand,line,WAIT_PROMPT_LINE);
}
else say("You must specify file(s) to resend");
}
/*************************************************************************
* resend3mcommand This parses nick resend list, and resends all files *
* in Files Linked list *
**************************************************************************/
static void resend3mcommand(blah,line)
char *blah;
char *line;
{
int count=0;
int total=0;
char byteschar;
char *nick=(char *) 0;
char tmpbuf1[mybufsize/4];
char tmpbuf2[mybufsize/8];
float mult;
Files *tmp;
unsigned int display;
if (line && *line) {
for (nick=new_next_arg(line,&line);nick;nick=new_next_arg(line,&line)) {
display=window_display;
window_display=0;
for (tmp=files;tmp;tmp=tmp->next) {
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s \"%s/%s\"",nick,tmp->path,tmp->file);
dcc_resend(tmpbuf1);
count++;
total=total+tmp->size;
}
window_display=display;
if (total>1048575) {
byteschar='M';
mult=1024.0;
}
else {
byteschar='k';
mult=1.0;
}
snprintf(tmpbuf2,sizeof(tmpbuf2),"%.2f %cB/%d file%s",(float) (total)/(1024.0*mult),byteschar,
count,count==1?empty_string:"s");
if (!CTCPCloaking) send_to_server("NOTICE %s :Resent : [%s]",nick,tmpbuf2);
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"%sCdcc%s %sresending%s %s%s%s : ",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF],
CmdsColors[COLCDCC].color1,nick,Colors[COLOFF]);
say("%s[%s%s%s]",tmpbuf1,CmdsColors[COLCDCC].color5,tmpbuf2,Colors[COLOFF]);
#else
say("Cdcc resending %s : [%s]",nick,tmpbuf2);
#endif
total=0;
count=0;
}
}
else say("You must specify nick(s) to resend file(s) to");
DeleteSend();
}
/**********************************************************************
* psendmcommand: Prompt User for pack *
***********************************************************************/
#ifndef LITE
static void psendmcommand(line)
char *line;
{
char *x = line, *comma = NULL;
if (packs) {
if (line && *line) {
while (x) {
x = strchr(x, ',');
if (x) {
comma = x;
x++;
}
}
if (!comma) {
PrintUsage("CDCC PSEND pattern , nick1 nick2");
return;
}
*comma='\0';
comma++;
while (*comma==' ') comma++;
psend3mcommand(line,comma);
}
else {
ShowPacks(NULL);
add_wait_prompt("Packs to send (1-6,3 or * for all) ? ",psend2mcommand,line,WAIT_PROMPT_LINE);
}
}
else say("No packs created");
}
/**********************************************************************
* psend2mcommand This parses nick send list, and sends all files in *
* Pack Linked list *
***********************************************************************/
static void psend2mcommand(blah,line)
char *blah;
char *line;
{
if (line && *line)
add_wait_prompt("Send to whom ? (ie. nick1 nick2 nick3) ",psend3mcommand,line,WAIT_PROMPT_LINE);
else say("You must specify pack(s) to send");
}
/**********************************************************************
* psend3mcommand This parses pack send list *
***********************************************************************/
static void psend3mcommand(blah,line)
char *blah;
char *line;
{
int packcount;
char *nick;
char *tmpstr;
char tmpbuf[mybufsize/32];
Packs *tmp;
if (line && *line) {
tmpstr=line;
for (nick=new_next_arg(tmpstr,&tmpstr);nick;nick=new_next_arg(tmpstr,&tmpstr)) {
packcount=1;
for (tmp=packs;tmp;tmp=tmp->next) {
if (matchmcommand(blah,packcount)) {
snprintf(tmpbuf,sizeof(tmpbuf),"%d",packcount);
/* if user is sending manually avoid queue/min speed */
sendcommand(nick,tmpbuf,0, 1);
}
packcount++;
}
}
}
else say("You must specify nicks(s) to send pack(s) to");
DeleteSend();
}
#endif /* LITE */
/**********************************************************************
* SeedFiles: Gets Users Line of Files with path, and rips em apart *
* Puts path, file, and size into Files linked list. *
***********************************************************************/
static int SeedFiles(line,error)
char *line;
int error;
{
int i=0;
int size=0;
int count=0;
char *file;
char *rest;
char *string;
char *fullname;
char tmpbuf1[mybufsize/2+1];
char tmpbuf2[mybufsize/4+1];
struct stat tmpstat;
file=line;
if (*file=='/') {
if (strlen(file)>1 && rindex(file,'/')==file) snprintf(tmpbuf1,sizeof(tmpbuf1),"/ %s",&file[1]);
else strmcpy(tmpbuf1,file,sizeof(tmpbuf1));
}
else if (*file=='~') {
if (0 == (fullname=expand_twiddle(file))) {
if (error) yell("Unable to expand %s!",file);
return(0);
}
strmcpy(tmpbuf1,fullname,sizeof(tmpbuf1));
new_free(&fullname);
}
else {
if (CdccUlDir) strmcpy(tmpbuf1,CdccUlDir,sizeof(tmpbuf1));
else getcwd(tmpbuf1,sizeof(tmpbuf1)-1);
strmcat(tmpbuf1,"/",sizeof(tmpbuf1));
strmcat(tmpbuf1,file,sizeof(tmpbuf1));
}
rest=rindex(tmpbuf1,'/');
if (rest==tmpbuf1) rest++;
if (rest) *rest++='\0';
if (access(tmpbuf1, R_OK)!=0) {
if (error) say("Can't access %s",tmpbuf1);
return(0);
}
GetDir(tmpbuf1);
for (i=0;i<CdccEntries;i++) {
strmcpy(tmpbuf2,CdccFileNames[i]->d_name,sizeof(tmpbuf2));
string=tmpbuf2;
#ifdef lame_dgux
string=string-2;
if (string[0]=='.') continue;
#endif
if (wild_match(rest,string)) {
char tmpbuf3[mybufsize/2+1];
strmcpy(tmpbuf3,tmpbuf1,mybufsize/2);
strmcat(tmpbuf3,"/",mybufsize/2);
strmcat(tmpbuf3,tmpbuf2,mybufsize/2);
tmpstat.st_mode=0;
size=stat(tmpbuf3,&tmpstat);
if (tmpstat.st_mode & S_IFDIR) {
if (error)
say("You tried to send a dir %s, please do a %s/* to send a whole dir",
tmpbuf2,tmpbuf2);
continue;
}
if ((size=GetSize(tmpbuf1,string))!=-1) {
AddFileToList(tmpbuf1,string,size);
count++;
}
}
}
return(count);
}
/**********************************************************************
* Add File to FILES linked list *
***********************************************************************/
static void AddFileToList(path,file,size)
char *path;
char *file;
int size;
{
Files *new;
Files *tmp;
new=(Files *) new_malloc(sizeof(Files));
new->path=(char *) 0;
new->file=(char *) 0;
new->next=(Files *) 0;
malloc_strcpy(&(new->path),path);
malloc_strcpy(&(new->file),file);
new->size=size;
for (tmp=files;tmp && tmp->next;) tmp=tmp->next;
if (tmp) tmp->next=new;
else files=new;
}
/**********************************************************************
* Returns number of files added to list *
***********************************************************************/
static int AddFiles2List(line)
char *line;
{
int count=0;
char *file=(char *) 0;
char tmpbuf[mybufsize*2];
Files *tmpfile;
for (file=new_next_arg(line,&line);file;file=new_next_arg(line,&line))
count+=SeedFiles(file,1);
if (count) {
#ifdef WANTANSI
snprintf(tmpbuf,sizeof(tmpbuf),"%sCdcc%s %sadded%s %s%d%s file%s (",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF],
CmdsColors[COLCDCC].color5,count,Colors[COLOFF],
count==1?empty_string:"s");
#else
snprintf(tmpbuf,sizeof(tmpbuf),"Added %d file%s (",count,count==1?empty_string:"s");
#endif
for (tmpfile=files;tmpfile;tmpfile=tmpfile->next) {
#ifdef WANTANSI
strmcat(tmpbuf,CmdsColors[COLCDCC].color5,sizeof(tmpbuf));
#endif
strmcat(tmpbuf,tmpfile->file,sizeof(tmpbuf));
if (tmpfile->next) strmcat(tmpbuf," ",sizeof(tmpbuf));
else {
#ifdef WANTANSI
strmcat(tmpbuf,Colors[COLOFF],sizeof(tmpbuf));
#endif
strmcat(tmpbuf,")",sizeof(tmpbuf));
}
if (strlen(tmpbuf)>mybufsize*2-mybufsize/4) {
say("%s",tmpbuf);
*tmpbuf='\0';
}
}
if (*tmpbuf) say("%s",tmpbuf);
}
else {
say("No files found, aborting...");
DeleteSend();
}
return(count);
}
/*********************************************************************
* Deletes the file link list *
**********************************************************************/
static void DeleteSend()
{
Files *tmp;
Files *next;
for (tmp=files;tmp;tmp=next) {
next=tmp->next;
new_free(&(tmp->path));
new_free(&(tmp->file));
new_free(&tmp);
}
files=(Files *) 0;
}
/*********************************************************************
* Shows the offer link list *
**********************************************************************/
static void ShowPacks(args)
char *args;
{
int packcount=1;
char byteschar;
char *word=(char *) 0;
char tmpbuf1[mybufsize/4];
char tmpbuf2[mybufsize/32];
float mult;
Packs *tmp;
Files *tmp1;
if (args && *args) word=new_next_arg(args,&args);
if (word) {
if (packs) {
for (tmp=packs;tmp;tmp=tmp->next) {
if (matchmcommand(word,packcount)) {
if (tmp->minspeed>0.0)
say("Pack: %d Description: %s Min: %.2f kB/s",packcount,
tmp->description,tmp->minspeed);
else say("Pack: %d Description: %s",packcount,tmp->description);
say("kBytes File");
for (tmp1=tmp->files;tmp1;tmp1=tmp1->next) {
snprintf(tmpbuf1,sizeof(tmpbuf1),"%-11.2f",(float) (tmp1->size)/1024.0);
say("%s %s",tmpbuf1,tmp1->file);
}
say("----------- ---------------");
}
packcount++;
}
formatstats(tmpbuf1,0);
say("%s",tmpbuf1);
}
else say("No packs created");
}
else {
if (packs) {
for (tmp=packs;tmp;tmp=tmp->next) {
if (tmp->minspeed>0.0)
snprintf(tmpbuf2,sizeof(tmpbuf2),"/min %.2f kB/s]",tmp->minspeed);
else strmcpy(tmpbuf2,"]",sizeof(tmpbuf2));
if (tmp->totalbytes>1048575) {
byteschar='M';
mult=1024.0;
}
else {
byteschar='k';
mult=1.0;
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"[%d file%s/%.2f %cB%s",
tmp->totalfiles,tmp->totalfiles==1?empty_string:"s",
(float) (tmp->totalbytes)/(1024.0*mult),byteschar,tmpbuf2);
snprintf(tmpbuf2,sizeof(tmpbuf2),"%d/%d",packcount,tmp->gets);
say("#%-4s %s %s",tmpbuf2,tmp->description,tmpbuf1);
packcount++;
}
formatstats(tmpbuf1,0);
say("%s",tmpbuf1);
}
else say("No packs created");
}
}
/*********************************************************************
* GetDir: This gets the listing of all the files in *ptr dir. *
**********************************************************************/
static void GetDir(path)
char *path;
{
CleanList();
CdccEntries=scandir(path, &CdccFileNames,
(const void *)(int (*) (const struct dirent *)) selectent,
(const void *)(int (*) (const struct dirent *, const struct dirent *)) compar);
}
/*********************************************************************
* CleanList: Cleans up global dirent *
**********************************************************************/
static void CleanList()
{
int i;
if (CdccFileNames) {
for (i=0;i<CdccEntries;i++) new_free(&(CdccFileNames[i]));
new_free(&CdccFileNames);
CdccEntries=0;
}
}
/*********************************************************************
* compar: used by scandir to alphabetize files in dir *
**********************************************************************/
static int compar(e1,e2)
struct dirent **e1;
struct dirent **e2;
{
return (my_stricmp((*e1)->d_name,(*e2)->d_name));
}
/***************************************************************************
* selectent: used by scandir to decide which entries to include in the dir *
* listing. Ignores ., includes all other files *
****************************************************************************/
static int selectent(entry)
struct dirent *entry;
{
if (*(entry->d_name)=='.') return (0);
else return(1);
}
/***********************************************************************
* GetSize: takes path, and filename, cats them together, and returns *
* filesize of file, if dir, returns -1 *
************************************************************************/
static int GetSize(path,file)
char *path;
char *file;
{
char tmpbuf[mybufsize/2];
snprintf(tmpbuf,sizeof(tmpbuf),"%s/%s",path,file);
stat(tmpbuf,&CdccStatBuf);
if (CdccStatBuf.st_mode & S_IFDIR) return(-1);
return(CdccStatBuf.st_size);
}
/**********************************************************************
* getmcommand: Prompt User for nick (* for all) *
***********************************************************************/
static void getmcommand(line)
char *line;
{
char *word;
if ((word=new_next_arg(line,&line))) get2mcommand(NULL,word);
else {
showdccsmcommand(66);
add_wait_prompt("What to get (1-6,3 or * for all) ",get2mcommand,
line,WAIT_PROMPT_LINE);
}
}
/**********************************************************************
* get2mcommand: This will parse your dcc list, and get files *
* Specified by your filter. *
***********************************************************************/
static void get2mcommand(data, line)
char *data;
char *line;
{
int count = 0;
int mode;
char *tmp = NULL;
char tmpbuf[mybufsize / 4];
DCC_list *Client;
unsigned flags;
if (!(tmp = new_next_arg(line, &line))) {
say("You must specify what to get");
return;
}
for (Client = ClientList; Client; Client = Client->next) {
flags = Client->flags;
if ((flags & DCC_OFFER) == DCC_OFFER) {
mode = 0;
if ((flags & DCC_TYPES) == DCC_FILEREAD) mode = 1;
else if ((flags & DCC_TYPES) == DCC_FILEREGET) mode = 2;
count++;
if (matchmcommand(tmp, count)) {
snprintf(tmpbuf, sizeof(tmpbuf), "%s \"%s\"",
Client->user, Client->description);
if (mode == 1) dcc_getfile(tmpbuf);
else if (mode == 2) dcc_regetfile(tmpbuf);
}
}
}
}
/* Parse message to see what they want. */
void CheckCdcc(nick,args,to,msg)
char *nick;
char *args;
char *to;
int msg;
{
int level=0;
char *command=(char *) 0;
#ifdef WANTANSI
char tmpbuf1[mybufsize/2];
#endif
#ifdef WANTANSI
char tmpbuf2[mybufsize/8];
char tmpbuf3[mybufsize/8];
#endif
char tmpbuf4[mybufsize];
time_t timenow;
static time_t lastcheck=0;
struct friends *tmpfriend=NULL;
if (msg) {
timenow=time((time_t *) 0);
if (timenow-lastcheck<3) return;
lastcheck=timenow;
}
snprintf(tmpbuf4,sizeof(tmpbuf4),"%s!%s",nick,FromUserHost);
if ((tmpfriend=CheckUsers(tmpbuf4,NULL))) level=tmpfriend->privs;
if (msg) command=new_next_arg(args,&args);
else command="CDCC";
#ifdef WANTANSI
if (args && *args)
snprintf(tmpbuf1,sizeof(tmpbuf1)," %s%s%s",
CmdsColors[COLCDCC].color3,args,Colors[COLOFF]);
else *tmpbuf1='\0';
ColorUserHost(FromUserHost,CmdsColors[COLCTCP].color2,tmpbuf2,1);
snprintf(tmpbuf4,sizeof(tmpbuf4),"%sCdcc%s%s request received from %s%s%s %s",
CmdsColors[COLCDCC].color4,Colors[COLOFF],tmpbuf1,
CmdsColors[COLCDCC].color1,nick,Colors[COLOFF],tmpbuf2);
if (to && is_channel(to)) {
snprintf(tmpbuf3,sizeof(tmpbuf3)," to %s%s%s",CmdsColors[COLCDCC].color6,to,Colors[COLOFF]);
strmcat(tmpbuf4,tmpbuf3,sizeof(tmpbuf4));
}
#else
snprintf(tmpbuf4,sizeof(tmpbuf4),"Cdcc%s request received from %s (%s)",args,nick,FromUserHost);
if (to && is_channel(to)) {
char buf[mybufsize];
snprintf(buf,sizeof(buf)," to %s",to);
strmcat(tmpbuf4,buf,sizeof(tmpbuf4));
}
#endif
if (away_set || LogOn) AwaySave(tmpbuf4,SAVECTCP);
if (Security && !(level&FLCDCC)) {
strmcat(tmpbuf4,", no access",sizeof(tmpbuf4));
if (!CTCPCloaking)
send_to_server("NOTICE %s :You do not have access... -ScrollZ-",nick);
say("%s",tmpbuf4);
return;
}
if (CdccVerbose==1) say("%s",tmpbuf4);
if (command && (!my_stricmp(command,"CDCC") || !my_stricmp(command,"XDCC")))
command=new_next_arg(args,&args);
if (command) {
if (!my_stricmp(command,"HELP")) helpcommand(nick,args);
else if (!my_stricmp(command,"SEND")) sendcommand(nick,args,0,level&FLCDCC);
else if (!my_stricmp(command,"RESEND")) sendcommand(nick,args,1,level&FLCDCC);
else if (!my_stricmp(command,"LIST")) listcommand(nick,args);
else if (!my_stricmp(command,"VERSION")) versioncommand(nick,args);
else if (!my_stricmp(command,"QUEUE")) queuecommand(nick,args);
else if (!CTCPCloaking) send_to_server("NOTICE %s :Try /CTCP %s CDCC HELP to get Cdcc help",nick,get_server_nickname(from_server));
}
else if (!CTCPCloaking) send_to_server("NOTICE %s :Try /CTCP %s CDCC HELP to get Cdcc help",nick,get_server_nickname(from_server));
}
/* send msg'er help menu */
static void helpcommand(from,args)
char *from;
char *args;
{
if (CTCPCloaking) return;
if (args && *args) {
if (!my_stricmp(args,"VERSION")) send_to_server("NOTICE %s :Cdcc VERSION will report Cdcc version",from);
else if (!my_stricmp(args,"HELP")) send_to_server("NOTICE %s :Cdcc HELP will give you Cdcc help",from);
else if (!my_stricmp(args,"LIST"))
send_to_server("NOTICE %s :Cdcc LIST will list offered packs",from);
else if (!my_stricmp(args,"SEND") || !my_stricmp(args,"RESEND")) {
upper(args);
send_to_server("NOTICE %s :Cdcc %s filter will %ssend packs matching filter",
from,args,!strcmp(args,"RESEND")?"re":"");
send_to_server("NOTICE %s :filter can be : -2,4,6-8,10- or * for all",from);
}
else if (!my_stricmp(args,"QUEUE"))
send_to_server("NOTICE %s :Cdcc QUEUE will show your queue position",from);
}
else send_to_server("NOTICE %s :/CTCP %s CDCC HELP command where command is one of the following : HELP VERSION LIST QUEUE SEND or RESEND",from,get_server_nickname(from_server));
}
/* send msg'er version reply */
static void versioncommand(from, args)
char *from;
char *args;
{
if (CTCPCloaking) return;
send_to_server("NOTICE %s :Cdcc v" CDCC_VERSION " written by Sheik & Flier",from);
send_to_server("NOTICE %s :IRC's first XDCC clone in C !",from);
}
/* Sends to server w/o print */
static void sendlist(text)
char *text;
{
send_to_server("%s",text);
}
/* Check what listing type they want. */
static void listcommand(from,args)
char *from;
char *args;
{
int count=0;
int multdelay;
int packcount=1;
char byteschar;
char *mynick=get_server_nickname(from_server);
char tmpbuf1[mybufsize];
char tmpbuf2[mybufsize/2];
char tmpbuf3[mybufsize/16];
float mult;
Packs *tmp;
void (*func)()=(void(*)()) sendlist;
time_t timenow=time((time_t *) 0);
static int delay=0;
if (packs) {
for (tmp=packs;tmp;tmp=tmp->next) count++;
multdelay=count/3*LIST_DELAY;
if (timenow>LastList+multdelay+10) delay=0;
else delay+=5;
LastList=timenow;
#if !defined(CELEHOOK) && !defined(LITE)
if (do_hook(CDCC_PLIST_HEADER,"%s %d %s",from,count,mynick))
#endif
{
snprintf(tmpbuf1,sizeof(tmpbuf1),"-INV %d NOTICE %s :%s %d PACK%s OFFERED /CTCP %s CDCC SEND N for pack N",
delay,from,CdccString,count,count==1?empty_string:"S",
mynick);
timercmd("FTIMER",tmpbuf1,(char *) func);
if (delay) delay++;
}
for (tmp=packs;tmp;tmp=tmp->next) {
if (tmp->minspeed>0.0)
snprintf(tmpbuf1,sizeof(tmpbuf1),"/min %.2f kB/s]",tmp->minspeed);
else strmcpy(tmpbuf1,"]",sizeof(tmpbuf1));
if (tmp->totalbytes>1048575) {
byteschar='M';
mult=1024.0;
}
else {
byteschar='k';
mult=1.0;
}
snprintf(tmpbuf2,sizeof(tmpbuf2),"[%d file%s/%.2f %cB%s",
tmp->totalfiles,tmp->totalfiles==1?empty_string:"s",
(float) (tmp->totalbytes)/(1024.0*mult),byteschar,tmpbuf1);
snprintf(tmpbuf3,sizeof(tmpbuf3),"%d/%dx",packcount,tmp->gets);
snprintf(tmpbuf1,sizeof(tmpbuf1),"%.2f",tmp->minspeed);
#if !defined(CELEHOOK) && !defined(LITE)
if (do_hook(CDCC_PLIST,"%d %d %d %s %d %s",packcount,
tmp->totalfiles,tmp->totalbytes,tmpbuf1,tmp->gets,
tmp->description))
#endif
{
snprintf(tmpbuf1,sizeof(tmpbuf1),"-INV %d NOTICE %s :#%-6s %s %s",delay,
from,tmpbuf3,tmp->description,tmpbuf2);
timercmd("FTIMER",tmpbuf1,(char *) func);
if (tmp->next && !(packcount%3)) delay+=LIST_DELAY;
}
packcount++;
}
#if !defined(CELEHOOK) && !defined(LITE)
snprintf(tmpbuf1,sizeof(tmpbuf1),"%.0f %.0f",BytesReceived,BytesSent);
if (do_hook(CDCC_PLIST_FOOTER,"%d %d %s",count,CdccStats,tmpbuf1))
#endif
{
if (CdccStats) {
formatstats(tmpbuf2,1);
snprintf(tmpbuf1,sizeof(tmpbuf1),"-INV %d NOTICE %s :%s",delay,from,tmpbuf2);
timercmd("FTIMER",tmpbuf1,(char *) func);
if (delay) delay++;
}
}
}
else if (!CTCPCloaking)
send_to_server("NOTICE %s :Sorry, there are no files offered",from);
}
/* List files in queue */
static void queuecommand(from,args)
char *from;
char *args;
{
int i=1;
int cnt=0;
char *tmpstr=(char *) 0;
char tmpbuf[mybufsize/64];
FileQueue *tmp=queuelist;
if (!queuelist) {
if (!CTCPCloaking)
send_to_server("NOTICE %s :There are no files in queue",from);
return;
}
for (;tmp;tmp=tmp->next) {
if (tmp->server==parsing_server_index && !my_stricmp(tmp->nick,from)) {
if (cnt) malloc_strcat(&tmpstr,",");
snprintf(tmpbuf,sizeof(tmpbuf),"%d",i);
malloc_strcat(&tmpstr,tmpbuf);
if (cnt>=10) {
malloc_strcat(&tmpstr,"...");
break;
}
cnt++;
}
i++;
}
if (cnt) {
send_to_server("NOTICE %s :Your queue position: %s",from,tmpstr);
new_free(&tmpstr);
}
}
/* Send pack that they request */
static void sendcommand(from,args,resend,level)
char *from;
char *args;
int resend;
int level;
{
int packcount=1;
int totalfiles=0;
int totalbytes=0;
int sent=0;
int queue=0;
int packsent;
int queueret;
int queuesay=0;
int queuesent=0;
char byteschar;
char *word;
char tmpbuf1[mybufsize/4];
char tmpbuf2[mybufsize/4];
char tmpbuf3[mybufsize/4];
float mult;
Packs *tmp;
Files *tmp1;
unsigned int display;
DCC_list *tmpdcc;
word=new_next_arg(args,&args);
if (word) {
*tmpbuf3='\0';
if (*word=='#') word++;
if (packs) {
for (tmp=packs;tmp;tmp=tmp->next) {
if (matchmcommand(word,packcount)) {
tmp->gets++;
packsent=0;
display=window_display;
window_display=0;
sent++;
for (tmp1=tmp->files;tmp1;tmp1=tmp1->next) {
if (level || TotalSendDcc()<CdccLimit) {
int dccflag;
packsent=1;
snprintf(tmpbuf2,sizeof(tmpbuf2),"%s/%s",tmp1->path,tmp1->file);
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s \"%s\"",from,tmpbuf2);
if (resend) {
dccflag=DCC_RESENDOFFER;
dcc_resend(tmpbuf1);
}
else {
dccflag=DCC_FILEOFFER;
dcc_filesend(tmpbuf1);
}
tmpdcc=dcc_searchlist(NULL,from,dccflag,0,tmpbuf2);
if (tmpdcc) {
if (!level) tmpdcc->minspeed=tmp->minspeed;
else tmpdcc->minspeed=0.0;
}
totalbytes+=tmp1->size;
totalfiles++;
}
else {
if ((queueret=AddToQueue(tmp1,from,resend+1))>0) {
packsent=1;
queue++;
totalbytes+=tmp1->size;
totalfiles++;
}
else if (!queuesent && queueret==0) {
queuesent=1;
if (!CTCPCloaking)
send_to_server("NOTICE %s :Sorry, my Cdcc queue is full",from);
}
if (!queuesay && queueret==-1) queuesay=1;
}
}
window_display=display;
if (packsent) {
snprintf(tmpbuf1,sizeof(tmpbuf1),"%d",packcount);
if (*tmpbuf3) strmcat(tmpbuf3,",",sizeof(tmpbuf3));
strmcat(tmpbuf3,tmpbuf1,sizeof(tmpbuf3));
}
}
packcount++;
}
if (totalfiles) {
if (totalbytes>1048575) {
byteschar='M';
mult=1024.0;
}
else {
byteschar='k';
mult=1.0;
}
snprintf(tmpbuf2,sizeof(tmpbuf2),"%.2f %cB/%d file%s",
(float) (totalbytes)/(1024.0*mult),byteschar,
totalfiles,totalfiles==1?empty_string:"s");
if (!queue) {
if (!CTCPCloaking) send_to_server("NOTICE %s :%sent packs %s : %s",from,
resend?"Res":"S",tmpbuf3,tmpbuf2);
}
else if (!CTCPCloaking) send_to_server("NOTICE %s :%sent packs %s : %s, %d file%s in queue",
from,resend?"Res":"S",tmpbuf3,tmpbuf2,queue,
queue==1?"":"s");
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"%sCdcc%s %s%ssent%s %s%s%s packs %s : ",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,resend?"re":"",Colors[COLOFF],
CmdsColors[COLCDCC].color1,from,Colors[COLOFF],tmpbuf3);
if (CdccVerbose==1) {
if (!queue) say("%s[%s%s%s]",tmpbuf1,
CmdsColors[COLCDCC].color5,tmpbuf2,Colors[COLOFF]);
else say("%s[%s%s%s], %s%d%s file%s in queue",tmpbuf1,
CmdsColors[COLCDCC].color5,tmpbuf2,Colors[COLOFF],
CmdsColors[COLCDCC].color5,queue,Colors[COLOFF],
queue==1?"":"s");
if (queuesent) say("%sCdcc%s %squeue%s is full",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF]);
}
#else
if (CdccVerbose==1) {
if (!queue) say("Cdcc %ssent %s %s : [%s]",resend?"re":"",
from,tmpbuf3,tmpbuf2);
else say("Cdcc %ssent %s %s : [%s], %d file%s in queue",
resend?"re":"",from,tmpbuf3,tmpbuf2,queue,queue==1?"":"s");
if (queuesent) say("Cdcc queue is full");
}
#endif
/****** Coded by Zakath ******/
#ifndef LITE
if (CdccReqTog && CdccRequest)
send_to_server("NOTICE %s :I need %s",from,CdccRequest);
#endif
/*****************************/
}
if (queuesay && CdccVerbose==1)
say("Duplicate files were not put in queue");
if (!sent && !CTCPCloaking) send_to_server("NOTICE %s :No packs found matching %s",from,word);
}
else if (!CTCPCloaking) send_to_server("NOTICE %s :Sorry, there are no files offered",from);
}
else if (!CTCPCloaking) send_to_server("NOTICE %s :Try /CTCP %s CDCC SEND N",from,get_server_nickname(from_server));
}
/**********************************************************************
* TotalSendDcc: Return Total Dcc Sends Currently on Dcc *
* Linked List. *
***********************************************************************/
int TotalSendDcc()
{
DCC_list *Client;
unsigned flags;
int counter=0;
for (Client=ClientList;Client;Client=Client->next) {
flags=Client->flags;
if (flags&DCC_DELETE) continue;
if (((flags&DCC_TYPES)==DCC_FILEOFFER) ||
((flags&DCC_TYPES)==DCC_RESENDOFFER)) counter++;
}
return(counter);
}
/* return number of files in queue */
int TotalQueue()
{
int count=0;
FileQueue *tmp;
for (tmp=queuelist;tmp;tmp=tmp->next) count++;
return(count);
}
/* get offer files if auto-get is on */
void CheckAutoGet(nick,userhost,file,type)
char *nick;
char *userhost;
char *file;
char *type;
{
char tmpbuf[mybufsize/4];
struct friends *tmpfriend;
if (Security) {
snprintf(tmpbuf,sizeof(tmpbuf),"%s!%s",nick,userhost);
tmpfriend=CheckUsers(tmpbuf,NULL);
if (!tmpfriend) return;
if (!((tmpfriend->privs)&FLCDCC)) return;
}
#ifdef WANTANSI
snprintf(tmpbuf,sizeof(tmpbuf),"%sCdcc%s %sauto getting%s %s%s%s from ",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF],
CmdsColors[COLCDCC].color5,file,Colors[COLOFF]);
say("%s%s%s%s",tmpbuf,CmdsColors[COLCDCC].color1,nick,Colors[COLOFF]);
#else
say("Cdcc auto getting %s from %s",file,nick);
#endif
if (away_set || LogOn) {
snprintf(tmpbuf,sizeof(tmpbuf),"Cdcc auto getting %s from %s (%s)",file,nick,FromUserHost);
AwaySave(tmpbuf,SAVECDCC);
}
snprintf(tmpbuf,sizeof(tmpbuf),"%s \"%s\"",nick,file);
if (!my_stricmp(type,"SEND")) dcc_getfile(tmpbuf);
else if (!my_stricmp(type,"RESEND")) dcc_regetfile(tmpbuf);
#ifdef BROKEN_MIRC_RESUME
else if (!my_stricmp(type,"RESUME")) dcc_getfile_resume(tmpbuf);
#endif /* BROKEN_MIRC_RESUME */
}
/**********************************************************************
* CheckCdccTimer: Checks pending Cdcc timer stuff *
***********************************************************************/
void CheckCdccTimers()
{
int current=0;
int oldserver;
char *tmpstr;
char *channel;
#ifdef WANTANSI
char tmpbuf1[mybufsize];
char tmpbuf2[mybufsize];
#endif
time_t timenow;
unsigned flags;
DCC_list *Client;
ChannelList *chan;
timenow=time((time_t *) 0);
if (timenow-LastIdleCheck>=60) {
LastIdleCheck=timenow;
for (Client=ClientList;CdccIdle && Client;Client=Client->next) {
flags=Client->flags;
if (!(flags&DCC_ACTIVE)) {
tmpstr=rindex(Client->description,'/');
if (tmpstr) tmpstr++;
else tmpstr=Client->description;
if ((flags&DCC_TYPES)==DCC_FILEOFFER || (flags&DCC_TYPES)==DCC_RESENDOFFER) {
if (timenow-Client->CdccTime>CdccIdle) {
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"%sCdcc%s %sclosing%s idle dcc %s%s%s",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF],
CmdsColors[COLCDCC].color3,dcc_types[flags&DCC_TYPES],
Colors[COLOFF]);
snprintf(tmpbuf2,sizeof(tmpbuf2)," %s%s%s to %s%s%s",
CmdsColors[COLCDCC].color5,tmpstr,Colors[COLOFF],
CmdsColors[COLCDCC].color1,Client->user,Colors[COLOFF]);
say("%s%s",tmpbuf1,tmpbuf2);
#else
say("Cdcc closing idle dcc %s %s to %s",
dcc_types[flags&DCC_TYPES],tmpstr,Client->user);
#endif
if (!CTCPCloaking) {
oldserver=from_server;
from_server=Client->server;
if (CheckServer(from_server))
send_to_server("NOTICE %s :Cdcc %s %s auto closed.",
Client->user,dcc_types[flags&DCC_TYPES],
tmpstr);
from_server=oldserver;
}
dcc_erase(Client);
}
}
else if (timenow-Client->CdccTime>3*CdccIdle) {
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"%sCdcc%s %sclosing%s idle dcc %s%s%s",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF],
CmdsColors[COLCDCC].color3,dcc_types[flags&DCC_TYPES],
Colors[COLOFF]);
snprintf(tmpbuf2,sizeof(tmpbuf2)," %s%s%s from %s%s%s",
CmdsColors[COLCDCC].color5,tmpstr,Colors[COLOFF],
CmdsColors[COLCDCC].color1,Client->user,Colors[COLOFF]);
say("%s%s",tmpbuf1,tmpbuf2);
#else
say("Cdcc closing idle dcc %s %s from %s",dcc_types[flags&DCC_TYPES],
tmpstr,Client->user);
#endif
dcc_erase(Client);
}
}
}
}
if (curr_scr_win->server!=-1) {
chan=server_list[curr_scr_win->server].chan_list;
if (packs && CdccChannels && PlistTime && timenow-LastPlist>PlistTime) {
if (!my_stricmp(CdccChannels,"current")) {
channel=get_channel_by_refnum(0);
if (!channel) current=-1;
else {
current=1;
chan=lookup_channel(channel,from_server,0);
}
}
if (current!=-1) doplist(CdccChannels,current,chan);
}
if (packs && CdccChannels && NlistTime && timenow-LastNlist>NlistTime) {
if (!my_stricmp(CdccChannels,"current")) {
channel=get_channel_by_refnum(0);
if (!channel) current=-1;
else {
current=1;
chan=lookup_channel(channel,from_server,0);
}
}
if (current!=-1) donotice(CdccChannels,current,chan);
}
}
}
/**********************************************************************
* CheckDCCSpeed: Checks the pending DCC speed *
***********************************************************************/
void CheckDCCSpeed(Client,timenow)
DCC_list *Client;
time_t timenow;
{
int oldserver;
float rate=-1.0;
char *tmpstr;
#ifdef WANTANSI
char tmpbuf1[mybufsize/4];
char tmpbuf2[mybufsize/4];
#endif
if (timenow-Client->starttime)
rate=((float) (Client->bytes_sent)/(float)(timenow-Client->starttime))/1024.0;
if (rate>=0.0 && rate<Client->minspeed) {
tmpstr=rindex(Client->description,'/');
if (tmpstr) tmpstr++;
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"%sCdcc%s %sclosing%s slow dcc %s%s%s ",
CmdsColors[COLCDCC].color4,Colors[COLOFF],
CmdsColors[COLCDCC].color3,Colors[COLOFF],
CmdsColors[COLCDCC].color3,dcc_types[Client->flags&DCC_TYPES],
Colors[COLOFF]);
snprintf(tmpbuf2,sizeof(tmpbuf2),"%s%s%s%s to %s%s%s (%srate %.2f",
tmpbuf1,CmdsColors[COLCDCC].color5,tmpstr,Colors[COLOFF],
CmdsColors[COLCDCC].color1,Client->user,Colors[COLOFF],
CmdsColors[COLCDCC].color5,rate);
say("%skB/s%s/%smin %.2f kB/s%s)",tmpbuf2,Colors[COLOFF],
CmdsColors[COLCDCC].color5,Client->minspeed,Colors[COLOFF]);
#else
say("Cdcc closing slow dcc %s %s to %s (rate %.2f kB/s/min %.2f kB/s)",
dcc_types[Client->flags&DCC_TYPES],tmpstr,Client->user,rate,
Client->minspeed);
#endif
if (!CTCPCloaking) {
oldserver=from_server;
from_server=Client->server;
if (CheckServer(from_server))
send_to_server("NOTICE %s :Cdcc %s %s auto closed, dcc was too slow (rate %.2f kB/s/min %.2f kB/s)",
Client->user,dcc_types[Client->flags&DCC_TYPES],tmpstr,
rate,Client->minspeed);
from_server=oldserver;
}
Client->flags|=DCC_DELETE;
}
else {
if (rate>4*Client->minspeed) Client->CdccTime+=25L;
else if (rate>2*Client->minspeed) Client->CdccTime+=20L;
else Client->CdccTime+=15L;
}
}
/**********************************************************************
* AddToQueue: Adds file to queue *
***********************************************************************/
static int AddToQueue(tmpfile,nick,flag)
Files *tmpfile;
char *nick;
int flag;
{
int count=0;
char *spath;
char tmpbuf[mybufsize/4];
DCC_list *Client;
FileQueue *tmp;
FileQueue *newfile;
count=TotalQueue();
if (CdccQueueLimit>0 && count>=CdccQueueLimit) return(0);
snprintf(tmpbuf,sizeof(tmpbuf),"%s/%s",tmpfile->path,tmpfile->file);
/* check if nick/file combination is already in DCC list */
for (Client=ClientList;Client;Client=Client->next) {
/* we're only interested in filename so we strip path */
if ((spath=rindex(Client->description,'/'))) spath++;
else spath=Client->description;
if (!strcmp(tmpfile->file,spath) && !my_stricmp(nick,Client->user))
return(-1);
}
/* check if nick/file combination is already in queue */
for (tmp=queuelist;tmp;tmp=tmp->next)
if (!strcmp(tmpbuf,tmp->file) && !my_stricmp(nick,tmp->nick))
return(-1);
newfile=(FileQueue *) new_malloc(sizeof(FileQueue));
newfile->server=from_server;
newfile->file=(char *) 0;
newfile->nick=(char *) 0;
newfile->next=(FileQueue *) 0;
malloc_strcpy(&(newfile->file),tmpbuf);
malloc_strcpy(&(newfile->nick),nick);
newfile->flag=flag;
if (!queuelist) queuelist=newfile;
else {
for (tmp=queuelist;tmp && tmp->next;) tmp=tmp->next;
tmp->next=newfile;
}
return(1);
}
/**********************************************************************
* RemoveFromQueue: Removes file from queue *
***********************************************************************/
void RemoveFromQueue(removed)
int removed;
{
int active=TotalSendDcc()-removed;
int oldserver;
char tmpbuf[mybufsize/4];
unsigned int display;
FileQueue *tmp=queuelist;
while (tmp && active<CdccLimit) {
queuelist=queuelist->next;
snprintf(tmpbuf,sizeof(tmpbuf),"%s \"%s\"",tmp->nick,tmp->file);
display=window_display;
window_display=0;
oldserver=from_server;
from_server=tmp->server;
if (CheckServer(from_server)) {
if (tmp->flag==1) dcc_filesend(tmpbuf);
else dcc_resend(tmpbuf);
active++;
}
from_server=oldserver;
window_display=display;
new_free(&(tmp->nick));
new_free(&(tmp->file));
new_free(&tmp);
tmp=queuelist;
}
}
/**********************************************************************
* CdccQueueNickChange: Handle nick change *
***********************************************************************/
void CdccQueueNickChange(oldnick,newnick)
char *oldnick;
char *newnick;
{
FileQueue *tmp=queuelist;
for (tmp=queuelist;tmp;tmp=tmp->next) {
if (tmp->server!=from_server) continue;
if (!my_stricmp(tmp->nick,oldnick)) malloc_strcpy(&(tmp->nick),newnick);
}
}
/**********************************************************************
* CleanUpCdcc: Free all allocated memory *
***********************************************************************/
void CleanUpCdcc() {
Files *tmpfile;
Files *tmpfilefree;
Packs *tmppack;
Packs *tmppackfree;
FileQueue *tmpqueue;
FileQueue *tmpqueuefree;
for (tmppack=packs;tmppack;) {
tmppackfree=tmppack;
tmppack=tmppack->next;
for (tmpfile=tmppackfree->files;tmpfile;) {
tmpfilefree=tmpfile;
tmpfile=tmpfile->next;
new_free(&(tmpfilefree->path));
new_free(&(tmpfilefree->file));
new_free(&tmpfilefree);
}
new_free(&(tmppackfree->description));
new_free(&tmppackfree);
}
for (tmpqueue=queuelist;tmpqueue;) {
tmpqueuefree=tmpqueue;
tmpqueue=tmpqueue->next;
new_free(&(tmpqueuefree->nick));
new_free(&(tmpqueuefree->file));
new_free(&tmpqueuefree);
}
}
void CdccTimeWarning() {
say("Warning: your CDCC PLIST or NLIST timer is set below two hours.");
say("Due to a lot of complaints about this the above timers have been");
say("increased to two hours. If you feel your values are apropriate");
say("enter the following commands:");
if (PlistTime<7200) {
say("/CDCC PTIME %d",PlistTime);
PlistTime=7200;
}
if (NlistTime<7200) {
say("/CDCC NTIME %d",NlistTime);
NlistTime=7200;
}
}
syntax highlighted by Code2HTML, v. 0.9.1