#include "ftpparse.h"
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include <stdint.h>
#define MATH_INT64_NATIVE_IF_AVAILABLE
#include "perl_math_int64.h"
MODULE = File::Listing::Ftpcopy PACKAGE = File::Listing::Ftpcopy
BOOT:
PERL_MATH_INT64_LOAD_OR_CROAK;
SV *
ftpparse(line)
char *line;
INIT:
HV * result;
struct ftpparse fp;
int val;
CODE:
val = ftpparse(&fp, line, strlen(line), 0);
if(val)
{
result = newHV();
hv_store(result, "name", 4, newSVpv(fp.name,fp.namelen), 0);
hv_store(result, "flagtrycwd", 10, newSViv(fp.flagtrycwd), 0);
hv_store(result, "flagtryretr", 11, newSViv(fp.flagtryretr), 0);
hv_store(result, "sizetype", 8, newSViv(fp.sizetype), 0);
/*
* If UV is 64 bit then store size as a UV,
* otherwise use sprintf and store it as a string.
* use PRIu64 which is c99, otherwise try %llu
* and cross fingers that it is supported.
*/
hv_store(result, "size", 4, newSVu64(fp.size), 0);
hv_store(result, "mtimetype", 9, newSViv(fp.mtimetype), 0);
/*
* okay this is slightly silly, the TAI implementation
* with ftpparse is converting from UNIX time to TAI but
* it isn't consulting any leap second tables or anything
* like that so it is sort of pointless. Since most Perl
* programmers are likely to be dealing with the UNIX time
* scale we will just quietly convert it back to UNIX time
* (at least in so far as it was converted to TAI in the
* first place).
*/
hv_store(result, "mtime", 5, newSVu64(fp.mtime.x-4611686018427387914ULL), 0);
hv_store(result, "idtype", 6, newSViv(fp.idtype), 0);
hv_store(result, "id", 2, newSVpv(fp.id, fp.idlen), 0);
hv_store(result, "format", 6, newSViv(fp.format), 0);
hv_store(result, "flagbrokenmlsx", 14, newSViv(fp.flagbrokenmlsx), 0);
if(fp.symlink != NULL)
{
hv_store(result, "symlink", 7, newSVpv(fp.symlink, fp.symlinklen), 0);
}
RETVAL = newRV_noinc((SV*)result);
}
else
{
XSRETURN_EMPTY;
}
OUTPUT:
RETVAL
SV *
_parse_dir(line)
char * line
INIT:
struct ftpparse fp;
int val;
AV * result;
char *type;
SV * size;
SV * mtime;
CODE:
val = ftpparse(&fp, line, strlen(line), 0);
if(val && !(fp.namelen == 1 && fp.name[0] == '.') && !(fp.namelen == 2 && fp.name[0] == '.' && fp.name[1] == '.'))
{
result = newAV();
av_push(result, newSVpv(fp.name,fp.namelen));
if(fp.symlink != NULL)
type = "l";
else if(fp.flagtrycwd && !fp.flagtryretr)
type = "d";
else if(!fp.flagtrycwd && fp.flagtryretr)
type = "f";
else
type = "?";
av_push(result, newSVpv(type, 1));
if(fp.sizetype == FTPPARSE_SIZE_UNKNOWN)
{
size = newSV(0);
}
else
{
size = newSVu64(fp.size);
}
av_push(result, size);
if(fp.mtimetype == FTPPARSE_MTIME_UNKNOWN)
{
mtime = newSV(0);
}
else
{
mtime = newSVu64(fp.mtime.x-4611686018427387914ULL);
}
av_push(result, mtime);
av_push(result, newSV(0));
av_push(result, newSViv(fp.mtimetype));
RETVAL = newRV_noinc((SV*)result);
}
else
{
XSRETURN_EMPTY;
}
OUTPUT:
RETVAL
int
_return42()
CODE:
RETVAL = (10*4+2);
OUTPUT:
RETVAL
int
_size_of_UV()
CODE:
RETVAL = sizeof(UV);
OUTPUT:
RETVAL
int
_constant(name)
char *name
CODE:
if(!strcmp(name, "FORMAT_EPLF"))
RETVAL = FTPPARSE_FORMAT_EPLF;
else if(!strcmp(name, "FORMAT_LS"))
RETVAL = FTPPARSE_FORMAT_LS;
else if(!strcmp(name, "FORMAT_MLSX"))
RETVAL = FTPPARSE_FORMAT_MLSX;
else if(!strcmp(name, "FORMAT_UNKNOWN"))
RETVAL = FTPPARSE_FORMAT_UNKNOWN;
else if(!strcmp(name, "ID_FULL"))
RETVAL = FTPPARSE_ID_FULL;
else if(!strcmp(name, "ID_UNKNOWN"))
RETVAL = FTPPARSE_ID_UNKNOWN;
else if(!strcmp(name, "MTIME_LOCAL"))
RETVAL = FTPPARSE_MTIME_LOCAL;
else if(!strcmp(name, "MTIME_REMOTEDAY"))
RETVAL = FTPPARSE_MTIME_REMOTEDAY;
else if(!strcmp(name, "MTIME_REMOTEMINUTE"))
RETVAL = FTPPARSE_MTIME_REMOTEMINUTE;
else if(!strcmp(name, "MTIME_REMOTESECOND"))
RETVAL = FTPPARSE_MTIME_REMOTESECOND;
else if(!strcmp(name, "MTIME_UNKNOWN"))
RETVAL = FTPPARSE_MTIME_UNKNOWN;
else if(!strcmp(name, "SIZE_ASCII"))
RETVAL = FTPPARSE_SIZE_ASCII;
else if(!strcmp(name, "SIZE_BINARY"))
RETVAL = FTPPARSE_SIZE_BINARY;
else if(!strcmp(name, "SIZE_UNKNOWN"))
RETVAL = FTPPARSE_SIZE_UNKNOWN;
else
RETVAL = -1;
OUTPUT:
RETVAL
SV *
_tai_now()
INIT:
SV *result;
struct tai to;
char b[21];
CODE:
tai_now(&to);
#ifdef PRIu64
sprintf(b, "%"PRIu64,to.x);
#else
sprintf(b, "%llu",to.x);
#endif
result = newSVpv(b,0);
RETVAL = newRV_noinc(result);
OUTPUT:
RETVAL