|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
* lftp - file transfer program
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* Copyright (c) 1996-2016 by Alexander V. Lukyanov (lav@yars.free.net)
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8f70b4 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8f70b4 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
8f70b4 |
* (at your option) any later version.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
8f70b4 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8f70b4 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8f70b4 |
* GNU General Public License for more details.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
8f70b4 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include <config.h>
|
|
Packit |
8f70b4 |
#include "FtpListInfo.h"
|
|
Packit |
8f70b4 |
#include "FileSet.h"
|
|
Packit |
8f70b4 |
#include <assert.h>
|
|
Packit |
8f70b4 |
#include <sys/types.h>
|
|
Packit |
8f70b4 |
#include <sys/stat.h>
|
|
Packit |
8f70b4 |
#include "xstring.h"
|
|
Packit |
8f70b4 |
#include <ctype.h>
|
|
Packit |
8f70b4 |
#include "misc.h"
|
|
Packit |
8f70b4 |
#include "ftpclass.h"
|
|
Packit |
8f70b4 |
#include "ascii_ctype.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#define number_of_parsers 7
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileSet *FtpListInfo::Parse(const char *buf,int len)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(mode==FA::LONG_LIST || mode==FA::MP_LIST)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(len==0 && mode==FA::LONG_LIST
|
|
Packit |
8f70b4 |
&& !ResMgr::QueryBool("ftp:list-empty-ok",session->GetHostName()))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
mode=FA::LIST;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
int err;
|
|
Packit |
8f70b4 |
FileSet *set=session->ParseLongList(buf,len,&err;;
|
|
Packit |
8f70b4 |
if(!set || err>0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(mode==FA::MP_LIST)
|
|
Packit |
8f70b4 |
mode=FA::LONG_LIST;
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
mode=FA::LIST;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return set;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
return ParseShortList(buf,len);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileSet *Ftp::ParseLongList(const char *buf,int len,int *err_ret) const
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(err_ret)
|
|
Packit |
8f70b4 |
*err_ret=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int err[number_of_parsers];
|
|
Packit |
8f70b4 |
FileSet *set[number_of_parsers];
|
|
Packit |
8f70b4 |
int i;
|
|
Packit |
8f70b4 |
for(i=0; i
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
err[i]=0;
|
|
Packit |
8f70b4 |
set[i]=new FileSet;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring line;
|
|
Packit |
8f70b4 |
xstring tmp_line;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FtpLineParser guessed_parser=0;
|
|
Packit |
8f70b4 |
FileSet **the_set=0;
|
|
Packit |
8f70b4 |
int *the_err=0;
|
|
Packit |
8f70b4 |
int *best_err1=&err[0];
|
|
Packit |
8f70b4 |
int *best_err2=&err[1];
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *tz=Query("timezone",hostname);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
for(;;)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *nl=(char*)memchr(buf,'\n',len);
|
|
Packit |
8f70b4 |
if(!nl)
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
line.nset(buf,nl-buf);
|
|
Packit |
8f70b4 |
line.chomp('\r');
|
|
Packit |
8f70b4 |
if(line.length()==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
len-=nl+1-buf;
|
|
Packit |
8f70b4 |
buf=nl+1;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
len-=nl+1-buf;
|
|
Packit |
8f70b4 |
buf=nl+1;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!guessed_parser)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
for(i=0; i
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
tmp_line.set(line); // parser can clobber the line - work on a copy
|
|
Packit |
8f70b4 |
FileInfo *info=(*line_parsers[i])(tmp_line.get_non_const(),&err[i],tz);
|
|
Packit |
8f70b4 |
if(info && info->name.length()>1)
|
|
Packit |
8f70b4 |
info->name.chomp('/');
|
|
Packit |
8f70b4 |
if(info && !strchr(info->name,'/'))
|
|
Packit |
8f70b4 |
set[i]->Add(info);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
delete info;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(*best_err1>err[i])
|
|
Packit |
8f70b4 |
best_err1=&err[i];
|
|
Packit |
8f70b4 |
if(*best_err2>err[i] && best_err1!=&err[i])
|
|
Packit |
8f70b4 |
best_err2=&err[i];
|
|
Packit |
8f70b4 |
if(*best_err1>16)
|
|
Packit |
8f70b4 |
goto leave; // too many errors with best parser.
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(*best_err2 > (*best_err1+1)*16)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
i=best_err1-err;
|
|
Packit |
8f70b4 |
guessed_parser=line_parsers[i];
|
|
Packit |
8f70b4 |
the_set=&set[i];
|
|
Packit |
8f70b4 |
the_err=&err[i];
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FileInfo *info=(*guessed_parser)(line.get_non_const(),the_err,tz);
|
|
Packit |
8f70b4 |
if(info && info->name.length()>1)
|
|
Packit |
8f70b4 |
info->name.chomp('/');
|
|
Packit |
8f70b4 |
if(info && !strchr(info->name,'/'))
|
|
Packit |
8f70b4 |
(*the_set)->Add(info);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
delete info;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!the_set)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
i=best_err1-err;
|
|
Packit |
8f70b4 |
the_set=&set[i];
|
|
Packit |
8f70b4 |
the_err=&err[i];
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
leave:
|
|
Packit |
8f70b4 |
for(i=0; i
|
|
Packit |
8f70b4 |
if(&set[i]!=the_set)
|
|
Packit |
8f70b4 |
delete set[i];
|
|
Packit |
8f70b4 |
if(err_ret && the_err)
|
|
Packit |
8f70b4 |
*err_ret=*the_err;
|
|
Packit |
8f70b4 |
return the_set?*the_set:0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileSet *FtpListInfo::ParseShortList(const char *buf,int len)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FileSet *set=new FileSet;
|
|
Packit |
8f70b4 |
char *line=0;
|
|
Packit |
8f70b4 |
int line_alloc=0;
|
|
Packit |
8f70b4 |
int line_len;
|
|
Packit |
8f70b4 |
for(;;)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// workaround for some ftp servers
|
|
Packit |
8f70b4 |
if(len>=2 && buf[0]=='.' && buf[1]=='/')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
buf+=2;
|
|
Packit |
8f70b4 |
len-=2;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
#if 0 // not possible here
|
|
Packit |
8f70b4 |
if(len>=2 && buf[0]=='/' && buf[1]=='/')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
buf++;
|
|
Packit |
8f70b4 |
len--;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *nl=(const char*)memchr(buf,'\n',len);
|
|
Packit |
8f70b4 |
if(!nl)
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
line_len=nl-buf;
|
|
Packit |
8f70b4 |
if(line_len>0 && buf[line_len-1]=='\r')
|
|
Packit |
8f70b4 |
line_len--;
|
|
Packit |
8f70b4 |
FileInfo::type type=FileInfo::UNKNOWN;
|
|
Packit |
8f70b4 |
const char *slash=(const char*)memchr(buf,'/',line_len);
|
|
Packit |
8f70b4 |
if(slash)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
type=FileInfo::DIRECTORY;
|
|
Packit |
8f70b4 |
line_len=slash-buf;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(line_len==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
len-=nl+1-buf;
|
|
Packit |
8f70b4 |
buf=nl+1;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(line_alloc
|
|
Packit |
8f70b4 |
line=string_alloca(line_alloc=line_len+128);
|
|
Packit |
8f70b4 |
memcpy(line,buf,line_len);
|
|
Packit |
8f70b4 |
line[line_len]=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
len-=nl+1-buf;
|
|
Packit |
8f70b4 |
buf=nl+1;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!strchr(line,'/'))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FileInfo *fi=new FileInfo(line);
|
|
Packit |
8f70b4 |
if(type!=fi->UNKNOWN)
|
|
Packit |
8f70b4 |
fi->SetType(type);
|
|
Packit |
8f70b4 |
set->Add(fi);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return set;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static
|
|
Packit |
8f70b4 |
FileInfo *ParseFtpLongList_UNIX(char *line,int *err,const char *tz)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int tmp;
|
|
Packit |
8f70b4 |
if(sscanf(line,"total %d",&tmp)==1)
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
if(!strncasecmp(line,"Status of ",10))
|
|
Packit |
8f70b4 |
return 0; // STAT output.
|
|
Packit |
8f70b4 |
if(strchr("bcpsD",line[0])) // block, char, pipe, socket, Door.
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileInfo *fi=FileInfo::parse_ls_line(line,tz);
|
|
Packit |
8f70b4 |
if(!fi)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
(*err)++;
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return fi;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#define FIRST_TOKEN strtok(line," \t")
|
|
Packit |
8f70b4 |
#define NEXT_TOKEN strtok(NULL," \t")
|
|
Packit |
8f70b4 |
#define ERR do{(*err)++;delete fi;return(0);}while(0)
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
07-13-98 09:06PM <DIR> aix
|
|
Packit |
8f70b4 |
07-13-98 09:06PM <DIR> hpux
|
|
Packit |
8f70b4 |
07-13-98 09:06PM <DIR> linux
|
|
Packit |
8f70b4 |
07-13-98 09:06PM <DIR> ncr
|
|
Packit |
8f70b4 |
07-13-98 09:06PM <DIR> solaris
|
|
Packit |
8f70b4 |
03-18-98 06:01AM 2109440 nlxb318e.tar
|
|
Packit |
8f70b4 |
07-02-98 11:17AM 13844 Whatsnew.txt
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
static
|
|
Packit |
8f70b4 |
FileInfo *ParseFtpLongList_NT(char *line,int *err,const char *tz)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
char *t = FIRST_TOKEN;
|
|
Packit |
8f70b4 |
FileInfo *fi=0;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
int month,day,year;
|
|
Packit |
8f70b4 |
if(sscanf(t,"%2d-%2d-%2d",&month,&day,&year)!=3)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
if(year>=70)
|
|
Packit |
8f70b4 |
year+=1900;
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
year+=2000;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
int hour,minute;
|
|
Packit |
8f70b4 |
char am='A'; // AM/PM is optional
|
|
Packit |
8f70b4 |
if(sscanf(t,"%2d:%2d%c",&hour,&minute,&am)<2)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(am=='P') // PM - after noon
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
hour+=12;
|
|
Packit |
8f70b4 |
if(hour==24)
|
|
Packit |
8f70b4 |
hour=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
struct tm tms;
|
|
Packit |
8f70b4 |
tms.tm_sec=30; /* seconds after the minute [0, 61] */
|
|
Packit |
8f70b4 |
tms.tm_min=minute; /* minutes after the hour [0, 59] */
|
|
Packit |
8f70b4 |
tms.tm_hour=hour; /* hour since midnight [0, 23] */
|
|
Packit |
8f70b4 |
tms.tm_mday=day; /* day of the month [1, 31] */
|
|
Packit |
8f70b4 |
tms.tm_mon=month-1; /* months since January [0, 11] */
|
|
Packit |
8f70b4 |
tms.tm_year=year-1900; /* years since 1900 */
|
|
Packit |
8f70b4 |
tms.tm_isdst=-1;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
fi=new FileInfo();
|
|
Packit |
8f70b4 |
fi->SetDate(mktime_from_tz(&tms,tz),30);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
long long size;
|
|
Packit |
8f70b4 |
if(!strcmp(t,"<DIR>"))
|
|
Packit |
8f70b4 |
fi->SetType(fi->DIRECTORY);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
fi->SetType(fi->NORMAL);
|
|
Packit |
8f70b4 |
if(sscanf(t,"%lld",&size)!=1)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
fi->SetSize(size);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t=strtok(NULL,"");
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
while(*t==' ')
|
|
Packit |
8f70b4 |
t++;
|
|
Packit |
8f70b4 |
if(*t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
fi->SetName(t);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return fi;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
ASUSER 8192 04/26/05 13:54:16 *DIR dir/
|
|
Packit |
8f70b4 |
ASUSER 8192 04/26/05 13:57:34 *DIR dir1/
|
|
Packit |
8f70b4 |
ASUSER 365255 02/28/01 15:41:40 *STMF readme.txt
|
|
Packit |
8f70b4 |
ASUSER 8489625 03/18/03 09:37:00 *STMF saved.zip
|
|
Packit |
8f70b4 |
ASUSER 365255 02/28/01 15:41:40 *STMF unist.old
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
static
|
|
Packit |
8f70b4 |
FileInfo *ParseFtpLongList_AS400(char *line,int *err,const char *tz)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
char *t = FIRST_TOKEN;
|
|
Packit |
8f70b4 |
FileInfo *fi=0;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
char *user=t;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
long long size;
|
|
Packit |
8f70b4 |
if(sscanf(t,"%lld",&size)!=1)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
int month,day,year;
|
|
Packit |
8f70b4 |
if(sscanf(t,"%2d/%2d/%2d",&month,&day,&year)!=3)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
if(year>=70)
|
|
Packit |
8f70b4 |
year+=1900;
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
year+=2000;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
int hour,minute,second;
|
|
Packit |
8f70b4 |
if(sscanf(t,"%2d:%2d:%2d",&hour,&minute,&second)!=3)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
struct tm tms;
|
|
Packit |
8f70b4 |
tms.tm_sec=second; /* seconds after the minute [0, 61] */
|
|
Packit |
8f70b4 |
tms.tm_min=minute; /* minutes after the hour [0, 59] */
|
|
Packit |
8f70b4 |
tms.tm_hour=hour; /* hour since midnight [0, 23] */
|
|
Packit |
8f70b4 |
tms.tm_mday=day; /* day of the month [1, 31] */
|
|
Packit |
8f70b4 |
tms.tm_mon=month-1; /* months since January [0, 11] */
|
|
Packit |
8f70b4 |
tms.tm_year=year-1900; /* years since 1900 */
|
|
Packit |
8f70b4 |
tms.tm_isdst=-1;
|
|
Packit |
8f70b4 |
time_t mtime=mktime_from_tz(&tms,tz);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
FileInfo::type type=FileInfo::UNKNOWN;
|
|
Packit |
8f70b4 |
if(!strcmp(t,"*DIR"))
|
|
Packit |
8f70b4 |
type=FileInfo::DIRECTORY;
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
type=FileInfo::NORMAL;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t=strtok(NULL,"");
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
while(*t==' ')
|
|
Packit |
8f70b4 |
t++;
|
|
Packit |
8f70b4 |
if(*t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
char *slash=strchr(t,'/');
|
|
Packit |
8f70b4 |
if(slash)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(slash==t)
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
*slash=0;
|
|
Packit |
8f70b4 |
type=FileInfo::DIRECTORY;
|
|
Packit |
8f70b4 |
if(slash[1])
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
fi=new FileInfo(t);
|
|
Packit |
8f70b4 |
fi->SetType(type);
|
|
Packit |
8f70b4 |
return fi;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
fi=new FileInfo(t);
|
|
Packit |
8f70b4 |
fi->SetType(type);
|
|
Packit |
8f70b4 |
fi->SetSize(size);
|
|
Packit |
8f70b4 |
fi->SetDate(mtime,0);
|
|
Packit |
8f70b4 |
fi->SetUser(user);
|
|
Packit |
8f70b4 |
return fi;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
+i774.71425,m951188401,/, users
|
|
Packit |
8f70b4 |
+i774.49602,m917883130,r,s79126, jgr_www2.exe
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
starts with +
|
|
Packit |
8f70b4 |
comma separated
|
|
Packit |
8f70b4 |
first character of field is type:
|
|
Packit |
8f70b4 |
i - ?
|
|
Packit |
8f70b4 |
m - modification time
|
|
Packit |
8f70b4 |
/ - means directory
|
|
Packit |
8f70b4 |
r - means plain file
|
|
Packit |
8f70b4 |
s - size
|
|
Packit |
8f70b4 |
up - permissions in octal
|
|
Packit |
8f70b4 |
\t - file name follows.
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
FileInfo *ParseFtpLongList_EPLF(char *line,int *err,const char *)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int len=strlen(line);
|
|
Packit |
8f70b4 |
const char *b=line;
|
|
Packit |
8f70b4 |
FileInfo *fi=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(len<2 || b[0]!='+')
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *name=0;
|
|
Packit |
8f70b4 |
int name_len=0;
|
|
Packit |
8f70b4 |
off_t size=NO_SIZE;
|
|
Packit |
8f70b4 |
time_t date=NO_DATE;
|
|
Packit |
8f70b4 |
long date_l;
|
|
Packit |
8f70b4 |
long long size_ll;
|
|
Packit |
8f70b4 |
bool dir=false;
|
|
Packit |
8f70b4 |
bool type_known=false;
|
|
Packit |
8f70b4 |
int perms=-1;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *scan=b+1;
|
|
Packit |
8f70b4 |
int scan_len=len-1;
|
|
Packit |
8f70b4 |
while(scan && scan_len>0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(*scan)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case '\t': // the rest is file name.
|
|
Packit |
8f70b4 |
name=scan+1;
|
|
Packit |
8f70b4 |
name_len=scan_len-1;
|
|
Packit |
8f70b4 |
scan=0;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 's':
|
|
Packit |
8f70b4 |
if(1 != sscanf(scan+1,"%lld",&size_ll))
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
size = size_ll;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'm':
|
|
Packit |
8f70b4 |
if(1 != sscanf(scan+1,"%ld",&date_l))
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
date = date_l;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case '/':
|
|
Packit |
8f70b4 |
dir=true;
|
|
Packit |
8f70b4 |
type_known=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'r':
|
|
Packit |
8f70b4 |
dir=false;
|
|
Packit |
8f70b4 |
type_known=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'i':
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case 'u':
|
|
Packit |
8f70b4 |
if(scan[1]=='p') // permissions.
|
|
Packit |
8f70b4 |
if(sscanf(scan+2,"%o",&perms)!=1)
|
|
Packit |
8f70b4 |
perms=-1;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
default:
|
|
Packit |
8f70b4 |
name=0;
|
|
Packit |
8f70b4 |
scan=0;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(scan==0 || scan_len==0)
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
const char *comma=find_char(scan,scan_len,',');
|
|
Packit |
8f70b4 |
if(comma)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
scan_len-=comma+1-scan;
|
|
Packit |
8f70b4 |
scan=comma+1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(name==0 || !type_known)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
fi=new FileInfo(xstring::get_tmp(name,name_len));
|
|
Packit |
8f70b4 |
if(size!=NO_SIZE)
|
|
Packit |
8f70b4 |
fi->SetSize(size);
|
|
Packit |
8f70b4 |
if(date!=NO_DATE)
|
|
Packit |
8f70b4 |
fi->SetDate(date,0);
|
|
Packit |
8f70b4 |
if(type_known)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(dir)
|
|
Packit |
8f70b4 |
fi->SetType(fi->DIRECTORY);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
fi->SetType(fi->NORMAL);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(perms!=-1)
|
|
Packit |
8f70b4 |
fi->SetMode(perms);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return fi;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
0 DIR 06-27-96 11:57 PROTOCOL
|
|
Packit |
8f70b4 |
169 11-29-94 09:20 SYSLEVEL.MPT
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
static
|
|
Packit |
8f70b4 |
FileInfo *ParseFtpLongList_OS2(char *line,int *err,const char *tz)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FileInfo *fi=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
char *t = FIRST_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
long long size;
|
|
Packit |
8f70b4 |
if(sscanf(t,"%lld",&size)!=1)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
fi=new FileInfo;
|
|
Packit |
8f70b4 |
fi->SetSize(size);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
fi->SetType(fi->NORMAL);
|
|
Packit |
8f70b4 |
if(!strcmp(t,"DIR"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
fi->SetType(fi->DIRECTORY);
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
int month,day,year;
|
|
Packit |
8f70b4 |
if(sscanf(t,"%2d-%2d-%2d",&month,&day,&year)!=3)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
if(year>=70)
|
|
Packit |
8f70b4 |
year+=1900;
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
year+=2000;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
int hour,minute;
|
|
Packit |
8f70b4 |
if(sscanf(t,"%2d:%2d",&hour,&minute)!=3)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
struct tm tms;
|
|
Packit |
8f70b4 |
tms.tm_sec=30; /* seconds after the minute [0, 61] */
|
|
Packit |
8f70b4 |
tms.tm_min=minute; /* minutes after the hour [0, 59] */
|
|
Packit |
8f70b4 |
tms.tm_hour=hour; /* hour since midnight [0, 23] */
|
|
Packit |
8f70b4 |
tms.tm_mday=day; /* day of the month [1, 31] */
|
|
Packit |
8f70b4 |
tms.tm_mon=month-1; /* months since January [0, 11] */
|
|
Packit |
8f70b4 |
tms.tm_year=year-1900; /* years since 1900 */
|
|
Packit |
8f70b4 |
tms.tm_isdst=-1;
|
|
Packit |
8f70b4 |
fi->SetDate(mktime_from_tz(&tms,tz),30);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
t=strtok(NULL,"");
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
while(*t==' ')
|
|
Packit |
8f70b4 |
t++;
|
|
Packit |
8f70b4 |
if(*t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
fi->SetName(t);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return fi;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static
|
|
Packit |
8f70b4 |
FileInfo *ParseFtpLongList_MacWebStar(char *line,int *err,const char *tz)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FileInfo *fi=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
char *t = FIRST_TOKEN;
|
|
Packit |
8f70b4 |
if(t==0)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
fi=new FileInfo;
|
|
Packit |
8f70b4 |
switch(t[0])
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('l'): // symlink
|
|
Packit |
8f70b4 |
fi->SetType(fi->SYMLINK);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('d'): // directory
|
|
Packit |
8f70b4 |
fi->SetType(fi->DIRECTORY);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('-'): // plain file
|
|
Packit |
8f70b4 |
fi->SetType(fi->NORMAL);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('b'): // block
|
|
Packit |
8f70b4 |
case('c'): // char
|
|
Packit |
8f70b4 |
case('p'): // pipe
|
|
Packit |
8f70b4 |
case('s'): // sock
|
|
Packit |
8f70b4 |
return 0; // ignore
|
|
Packit |
8f70b4 |
default:
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
mode_t mode=parse_perms(t+1);
|
|
Packit |
8f70b4 |
if(mode==(mode_t)-1)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
// permissions are meaningless here.
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// "folder" or 0
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(!t)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(strcmp(t,"folder"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// size?
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(!t)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
// size
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(!t)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
if(isdigit((unsigned char)*t))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
long long size;
|
|
Packit |
8f70b4 |
if(sscanf(t,"%lld",&size)==1)
|
|
Packit |
8f70b4 |
fi->SetSize(size);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// ??
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(!t)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// month
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(!t)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
struct tm date;
|
|
Packit |
8f70b4 |
memset(&date,0,sizeof(date));
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
date.tm_mon=parse_month(t);
|
|
Packit |
8f70b4 |
if(date.tm_mon==-1)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *day_of_month = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(!day_of_month)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
date.tm_mday=atoi(day_of_month);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// time or year
|
|
Packit |
8f70b4 |
t = NEXT_TOKEN;
|
|
Packit |
8f70b4 |
if(!t)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
if(parse_year_or_time(t,&date.tm_year,&date.tm_hour,&date.tm_min)==-1)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
date.tm_isdst=-1;
|
|
Packit |
8f70b4 |
date.tm_sec=30;
|
|
Packit |
8f70b4 |
int prec=30;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(date.tm_year==-1)
|
|
Packit |
8f70b4 |
date.tm_year=guess_year(date.tm_mon,date.tm_mday,date.tm_hour,date.tm_min) - 1900;
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
date.tm_hour=12;
|
|
Packit |
8f70b4 |
prec=12*60*60;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
fi->SetDate(mktime_from_tz(&date,tz),prec);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
char *name=strtok(NULL,"");
|
|
Packit |
8f70b4 |
if(!name)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// no symlinks on Mac, but anyway.
|
|
Packit |
8f70b4 |
if(fi->filetype==fi->SYMLINK)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
char *arrow=name;
|
|
Packit |
8f70b4 |
while((arrow=strstr(arrow," -> "))!=0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(arrow!=name && arrow[4]!=0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
*arrow=0;
|
|
Packit |
8f70b4 |
fi->SetSymlink(arrow+4);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
arrow++;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
fi->SetName(name);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return fi;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
Type=cdir;Modify=20021029173810;Perm=el;Unique=BP8AAjJufAA; /
|
|
Packit |
8f70b4 |
Type=pdir;Modify=20021029173810;Perm=el;Unique=BP8AAjJufAA; ..
|
|
Packit |
8f70b4 |
Type=dir;Modify=20010118144705;Perm=e;Unique=BP8AAjNufAA; bin
|
|
Packit |
8f70b4 |
Type=dir;Modify=19981021003019;Perm=el;Unique=BP8AAlhufAA; pub
|
|
Packit |
8f70b4 |
Type=file;Size=12303;Modify=19970124132601;Perm=r;Unique=BP8AAo9ufAA; mailserv.FAQ
|
|
Packit |
8f70b4 |
modify=20161215062118;perm=flcdmpe;type=dir;UNIX.group=503;UNIX.mode=0700; directory-name
|
|
Packit |
8f70b4 |
modify=20161213121618;perm=adfrw;size=6369064;type=file;UNIX.group=503;UNIX.mode=0644; file-name
|
|
Packit |
8f70b4 |
modify=20120103123744;perm=adfrw;size=11;type=OS.unix=symlink;UNIX.group=0;UNIX.mode=0777; www
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
FileInfo *ParseFtpLongList_MLSD(char *line,int *err,const char *)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FileInfo *fi=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *name=0;
|
|
Packit |
8f70b4 |
off_t size=NO_SIZE;
|
|
Packit |
8f70b4 |
time_t date=NO_DATE;
|
|
Packit |
8f70b4 |
const char *owner=0;
|
|
Packit |
8f70b4 |
const char *group=0;
|
|
Packit |
8f70b4 |
FileInfo::type type=FileInfo::UNKNOWN;
|
|
Packit |
8f70b4 |
int perms=-1;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
char *space=strstr(line,"; ");
|
|
Packit |
8f70b4 |
if(space) {
|
|
Packit |
8f70b4 |
name=space+2;
|
|
Packit |
8f70b4 |
*space=0;
|
|
Packit |
8f70b4 |
} else {
|
|
Packit |
8f70b4 |
/* NcFTPd does not put a semicolon after last fact, workaround it. */
|
|
Packit |
8f70b4 |
space=strchr(line,' ');
|
|
Packit |
8f70b4 |
if(!space)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
name=space+1;
|
|
Packit |
8f70b4 |
*space=0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
for(char *tok=strtok(line,";"); tok; tok=strtok(0,";"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!strcasecmp(tok,"Type=cdir")
|
|
Packit |
8f70b4 |
|| !strcasecmp(tok,"Type=pdir")
|
|
Packit |
8f70b4 |
|| !strcasecmp(tok,"Type=dir"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
type=FileInfo::DIRECTORY;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strcasecmp(tok,"Type=file"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
type=FileInfo::NORMAL;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strcasecmp(tok,"Type=OS.unix=symlink"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
type=FileInfo::SYMLINK;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strncasecmp(tok,"Modify=",7))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
date=Ftp::ConvertFtpDate(tok+7);
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strncasecmp(tok,"Size=",5))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
long long size_ll;
|
|
Packit |
8f70b4 |
if(sscanf(tok+5,"%lld",&size_ll)==1)
|
|
Packit |
8f70b4 |
size=size_ll;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strncasecmp(tok,"Perm=",5))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
perms=0;
|
|
Packit |
8f70b4 |
for(tok+=5; *tok; tok++)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(to_ascii_lower(*tok))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case 'e': perms|=0111; break;
|
|
Packit |
8f70b4 |
case 'l': perms|=0444; break;
|
|
Packit |
8f70b4 |
case 'r': perms|=0444; break;
|
|
Packit |
8f70b4 |
case 'c': perms|=0200; break;
|
|
Packit |
8f70b4 |
case 'w': perms|=0200; break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strncasecmp(tok,"UNIX.mode=",10))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(sscanf(tok+10,"%o",&perms)!=1)
|
|
Packit |
8f70b4 |
perms=-1;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strncasecmp(tok,"UNIX.owner=",11))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
owner=tok+11;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strncasecmp(tok,"UNIX.group=",11))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
group=tok+11;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strncasecmp(tok,"UNIX.uid=",9))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!owner)
|
|
Packit |
8f70b4 |
owner=tok+9;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!strncasecmp(tok,"UNIX.gid=",9))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!group)
|
|
Packit |
8f70b4 |
group=tok+9;
|
|
Packit |
8f70b4 |
continue;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(name==0 || !*name || type==FileInfo::UNKNOWN)
|
|
Packit |
8f70b4 |
ERR;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
fi=new FileInfo(name);
|
|
Packit |
8f70b4 |
if(size!=NO_SIZE)
|
|
Packit |
8f70b4 |
fi->SetSize(size);
|
|
Packit |
8f70b4 |
if(date!=NO_DATE)
|
|
Packit |
8f70b4 |
fi->SetDate(date,0);
|
|
Packit |
8f70b4 |
fi->SetType(type);
|
|
Packit |
8f70b4 |
if(perms!=-1)
|
|
Packit |
8f70b4 |
fi->SetMode(perms);
|
|
Packit |
8f70b4 |
if(owner)
|
|
Packit |
8f70b4 |
fi->SetUser(owner);
|
|
Packit |
8f70b4 |
if(group)
|
|
Packit |
8f70b4 |
fi->SetGroup(group);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return fi;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Ftp::FtpLineParser Ftp::line_parsers[number_of_parsers]={
|
|
Packit |
8f70b4 |
ParseFtpLongList_UNIX,
|
|
Packit |
8f70b4 |
ParseFtpLongList_NT,
|
|
Packit |
8f70b4 |
ParseFtpLongList_EPLF,
|
|
Packit |
8f70b4 |
ParseFtpLongList_MLSD,
|
|
Packit |
8f70b4 |
ParseFtpLongList_AS400,
|
|
Packit |
8f70b4 |
ParseFtpLongList_OS2,
|
|
Packit |
8f70b4 |
ParseFtpLongList_MacWebStar,
|
|
Packit |
8f70b4 |
};
|