ClamAV-Clamd
view release on metacpan or search on metacpan
memset(sc, 0, sizeof *sc);
sc->sock = CC_INVALID_SOCK;
if (strEQ(kind, "path")) {
const char *path = SvPV_nolen(what);
fd = open(path, O_RDONLY);
if (fd < 0) {
cc_err_set(&sc->err, CC_ERR_IO, "open", strerror(errno));
sc->rc = CC_ERR_IO; sc->phase = CC_PH_DONE;
goto made;
}
mode = (CC_HAVE_FD_PASSING && t.path) ? CC_TRANSPORT_FILDES : CC_TRANSPORT_INSTREAM;
if (mode == CC_TRANSPORT_FILDES)
rc = cc_scan_start(sc, &t, mode, fd, 1, NULL, 0, -1);
else
rc = cc_scan_start(sc, &t, mode, -1, 1, NULL, 0, fd);
(void)rc;
}
else if (strEQ(kind, "fd")) {
fd = cc_fileno(aTHX_ what);
if (fd < 0) {
cc_err_set(&sc->err, CC_ERR_CONFIG,
"start_scan needs an open filehandle or descriptor", NULL);
sc->rc = CC_ERR_CONFIG; sc->phase = CC_PH_DONE;
goto made;
}
keep = what;
mode = (CC_HAVE_FD_PASSING && t.path) ? CC_TRANSPORT_FILDES : CC_TRANSPORT_INSTREAM;
if (mode == CC_TRANSPORT_FILDES)
rc = cc_scan_start(sc, &t, mode, fd, 0, NULL, 0, -1);
else
rc = cc_scan_start(sc, &t, mode, -1, 0, NULL, 0, fd);
(void)rc;
}
else {
if (!SvOK(what)) {
cc_err_set(&sc->err, CC_ERR_CONFIG, "start_scan needs bytes", NULL);
sc->rc = CC_ERR_CONFIG; sc->phase = CC_PH_DONE;
goto made;
}
if (DO_UTF8(what) && !sv_utf8_downgrade(what, 1)) {
cc_err_set(&sc->err, CC_ERR_CONFIG,
"start_scan needs bytes, not wide characters", NULL);
sc->rc = CC_ERR_CONFIG; sc->phase = CC_PH_DONE;
goto made;
}
dp = SvPV_const(what, dlen);
keep = what;
if (t.max_size && (size_t)dlen > t.max_size) {
cc_err_set(&sc->err, CC_ERR_TOOBIGLOC,
"larger than max_size; refused without scanning", NULL);
sc->rc = CC_ERR_TOOBIGLOC; sc->phase = CC_PH_DONE;
goto made;
}
(void)cc_scan_start(sc, &t, CC_TRANSPORT_INSTREAM, -1, 0, dp, (size_t)dlen, -1);
}
made:
h = newHV();
(void)hv_stores(h, "_ptr", newSViv(PTR2IV(sc)));
/* Hold the source alive for as long as the scan can read it. */
if (keep) (void)hv_stores(h, "_keep", newSVsv(keep));
RETVAL = sv_bless(newRV_noinc((SV *)h),
gv_stashpvs("ClamAV::Clamd::Scan", GV_ADD));
OUTPUT:
RETVAL
MODULE = ClamAV::Clamd PACKAGE = ClamAV::Clamd::Scan PREFIX = ccs_
PROTOTYPES: DISABLE
# The socket to register with a loop. Undef once finished - there is
# nothing left to watch, and watching a closed descriptor is how a loop
# ends up dispatching on somebody else's connection.
void
ccs_fd(self)
SV *self
PREINIT:
cc_scan *sc;
PPCODE:
sc = cc_scan_of(aTHX_ self);
if (!sc || sc->sock == CC_INVALID_SOCK) XSRETURN_UNDEF;
XPUSHs(sv_2mortal(newSViv(sc->sock)));
# 'read', 'write', or undef when finished.
void
ccs_want(self)
SV *self
PREINIT:
cc_scan *sc;
PPCODE:
sc = cc_scan_of(aTHX_ self);
if (!sc || sc->phase == CC_PH_DONE) XSRETURN_UNDEF;
if (sc->want == CC_WANT_READ) XPUSHs(sv_2mortal(newSVpvs("read")));
else if (sc->want == CC_WANT_WRITE) XPUSHs(sv_2mortal(newSVpvs("write")));
else XSRETURN_UNDEF;
# Advance as far as possible without blocking. True when finished.
void
ccs_step(self)
SV *self
PREINIT:
cc_scan *sc;
PPCODE:
sc = cc_scan_of(aTHX_ self);
if (!sc) XSRETURN_YES;
if (cc_scan_step(sc) == CC_STEP_DONE) XSRETURN_YES;
XSRETURN_NO;
void
ccs_is_done(self)
SV *self
PREINIT:
cc_scan *sc;
PPCODE:
sc = cc_scan_of(aTHX_ self);
if (!sc || sc->phase == CC_PH_DONE) XSRETURN_YES;
XSRETURN_NO;
# The verdict, once finished. Undef while the scan is still running -
# asking early is a question with no answer, not a clean one.
( run in 1.361 second using v1.01-cache-2.11-cpan-14f38c9f855 )