#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "perlmulticore.h"
#include "uulib/fptools.h"
#include "uulib/uudeview.h"
#include "uulib/uuint.h"
static int perlinterp_released;
#define RELEASE do { perlinterp_released = 1; perlinterp_release (); } while (0)
#define ACQUIRE do { perlinterp_acquire (); perlinterp_released = 0; } while (0)
#define TEMP_ACQUIRE if (perlinterp_released) perlinterp_acquire ();
#define TEMP_RELEASE if (perlinterp_released) perlinterp_release ();
static void
uu_msg_callback (void *cb, char *msg, int level)
{
TEMP_ACQUIRE {
dSP;
ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 2);
PUSHs (sv_2mortal (newSVpv (msg, 0)));
PUSHs (sv_2mortal (newSViv (level)));
PUTBACK; (void) perl_call_sv ((SV *)cb, G_VOID|G_DISCARD); SPAGAIN;
PUTBACK; FREETMPS; LEAVE;
} TEMP_RELEASE;
}
static int
uu_busy_callback (void *cb, uuprogress *uup)
{
int retval;
TEMP_ACQUIRE {
dSP;
int count;
ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 6);
PUSHs (sv_2mortal (newSViv (uup->action)));
PUSHs (sv_2mortal (newSVpv (uup->curfile, 0)));
PUSHs (sv_2mortal (newSViv (uup->partno)));
PUSHs (sv_2mortal (newSViv (uup->numparts)));
PUSHs (sv_2mortal (newSViv (uup->fsize)));
PUSHs (sv_2mortal (newSViv (uup->percent)));
PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
if (count != 1)
croak ("busycallback perl callback returned more than one argument");
retval = POPi;
PUTBACK; FREETMPS; LEAVE;
} TEMP_RELEASE;
return retval;
}
static char *
uu_fnamefilter_callback (void *cb, char *fname)
{
static char *str;
TEMP_ACQUIRE {
dSP;
int count;
ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 1);
PUSHs (sv_2mortal (newSVpv (fname, 0)));
PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
if (count != 1)
croak ("fnamefilter perl callback MUST return a single filename exactly");
FP_free (str); str = FP_strdup (SvPV_nolen (TOPs));
PUTBACK; FREETMPS; LEAVE;
} TEMP_RELEASE;
return str;
}
static int
uu_file_callback (void *cb, char *id, char *fname, int retrieve)
{
int retval;
TEMP_ACQUIRE {
dSP;
int count;
SV *xfname = newSVpv ("", 0);
ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 3);
PUSHs (sv_2mortal (newSVpv (id, 0)));
PUSHs (sv_2mortal (xfname));
PUSHs (sv_2mortal (newSViv (retrieve)));
PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
if (count != 1)
croak ("filecallback perl callback must return a single return status");
strcpy (fname, SvPV_nolen (xfname));
retval = POPi;
PUTBACK; FREETMPS; LEAVE;
} TEMP_RELEASE;
return retval;
}
static char *
uu_filename_callback (void *cb, char *subject, char *filename)
{
TEMP_ACQUIRE {
dSP;
int count;
ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 2);
PUSHs (sv_2mortal(newSVpv(subject, 0)));
PUSHs (filename ? sv_2mortal(newSVpv(filename, 0)) : &PL_sv_undef);
PUTBACK; count = perl_call_sv ((SV *)cb, G_ARRAY); SPAGAIN;
if (count > 1)
croak ("filenamecallback perl callback must return nothing or a single filename");
if (count)
{
FP_free (filename);
filename = SvOK (TOPs)
? FP_strdup (SvPV_nolen (TOPs))
: 0;
}
PUTBACK; FREETMPS; LEAVE;
} TEMP_RELEASE;
return filename;
}
static SV *uu_msg_sv, *uu_busy_sv, *uu_file_sv, *uu_fnamefilter_sv, *uu_filename_sv;
#define FUNC_CB(cb) (void *)(sv_setsv (cb ## _sv, func), cb ## _sv), func ? cb ## _callback : NULL
static int
uu_info_file (void *cb, char *info)
{
int retval;
TEMP_ACQUIRE {
dSP;
int count;
ENTER; SAVETMPS; PUSHMARK(SP); EXTEND(SP,1);
PUSHs(sv_2mortal(newSVpv(info,0)));
PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
if (count != 1)
croak ("info_file perl callback returned more than one argument");
retval = POPi;
PUTBACK; FREETMPS; LEAVE;
} TEMP_RELEASE;
return retval;
}
static int
uu_opt_isstring (int opt)
{
switch (opt)
{
case UUOPT_VERSION:
case UUOPT_SAVEPATH:
case UUOPT_ENCEXT:
return 1;
default:
return 0;
}
}
static void
initialise (void)
{
int retval = UUInitialize ();
if (retval != UURET_OK)
croak ("unable to initialize uudeview library (%s)", UUstrerror (retval));
}
MODULE = Convert::UUlib PACKAGE = Convert::UUlib PREFIX = UU
PROTOTYPES: ENABLE
void
UUCleanUp ()
CODE:
UUCleanUp ();
initialise ();
SV *
UUGetOption (opt)
int opt
CODE:
{
if (opt == UUOPT_PROGRESS)
croak ("GetOption(UUOPT_PROGRESS) is not yet implemented");
else if (uu_opt_isstring (opt))
{
char cval[8192];
UUGetOption (opt, 0, cval, sizeof cval);
RETVAL = newSVpv (cval, 0);
}
else
{
RETVAL = newSViv (UUGetOption (opt, 0, 0, 0));
}
}
OUTPUT:
RETVAL
int
UUSetOption (opt, val)
int opt
SV * val
CODE:
{
STRLEN dc;
if (uu_opt_isstring (opt))
RETVAL = UUSetOption (opt, 0, SvPV (val, dc));
else
RETVAL = UUSetOption (opt, SvIV (val), (void *)0);
}
OUTPUT:
RETVAL
char *
UUstrerror (errcode)
int errcode
void
UUSetMsgCallback (func = 0)
SV * func
CODE:
UUSetMsgCallback (FUNC_CB (uu_msg));
void
UUSetBusyCallback (func = 0,msecs = 1000)
SV * func
long msecs
CODE:
UUSetBusyCallback (FUNC_CB (uu_busy), msecs);
void
UUSetFileCallback (func = 0)
SV * func
CODE:
UUSetFileCallback (FUNC_CB (uu_file));
void
UUSetFNameFilter (func = 0)
SV * func
CODE:
UUSetFNameFilter (FUNC_CB (uu_fnamefilter));
void
UUSetFileNameCallback (func = 0)
SV * func
CODE:
UUSetFileNameCallback (FUNC_CB (uu_filename));
char *
UUFNameFilter (fname)
char * fname
void
UULoadFile (fname, id = 0, delflag = 0, partno = -1)
char * fname
char * id
int delflag
int partno
PPCODE:
{
int count;
IV ret;
RELEASE;
ret = UULoadFileWithPartNo (fname, id, delflag, partno, &count);
ACQUIRE;
XPUSHs (sv_2mortal (newSViv (ret)));
if (GIMME_V == G_ARRAY)
XPUSHs (sv_2mortal (newSViv (count)));
}
int
UUSmerge (pass)
int pass
int
UUQuickDecode(datain,dataout,boundary,maxpos)
FILE * datain
FILE * dataout
char * boundary
long maxpos
int
UUEncodeMulti(outfile,infile,infname,encoding,outfname,mimetype,filemode)
FILE * outfile
FILE * infile
char * infname
int encoding
char * outfname
char * mimetype
int filemode
int
UUEncodePartial(outfile,infile,infname,encoding,outfname,mimetype,filemode,partno,linperfile)
FILE * outfile
FILE * infile
char * infname
int encoding
char * outfname
char * mimetype
int filemode
int partno
long linperfile
int
UUEncodeToStream(outfile,infile,infname,encoding,outfname,filemode)
FILE * outfile
FILE * infile
char * infname
int encoding
char * outfname
int filemode
int
UUEncodeToFile(infile,infname,encoding,outfname,diskname,linperfile)
FILE * infile
char * infname
int encoding
char * outfname
char * diskname
long linperfile
int
UUE_PrepSingle(outfile,infile,infname,encoding,outfname,filemode,destination,from,subject,isemail)
FILE * outfile
FILE * infile
char * infname
int encoding
char * outfname
int filemode
char * destination
char * from
char * subject
int isemail
int
UUE_PrepPartial(outfile,infile,infname,encoding,outfname,filemode,partno,linperfile,filesize,destination,from,subject,isemail)
FILE * outfile
FILE * infile
char * infname
int encoding
char * outfname
int filemode
int partno
long linperfile
long filesize
char * destination
char * from
char * subject
int isemail
uulist *
UUGetFileListItem (num)
int num
void
GetFileList ()
PPCODE:
{
uulist *iter;
for (iter = UUGlobalFileList; iter; iter = iter->NEXT)
XPUSHs (sv_setref_pv (sv_newmortal (), "Convert::UUlib::Item", iter));
}
MODULE = Convert::UUlib PACKAGE = Convert::UUlib::Item
int
rename (item, newname)
uulist *item
char * newname
CODE:
RETVAL = UURenameFile (item, newname);
OUTPUT:
RETVAL
int
decode_temp (item)
uulist *item
CODE:
RELEASE;
RETVAL = UUDecodeToTemp (item);
ACQUIRE;
OUTPUT:
RETVAL
int
remove_temp (item)
uulist *item
CODE:
RELEASE;
RETVAL = UURemoveTemp (item);
ACQUIRE;
OUTPUT:
RETVAL
int
decode (item, target = 0)
uulist *item
char * target
CODE:
RELEASE;
RETVAL = UUDecodeFile (item, target);
ACQUIRE;
OUTPUT:
RETVAL
void
info (item, func)
uulist *item
SV * func
CODE:
RELEASE;
UUInfoFile (item, (void *)func, uu_info_file);
ACQUIRE;
short
state(li)
uulist *li
CODE:
RETVAL = li->state;
OUTPUT:
RETVAL
short
mode(li,newmode=0)
uulist *li
short newmode
CODE:
if (newmode)
li->mode = newmode;
RETVAL = li->mode;
OUTPUT:
RETVAL
short
uudet(li)
uulist *li
CODE:
RETVAL = li->uudet;
OUTPUT:
RETVAL
long
size(li)
uulist *li
CODE:
RETVAL = li->size;
OUTPUT:
RETVAL
char *
filename (li, newfilename = 0)
uulist *li
char * newfilename
CODE:
if (newfilename)
{
FP_free (li->filename);
li->filename = FP_strdup (newfilename);
}
RETVAL = li->filename;
OUTPUT:
RETVAL
char *
subfname (li)
uulist *li
CODE:
RETVAL = li->subfname;
OUTPUT:
RETVAL
char *
mimeid (li)
uulist *li
CODE:
RETVAL = li->mimeid;
OUTPUT:
RETVAL
char *
mimetype (li)
uulist *li
CODE:
RETVAL = li->mimetype;
OUTPUT:
RETVAL
char *
binfile (li)
uulist *li
CODE:
RETVAL = li->binfile;
OUTPUT:
RETVAL
# methods accessing internal data(!)
void
parts (li)
uulist *li
PPCODE:
{
struct _uufile *p = li->thisfile;
while (p)
{
HV *pi = newHV ();
hv_store (pi, "partno" , 6, newSViv (p->partno) , 0);
if (p->filename ) hv_store (pi, "filename", 8, newSVpv (p->filename, 0) , 0);
if (p->subfname ) hv_store (pi, "subfname", 8, newSVpv (p->subfname, 0) , 0);
if (p->mimeid ) hv_store (pi, "mimeid" , 6, newSVpv (p->mimeid , 0) , 0);
if (p->mimetype ) hv_store (pi, "mimetype", 8, newSVpv (p->mimetype, 0) , 0);
if (p->data->subject) hv_store (pi, "subject" , 7, newSVpv (p->data->subject,0), 0);
if (p->data->origin ) hv_store (pi, "origin" , 6, newSVpv (p->data->origin ,0), 0);
if (p->data->sfname ) hv_store (pi, "sfname" , 6, newSVpv (p->data->sfname ,0), 0);
XPUSHs (sv_2mortal (newRV_noinc ((SV *)pi)));
p = p->NEXT;
}
}
BOOT:
{
HV *stash = GvSTASH (CvGV (cv));
static const struct {
const char *name;
IV iv;
} *civ, const_iv[] = {
# define const_iv(name, value) { # name, (IV) value },
const_iv (ACT_COPYING , UUACT_COPYING)
const_iv (ACT_DECODING , UUACT_DECODING)
const_iv (ACT_ENCODING , UUACT_ENCODING)
const_iv (ACT_IDLE , UUACT_IDLE)
const_iv (ACT_SCANNING , UUACT_SCANNING)
const_iv (FILE_DECODED , UUFILE_DECODED)
const_iv (FILE_ERROR , UUFILE_ERROR)
const_iv (FILE_MISPART , UUFILE_MISPART)
const_iv (FILE_NOBEGIN , UUFILE_NOBEGIN)
const_iv (FILE_NODATA , UUFILE_NODATA)
const_iv (FILE_NOEND , UUFILE_NOEND)
const_iv (FILE_OK , UUFILE_OK)
const_iv (FILE_READ , UUFILE_READ)
const_iv (FILE_TMPFILE , UUFILE_TMPFILE)
const_iv (MSG_ERROR , UUMSG_ERROR)
const_iv (MSG_FATAL , UUMSG_FATAL)
const_iv (MSG_MESSAGE , UUMSG_MESSAGE)
const_iv (MSG_NOTE , UUMSG_NOTE)
const_iv (MSG_PANIC , UUMSG_PANIC)
const_iv (MSG_WARNING , UUMSG_WARNING)
const_iv (OPT_VERSION , UUOPT_VERSION)
const_iv (OPT_FAST , UUOPT_FAST)
const_iv (OPT_DUMBNESS , UUOPT_DUMBNESS)
const_iv (OPT_BRACKPOL , UUOPT_BRACKPOL)
const_iv (OPT_VERBOSE , UUOPT_VERBOSE)
const_iv (OPT_DESPERATE, UUOPT_DESPERATE)
const_iv (OPT_IGNREPLY , UUOPT_IGNREPLY)
const_iv (OPT_OVERWRITE, UUOPT_OVERWRITE)
const_iv (OPT_SAVEPATH , UUOPT_SAVEPATH)
const_iv (OPT_IGNMODE , UUOPT_IGNMODE)
const_iv (OPT_DEBUG , UUOPT_DEBUG)
const_iv (OPT_ERRNO , UUOPT_ERRNO)
const_iv (OPT_PROGRESS , UUOPT_PROGRESS)
const_iv (OPT_USETEXT , UUOPT_USETEXT)
const_iv (OPT_PREAMB , UUOPT_PREAMB)
const_iv (OPT_TINYB64 , UUOPT_TINYB64)
const_iv (OPT_ENCEXT , UUOPT_ENCEXT)
const_iv (OPT_REMOVE , UUOPT_REMOVE)
const_iv (OPT_MOREMIME , UUOPT_MOREMIME)
const_iv (OPT_DOTDOT , UUOPT_DOTDOT)
const_iv (OPT_RBUF , UUOPT_RBUF)
const_iv (OPT_WBUF , UUOPT_WBUF)
const_iv (OPT_AUTOCHECK, UUOPT_AUTOCHECK)
const_iv (RET_CANCEL , UURET_CANCEL)
const_iv (RET_CONT , UURET_CONT)
const_iv (RET_EXISTS , UURET_EXISTS)
const_iv (RET_ILLVAL , UURET_ILLVAL)
const_iv (RET_IOERR , UURET_IOERR)
const_iv (RET_NODATA , UURET_NODATA)
const_iv (RET_NOEND , UURET_NOEND)
const_iv (RET_NOMEM , UURET_NOMEM)
const_iv (RET_OK , UURET_OK)
const_iv (RET_UNSUP , UURET_UNSUP)
const_iv (B64_ENCODED , B64ENCODED)
const_iv (BH_ENCODED , BH_ENCODED)
const_iv (PT_ENCODED , PT_ENCODED)
const_iv (QP_ENCODED , QP_ENCODED)
const_iv (UU_ENCODED , UU_ENCODED)
const_iv (XX_ENCODED , XX_ENCODED)
const_iv (YENC_ENCODED , YENC_ENCODED)
};
for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
uu_msg_sv = newSVsv (&PL_sv_undef);
uu_busy_sv = newSVsv (&PL_sv_undef);
uu_file_sv = newSVsv (&PL_sv_undef);
uu_fnamefilter_sv = newSVsv (&PL_sv_undef);
uu_filename_sv = newSVsv (&PL_sv_undef);
initialise ();
}