/* file subsystem */ #include #include #include #include #include #include "eggdrop.h" extern struct dcc_t dcc[]; extern char dccdir[]; extern char dccin[]; extern char botname[]; /* add a file to the catalog in '.files' */ /* dir is relative to dcc */ /* flag is one of these: */ #define NEWFILE 0 /* add file entry */ #define INCGOT 1 /* just increment got counter (ignore who,when) */ #define DELFILE 2 /* delete entry */ #define DESC 3 /* change desc (who), ignore when */ #define CHGFILE 4 /* change entry except got counter */ #define UPLOAD 5 /* add file entry as upload */ void add_file(dir,nfn,who,when,flag) char *dir,*nfn,*who; time_t when; int flag; { FILE *f,*g; char s[161],fn[41],oldfn[81],nick[21],tm[21]; sprintf(s,"%s%s/.files",dccdir,dir); oldfn[0]=0; if (flag==UPLOAD) sprintf(s,"%s.files",dccin); f=fopen(s,"r"); sprintf(s,"%s%s/.files.new",dccdir,dir); if (flag==UPLOAD) sprintf(s,"%s.files.new",dccin); g=fopen(s,"w"); if (g==NULL) { fclose(f); return; } if (f!=NULL) while (!feof(f)) { fgets(s,120,f); if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!feof(f)) { split(fn,s); if (!fn[0]) { strcpy(fn,s); s[0]=0; } rmspace(fn); if ((!fn[0]) || (fn[0]==';') || (fn[0]=='#')) { fprintf(g,"%s %s\n",fn,s); /* ignore */ } else if (fn[0]=='-') { if (((flag==DESC) || (flag==DELFILE)) && (strcmp(nfn,oldfn)==0)) ; /* erase it */ else fprintf(g,"- %s\n",s); } else { if (strcmp(fn,nfn)==0) { rmspace(s); split(nick,s); rmspace(nick); rmspace(s); split(tm,s); rmspace(tm); rmspace(s); if (flag==CHGFILE) fprintf(g,"%-20s %-10s%lu %s\n",fn,who,when,s); else if (flag==INCGOT) fprintf(g,"%-20s %-10s%s %d\n",fn,nick,tm,atoi(s)+1); else if (flag!=DELFILE) fprintf(g,"%-20s %-10s%s %s\n",fn,nick,tm,s); if ((flag==DESC) && (who[0])) fprintf(g,"- %s\n",who); } else { rmspace(s); fprintf(g,"%-20s %s\n",fn,s); } strcpy(oldfn,fn); } } } if (f!=NULL) fclose(f); if ((flag==NEWFILE) || (flag==UPLOAD)) fprintf(g,"%-20s %-10s%lu 0\n",nfn,who,when); fclose(g); sprintf(s,"%s%s/.files",dccdir,dir); if (flag==UPLOAD) sprintf(s,"%s.files",dccin); unlink(s); sprintf(s,"mv %s%s/.files.new %s%s/.files",dccdir,dir,dccdir,dir); if (flag==UPLOAD) sprintf(s,"mv %s.files.new %s.files",dccin,dccin); system(s); } /* show file listing in this dir */ void tell_files(z,dir) int z; char *dir; { FILE *f; char nick[10],fn[40],tm[40],s[121],s1[121]; struct stat ss; time_t t; int i,cnt=0; if (dir[strlen(dir)-1]!='/') strcat(dir,"/"); sprintf(s,"%s.files",dir); f=fopen(s,"r"); if (f==NULL) { tprintf(z,"No files in this directory.\n"); return; } while (!feof(f)) { fgets(s,120,f); if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!feof(f)) { split(fn,s); if (!fn[0]) { strcpy(fn,s); s[0]=0; } rmspace(fn); rmspace(s); if ((!fn[0]) || (fn[0]=='#') || (fn[0]==';')) /* comment */ ; else if (fn[0]=='-') { tprintf(z," %s\n",s); } else { if (cnt==0) { tprintf(z,"%-20s Size %-19s # Gets\n","Filename","Sent by/date"); tprintf(z,"-------------------- ---- ------------------- %s\n", "------"); } sprintf(s1,"%s%s",dir,fn); cnt++; if (s1[strlen(s1)-1]=='/') s1[strlen(s1)-1]=0; i=stat(s1,&ss); if (i<0) { /* missing! */ tprintf(z,"%-20s *** MISSING ***\n",fn); } else if (ss.st_mode&S_IFDIR) { /* directory */ tprintf(z,"%-20s \n",fn); } else { split(nick,s); rmspace(nick); rmspace(s); split(tm,s); rmspace(tm); rmspace(s); if (!tm[0]) { strcpy(tm,s); s[0]=0; } t=atol(tm); strcpy(tm,ctime(&t)); s1[0]=tm[8]; s1[1]=tm[9]; s1[2]=0; tm[7]=0; strcat(s1,&tm[4]); tm[24]=0; strcat(s1,&tm[22]); strcpy(tm,s1); i=ss.st_size; if (i<1024) sprintf(s1,"%5d",i); else sprintf(s1,"%4dk",(int)(i/1024)); tprintf(z,"%-20s %s %-9s (%s) %6d\n",fn,s1,nick,tm,atoi(s)); } } } } if (cnt==0) tprintf(z,"No files in this directory.\n"); else tprintf(z,"--- %d file%s.\n",cnt,cnt>1?"s":""); } void change_dir(z,idx,msg) int z,idx; char *msg; { char elem[81],olddir[121],s[121],*p; FILE *f; if (!msg[0]) { tprintf(z,"Uhh... What?\n"); return; } strcpy(olddir,dcc[idx].param); if (msg[0]=='/') { dcc[idx].param[0]=0; strcpy(msg,&msg[1]); } /* cycle thru the elements */ strcat(msg,"/"); p=strchr(msg,'/'); while (p!=NULL) { *p=0; p++; strcpy(elem,msg); strcpy(msg,p); if (strcmp(elem,".")==0) { /* do nothing */ } else if (strcmp(elem,"..")==0) { /* go back */ p=strrchr(dcc[idx].param,'/'); if (p==NULL) { if (!dcc[idx].param[0]) { tprintf(z,"No such dir.\n"); strcpy(dcc[idx].param,olddir); return; } dcc[idx].param[0]=0; } else *p=0; } else { strcpy(s,dcc[idx].param); if (s[0]) if (s[strlen(s)-1]!='/') strcat(s,"/"); sprintf(dcc[idx].param,"%s%s",s,elem); sprintf(s,"%s%s",dccdir,dcc[idx].param); f=fopen(s,"r"); if (f==NULL) { tprintf(z,"No such dir.\n"); strcpy(dcc[idx].param,olddir); return; } fclose(f); } p=strchr(msg,'/'); } tprintf(z,"Now in: /%s\n",dcc[idx].param); if (dcc[idx].status&STAT_TALK) tprintf(z,"/// PROMPT /%s\n",dcc[idx].param); } void relative_dir(s) char *s; { strcpy(s,&s[strlen(dccdir)]); } void uploaded(s,nick) char *s,*nick; { add_file("",s,nick,time(NULL),UPLOAD); } void welcome_to_files(idx,z) { tprintf(z,"\n"); tprintf(z,"File server: %s\n",botname); tprintf(z,"Type 'help' for help.\n"); get_handle_dccdir(dcc[idx].nick,dcc[idx].param); if (dcc[idx].status&STAT_TALK) { tprintf(z,"/// PROMPT /%s\n",dcc[idx].param); tprintf(z,"/// ECHO ON\n"); } } int got_files_cmd(idx,z,msg) int idx,z; char *msg; { char s[256],code[41]; int i; split(code,msg); if (code[0]==0) { strcpy(code,msg); msg[0]=0; } if (code[0]=='.') strcpy(code,&code[1]); if ((strcasecmp(code,"help")==0) || (strcmp(code,"?")==0)) { tprintf(z,"FILE TRANSFER COMMANDS\n"); tprintf(z," quit leave file transfer area\n"); tprintf(z," ls show list of files in this direcotry\n"); tprintf(z," pwd display present working directory\n"); tprintf(z," cd xxx... change current directory\n"); tprintf(z," get xxx receive 'xxx' from %s\n",botname); if (dcc[idx].status&STAT_MASTER) { tprintf(z,"--- Masters only:\n"); tprintf(z," desc xx yy change file description of xx to 'yy'\n"); tprintf(z," import xx add xx to list of available files\n"); tprintf(z," hide xx remove xx from file list\n"); tprintf(z," rm xx remove xx from file list and delete file\n"); tprintf(z," mkdir xx create subdirectory xx\n"); tprintf(z," rmdir xx remove subdirectory xx\n"); } tprintf(z,"--- End of help.\n"); } else if (strcasecmp(code,"quit")==0) return 1; else if (strcasecmp(code,"ls")==0) { sprintf(s,"%s%s",dccdir,dcc[idx].param); tell_files(z,s); } else if (strcasecmp(code,"pwd")==0) { tprintf(z,"Current directory: /%s\n",dcc[idx].param); } else if (strcasecmp(code,"cd")==0) { change_dir(z,idx,msg); } else if (strcasecmp(code,"get")==0) { if (do_dcc_send(idx,z,dcc[idx].param,msg)) add_file(dcc[idx].param,msg,"",0,INCGOT); } else if (dcc[idx].status&STAT_MASTER) { if (strcasecmp(code,"desc")==0) { char fn[41]; split(fn,msg); if (!fn[0]) { tprintf(z,"Usage: desc \n"); } else { add_file(dcc[idx].param,fn,msg,0,DESC); tprintf(z,"Okay.\n"); } } else if (strcasecmp(code,"import")==0) { add_file(dcc[idx].param,msg,dcc[idx].nick,time(NULL),NEWFILE); tprintf(z,"Okay.\n"); } else if (strcasecmp(code,"hide")==0) { add_file(dcc[idx].param,msg,"",0,DELFILE); tprintf(z,"Okay.\n"); } else if (strcasecmp(code,"rm")==0) { add_file(dcc[idx].param,msg,"",0,DELFILE); sprintf(s,"%s%s/%s",dccdir,dcc[idx].param,msg); unlink(s); tprintf(z,"Okay.\n"); } else if (strcasecmp(code,"mkdir")==0) { sprintf(s,"mkdir %s%s/%s",dccdir,dcc[idx].param,msg); system(s); tprintf(z,"Okay.\n"); sprintf(s,"%s/",msg); add_file(dcc[idx].param,s,"*",0,NEWFILE); } else if (strcasecmp(code,"rmdir")==0) { sprintf(s,"rmdir %s%s/%s",dccdir,dcc[idx].param,msg); system(s); tprintf(z,"Okay.\n"); sprintf(s,"%s/",msg); add_file(dcc[idx].param,s,"*",0,DELFILE); } else tprintf(z,"What? Try 'help'.\n"); } else { tprintf(z,"What? Try 'help'.\n"); } return 0; }