/* fileq.c -- handles: adding and removing files to/from the file queue listing files on the queue sending the next queued file for a user cancelling a queued file dprintf'ized, 1nov95 */ /* This file is part of the eggdrop source code copyright (c) 1997 Robey Pointer and is distributed according to the GNU general public license. For full details, read the top of 'main.c' or the file called COPYING that was distributed with this code. */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "eggdrop.h" #include "proto.h" #include "../lush.h" extern char dccdir[]; extern char tempdir[]; extern int serv; extern int dcc_total; extern struct dcc_t dcc[]; extern int copy_to_tmp; typedef struct zarrf { char *dir; /* starts with '*' -> absolute dir */ char *file; /* (otherwise -> dccdir) */ char nick[NICKLEN]; /* who queued this file */ char to[NICKLEN]; /* who will it be sent to */ struct zarrf *next; } fileq_t; fileq_t *fileq=NULL; int expmem_fileq() { fileq_t *q=fileq; int tot=0; while (q!=NULL) { tot+=strlen(q->dir)+strlen(q->file)+2+sizeof(fileq_t); q=q->next; } return tot; } void queue_file(dir,file,from,to) char *dir,*file,*from,*to; { fileq_t *q=fileq; fileq=(fileq_t *)nmalloc(sizeof(fileq_t)); fileq->next=q; fileq->dir=(char *)nmalloc(strlen(dir)+1); fileq->file=(char *)nmalloc(strlen(file)+1); strcpy(fileq->dir,dir); strcpy(fileq->file,file); strcpy(fileq->nick,from); strcpy(fileq->to,to); } void deq_this(this) fileq_t *this; { fileq_t *q=fileq,*last=NULL; while ((q!=this) && (q!=NULL)) { last=q; q=q->next; } if (q==NULL) return; /* bogus ptr */ if (last!=NULL) last->next=q->next; else fileq=q->next; nfree(q->dir); nfree(q->file); nfree(q); } /* remove all files queued to a certain user */ void flush_fileq(to) char *to; { fileq_t *q=fileq; int fnd=1; while (fnd) { q=fileq; fnd=0; while (q!=NULL) { if (strcasecmp(q->to,to)==0) { deq_this(q); q=NULL; fnd=1; } if (q!=NULL) q=q->next; } } } void send_next_file(to) char *to; { fileq_t *q=fileq,*this=NULL; char s[256],s1[256]; int x; while (q!=NULL) { if (strcasecmp(q->to,to)==0) this=q; q=q->next; } if (this==NULL) return; /* none */ /* copy this file to /tmp */ if (this->dir[0]=='*') /* absolute path */ sprintf(s,"%s/%s",&this->dir[1],this->file); else sprintf(s,"%s%s%s%s",dccdir,this->dir,this->dir[0]?"/":"",this->file); if (copy_to_tmp) { sprintf(s1,"%s%s",tempdir,this->file); if (copyfile(s,s1)!=0) { putlog(LOG_FILES|LOG_MISC,"*","Refused dcc get %s: copy to %s FAILED!", this->file,tempdir); mprintf(serv,"NOTICE %s :File system is broken; aborting queued files.\n", this->to); strcpy(s,this->to); flush_fileq(s); return; } } else strcpy(s1,s); if (this->dir[0]=='*') sprintf(s,"%s/%s",&this->dir[1],this->file); else sprintf(s,"%s%s%s",this->dir,this->dir[0]?"/":"",this->file); x=raw_dcc_send(s1,this->to,this->nick,s); if (x==1) { wipe_tmp_filename(s1,-1); putlog(LOG_FILES,"*","DCC connections full: GET %s [%s]",s1,this->nick); mprintf(serv,"NOTICE %s :DCC connections full; aborting queued files.\n", this->to); strcpy(s,this->to); flush_fileq(s); return; } if (x==2) { wipe_tmp_filename(s1,-1); putlog(LOG_FILES,"*","DCC socket error: GET %s [%s]",s1,this->nick); mprintf(serv,"NOTICE %s :DCC socket error; aborting queued files.\n", this->to); strcpy(s,this->to); flush_fileq(s); return; } if (strcasecmp(this->to,this->nick)!=0) mprintf(serv,"NOTICE %s :Here is a file from %s ...\n",this->to, this->nick); deq_this(this); } /* let tcl see the queued files for (x) */ void tcl_get_queued(irp,who) Tcl_Interp *irp; char *who; { char s[512]; fileq_t *q=fileq; while (q!=NULL) { if (strcasecmp(q->nick,who)==0) { if (q->dir[0]=='*') sprintf(s,"%s %s/%s",q->to,&q->dir[1],q->file); else sprintf(s,"%s /%s%s%s",q->to,q->dir,q->dir[0]?"/":"",q->file); Tcl_AppendElement(irp,s); } q=q->next; } } void show_queued_files(idx) int idx; { int i,cnt=0; fileq_t *q=fileq; while (q!=NULL) { if (strcasecmp(q->nick,dcc[idx].nick)==0) { if (!cnt) { dprintf(idx," Send to Filename\n"); dprintf(idx," --------- --------------------\n"); } cnt++; if (q->dir[0]=='*') dprintf(idx," %-9s %s/%s\n",q->to,&q->dir[1],q->file); else dprintf(idx," %-9s /%s%s%s\n",q->to,q->dir,q->dir[0]?"/":"", q->file); } q=q->next; } for (i=0; ifrom,dcc[idx].nick)==0))) { char *nfn; if (!cnt) { dprintf(idx," Send to Filename\n"); dprintf(idx," --------- --------------------\n"); } nfn=strrchr(dcc[i].u.xfer->filename,'/'); if (nfn==NULL) nfn=dcc[i].u.xfer->filename; else nfn++; cnt++; if (dcc[i].type==DCC_GET_PENDING) dprintf(idx," %-9s %s [WAITING]\n",dcc[i].nick,nfn); else dprintf(idx," %-9s %s (%.1f%% done)\n",dcc[i].nick,nfn, (100.0*((float)dcc[i].u.xfer->sent / (float)dcc[i].u.xfer->length))); } } if (!cnt) dprintf(idx,"No files queued up.\n"); else dprintf(idx,"Total: %d\n",cnt); } void fileq_cancel(idx,par) int idx; char *par; { int fnd=1,matches=0,atot=0,i; fileq_t *q; char s[256]; while (fnd) { q=fileq; fnd=0; while (q!=NULL) { if (strcasecmp(dcc[idx].nick,q->nick)==0) { if (q->dir[0]=='*') sprintf(s,"%s/%s",&q->dir[1],q->file); else sprintf(s,"/%s%s%s",q->dir,q->dir[0]?"/":"",q->file); if (wild_match_file(par,s)) { dprintf(idx,"Cancelled: %s to %s\n",s,q->to); fnd=1; deq_this(q); q=NULL; matches++; } if ((!fnd) && (wild_match_file(par,q->file))) { dprintf(idx,"Cancelled: %s to %s\n",s,q->to); fnd=1; deq_this(q); q=NULL; matches++; } } if (q!=NULL) q=q->next; } } for (i=0; ifrom,dcc[idx].nick)==0))) { char *nfn=strrchr(dcc[i].u.xfer->filename,'/'); if (nfn==NULL) nfn=dcc[i].u.xfer->filename; else nfn++; if (wild_match_file(par,nfn)) { dprintf(idx,"Cancelled: %s (aborted dcc send)\n",nfn); if (strcasecmp(dcc[i].nick,dcc[idx].nick)!=0) mprintf(serv,"NOTICE %s :Transfer of %s aborted by %s\n",dcc[i].nick, nfn,dcc[idx].nick); if (dcc[i].type==DCC_GET) putlog(LOG_FILES,"*","DCC cancel: GET %s (%s) at %lu/%lu",nfn, dcc[i].nick,dcc[i].u.xfer->sent,dcc[i].u.xfer->length); wipe_tmp_file(i); atot++; matches++; killsock(dcc[i].sock); lostdcc(i); i--; } } } if (!matches) dprintf(idx,"No matches.\n"); else dprintf(idx,"Cancelled %d file%s.\n",matches,matches>1?"s":""); for (i=0; i