home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HomeWare 14
/
HOMEWARE14.bin
/
archive
/
au116_4s.arj
/
SCAN.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-17
|
10KB
|
367 lines
// ASCAN.CPP 1 1 6666
// Dave Harris 11 11 6
// Compiled using Borland C++ ver 3.1 1 1 1 1 6666
// 03-03-94 1 .. 1 6 6
// 11111 .. 11111 666
////////////////////////////////////////////////////////////////////////
#include "au.hpp"
#define PROGRAM "SCAN" // Name of module
/*********************************************************************/
typedef struct
{
char rename_virus[FILE_SIZE]; // What to rename it to
char archives; // do inside arcs period
int newer_than;
long random_num;
int scan_version;
char recurse;
} SCAN_INFO;
static int scan_process(AU *, char *, char *, char *, ARC_FILE *);
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int is_newer(AU *au, char *file_name)
{
HANDLE file;
struct ftime ftime_hold;
long value;
SCAN_INFO *in = (SCAN_INFO *)au->info;
file = au_open(au, file_name);
getftime(file, &ftime_hold);
close(file);
if (in->scan_version == 0 || in->newer_than == 0)
return TRUE;
value = (long)ftime_hold.ft_hour*60*30+ftime_hold.ft_min*30+
ftime_hold.ft_tsec;
value -= in->scan_version + in->random_num;
if (value < 0)
value = -value;
if (value < in->newer_than)
return FALSE;
else
return TRUE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
int scan_one_file(AU *au, char *file_name)
{
char string2[CLENGTH];
sprintf(string2, "%s %s", au->scanner, file_name);
return execute(au, string2, au->output, NULL, au->scannerMemNeeded);
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int recurse(AU *au, char *path)
{
struct ffblk ffblk; // directory entry structure
LISTPTR file_list;
LIST *el;
int retCode = FALSE;
char holdCurDir[FLENGTH];
char curDir[FLENGTH];
char destDir[FLENGTH];
ARC_FILE arcFile;
cd(au, path, holdCurDir);
getcwd(curDir, FLENGTH);
build_fname(destDir, curDir, TEMP_DIR);
mkdir(TEMP_DIR);
memset(&file_list, '\0', sizeof(LISTPTR));
if (!findfirst("*.*", &ffblk, 0))
{
do
{
add_to_list(au, &file_list, ffblk.ff_name);
} while (!findnext(&ffblk));
}
for (el = file_list.head; el != NULL; el = el->next)
{
arc_file_init(au, &arcFile, el->data);
arc_file_deinit(au, &arcFile);
if (arcFile.type > 0)
{
if (scan_process(au, path, destDir, el->data, &arcFile) != 0)
retCode = TRUE;
}
}
destroy_list(&file_list);
cd(au, curDir, NULL);
rmdir(TEMP_DIR);
cd(au, holdCurDir, NULL);
return retCode;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int scan_process(AU *au, char *sourceDir, char *destDir, char *file_name,
ARC_FILE *arcFile)
{
HANDLE file;
int virus_found;
int ret_code;
char *char_ptr;
LISTPTR paths;
LIST *el;
SCAN_INFO *in = (SCAN_INFO *)au->info;
if (in->archives == ON) /* Test self extracts itself for viruses */
{ /* and gets regular files too */
if (arcFile->type > 0)
goto noscan;
}
/* self extract or individual file **************************/
ret_code = scan_one_file(au, file_name);
if (ret_code == au->SC_Virus_EL || (au->SC_Virus_EL == -1 && ret_code > 0))
{
if (in->rename_virus[0] != '\0')
{
rename(file_name, fit_mask(file_name, in->rename_virus));
fix_flist(au, file_name, fit_mask(file_name, in->rename_virus));
}
add_to_bad_list(au, sourceDir, file_name, ret_code, 2);
if (arcFile->is_self) // now lets not go and unarc (execute) it
return TRUE;
}
else if (ret_code != au->SC_NoVirus_EL || (au->SC_NoVirus_EL == -1 && ret_code != 0))
add_to_bad_list(au, sourceDir, file_name, ret_code, 4);
/**************************************/
noscan:
if (in->archives==OFF || !(arcFile->type > 0 || arcFile->is_self) )
goto around;
memset(&paths, '\0', sizeof(LISTPTR));
unarc(au, file_name, destDir, &paths, 0, FALSE);
add_to_list(au, &paths, destDir);
virus_found = FALSE;
for (el = paths.head; el != NULL; el = el->next)
{
if (in->recurse == ON)
{
if (recurse(au, el->data) != 0)
virus_found = TRUE;
}
ret_code = scan_one_file(au, el->data);
if (ret_code == au->SC_Virus_EL || (au->SC_Virus_EL == -1 && ret_code > 0))
{
virus_found = TRUE;
if (in->rename_virus[0] != '\0')
{
rename(file_name, fit_mask(file_name, in->rename_virus));
fix_flist(au, file_name, fit_mask(file_name, in->rename_virus));
}
add_to_bad_list(au, sourceDir, file_name, ret_code, 2);
break;
}
else if (ret_code != au->SC_NoVirus_EL || (au->SC_NoVirus_EL == -1 && ret_code != 0))
add_to_bad_list(au, sourceDir, file_name, ret_code, 4);
}
clean_paths(au, &paths);
if (virus_found)
return TRUE;
around:
if (in->scan_version!=0)
{
struct ftime ftime_hold;
long value = in->random_num + in->scan_version;
file = au_open(au, file_name);
getftime(file, &ftime_hold);
ftime_hold.ft_tsec = 0;
ftime_hold.ft_hour = value / (60*30);
value-= ftime_hold.ft_hour*(60*30);
ftime_hold.ft_min = value / 30;
value-= ftime_hold.ft_min*(30);
ftime_hold.ft_tsec = value;
setftime(file,&ftime_hold);
close(file);
}
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static int scan(AU *au, char *file_name)
{
ARC_FILE arcFile;
check_for_key();
if (!is_newer(au, file_name))
return 0;
if (!au->no_extra)
au_printf(au, "@?6Scanning @?1%s@?H\n", file_name);
act_log_printf(au, " + SCAN : %s", file_name);
au->number_processed++;
arc_file_init(au, &arcFile, file_name);
arc_file_deinit(au, &arcFile);
scan_process(au, au->source_directory, au->dest_directory, file_name,
&arcFile);
return 0;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static void ReadCFGInfo(AU *au, HANDLE file, char *cfg_file, int *cfg_line)
{
char string[200],
string2[200],
string3[200];
SCAN_INFO *in = (SCAN_INFO *)au->info;
for(EVER)
{
if (get_file_line(au, file, string)==EOF)
break;
split_string(string, string2);
split_string(string, string3);
if (string2[0] == '\0')
continue;
strcpy(au->curOpt, string2);
au->curVal = string3;
switch (toupper(string2[1]) << 8 | toupper(string2[0]))
{
case 'BE': // Begin
return;
case 'SE': // Self_Extracts
au->self_extracts = get_value(au, OFF | ON);
break;
case 'RE': // Recurse
in->recurse = get_value(au, OFF | ON);
break;
case 'VE': // Version
in->scan_version = atoi(string3);
break;
case 'NE': // Newer_than
in->newer_than = atoi(string3);
break;
case 'RA':
in->random_num = atoi(string3);
break;
case 'VI':
strcpy(in->rename_virus, string3);
break;
case 'PA':
au->pause = get_value(au, OFF | ON);
break;
default:
au_invalid_cfg_option(au, string2, cfg_file, *cfg_line);
}
}
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static BYTE parse_comm_line(AU *au, char option, char *cur_argv,
PARSE_TYPE type)
{
SCAN_INFO *in = (SCAN_INFO *)au->info;
switch (type)
{
case PARSE_PARAM_OPTION:
switch (option)
{
case 'X':
au->self_extracts = get_value(au, OFF | ON);
break;
case 'A':
in->archives = get_value(au, OFF | ON);
break;
case 'R':
in->recurse = get_value(au, OFF | ON);
break;
case 'N':
in->newer_than = atoi(cur_argv);
break;
case 'V':
in->scan_version = atoi(cur_argv);
break;
case 'W':
strcpy(au->dest_directory, cur_argv);
break;
case 'P':
au->pause = get_value(au, OFF | ON);
break;
case '?':
au_standard_opt_header(au, "SCan",
"@?3-X@?Hon|off self eXtracts\n"
"@?3-A@?Hon|off look inside Archives\n"
"@?3-R@?Hon|off Recurse\n"
"@?3-V@?Hn n=Version of scanner being used\n"
" use 0 to leave time stamp unchanged\n"
"@?3-N@?Hn scan only if scanned more than n versions ago\n"
"@?3-P@?Hon|off Pause after bad archive found\n"
"@?3-W@?H<dir> Work directory\n");
exit (0);
default:
au_invalid_option(au, PROGRAM, option);
} /* end switch */
return TRUE;
case PARSE_POST_CHECK:
if (in->random_num == 0)
{
au_printf_error(au, "Need a non-zero random number in the .cfg file");
exit(1);
}
if (in->newer_than > 10)
{
au_printf_error(au, "Newer_Than is larger than recommended!!!!!");
if (!ask_continue())
exit(1);
}
return TRUE;
}
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
int main_scan(AU *au, int argc, char *argv[])
{
SCAN_INFO *in;
in = (SCAN_INFO *)au_malloc(au, sizeof(SCAN_INFO));
memset(in, '\0', sizeof(SCAN_INFO));
au->info = in;
in->archives=ON;
ReadGlobalCFGInfo(au, au->cfg_file, PROGRAM, ReadCFGInfo);
generic_parse_comm_line(au, argc, argv, parse_comm_line);
if (au->dest_directory[0] != '\0')
{
/* make sure it exists */
cd(au, au->dest_directory, au->old_dest_dir);
getcwd(au->dest_directory, FLENGTH);
cd(au, au->cur_directory);
}
else
build_fname(au->dest_directory, au->cur_directory, TEMP_DIR);
au->unarc_paths = ON;
au->recurse = OFF; // uses a different style of recurse
mkdir(TEMP_DIR);
process_files(au, scan);
rmdir(TEMP_DIR);
if (!au->no_extra)
au_printf_c(au, 15, "\nFiles Scanned = %d\n\n", au->number_processed);
return 0;
}