static int scanstdin(const struct cl_engine *engine, const struct optstruct *opts, int options) { int ret; unsigned int fsize = 0; const char *virname, *tmpdir; char *file, buff[FILEBUFF]; size_t bread; FILE *fs; struct clamscan_cb_data data; if(optget(opts, "tempdir")->enabled) { tmpdir = optget(opts, "tempdir")->strarg; } else { /* check write access */ tmpdir = cli_gettmpdir(); } if(checkaccess(tmpdir, CLAMAVUSER, W_OK) != 1) { logg("!Can't write to temporary directory\n"); return 2; } if(!(file = cli_gentemp(tmpdir))) { logg("!Can't generate tempfile name\n"); return 2; } if(!(fs = fopen(file, "wb"))) { logg("!Can't open %s for writing\n", file); free(file); return 2; } while((bread = fread(buff, 1, FILEBUFF, stdin))) { fsize += bread; if(fwrite(buff, 1, bread, fs) < bread) { logg("!Can't write to %s\n", file); free(file); fclose(fs); return 2; } } fclose(fs); logg("*Checking %s\n", file); info.files++; info.rblocks += fsize / CL_COUNT_PRECISION; data.filename = "stdin"; data.chain = NULL; if((ret = cl_scanfile_callback(file, &virname, &info.blocks, engine, options, &data)) == CL_VIRUS) { info.ifiles++; if(bell) fprintf(stderr, "\007"); } else if(ret == CL_CLEAN) { if(!printinfected) mprintf("stdin: OK\n"); } else { if(!printinfected) logg("stdin: %s ERROR\n", cl_strerror(ret)); info.errors++; } unlink(file); free(file); return ret; }
static int sigtool_scandir (const char *dirname, int hex_output) { DIR *dd; struct dirent *dent; STATBUF statbuf; char *fname; const char *tmpdir; char *dir; int ret = CL_CLEAN, desc; cli_ctx *ctx; fname = NULL; if ((dd = opendir (dirname)) != NULL) { while ((dent = readdir (dd))) { if (dent->d_ino) { if (strcmp (dent->d_name, ".") && strcmp (dent->d_name, "..")) { /* build the full name */ fname = (char *) cli_calloc (strlen (dirname) + strlen (dent->d_name) + 2, sizeof (char)); if(!fname){ closedir(dd); return -1; } sprintf (fname, "%s"PATHSEP"%s", dirname, dent->d_name); /* stat the file */ if (LSTAT (fname, &statbuf) != -1) { if (S_ISDIR (statbuf.st_mode) && !S_ISLNK (statbuf.st_mode)) { if (sigtool_scandir (fname, hex_output)) { free (fname); closedir (dd); return CL_VIRUS; } } else { if (S_ISREG (statbuf.st_mode)) { struct uniq *vba = NULL; tmpdir = cli_gettmpdir(); /* generate the temporary directory */ dir = cli_gentemp (tmpdir); if(!dir) { printf("cli_gentemp() failed\n"); free(fname); closedir (dd); return -1; } if (mkdir (dir, 0700)) { printf ("Can't create temporary directory %s\n", dir); free(fname); closedir (dd); free(dir); return CL_ETMPDIR; } if ((desc = open (fname, O_RDONLY|O_BINARY)) == -1) { printf ("Can't open file %s\n", fname); free(fname); closedir (dd); free(dir); return 1; } if(!(ctx = convenience_ctx(desc))) { free(fname); close(desc); closedir(dd); free(dir); return 1; } if ((ret = cli_ole2_extract (dir, ctx, &vba))) { printf ("ERROR %s\n", cl_strerror (ret)); destroy_ctx(desc, ctx); cli_rmdirs (dir); free (dir); closedir (dd); free(fname); return ret; } if(vba) sigtool_vba_scandir (dir, hex_output, vba); destroy_ctx(desc, ctx); cli_rmdirs (dir); free (dir); } } } free (fname); } } } } else { logg("!Can't open directory %s.\n", dirname); return CL_EOPEN; } closedir (dd); return 0; }