Newer
Older
sockprintf(sock,"226 No tranfer in progress.");
else {
lprintf(LOG_WARNING,"%04d %s aborting transfer"
,sock,user.alias);
YIELD(); /* give send thread time to abort */
sockprintf(sock,"226 Transfer aborted.");
}
continue;
}
if(!strnicmp(cmd,"SMNT ",5) && sysop && !(startup->options&FTP_OPT_NO_LOCAL_FSYS)) {
p=cmd+5;
SKIP_WHITESPACE(p);
if(!stricmp(p,BBS_FSYS_DIR))
local_fsys=FALSE;
else {
if(!direxist(p)) {
sockprintf(sock,"550 Directory does not exist.");
lprintf(LOG_WARNING,"%04d !%s attempted to mount invalid directory: %s"
,sock, user.alias, p);
continue;
}
local_fsys=TRUE;
}
sockprintf(sock,"250 %s file system mounted."
,local_fsys ? "Local" : "BBS");
lprintf(LOG_INFO,"%04d %s mounted %s file system"
,sock, user.alias, local_fsys ? "local" : "BBS");
continue;
}
/****************************/
/* Local File System Access */
/****************************/
if(sysop && local_fsys && !(startup->options&FTP_OPT_NO_LOCAL_FSYS)) {
if(local_dir[0]
&& local_dir[strlen(local_dir)-1]!='\\'
&& local_dir[strlen(local_dir)-1]!='/')
strcat(local_dir,"/");
if(!strnicmp(cmd, "LIST", 4) || !strnicmp(cmd, "NLST", 4)) {
if((fp=fopen(ftp_tmpfname(fname,sock),"w+b"))==NULL) {
lprintf(LOG_ERR,"%04d !ERROR %d opening %s",sock,errno,fname);
sockprintf(sock, "451 Insufficient system storage");
continue;
}
if(!strnicmp(cmd, "LIST", 4))
detail=TRUE;
else
detail=FALSE;
p=cmd+4;
SKIP_WHITESPACE(p);
if(*p=='-') { /* -Letc */
FIND_WHITESPACE(p);
SKIP_WHITESPACE(p);
filespec=p;
if(*filespec==0)
filespec="*";
SAFEPRINTF2(path,"%s%s",local_dir, filespec);
lprintf(LOG_INFO,"%04d %s listing: %s in %s mode", sock, user.alias, path, mode);
sockprintf(sock, "150 Directory of %s%s", local_dir, filespec);
now=time(NULL);
if(localtime_r(&now,&cur_tm)==NULL)
memset(&cur_tm,0,sizeof(cur_tm));

rswindell
committed
glob(path,0,NULL,&g);
for(i=0;i<(int)g.gl_pathc;i++) {

rswindell
committed
f.size=flength(g.gl_pathv[i]);
t=fdate(g.gl_pathv[i]);
if(localtime_r(&t,&tm)==NULL)
memset(&tm,0,sizeof(tm));
fprintf(fp,"%crw-r--r-- 1 %-8s local %9ld %s %2d "

rswindell
committed
,isdir(g.gl_pathv[i]) ? 'd':'-'
,ftp_mon[tm.tm_mon],tm.tm_mday);
if(tm.tm_year==cur_tm.tm_year)
fprintf(fp,"%02d:%02d %s\r\n"
,tm.tm_hour,tm.tm_min

rswindell
committed
,getfname(g.gl_pathv[i]));
else
fprintf(fp,"%5d %s\r\n"
,1900+tm.tm_year

rswindell
committed
,getfname(g.gl_pathv[i]));

rswindell
committed
fprintf(fp,"%s\r\n",getfname(g.gl_pathv[i]));

rswindell
committed
globfree(&g);
fclose(fp);
filexfer(&data_addr,sock,pasv_sock,&data_sock,fname,0L
,&transfer_inprogress,&transfer_aborted
,TRUE /* delfile */
,TRUE /* tmpfile */
,&lastactive,&user,-1,FALSE,FALSE,FALSE,NULL);
continue;
} /* Local LIST/NLST */
if(!strnicmp(cmd, "CWD ", 4) || !strnicmp(cmd,"XCWD ",5)) {
if(!strnicmp(cmd,"CWD ",4))
p=cmd+4;
else
p=cmd+5;
SKIP_WHITESPACE(p);
tp=p;
if(*tp=='/' || *tp=='\\') /* /local: and /bbs: are valid */
tp++;
if(!strnicmp(tp,BBS_FSYS_DIR,strlen(BBS_FSYS_DIR))) {
local_fsys=FALSE;
sockprintf(sock,"250 CWD command successful (BBS file system mounted).");
lprintf(LOG_INFO,"%04d %s mounted BBS file system", sock, user.alias);
continue;
}
if(!strnicmp(tp,LOCAL_FSYS_DIR,strlen(LOCAL_FSYS_DIR))) {
tp+=strlen(LOCAL_FSYS_DIR); /* already mounted */
p=tp;
}
if(p[1]==':' || !strncmp(p,"\\\\",2))
SAFEPRINTF2(path,"%s%s",root_dir(local_dir),p);
SAFEPRINTF2(fname,"%s%s",local_dir,p);
}
if(!direxist(path)) {
sockprintf(sock,"550 Directory does not exist (%s).",path);
lprintf(LOG_WARNING,"%04d !%s attempted to change to an invalid directory: %s"
,sock, user.alias, path);
} else {
sockprintf(sock,"250 CWD command successful (%s).", local_dir);
}
continue;
} /* Local CWD */
if(!stricmp(cmd,"CDUP") || !stricmp(cmd,"XCUP")) {
SAFEPRINTF(path,"%s..",local_dir);
if(FULLPATH(local_dir,path,sizeof(local_dir))==NULL)
sockprintf(sock,"550 Directory does not exist.");
else
sockprintf(sock,"200 CDUP command successful.");
continue;
}
if(!stricmp(cmd, "PWD") || !stricmp(cmd,"XPWD")) {
if(strlen(local_dir)>3)
local_dir[strlen(local_dir)-1]=0; /* truncate '/' */
sockprintf(sock,"257 \"%s\" is current directory."
,local_dir);
continue;
} /* Local PWD */
if(!strnicmp(cmd, "MKD ", 4) || !strnicmp(cmd,"XMKD",4)) {
p=cmd+4;
SKIP_WHITESPACE(p);
SAFEPRINTF2(fname,"%s%s",root_dir(local_dir),p+1);
SAFEPRINTF2(fname,"%s%s",local_dir,p);
sockprintf(sock,"257 \"%s\" directory created",fname);
lprintf(LOG_NOTICE,"%04d %s created directory: %s",sock,user.alias,fname);
} else {
sockprintf(sock,"521 Error %d creating directory: %s",i,fname);
lprintf(LOG_WARNING,"%04d !%s attempted to create directory: %s (Error %d)"
,sock,user.alias,fname,i);
}
continue;
}
if(!strnicmp(cmd, "RMD ", 4) || !strnicmp(cmd,"XRMD",4)) {
p=cmd+4;
SKIP_WHITESPACE(p);
SAFEPRINTF2(fname,"%s%s",root_dir(local_dir),p+1);
SAFEPRINTF2(fname,"%s%s",local_dir,p);
sockprintf(sock,"250 \"%s\" directory removed",fname);
lprintf(LOG_NOTICE,"%04d %s removed directory: %s",sock,user.alias,fname);
} else {
sockprintf(sock,"450 Error %d removing directory: %s",i,fname);
lprintf(LOG_WARNING,"%04d !%s attempted to remove directory: %s (Error %d)"
,sock,user.alias,fname,i);
}
continue;
}
if(!strnicmp(cmd, "RNFR ",5)) {
p=cmd+5;
SKIP_WHITESPACE(p);
SAFEPRINTF2(ren_from,"%s%s",root_dir(local_dir),p+1);
SAFEPRINTF2(ren_from,"%s%s",local_dir,p);
if(!fexist(ren_from)) {
sockprintf(sock,"550 File not found: %s",ren_from);
lprintf(LOG_WARNING,"%04d !%s attempted to rename %s (not found)"
,sock,user.alias,ren_from);
} else
sockprintf(sock,"350 File exists, ready for destination name");
continue;
}
if(!strnicmp(cmd, "RNTO ",5)) {
p=cmd+5;
SKIP_WHITESPACE(p);
SAFEPRINTF2(fname,"%s%s",root_dir(local_dir),p+1);
SAFEPRINTF2(fname,"%s%s",local_dir,p);
if((i=rename(ren_from, fname))==0) {
sockprintf(sock,"250 \"%s\" renamed to \"%s\"",ren_from,fname);
lprintf(LOG_NOTICE,"%04d %s renamed %s to %s",sock,user.alias,ren_from,fname);
} else {
sockprintf(sock,"450 Error %d renaming file: %s",i,ren_from);
lprintf(LOG_WARNING,"%04d !%s attempted to rename file: %s (Error %d)"
,sock,user.alias,ren_from,i);
}
continue;
}
if(!strnicmp(cmd, "RETR ", 5) || !strnicmp(cmd,"SIZE ",5)
|| !strnicmp(cmd, "MDTM ",5) || !strnicmp(cmd, "DELE ",5)) {
p=cmd+5;
SKIP_WHITESPACE(p);
if(!strnicmp(p,LOCAL_FSYS_DIR,strlen(LOCAL_FSYS_DIR)))
p+=strlen(LOCAL_FSYS_DIR); /* already mounted */
if(p[1]==':') /* drive specified */
else if(*p=='/') /* absolute, current drive */
SAFEPRINTF2(fname,"%s%s",root_dir(local_dir),p+1);
SAFEPRINTF2(fname,"%s%s",local_dir,p);
lprintf(LOG_WARNING,"%04d !%s file not found: %s",sock,user.alias,fname);
sockprintf(sock,"550 File not found: %s",fname);
continue;
}
if(!strnicmp(cmd,"SIZE ",5)) {
sockprintf(sock,"213 %lu",flength(fname));
continue;
}
if(!strnicmp(cmd,"MDTM ",5)) {
t=fdate(fname);
if(gmtime_r(&t,&tm)==NULL) /* specifically use GMT/UTC representation */
memset(&tm,0,sizeof(tm));
sockprintf(sock,"213 %u%02u%02u%02u%02u%02u"
,1900+tm.tm_year,tm.tm_mon+1,tm.tm_mday
,tm.tm_hour,tm.tm_min,tm.tm_sec);
continue;
}
if(!strnicmp(cmd,"DELE ",5)) {
if((i=remove(fname))==0) {
sockprintf(sock,"250 \"%s\" removed successfully.",fname);
lprintf(LOG_NOTICE,"%04d %s deleted file: %s",sock,user.alias,fname);
} else {
sockprintf(sock,"450 Error %d removing file: %s",i,fname);
lprintf(LOG_WARNING,"%04d !%s attempted to delete file: %s (Error %d)"
,sock,user.alias,fname,i);
}
continue;
}
/* RETR */
lprintf(LOG_INFO,"%04d %s downloading: %s (%lu bytes) in %s mode"
,sock,user.alias,fname,flength(fname)
,mode);
sockprintf(sock,"150 Opening BINARY mode data connection for file transfer.");
filexfer(&data_addr,sock,pasv_sock,&data_sock,fname,filepos
,&transfer_inprogress,&transfer_aborted,FALSE,FALSE
,&lastactive,&user,-1,FALSE,FALSE,FALSE,NULL);
continue;
} /* Local RETR/SIZE/MDTM */
if(!strnicmp(cmd, "STOR ", 5) || !strnicmp(cmd, "APPE ", 5)) {
p=cmd+5;
SKIP_WHITESPACE(p);
if(!strnicmp(p,LOCAL_FSYS_DIR,strlen(LOCAL_FSYS_DIR)))
p+=strlen(LOCAL_FSYS_DIR); /* already mounted */
if(p[1]==':') /* drive specified */
else if(*p=='/') /* absolute, current drive */
SAFEPRINTF2(fname,"%s%s",root_dir(local_dir),p+1);
SAFEPRINTF2(fname,"%s%s",local_dir,p);
lprintf(LOG_INFO,"%04d %s uploading: %s in %s mode", sock,user.alias,fname
,mode);
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
sockprintf(sock,"150 Opening BINARY mode data connection for file transfer.");
filexfer(&data_addr,sock,pasv_sock,&data_sock,fname,filepos
,&transfer_inprogress,&transfer_aborted,FALSE,FALSE
,&lastactive
,&user
,-1 /* dir */
,TRUE /* uploading */
,FALSE /* credits */
,!strnicmp(cmd,"APPE",4) ? TRUE : FALSE /* append */
,NULL /* desc */
);
filepos=0;
continue;
} /* Local STOR */
}
if(!strnicmp(cmd, "LIST", 4) || !strnicmp(cmd, "NLST", 4)) {
dir=curdir;
lib=curlib;
if(cmd[4]!=0)
lprintf(LOG_DEBUG,"%04d LIST/NLST: %s",sock,cmd);
/* path specified? */
p=cmd+4;
SKIP_WHITESPACE(p);
if(*p=='-') { /* -Letc */
FIND_WHITESPACE(p);
SKIP_WHITESPACE(p);
}
parsepath(&p,&user,&lib,&dir);
filespec=p;
if(*filespec==0)
filespec="*";
if((fp=fopen(ftp_tmpfname(fname,sock),"w+b"))==NULL) {
lprintf(LOG_ERR,"%04d !ERROR %d opening %s",sock,errno,fname);
sockprintf(sock, "451 Insufficient system storage");
continue;
}
if(!strnicmp(cmd, "LIST", 4))
detail=TRUE;
else
detail=FALSE;
sockprintf(sock,"150 Opening ASCII mode data connection for /bin/ls.");
now=time(NULL);
if(localtime_r(&now,&cur_tm)==NULL)
memset(&cur_tm,0,sizeof(cur_tm));
if(startup->options&FTP_OPT_INDEX_FILE && startup->index_file_name[0]
&& wildmatchi(startup->index_file_name, filespec, FALSE)) {
fprintf(fp,"-r--r--r-- 1 %-*s %-8s %9ld %s %2d %02d:%02d %s\r\n"
,NAME_LEN
,scfg.sys_id
,lib<0 ? scfg.sys_id : dir<0
? scfg.lib[lib]->sname : scfg.dir[dir]->code_suffix
,ftp_mon[cur_tm.tm_mon],cur_tm.tm_mday,cur_tm.tm_hour,cur_tm.tm_min
,startup->index_file_name);
else
fprintf(fp,"%s\r\n",startup->index_file_name);
}
/* HTML Index File */
if(startup->options&FTP_OPT_HTML_INDEX_FILE && startup->html_index_file[0]
&& wildmatchi(startup->html_index_file, filespec, FALSE)) {
fprintf(fp,"-r--r--r-- 1 %-*s %-8s %9ld %s %2d %02d:%02d %s\r\n"
,NAME_LEN
,scfg.sys_id
,lib<0 ? scfg.sys_id : dir<0
? scfg.lib[lib]->sname : scfg.dir[dir]->code_suffix
,ftp_mon[cur_tm.tm_mon],cur_tm.tm_mday,cur_tm.tm_hour,cur_tm.tm_min
,startup->html_index_file);
else
fprintf(fp,"%s\r\n",startup->html_index_file);
}
lprintf(LOG_INFO,"%04d %s listing: root in %s mode",sock,user.alias, mode);
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
if(startup->options&FTP_OPT_ALLOW_QWK) {
SAFEPRINTF(str,"%s.qwk",scfg.sys_id);
if(wildmatchi(str, filespec, FALSE)) {
if(detail) {
if(fexistcase(qwkfile)) {
t=fdate(qwkfile);
l=flength(qwkfile);
} else {
t=time(NULL);
l=10240;
};
if(localtime_r(&t,&tm)==NULL)
memset(&tm,0,sizeof(tm));
fprintf(fp,"-r--r--r-- 1 %-*s %-8s %9ld %s %2d %02d:%02d %s\r\n"
,NAME_LEN
,scfg.sys_id
,scfg.sys_id
,l
,ftp_mon[tm.tm_mon],tm.tm_mday,tm.tm_hour,tm.tm_min
,str);
} else
fprintf(fp,"%s\r\n",str);
}
}
/* File Aliases */

rswindell
committed
sprintf(aliasfile,"%sftpalias.cfg",scfg.ctrl_dir);
if((alias_fp=fopen(aliasfile,"r"))!=NULL) {
while(!feof(alias_fp)) {
if(!fgets(aliasline,sizeof(aliasline),alias_fp))
break;
alias_dir=FALSE;
p=aliasline; /* alias pointer */
SKIP_WHITESPACE(p);
if(*p==';') /* comment */
continue;
tp=p; /* terminator pointer */
FIND_WHITESPACE(tp);
if(*tp) *tp=0;
np=tp+1; /* filename pointer */
SKIP_WHITESPACE(np);
tp=np; /* terminator pointer */
FIND_WHITESPACE(tp);
dp=tp+1; /* description pointer */
SKIP_WHITESPACE(dp);
truncsp(dp);
if(stricmp(dp,BBS_HIDDEN_ALIAS)==0)
continue;
if(!wildmatchi(p, filespec, FALSE))
continue;
/* Virtual Path? */
if(!strnicmp(np,BBS_VIRTUAL_PATH,strlen(BBS_VIRTUAL_PATH))) {
if((dir=getdir(np+strlen(BBS_VIRTUAL_PATH),&user))<0) {
lprintf(LOG_WARNING,"0000 !Invalid virtual path (%s) for %s",np,user.alias);
continue; /* No access or invalid virtual path */
tp=strrchr(np,'/');
if(tp==NULL)
continue;
tp++;
if(*tp) {
SAFEPRINTF2(aliasfile,"%s%s",scfg.dir[dir]->path,tp);
np=aliasfile;
}
else
alias_dir=TRUE;
}
if(!alias_dir && !fexist(np)) {
lprintf(LOG_WARNING,"0000 !Missing aliased file (%s) for %s",np,user.alias);
if(detail) {
if(alias_dir==TRUE) {
fprintf(fp,"drwxrwxrwx 1 %-*s %-8s %9ld %s %2d %02d:%02d %s\r\n"
,NAME_LEN
,scfg.sys_id
,scfg.lib[scfg.dir[dir]->lib]->sname
,ftp_mon[cur_tm.tm_mon],cur_tm.tm_mday,cur_tm.tm_hour,cur_tm.tm_min
,p);
}
else {
t=fdate(np);
if(localtime_r(&t,&tm)==NULL)
fprintf(fp,"-r--r--r-- 1 %-*s %-8s %9ld %s %2d %02d:%02d %s\r\n"
,NAME_LEN
,scfg.sys_id
,scfg.sys_id
,flength(np)
,ftp_mon[tm.tm_mon],tm.tm_mday,tm.tm_hour,tm.tm_min
,p);
}
} else
fprintf(fp,"%s\r\n",p);
}
fclose(alias_fp);
}
/* Library folders */
for(i=0;i<scfg.total_libs;i++) {
if(!chk_ar(&scfg,scfg.lib[i]->ar,&user))
continue;
if(!wildmatchi(scfg.lib[i]->sname, filespec, FALSE))
continue;
fprintf(fp,"dr-xr-xr-x 1 %-*s %-8s %9ld %s %2d %02d:%02d %s\r\n"
,NAME_LEN
,scfg.sys_id
,scfg.sys_id
,ftp_mon[cur_tm.tm_mon],cur_tm.tm_mday,cur_tm.tm_hour,cur_tm.tm_min
,scfg.lib[i]->sname);
else
fprintf(fp,"%s\r\n",scfg.lib[i]->sname);
}
} else if(dir<0) {
lprintf(LOG_INFO,"%04d %s listing: %s library in %s mode"
,sock,user.alias,scfg.lib[lib]->sname,mode);
for(i=0;i<scfg.total_dirs;i++) {
if(scfg.dir[i]->lib!=lib)
continue;
if(i!=scfg.sysop_dir && i!=scfg.upload_dir
&& !chk_ar(&scfg,scfg.dir[i]->ar,&user))
continue;
if(!wildmatchi(scfg.dir[i]->code_suffix, filespec, FALSE))
continue;
fprintf(fp,"drwxrwxrwx 1 %-*s %-8s %9ld %s %2d %02d:%02d %s\r\n"
,NAME_LEN
,scfg.sys_id
,scfg.lib[lib]->sname
,ftp_mon[cur_tm.tm_mon],cur_tm.tm_mday,cur_tm.tm_hour,cur_tm.tm_min
,scfg.dir[i]->code_suffix);
fprintf(fp,"%s\r\n",scfg.dir[i]->code_suffix);
}
} else if(chk_ar(&scfg,scfg.dir[dir]->ar,&user)) {
lprintf(LOG_INFO,"%04d %s listing: %s/%s directory in %s mode"
,sock,user.alias,scfg.lib[lib]->sname,scfg.dir[dir]->code_suffix,mode);
SAFEPRINTF2(path,"%s%s",scfg.dir[dir]->path,filespec);

rswindell
committed
glob(path,0,NULL,&g);
for(i=0;i<(int)g.gl_pathc;i++) {
if(isdir(g.gl_pathv[i]))
continue;
#ifdef _WIN32
GetShortPathName(g.gl_pathv[i], str, sizeof(str));
#else
SAFECOPY(str,g.gl_pathv[i]);

rswindell
committed
#endif
padfname(getfname(str),f.name);

rswindell
committed
if((filedat=getfileixb(&scfg,&f))==FALSE
&& !(startup->options&FTP_OPT_DIR_FILES))
continue;
if(detail) {
f.size=flength(g.gl_pathv[i]);
getfiledat(&scfg,&f);
t=fdate(g.gl_pathv[i]);
if(localtime_r(&t,&tm)==NULL)

rswindell
committed
memset(&tm,0,sizeof(tm));
if(filedat) {
if(f.misc&FM_ANON)
else
dotname(f.uler,str);
} else
fprintf(fp,"-r--r--r-- 1 %-*s %-8s %9ld %s %2d "

rswindell
committed
,NAME_LEN
,scfg.dir[dir]->code_suffix

rswindell
committed
,f.size
,ftp_mon[tm.tm_mon],tm.tm_mday);

rswindell
committed
if(tm.tm_year==cur_tm.tm_year)
fprintf(fp,"%02d:%02d %s\r\n"
,tm.tm_hour,tm.tm_min
,getfname(g.gl_pathv[i]));
else
fprintf(fp,"%5d %s\r\n"
,1900+tm.tm_year
,getfname(g.gl_pathv[i]));
} else
fprintf(fp,"%s\r\n",getfname(g.gl_pathv[i]));

rswindell
committed
globfree(&g);
lprintf(LOG_INFO,"%04d %s listing: %s/%s directory in %s mode (empty - no access)"
,sock,user.alias,scfg.lib[lib]->sname,scfg.dir[dir]->code_suffix,mode);
fclose(fp);
filexfer(&data_addr,sock,pasv_sock,&data_sock,fname,0L
,&transfer_inprogress,&transfer_aborted
,TRUE /* delfile */
,TRUE /* tmpfile */
,&lastactive,&user,dir,FALSE,FALSE,FALSE,NULL);
continue;
}

rswindell
committed
if(!strnicmp(cmd, "RETR ", 5)
|| !strnicmp(cmd, "SIZE ",5)
|| !strnicmp(cmd, "MDTM ",5)
|| !strnicmp(cmd, "DELE ",5)) {
getdate=FALSE;
getsize=FALSE;

rswindell
committed
delecmd=FALSE;
file_date=0;
if(!strnicmp(cmd,"SIZE ",5))
getsize=TRUE;
else if(!strnicmp(cmd,"MDTM ",5))
getdate=TRUE;

rswindell
committed
else if(!strnicmp(cmd,"DELE ",5))
delecmd=TRUE;
if(!getsize && !getdate && user.rest&FLAG('D')) {
sockprintf(sock,"550 Insufficient access.");
filepos=0;
continue;
}
credits=TRUE;
success=FALSE;
delfile=FALSE;
tmpfile=FALSE;
lib=curlib;
dir=curdir;
p=cmd+5;
SKIP_WHITESPACE(p);
if(!strnicmp(p,BBS_FSYS_DIR,strlen(BBS_FSYS_DIR)))
p+=strlen(BBS_FSYS_DIR); /* already mounted */
if(*p=='/') {
lib=-1;
p++;
}
else if(!strncmp(p,"./",2))
p+=2;
if(lib<0 && ftpalias(p, fname, &user, &dir)==TRUE) {
success=TRUE;
credits=TRUE; /* include in d/l stats */
tmpfile=FALSE;
delfile=FALSE;
lprintf(LOG_INFO,"%04d %s %.4s by alias: %s"
if(dir>=0)
lib=scfg.dir[dir]->lib;
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
}
if(!success && lib<0 && (tp=strchr(p,'/'))!=NULL) {
dir=-1;
*tp=0;
for(i=0;i<scfg.total_libs;i++) {
if(!chk_ar(&scfg,scfg.lib[i]->ar,&user))
continue;
if(!stricmp(scfg.lib[i]->sname,p))
break;
}
if(i<scfg.total_libs)
lib=i;
p=tp+1;
}
if(!success && dir<0 && (tp=strchr(p,'/'))!=NULL) {
*tp=0;
for(i=0;i<scfg.total_dirs;i++) {
if(scfg.dir[i]->lib!=lib)
continue;
if(!chk_ar(&scfg,scfg.dir[i]->ar,&user))
continue;
if(!stricmp(scfg.dir[i]->code_suffix,p))
break;
}
if(i<scfg.total_dirs)
dir=i;
p=tp+1;
}
sprintf(html_index_ext,"%s?",startup->html_index_file);
sprintf(str,"%s.qwk",scfg.sys_id);
if(lib<0 && startup->options&FTP_OPT_ALLOW_QWK

rswindell
committed
&& !stricmp(p,str) && !delecmd) {
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
if(!fexistcase(qwkfile)) {
lprintf(LOG_INFO,"%04d %s creating QWK packet...",sock,user.alias);
sprintf(str,"%spack%04u.now",scfg.data_dir,user.number);
if(!ftouch(str))
lprintf(LOG_ERR,"%04d !ERROR creating semaphore file: %s"
,sock, str);
t=time(NULL);
while(fexist(str)) {
if(time(NULL)-t>startup->qwk_timeout)
break;
mswait(1000);
}
if(fexist(str)) {
lprintf(LOG_WARNING,"%04d !TIMEOUT waiting for QWK packet creation",sock);
sockprintf(sock,"451 Time-out waiting for packet creation.");
remove(str);
filepos=0;
continue;
}
if(!fexistcase(qwkfile)) {
lprintf(LOG_INFO,"%04d No QWK Packet created (no new messages)",sock);
sockprintf(sock,"550 No QWK packet created (no new messages)");
filepos=0;
continue;
}
success=TRUE;
delfile=TRUE;
credits=FALSE;
if(!getsize && !getdate)
lprintf(LOG_INFO,"%04d %s downloading QWK packet (%lu bytes) in %s mode"
,sock,user.alias,flength(fname)
,mode);
} else if(startup->options&FTP_OPT_INDEX_FILE

rswindell
committed
&& !stricmp(p,startup->index_file_name)
&& !delecmd) {
if(getsize) {
sockprintf(sock, "500 Size not available for dynamically generated files");
continue;
}
if((fp=fopen(ftp_tmpfname(fname,sock),"w+b"))==NULL) {
lprintf(LOG_ERR,"%04d !ERROR %d opening %s",sock,errno,fname);
sockprintf(sock, "451 Insufficient system storage");
filepos=0;
continue;
}
success=TRUE;
if(getdate)
file_date=time(NULL);
else {
lprintf(LOG_INFO,"%04d %s downloading index for %s in %s mode"
,sock,user.alias,genvpath(lib,dir,str)
,mode);
credits=FALSE;
tmpfile=TRUE;
delfile=TRUE;
fprintf(fp,"%-*s File/Folder Descriptions\r\n"
,INDEX_FNAME_LEN,startup->index_file_name);
if(startup->options&FTP_OPT_HTML_INDEX_FILE)
fprintf(fp,"%-*s File/Folder Descriptions (HTML)\r\n"
,INDEX_FNAME_LEN,startup->html_index_file);
if(lib<0) {
/* File Aliases */
sprintf(aliasfile,"%sftpalias.cfg",scfg.ctrl_dir);
if((alias_fp=fopen(aliasfile,"r"))!=NULL) {
while(!feof(alias_fp)) {
if(!fgets(aliasline,sizeof(aliasline),alias_fp))
break;
p=aliasline; /* alias pointer */
SKIP_WHITESPACE(p);
if(*p==';') /* comment */
continue;
tp=p; /* terminator pointer */
FIND_WHITESPACE(tp);
if(*tp) *tp=0;
np=tp+1; /* filename pointer */
SKIP_WHITESPACE(np);
np++; /* description pointer */
FIND_WHITESPACE(np);
while(*np && *np<' ') np++;
truncsp(np);
fprintf(fp,"%-*s %s\r\n",INDEX_FNAME_LEN,p,np);
}
fclose(alias_fp);
}
/* QWK Packet */
if(startup->options&FTP_OPT_ALLOW_QWK /* && fexist(qwkfile) */) {
sprintf(str,"%s.qwk",scfg.sys_id);
fprintf(fp,"%-*s QWK Message Packet\r\n"
,INDEX_FNAME_LEN,str);
}
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
/* Library Folders */
for(i=0;i<scfg.total_libs;i++) {
if(!chk_ar(&scfg,scfg.lib[i]->ar,&user))
continue;
fprintf(fp,"%-*s %s\r\n"
,INDEX_FNAME_LEN,scfg.lib[i]->sname,scfg.lib[i]->lname);
}
} else if(dir<0) {
for(i=0;i<scfg.total_dirs;i++) {
if(scfg.dir[i]->lib!=lib)
continue;
if(i!=scfg.sysop_dir && i!=scfg.upload_dir
&& !chk_ar(&scfg,scfg.dir[i]->ar,&user))
continue;
fprintf(fp,"%-*s %s\r\n"
,INDEX_FNAME_LEN,scfg.dir[i]->code_suffix,scfg.dir[i]->lname);
}
} else if(chk_ar(&scfg,scfg.dir[dir]->ar,&user)){
sprintf(cmd,"%s*",scfg.dir[dir]->path);
glob(cmd,0,NULL,&g);
for(i=0;i<(int)g.gl_pathc;i++) {
if(isdir(g.gl_pathv[i]))
continue;
#ifdef _WIN32
GetShortPathName(g.gl_pathv[i], str, sizeof(str));
#else
SAFECOPY(str,g.gl_pathv[i]);
#endif
padfname(getfname(str),f.name);
f.dir=dir;
if(getfileixb(&scfg,&f)) {
f.size=flength(g.gl_pathv[i]);
getfiledat(&scfg,&f);
fprintf(fp,"%-*s %s\r\n",INDEX_FNAME_LEN
,getfname(g.gl_pathv[i]),f.desc);
}
globfree(&g);
fclose(fp);
/* HTML Index File */
} else if(startup->options&FTP_OPT_HTML_INDEX_FILE
&& (!stricmp(p,startup->html_index_file)
|| !strnicmp(p,html_index_ext,strlen(html_index_ext)))
success=TRUE;
if(getsize) {
sockprintf(sock, "500 Size not available for dynamically generated files");
else if(getdate)
file_date=time(NULL);
else {
#ifdef JAVASCRIPT
if(startup->options&FTP_OPT_NO_JAVASCRIPT) {
lprintf(LOG_ERR,"%04d !JavaScript disabled, cannot generate %s",sock,fname);
sockprintf(sock, "451 JavaScript disabled");

rswindell
committed
filepos=0;
continue;
}
if(js_runtime == NULL) {
lprintf(LOG_DEBUG,"%04d JavaScript: Creating runtime: %lu bytes"
,sock,startup->js.max_bytes);
if((js_runtime = JS_NewRuntime(startup->js.max_bytes))==NULL) {
lprintf(LOG_ERR,"%04d !ERROR creating JavaScript runtime",sock);
sockprintf(sock,"451 Error creating JavaScript runtime");
filepos=0;
continue;
}
}
if(js_cx==NULL) { /* Context not yet created, create it now */
if(((js_cx=js_initcx(js_runtime, sock,&js_glob,&js_ftp))==NULL)) {
lprintf(LOG_ERR,"%04d !ERROR initializing JavaScript context",sock);
sockprintf(sock,"451 Error initializing JavaScript context");
filepos=0;
continue;
}
if(js_CreateUserClass(js_cx, js_glob, &scfg)==NULL)
lprintf(LOG_ERR,"%04d !JavaScript ERROR creating user class",sock);
if(js_CreateFileClass(js_cx, js_glob)==NULL)
lprintf(LOG_ERR,"%04d !JavaScript ERROR creating file class",sock);
if(js_CreateUserObject(js_cx, js_glob, &scfg, "user", user.number)==NULL)
lprintf(LOG_ERR,"%04d !JavaScript ERROR creating user object",sock);
if(js_CreateClientObject(js_cx, js_glob, "client", &client, sock)==NULL)
lprintf(LOG_ERR,"%04d !JavaScript ERROR creating client object",sock);
if(js_CreateFileAreaObject(js_cx, js_glob, &scfg, &user
,startup->html_index_file)==NULL)
lprintf(LOG_ERR,"%04d !JavaScript ERROR creating file area object",sock);
}
if((js_str=JS_NewStringCopyZ(js_cx, "name"))!=NULL) {
js_val=STRING_TO_JSVAL(js_str);
JS_SetProperty(js_cx, js_ftp, "sort", &js_val);
}
js_val=BOOLEAN_TO_JSVAL(FALSE);
JS_SetProperty(js_cx, js_ftp, "reverse", &js_val);
if(!strnicmp(p,html_index_ext,strlen(html_index_ext))) {
p+=strlen(html_index_ext);
tp=strrchr(p,'$');
if(tp!=NULL)
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
if(!strnicmp(p,"ext=",4)) {
p+=4;
if(!strcmp(p,"on"))
user.misc|=EXTDESC;
else
user.misc&=~EXTDESC;
if(!(user.rest&FLAG('G')))
putuserrec(&scfg,user.number,U_MISC,8,ultoa(user.misc,str,16));
}
else if(!strnicmp(p,"sort=",5)) {
p+=5;
tp=strchr(p,'&');
if(tp!=NULL) {
*tp=0;
tp++;
if(!stricmp(tp,"reverse")) {
js_val=BOOLEAN_TO_JSVAL(TRUE);
JS_SetProperty(js_cx, js_ftp, "reverse", &js_val);
}
}
if((js_str=JS_NewStringCopyZ(js_cx, p))!=NULL) {
js_val=STRING_TO_JSVAL(js_str);
JS_SetProperty(js_cx, js_ftp, "sort", &js_val);
js_val=BOOLEAN_TO_JSVAL(INT_TO_BOOL(user.misc&EXTDESC));
JS_SetProperty(js_cx, js_ftp, "extended_descriptions", &js_val);
if((fp=fopen(ftp_tmpfname(fname,sock),"w+b"))==NULL) {
lprintf(LOG_ERR,"%04d !ERROR %d opening %s",sock,errno,fname);
sockprintf(sock, "451 Insufficient system storage");
filepos=0;
continue;
}
lprintf(LOG_INFO,"%04d %s downloading HTML index for %s in %s mode"
,sock,user.alias,genvpath(lib,dir,str)
,mode);
credits=FALSE;
tmpfile=TRUE;
delfile=TRUE;
js_val=INT_TO_JSVAL(timeleft);
if(!JS_SetProperty(js_cx, js_ftp, "time_left", &js_val))
lprintf(LOG_ERR,"%04d !JavaScript ERROR setting user.time_left",sock);
js_generate_index(js_cx, js_ftp, sock, fp, lib, dir, &user);
fclose(fp);
}
} else if(dir>=0) {
if(!chk_ar(&scfg,scfg.dir[dir]->ar,&user)) {
lprintf(LOG_WARNING,"%04d !%s has insufficient access to /%s/%s"
,sock,user.alias
,scfg.lib[scfg.dir[dir]->lib]->sname
,scfg.dir[dir]->code_suffix);
sockprintf(sock,"550 Insufficient access.");
filepos=0;
continue;
}

rswindell
committed
if(!getsize && !getdate && !delecmd
&& !chk_ar(&scfg,scfg.dir[dir]->dl_ar,&user)) {
lprintf(LOG_WARNING,"%04d !%s has insufficient access to download from /%s/%s"
,sock,user.alias
,scfg.lib[scfg.dir[dir]->lib]->sname
,scfg.dir[dir]->code_suffix);
sockprintf(sock,"550 Insufficient access.");
filepos=0;
continue;
}

rswindell
committed
if(delecmd && !dir_op(&scfg,&user,dir)) {
lprintf(LOG_WARNING,"%04d !%s has insufficient access to delete files in /%s/%s"
,sock,user.alias
,scfg.lib[scfg.dir[dir]->lib]->sname
,scfg.dir[dir]->code_suffix);

rswindell
committed
sockprintf(sock,"550 Insufficient access.");
filepos=0;
continue;
}
SAFEPRINTF2(fname,"%s%s",scfg.dir[dir]->path,p);
GetShortPathName(fname, str, sizeof(str));