Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中找不到内存泄漏_C_Arrays_Pointers_Memory Leaks_Heap Memory - Fatal编程技术网

在C中找不到内存泄漏

在C中找不到内存泄漏,c,arrays,pointers,memory-leaks,heap-memory,C,Arrays,Pointers,Memory Leaks,Heap Memory,在我发现某个地方有内存泄漏/错误后,我已经坐了好几个小时检查这段代码 那个漏洞在哪里?怎么能修好呢? 这是Dr.Memory报告: Dr. Memory version 2.3.0 Running "C:\Users\Beni\source\repos\Magshimim_EX8\Debug\Magshimim_EX8.exe" Using system call file C:\Users\Beni\AppData\Roaming\Dr. Memory\sy

在我发现某个地方有内存泄漏/错误后,我已经坐了好几个小时检查这段代码 那个漏洞在哪里?怎么能修好呢? 这是Dr.Memory报告:

Dr. Memory version 2.3.0
         Running "C:\Users\Beni\source\repos\Magshimim_EX8\Debug\Magshimim_EX8.exe"
         Using system call file C:\Users\Beni\AppData\Roaming\Dr. Memory\symcache\syscalls_wow64.txt

         Error #1: UNADDRESSABLE ACCESS: reading 1 byte(s)
         replace_strlen 
             d:\drmemory_package\drmemory\replace.c(412):
         Magshimim_EX8.exe!?                
             ??:0
         Magshimim_EX8.exe!?                
             ??:0
         Magshimim_EX8.exe!?                
             ??:0
         Magshimim_EX8.exe!?                
             ??:0
         Magshimim_EX8.exe!?                
             ??:0
         KERNEL32.dll!BaseThreadInitThunk
             ??:0

         ERRORS FOUND:
               1 unique,     1 total unaddressable access(es)
               0 unique,     0 total uninitialized access(es)
               0 unique,     0 total invalid heap argument(s)
               0 unique,     0 total GDI usage error(s)
               0 unique,     0 total handle leak(s)
               0 unique,     0 total warning(s)
               0 unique,     0 total,      0 byte(s) of leak(s)
               0 unique,     0 total,      0 byte(s) of possible leak(s)
         Details: C:\Users\Beni\AppData\Roaming\Dr. Memory\DrMemory-Magshimim_EX8.exe.5208.000\results.txt
         WARNING: application exited with abnormal code 0xc0000005
#包括
#包括
#包括
#包括
#定义FALSE 0
#定义为真!错误的
#定义第一个\u两个\u文件2
#定义前二十项1
#定义中间60个字母2
#定义最后二十项3
长findLenOfFile(FILE*FILE);
char*readFile(文件*f,char*dest,长len);
char菜单(char*scanFolder,char*virusignature);
char**writeFilesFromFolder(char*scanFolder,char**filesList,int*len);
char*writePart(char*src,char*dest,int-length,int*newLen,int-part);
int-findSignature(char*virusignature,char*buffer,int-sigLen,int-bufferLen);
void scanFiles(char*scanFolder、char**filesList、int-amountoffices、char*virusignature、long-virusLength、char选项);
int main(int argc,char*argv[])
{
char*log=malloc(sizeof(char)*strlen(argv[1])+sizeof(char)*strlen(\\log.txt)+4);
文件*virusSignatureFile=fopen(argv[2],“rb”);
长病毒长度=0;
char**filesList=(char**)malloc(sizeof(char)*0);
char*virusSignature=0;
int amountofiles=0;
字符选项=0;
int i=0;
virusLength=findLenOfFile(virusSignatureFile);
//以字符串形式获取virusSignature,并写入要签入文件列表的文件
virusSignature=readFile(virusSignatureFile、virusSignature、virusLength);
filesList=writeFilesFromFolder(argv[1]、filesList和amontoffiles);
//创建日志文件
strcpy(log,“”);
strcat(log,argv[1]);
strcat(log,\\log.txt);
FILE*logFile=fopen(log,“w”);
fprintf(日志文件,“防病毒开始!欢迎!\n\n要扫描的文件夹:\n%s\n病毒签名:\n%s\n\n扫描选项:\n”,argv[1],argv[2]);
//获取扫描选项(正常或快速)并相应地继续
选项=菜单(argv[1],argv[2]);
如果(选项==“0”){
fprintf(日志文件,“正常扫描\n\n”);
}
否则{
fprintf(日志文件,“快速扫描\n\n”);
}
fprintf(日志文件,“结果:\n”);
fclose(日志文件);
//启动扫描
扫描文件(argv[1],文件列表,amountOfFiles,virusSignature,virusLength,option);
fclose(virusSignatureFile);
免费(原木);
免费(文件列表);
免费(虚拟签名);
getchar();
返回0;
}
/*
此功能将打印扫描文件夹路径和签名路径,还将向快速或正常扫描的用户打印选项菜单,
之后,函数将返回用户选项(0或其他键)
输入:扫描文件夹路径(字符串)、病毒特征码路径(也是字符串)
输出:用户选项(字符:“0”或其他键)
*/
char菜单(char*scanFolder,char*virusSignature)
{
char userOption='\0';
printf(“欢迎使用我的病毒扫描!\n\n要扫描的文件夹:%s\n病毒签名:%s\n\n按0进行诺曼扫描,或按任何其他键进行快速扫描:”,scanFolder,virusSignature);
userOption=getchar();
printf(“扫描开始…\n此过程可能需要几分钟…\n\n”);
返回用户选项;
}
/*
此函数用于将文件夹中的所有文件名写入文件列表
输入:扫描文件夹路径
输出:文件量
*/
char**writeFilesFromFolder(char*scanFolder,char**filesList,int*len)
{
DIR*d=0;
结构方向*dir;
d=opendir(扫描文件夹);
int i=0;
如果(d)
{
而((dir=readdir(d))!=NULL)
{
如果(i>1)
{
filesList=(char**)realloc(filesList,sizeof(filelist)+sizeof(char*)+4);
*(filesList+(i-FIRST_TWO_FILES))=(char*)malloc(sizeof(char)*strlen(dir->d_name)+1;
strcpy(*(filesList+(i-FIRST_TWO_FILES)),(dir->d_name));
}
i++;
}
closedir(d);
}
*len=i-FIRST\u TWO\u FILES;//前两个名称是“.”和“.”
返回文件列表;
}
/*
此函数将文件内容读入字符串
输入:要从中读取的文件(文件*)
输出:带有文件内容的char*
*/
char*readFile(文件*f,char*dest,长len)
{
dest=(char*)malloc(sizeof(char)*len);
fread(目的地,1,len,f);
返回目的地;
}
void scanFiles(char*scanFolder、char**filesList、int-amountoffices、char*virusignature、long-virusLength、char选项)
{
char*log=malloc(sizeof(char)*strlen(scanFolder)+sizeof(char)*strlen(\\log.txt)+1);
char*buffer=(char*)malloc(sizeof(char)*0);
char*subBuffer=0;
字符*斜杠=“\\”;
长长度=0;
char*name=0;
int-n=0;
int i=0;
文件*f;
//重新打开日志文件并附加到它
strcpy(log,“”);
strcat(日志、扫描文件夹);
strcat(log,\\log.txt);
FILE*logFile=fopen(log,“a”);
//迭代每个文件
对于(i=0;i#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>

#define FALSE 0
#define TRUE !FALSE
#define FIRST_TWO_FILES 2
#define FIRST_TWENTY_PRECENTS 1
#define MIDDLE_SIXTY_PRECENTS 2
#define LAST_TWENTY_PRECENTS 3

long findLenOfFile(FILE * file);
char* readFile(FILE* f, char* dest, long len);
char menu(char* scanFolder, char* virusSignature);
char** writeFilesFromFolder(char* scanFolder, char ** filesList, int* len);
char* writePart(char* src, char* dest, int length, int* newLen, int part);
int findSignature(char* virusSignature, char* buffer, int sigLen, int bufferLen);
void scanFiles(char* scanFolder, char** filesList, int amountOfFiles, char* virusSignature, long virusLength, char option);


int main(int argc, char* argv[])
{
    char* log = malloc(sizeof(char)*strlen(argv[1]) + sizeof(char)*strlen("\\Log.txt") + 4);
    FILE* virusSignatureFile = fopen(argv[2], "rb");
    long virusLength = 0;
    char** filesList = (char**)malloc(sizeof(char) * 0);
    char* virusSignature = 0;
    int amountOfFiles = 0;
    char option = 0;
    int i = 0;

    virusLength = findLenOfFile(virusSignatureFile);

    // get the virusSignature as a string and write the files to check into the filesList
    virusSignature = readFile(virusSignatureFile, virusSignature, virusLength);
    filesList = writeFilesFromFolder(argv[1], filesList, &amountOfFiles);

    // create log file
    strcpy(log, "");
    strcat(log, argv[1]);
    strcat(log, "\\Log.txt");
    FILE * logFile = fopen(log, "w");
    fprintf(logFile, "Anti-virus began! Welcome!\n\nFolder to scan:\n%s\nVirus signature:\n%s\n\nScanning option:\n", argv[1], argv[2]);

    // get scanning option (normal or quick) and continue accordingly
    option = menu(argv[1], argv[2]);
    if (option == '0') {
        fprintf(logFile, "Normal Scan\n\n");
    }
    else {
        fprintf(logFile, "Quick Scan\n\n");
    }
    fprintf(logFile, "Results:\n");
    fclose(logFile);

    // initiate scan
    scanFiles(argv[1], filesList, amountOfFiles, virusSignature, virusLength, option);

    fclose(virusSignatureFile);
    free(log);
    free(filesList);
    free(virusSignature);
    getchar();
    return 0;
}



/*
This function will print the scanning folder path and signature path, also will print the option menu to the user of quick or normal scan,
after that function will return user option(0, or other key)
input: scanFolder path (string), virus signature path (also string)
output: user option (char: '0', or other key)
*/
char menu(char * scanFolder, char * virusSignature)
{
    char userOption = '\0';
    printf("Welcome to my Virus Scan!\n\nFolder to scan: %s\nVirus signature: %s\n\nPress 0 for a norman scan or any other key for a quick scan: ", scanFolder, virusSignature);
    userOption = getchar();
    printf("Scanning began...\nThis process may take several minutes...\n\n");
    return userOption;
}


/*
This function writes all files name from folder to the filesList
input: the scanning folder path
output: amount of files
*/
char** writeFilesFromFolder(char * scanFolder, char ** filesList, int* len)
{
    DIR *d = 0;

    struct dirent *dir;
    d = opendir(scanFolder);
    int i = 0;

    if (d)
    {
        while ((dir = readdir(d)) != NULL)
        {
            if (i > 1)
            {
                filesList = (char**)realloc(filesList, sizeof(filesList) + sizeof(char*) + 4);
                *(filesList + (i - FIRST_TWO_FILES)) = (char*)malloc(sizeof(char) * strlen(dir->d_name) + 1);
                strcpy(*(filesList + (i - FIRST_TWO_FILES)), (dir->d_name));
            }
            i++;
        }
        closedir(d);
    }
    *len = i - FIRST_TWO_FILES; //first two names is "." and ".."
    return filesList;
}

/*
This function will read the contents of a file into a string
input: a file (FILE *) to read from
output: char* with the contents of the file
*/
char* readFile(FILE* f, char * dest, long len)
{
    dest = (char*)malloc(sizeof(char) * len);
    fread(dest, 1, len, f);
    return dest;
}


void scanFiles(char * scanFolder, char ** filesList, int amountOfFiles, char * virusSignature, long virusLength, char option)
{
    char* log = malloc(sizeof(char)*strlen(scanFolder) + sizeof(char)*strlen("\\Log.txt") + 1);
    char * buffer = (char*)malloc(sizeof(char) * 0);
    char* subBuffer = 0;
    char* slash = "\\";
    long length = 0;
    char* name = 0;
    int subLen = 0;
    int i = 0;
    FILE * f;

    // reopen log file and append to it
    strcpy(log, "");
    strcat(log, scanFolder);
    strcat(log, "\\Log.txt");
    FILE * logFile = fopen(log, "a");

    // iterate over each file
    for (i = 0; i < amountOfFiles; i++)
    {
        name = (char*)malloc(sizeof(char) * strlen(scanFolder) + 1 + sizeof(char) * strlen(slash) + sizeof(char) * strlen(*(filesList + i)) + 20);

        // open current file
        strcpy(name, "");
        strcat(name, scanFolder);
        strcat(name, slash);
        strcat(name, *(filesList + i));
        f = fopen(name, "rb");

        length = findLenOfFile(f);

        if (f != NULL) // if file can be accessed
        {
            buffer = readFile(f, buffer, length);
            if (option == '0') { // Normal Mode
                if (findSignature(virusSignature, buffer, virusLength, length))
                {
                    printf("%s - Infected!\n", name);
                    fprintf(logFile, "%s - Infected!\n", name);
                }
                else
                {
                    printf("%s - Clean\n", name);
                    fprintf(logFile, "%s - Clean\n", name);
                }
            }
            else { // Quick Mode
                subBuffer = writePart(buffer, subBuffer, length, &subLen, FIRST_TWENTY_PRECENTS); // get first 20%
                if (findSignature(virusSignature, subBuffer, virusLength, subLen))
                {
                    printf("%s - infected! (first 20%%)\n", name);
                    fprintf(logFile, "%s - infected! (first 20%%)\n", name);
                }
                else {
                    free(subBuffer);
                    subBuffer = writePart(buffer, subBuffer, length, &subLen, LAST_TWENTY_PRECENTS); // get last 20%
                    if (findSignature(virusSignature, subBuffer, virusLength, subLen))
                    {

                        printf("%s - Infected! (last 20%%)\n", name);
                        fprintf(logFile, "%s - Infected! (last 20%%)\n", name);
                    }
                    else {
                        subBuffer = writePart(buffer, subBuffer, length, &subLen, MIDDLE_SIXTY_PRECENTS); // get the 60% left in the middle
                        if (findSignature(virusSignature, subBuffer, virusLength, subLen))
                        {
                            printf("%s - Infected!\n", name);
                            fprintf(logFile, "%s - Infected!\n", name);
                        }
                        else {
                            printf("%s - clean\n", name);
                            fprintf(logFile, "%s - Clean\n", name);
                        }
                    }
                }
                free(subBuffer);
            }
            fclose(f);
        }
        else
        {
            printf("No file found\n");
        }
        free(*(filesList + i));
        free(name);
    }
    fclose(logFile);
    free(log);
    free(buffer);
    getchar();
}


/*
This function will write part of the file (beginning, middle or end) to a string
input: source (string) to take the information from, destination (string) to write a part of the source to it,
       length (int) of the source string, a pointer (int*) to store the new length of the destination string and
       part of the file to write from (int) 1,2 or 3: first 20%, 60% in the middle and last 20% accordingly
output: string containing the desired part of the source string
*/
char* writePart(char *src, char *dest, int length, int *newLen, int part) {
    int i = 0;
    int percentedLength = 0;
    int count = 0;
    percentedLength = (int)(length / 5); // this len is 20% of the entire file's length


    if (part == FIRST_TWENTY_PRECENTS) // return beginning
    {
        dest = (char*)malloc(sizeof(char) * percentedLength);
        *newLen = percentedLength;

        for (i = 0; i < percentedLength; i++)
        {
            *(dest + i) = *(src + i);
        }
    }
    else if (part == MIDDLE_SIXTY_PRECENTS)  // return middle
    {
        // allocate space for the middle: The entire file size minus 20% from the start and 20% from the end
        dest = (char*)malloc(sizeof(char) * (length - 2 * percentedLength));
        *newLen = length - 2 * percentedLength;

        for (i = percentedLength; i < length - percentedLength; i++) {
            *(dest + count) = *(src + i);
            count++;
        }
    }
    else if (part == LAST_TWENTY_PRECENTS) // return end
    {
        dest = (char*)malloc(sizeof(char) * percentedLength);
        *newLen = percentedLength;

        for (i = length - percentedLength; i < length; i++)
        {
            *(dest + count) = *(src + i);
            count++;
        }
    }
    return dest;
}

/*
function that finds the length of a file
input: file (FILE *)
output: the file's length (long)
*/
long findLenOfFile(FILE * file)
{
    long length = 0;
    fseek(file, 0, SEEK_END);
    length = ftell(file);
    fseek(file, 0, SEEK_SET);
    return length;
}

/*
function checks whether a file contains the virusSignature. It iterates over each letter of the file and checks
if it is the same as the first letter in the virusSignature. If it is, it checks the rest of the characters and
returns True if a match is found. if not it continues the same process until the end of the file is reached.
input: The virusSignature (string), a buffer with the content of a file (string), the signature's length (int)
       and the buffer's length (int)
output: True if signature is in file, False otherwise
*/
int findSignature(char* virusSignature, char* buffer, int sigLen, int bufferLen)
{
    int found = 0;
    int i = 0;
    int j = 0;

    for (i = 0; i < bufferLen - (sigLen - 1); i++) {
        if (*(buffer + i) == *virusSignature) // check if a letter is the same as first letter in virusSignature
        {
            found = TRUE;
            // check if the rest of the letters match the signature and stop if one doesn't
            for (j = 1; (j < sigLen) && found; j++) {
                if (*(buffer + (i + j)) != *(virusSignature + j)) {
                    found = FALSE;
                }
            }
            if (found) {
                return TRUE; // if we got a match, return true!
            }
        }
    }
    return FALSE;
}
filesList = (char **) realloc(filesList, sizeof(filesList) + sizeof(char *) + 4);
*(filesList + i)
filesList[i]
/*
This function writes all files name from folder to the filesList
input: the scanning folder path
output: amount of files
*/
char **
writeFilesFromFolder(char *scanFolder, char **filesList, int *len)
{
    DIR *d = 0;

    struct dirent *dir;

    d = opendir(scanFolder);
    int i = -FIRST_TWO_FILES;

    if (d) {
        while ((dir = readdir(d)) != NULL) {
            if (i >= 0) {
                filesList = realloc(filesList,sizeof(*filesList) * (i + 1));
                filesList[i] = strdup(dir->d_name);
            }
            i++;
        }
        closedir(d);
    }

    *len = i;           // first two names is "." and ".."

    return filesList;
}
dest = malloc(percentedLength);
if (...) { // process the file
// process the file
if (...) {
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <assert.h>

#define FALSE 0
#define TRUE (! FALSE)
#define FIRST_TWO_FILES 2
#define FIRST_TWENTY_PRECENTS 1
#define MIDDLE_SIXTY_PRECENTS 2
#define LAST_TWENTY_PRECENTS 3

#define ALLOCME(_ptr,_len) \
    do { \
        _ptr = allocme(_ptr,_len,__FUNCTION__,__LINE__); \
    } while (0)

#define FREEME(_ptr) \
    do { \
        if (_ptr != NULL) \
            free(_ptr); \
        _ptr = NULL; \
    } while (0)

void
sysfault(const char *fmt,...)
{
    va_list ap;

    va_start(ap,fmt);
    vfprintf(stderr,fmt,ap);
    va_end(ap);

    exit(1);
}

long findLenOfFile(FILE * file);
char *readFile(FILE * f, char *dest, long len);
char menu(const char *scanFolder, const char *virusSignature);
char **writeFilesFromFolder(const char *scanFolder, char **filesList, int *len);
char *writePart(char *src, char *dest, int length, int *newLen, int part);
int findSignature(char *virusSignature, char *buffer, int sigLen,
int bufferLen);
void scanFiles(const char *scanFolder, char **filesList, int amountOfFiles,
char *virusSignature, long virusLength, char option);

int opt_fixme = 0;

// allocme -- guarded allocation
void *
allocme(void *ptr,size_t len,const char *fnc,int lno)
{

    if (! opt_fixme) {
        if (ptr != NULL)
            sysfault("allocme: leaking ptr=%p len=%zu (from %s at line %d)\n",
                ptr,len,fnc,lno);
    }

    ptr = realloc(ptr,len);

    if (ptr == NULL)
        sysfault("allocme: realloc failure\n");

    return ptr;
}

#ifdef __linux__
const char *slash = "/";
#else
const char *slash = "\\";
#endif

// filejoin -- create filename from directory and file tail
char *
filejoin(const char *dir,const char *tail)
{
    size_t len;
    char *file;

    len = 0;
    len += strlen(dir);
    len += strlen(slash);
    len += strlen(tail);
    len += 1;

    file = malloc(len);
    if (file == NULL)
        sysfault("filejoin: unable to alloc -- %s\n",strerror(errno));

    *file = 0;

    strcat(file,dir);
    strcat(file,slash);
    strcat(file,tail);

    return file;
}

int
main(int argc, char **argv)
{
#if 0
    char *log = malloc(strlen(argv[1]) + strlen("\\Log.txt") + 4);
#else
    char *log;
#endif

    --argc;
    ++argv;

    for (;  argc > 0;  --argc, ++argv) {
        char *cp = *argv;
        if (*cp != '-')
            break;

        switch (cp[1]) {
        case 'f':
            opt_fixme = ! opt_fixme;
            break;
        }
    }

    if (argc != 2)
        sysfault("usage: <folder_to_scan> <virus_signature_file>\n");

    const char *topdir = argv[0];
    const char *sigfile = argv[1];

    FILE *virusSignatureFile = fopen(sigfile, "rb");
    if (virusSignatureFile == NULL)
        sysfault("main: unable to open '%s' -- %s\n",sigfile,strerror(errno));

    long virusLength = 0;
#if 0
    char **filesList = malloc(0);
#else
    char **filesList = NULL;
#endif
    char *virusSignature = NULL;
    int amountOfFiles = 0;
    char option = 0;

    virusLength = findLenOfFile(virusSignatureFile);

    // get the virusSignature as a string and write the files to check into the
    // filesList
    virusSignature = readFile(virusSignatureFile, virusSignature, virusLength);

#if 1
    fclose(virusSignatureFile);
#endif

    filesList = writeFilesFromFolder(topdir, filesList, &amountOfFiles);

    // create log file
#if 0
    strcpy(log, "");
    strcat(log, argv[1]);
    strcat(log, "\\Log.txt");
#else
    log = filejoin(topdir,"Log.txt");
#endif
    FILE *logFile = fopen(log, "w");

    fprintf(logFile, "Anti-virus began! Welcome!\n\n"
        "Folder to scan:\n%s\n"
        "Virus signature:\n%s\n\n"
        "Scanning option:\n", topdir, sigfile);

    // get scanning option (normal or quick) and continue accordingly
    option = menu(topdir, sigfile);
    if (option == '0') {
        fprintf(logFile, "Normal Scan\n\n");
    }
    else {
        fprintf(logFile, "Quick Scan\n\n");
    }
    fprintf(logFile, "Results:\n");
    fclose(logFile);

    // initiate scan
    scanFiles(topdir, filesList, amountOfFiles, virusSignature, virusLength,
        option);

#if 0
    fclose(virusSignatureFile);
#endif

    FREEME(log);
    FREEME(filesList);
    FREEME(virusSignature);

#ifndef __linux__
    getchar();
#endif

    return 0;
}

/*
This function will print the scanning folder path and signature path, also
will print the option menu to the user of quick or normal scan,
after that function will return user option(0, or other key)
input: scanFolder path (string), virus signature path (also string)
output: user option (char: '0', or other key)
*/
char
menu(const char *scanFolder, const char *virusSignature)
{
    char userOption = '\0';

    printf("Welcome to my Virus Scan!\n\n"
        "Folder to scan: %s\n"
        "Virus signature: %s\n\n"
        "Press 0 for a norman scan or any other key for a quick scan: ",
        scanFolder, virusSignature);
    userOption = getchar();
    printf("Scanning began...\nThis process may take several minutes...\n\n");
    return userOption;
}

/*
This function writes all files name from folder to the filesList
input: the scanning folder path
output: amount of files
*/
char **
writeFilesFromFolder(const char *scanFolder, char **filesList, int *len)
{
    DIR *d = 0;

    struct dirent *dir;

    d = opendir(scanFolder);
    int i = -FIRST_TWO_FILES;

    if (d) {
        while ((dir = readdir(d)) != NULL) {
            if (i >= 0) {
                filesList = realloc(filesList,sizeof(*filesList) * (i + 1));
                filesList[i] = strdup(dir->d_name);
            }
            i++;
        }
        closedir(d);
    }

    // first two names is "." and ".."
    *len = i;

    return filesList;
}

/*
This function will read the contents of a file into a string
input: a file (FILE *) to read from
output: char* with the contents of the file
*/
char *
readFile(FILE * f, char *dest, long len)
{

// NOTE/BUG: this does _not_ free the prior value -- memory leak!
    ALLOCME(dest,len);

    fread(dest, 1, len, f);

    return dest;
}

void
scanFiles(const char *scanFolder, char **filesList, int amountOfFiles,
char *virusSignature, long virusLength, char option)
{
#if 0
    char *log = malloc(strlen(scanFolder) + strlen("\\Log.txt") + 1);
#else
    char *log;
#endif
#if 0
    char *buffer = malloc(0);
#else
    char *buffer = NULL;
#endif
    char *subBuffer = NULL;
    long length = 0;
    char *name = NULL;
    int subLen = 0;
    int i = 0;
    FILE *f;

    // reopen log file and append to it
#if 0
    strcpy(log, "");
    strcat(log, scanFolder);
    strcat(log, "\\Log.txt");
#else
    log = filejoin(scanFolder,"Log.txt");
#endif
    FILE *logFile = fopen(log, "a");

    // iterate over each file
    for (i = 0; i < amountOfFiles; i++) {
#if 0
        name = malloc(strlen(scanFolder) + 1 + strlen(slash) + strlen(*(filesList + i)) + 20);
#endif

        // open current file
#if 0
        strcpy(name, "");
        strcat(name, scanFolder);
        strcat(name, slash);
        strcat(name, *(filesList + i));
#else
        name = filejoin(scanFolder,filesList[i]);
#endif
        f = fopen(name, "rb");

        length = findLenOfFile(f);

        // if file can be accessed
        if (f != NULL) {
            buffer = readFile(f, buffer, length);

            // Normal Mode
            if (option == '0') {
                if (findSignature(virusSignature, buffer, virusLength, length)) {
                    printf("%s - Infected!\n", name);
                    fprintf(logFile, "%s - Infected!\n", name);
                }
                else {
                    printf("%s - Clean\n", name);
                    fprintf(logFile, "%s - Clean\n", name);
                }
            }

            // Quick Mode
            else {
                // get first 20%
                subBuffer = writePart(buffer, subBuffer, length, &subLen,
                    FIRST_TWENTY_PRECENTS);

                if (findSignature(virusSignature, subBuffer, virusLength,
                    subLen)) {
                    printf("%s - infected! (first 20%%)\n", name);
                    fprintf(logFile, "%s - infected! (first 20%%)\n", name);
                }

                else {
                    FREEME(subBuffer);

                    // get last 20%
                    subBuffer = writePart(buffer, subBuffer, length, &subLen,
                        LAST_TWENTY_PRECENTS);

                    if (findSignature(virusSignature, subBuffer, virusLength,
                        subLen)) {
                        printf("%s - Infected! (last 20%%)\n", name);
                        fprintf(logFile, "%s - Infected! (last 20%%)\n", name);
                    }

                    else {
                        // get the 60% left in the middle
                        subBuffer = writePart(buffer, subBuffer, length,
                            &subLen, MIDDLE_SIXTY_PRECENTS);

                        if (findSignature(virusSignature, subBuffer,
                            virusLength, subLen)) {
                            printf("%s - Infected!\n", name);
                            fprintf(logFile, "%s - Infected!\n", name);
                        }

                        else {
                            printf("%s - clean\n", name);
                            fprintf(logFile, "%s - Clean\n", name);
                        }
                    }
                }
                FREEME(subBuffer);
            }
            fclose(f);
        }
        else {
            printf("No file found\n");
        }

        FREEME(filesList[i]);
        FREEME(name);
    }

    fclose(logFile);
    FREEME(log);
    FREEME(buffer);

    getchar();
}

/*
This function will write part of the file (beginning, middle or end) to a string
input: source (string) to take the information from, destination (string) to
write a part of the source to it, length (int) of the source string, a pointer
(int*) to store the new length of the destination string and part of the file
to write from (int) 1,2 or 3: first 20%, 60% in the middle and last 20%
accordingly
output: string containing the desired part of the source string
*/
char *
writePart(char *src, char *dest, int length, int *newLen, int part)
{
    int i = 0;
    int percentedLength = 0;
    int count = 0;

    // this len is 20% of the entire file's length
    percentedLength = (int) (length / 5);

// NOTE/BUG: this does _not_ free the prior value -- memory leak!

    switch (part) {
    case FIRST_TWENTY_PRECENTS:  // return beginning
        ALLOCME(dest,percentedLength);
        *newLen = percentedLength;

        for (i = 0; i < percentedLength; i++) {
            *(dest + i) = *(src + i);
        }
        break;

    case MIDDLE_SIXTY_PRECENTS:  // return middle
        // allocate space for the middle: The entire file size minus 20% from
        // the start and 20% from the end
        ALLOCME(dest,length - 2 * percentedLength);
        *newLen = length - 2 * percentedLength;

        for (i = percentedLength; i < length - percentedLength; i++) {
            *(dest + count) = *(src + i);
            count++;
        }
        break;

    case LAST_TWENTY_PRECENTS:  // return end
        ALLOCME(dest,percentedLength);
        *newLen = percentedLength;

        for (i = length - percentedLength; i < length; i++) {
            *(dest + count) = *(src + i);
            count++;
        }
        break;
    }

    return dest;
}

/*
function that finds the length of a file
input: file (FILE *)
output: the file's length (long)
*/
long
findLenOfFile(FILE * file)
{
    long length = 0;

    fseek(file, 0, SEEK_END);
    length = ftell(file);
    fseek(file, 0, SEEK_SET);

    return length;
}

/*
function checks whether a file contains the virusSignature.

It iterates over each letter of the file and checks if it is the same as the
first letter in the virusSignature.
If it is, it checks the rest of the characters and returns True if a match is
found.
if not it continues the same process until the end of the file is reached.

input: The virusSignature (string), a buffer with the content of a file
       (string), the signature's length (int)
       and the buffer's length (int)

output: True if signature is in file, False otherwise
*/
int
findSignature(char *virusSignature, char *buffer, int sigLen, int bufferLen)
{
    int found = 0;
    int i = 0;
    int j = 0;

    for (i = 0; i < bufferLen - (sigLen - 1); i++) {
        // check if a letter is the same as first letter in virusSignature
        if (*(buffer + i) == *virusSignature)
        {
            found = TRUE;

            // check if the rest of the letters match the signature and stop
            // if one doesn't
            for (j = 1; (j < sigLen) && found; j++) {
                if (*(buffer + (i + j)) != *(virusSignature + j)) {
                    found = FALSE;
                }
            }

            // if we got a match, return true!
            if (found) {
                return TRUE;
            }
        }
    }

    return FALSE;
}