ClamAV-Clamd

 view release on metacpan or  search on metacpan

Clamd.xs  view on Meta::CPAN

    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 )