File isn't closing and read access violation exception in C? - c

I'm making kind of an antivirus as a part of a project I got. I need to find if a binary file includes a certain string anywhere in it. What I'm trying to do is add 7 chars to an array, because i know the virus signature is 7 chars long, then compare to the string and if they are equal, means the file is infected. But, it doesn't work. it says "Exception thrown: read access violation.
currStr was 0x1110113.". Also, whenever I try to free arrays or free files, the program crashed. Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#define ARR_SIZE 250
void Search_in_File(char* dir, char* str)
{
FILE *fp;
DIR *folder;
char currFilePath[ARR_SIZE] = { 0 };
struct dirent *entry;
int files = 0;
char ch = 0;
char* virusStr;
char* currStr;
char* buffer;
int fSize = 0;
int index = 0;
folder = opendir(dir); //Opening the folder
if (folder == NULL)
{
perror("Unable to read directory");
return(1);
}
virusStr = (char*)malloc(sizeof(char) * ARR_SIZE);
strcpy(virusStr, str); // Getting the virus detection string
while ((entry = readdir(folder))) // Reading each file in the folder
{
if ((entry->d_name)[0] != '.') //Making sure that we will go over valid files only
{
strcpy(currFilePath, dir); //Coppy the folder name into the file path
files++;
printf("File %3d: %s\n",
files,
entry->d_name
);
strcat(currFilePath, "/"); //Add slash so we can add the filename and get full path
strcat(currFilePath, entry->d_name); // Adding file name after the slash
fp = fopen(currFilePath, "rb"); //Opening the file with the full path
if (fp == NULL)
{
printf("Error opening file!\n");
}
fseek(fp, 0, SEEK_END);
fSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
buffer = (char*)malloc(fSize + 1);
fread(buffer, sizeof(char), fSize, fp); // Reading the file content into a string
currStr = (char*)malloc(sizeof(char) * strlen(str) + 1); //Memory for the checking string
printf("%d", strlen(currStr));
printf("%p", &currStr);
for (index; index < fSize; index++)
{
printf("%c", buffer[index]);
if (buffer[index] != EOF)
{
//Error happens here
strcat(currStr[index], buffer[index]); // Adding the current char to the current string
// Checking if we have a string the same length as the virus signature
if ((index % strlen(virusStr)) == 0)
{
if (strcmp(currStr, virusStr) == 0) // Checking if we have the same string
{
printf("%s - Infected!", entry->d_name);
break;
}
}
}
currStr = '\0'; // Reset the current string
}
index = 0;
currFilePath[0] = '\0'; // Resetting the file path in order to get the new one
}
}
closedir(folder);
//fclose(fp); //Doesnt Work - ????
//free(virusStr); //Doesnt Work - ????
//free(currStr);//Doesnt Work - ????
//free(buffer);//Doesnt Work - ????
}

Related

C Troubles with comparison between two binary data

I am writing a program that get a path for a folder with two pictures files and a path for a file that containing binary data that simulator virus. and the purpose of this final project is to scan the files in the folder and say if one hold the virus. I succeeded with opening all the files but my comparison does not working. please someone help me fix this code because I am clueless why this is happening and this is my final project to get a grade on. The problem is in the line when I use memcmp function.
#include <stdio.h>
#include "dirent.h"
#include <string.h>
int print_menu(char *argv[]); // this is a function that print to the user the menu and it's not appears in this question.
void long_scan(char *info[]);
#define STR_LEN 100
int main(int argc, char *argv[])
{
int option = 0;
if (argc == 3)
{
option = print_menu(argv);
if (option == 0)
{
long_scan(argv);
}
}
else
{
printf("The program didn't got the number of paramter's that she expect to get\n");
}
getchar();
return 0;
}
void long_scan(char *info[])
{
DIR *file = 0; // the folder
FILE *file_to_check = 0; // the files to check in this case the pictures
FILE *virus; // the virus file
struct dirent *files = 0;
char temp[STR_LEN] = { 0 }; // using to play with the strings to open the files
int len = 0, result = 0, c = 0, virus_len = 0, i = 0;
char file_p[STR_LEN] = { 0 };
char virus_path[STR_LEN] = { 0 };
strcpy(file_p, info[1]); // the path of the folder
strcpy(virus_path, info[2]); // the path to the virus
file = opendir(file_p); // opening the folder
strcat(file_p, "\\\\"); add "\\" to the path so I can get the files in the folder later on
virus = fopen(virus_path, "rb"); // opening the virus
fseek(virus, 0, SEEK_END);
virus_len = ftell(virus); // get the virus len = 494
fseek(virus, 0, SEEK_SET);
char* virus_holder = (char *)malloc(sizeof(char) * virus_len); // create variable for the virus
fread(virus_holder, sizeof(char), virus_len, virus); // get the virus to the variable (his len is 61 dont know why)
if (file == NULL) // check if the file exist
{
printf("Error. file does not exists\n");
exit(0);
}
while ((files = readdir(file)) != NULL) // get one file every time
{
if (strcmp(files->d_name, "..") && strcmp(files->d_name, "."))
{
strcpy(temp, file_p); // copy the original path for later
strcat(file_p, files->d_name); // get the path to the file
file_to_check = fopen(file_p, "rb"); // open the file (picture)
fseek(file_to_check, 0, SEEK_END);
len = ftell(file_to_check); // get the file len
fseek(file_to_check, 0, SEEK_SET);
char* buffer = (char *)malloc(sizeof(char) * len); // create buffer to hold the file binary data
fread(buffer, sizeof(char), len, file_to_check);
fclose(file_to_check);
/*******/
result = memcmp(virus_holder, buffer, virus_len); // here the problem his. for some resone th compare does not work for me. and one of the file his holding the virus for 100%
/*******/
if (result == 0)
{
printf("%s is holding the virus\n", files->d_name);
}
strcpy(file_p, temp); // get the original path
free(buffer);
}
}
free(virus_holder);
}

Reading all .txt files from a folder?

I am trying to read all .txt files which is in the directory named "dataset". All text files has name like 1.txt, 2.txt, 3.txt... And then saving the contents of the files to a structure named FILES.
I used the dirent.h library and readdir( ) function as I saw in some sources. But the file name which program read from directory does not return correctly. Here is my related code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
typedef struct FILES{
char **words;
int wordCount;
}FILES;
void readFiles();
FILES *files;
int fileCount;
int main(){
readFiles();
return 0;
}
void readFiles(){
FILE *file;
DIR *directory;
struct dirent *filesInDirectory;
int counter;
fileCount = 1;
files = (FILES *)malloc(sizeof(FILES));
directory = opendir("dataset");
if(directory == NULL){
printf("Warning: The directory name that is given in the code is not
valid ..!");
return;
}else{
while((filesInDirectory = readdir(directory)) != NULL){
printf("%s\n", filesInDirectory->d_name);
file = fopen(filesInDirectory->d_name, "r+");
if(file == NULL){
printf("Warning: The file named %s could not open ..!",
filesInDirectory->d_name);
return;
}
files[fileCount-1].wordCount = 1;
files[fileCount-1].words = (char **)malloc(files[fileCount-
1].wordCount * sizeof(char *));
counter = 0;
while(!feof(file)){
files[fileCount-1].words[counter] = (char *)malloc(20 *
sizeof(char));
fscanf(file, "%s", files[fileCount-1].words[counter]);
files[fileCount-1].wordCount++;
files[fileCount-1].words = (char **)realloc(files[fileCount-
1].words, files[fileCount-1].wordCount * sizeof(char *));
counter++;
}
fileCount++;
fclose(file);
}
}
}
The file name that I printed in here "printf("%s\n", filesInDirectory->d_name);" is ".". Where am I doing wrong?
THIS IS NOT AN ANSWER BUT TOO BIG FOR A COMMENT
Here are your problems:
1.
files = (FILES *)malloc(sizeof(FILES));
This is enough size of one FILES. This is will not be enough
After
while((filesInDirectory = readdir(directory)) != NULL){
Put something like
size_t len = strlen(filesInDirectory->d_name);
if (len < 5 || strcmp(filesInDirectory->d_name + len - 4, ".txt") != 0) {
continue;
}
This will check to ensure files end in .txt
Consider using fstat to ensure that the file is a text file
Remove the casts on malloc
Perhaps use realloc for files
while ... feof is bad - see link above
fscanf(file, "%s", - Buffer overruns is possible. Do something about this. Read the manual page

fseek() and ftell() fail in a loop

I need to loop trough a directory, data and read each file, that meets certain conditions, in a string and do something with it. For some reason it fails after the fseek call (the output is only the name of the first file in the directory).
Any idea what am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
void doAlgorithm(char *input) {
printf("%s\n", input);
}
int main(int argc, char** argv) {
struct dirent *dir;
DIR *d = opendir("data");
FILE *file;
while ((dir = readdir(d)) != NULL) {
if (strlen(dir->d_name) > 6 && dir->d_name[6] == 'i') {
printf("Filename: %s\n", dir->d_name);
file = fopen(dir->d_name, "r");
fseek(file, 0, SEEK_END);
long length = ftell(file);
fseek(file, 0, SEEK_SET);
printf(", Filesize: %ld\n", length);
char *buffer = malloc(length + 1);
fread(buffer, 1, length, file);
buffer[length] = '\0';
fclose(file);
doAlgorithm(buffer);
}
}
closedir(d);
return (EXIT_SUCCESS);
}
Your problem is that you file = fopen(dir->d_name, "r"); doesn't know where that file is in the directory. you need to give it the full path. You can do this;
struct dirent *dir;
// put the directory path here. on windows is \ instead of /
char *path = "/Users/adnis/CLion/Stackoverflow/testdir";
char *slash = "";
DIR *d = opendir(path);
FILE *file;
while ((dir = readdir(d)) != NULL) {
if (strlen(dir->d_name) > 6 && dir->d_name[6] == 'i') {
printf("Filename: %s\n", dir->d_name);
int length = strlen(path);
/*check if the path already contains a '/' at
the end before joining the filename to the directory*/
if(path[strlen(path)-1] != '/'){ //on windows is '\'
slash = "/";
}
length += strlen(dir->d_name)+2;
// allocate memory for the new path
// and make sure we have enough memory.
char *newpath = malloc(length);
assert(newpath != NULL);
snprintf(newpath,length,"%s%s%s",path,slash,dir->d_name);
file = fopen(newpath, "r");
if(file == NULL){
fprintf(stderr, "fopen: %s\n", strerror(errno));
break;
}
fseek(file, 0, SEEK_END);
long len = ftell(file);
fseek(file, SEEK_SET, 0);
char *buffer = malloc(len + 1);
fread(buffer, 1, len, file);
buffer[strlen(buffer)] = '\0';
printf("%s \n",buffer);
fclose(file);
}
}
closedir(d);
return (EXIT_SUCCESS);
I suggest that when reading directory you have to also try and avoid reading "." and ".." since they are just current directory and previous directory. something like this will help. In your while loop
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..") == 0)
continue;

Char* parse error from char array

I read a file and stock all characters like this:
void ReadFile()
{
int c;
FILE *file;
int string_size;
file = fopen("/userFiles/ex.txt", "r");
char * content;
if (file)
{
// Seek the last byte of the file
fseek(file, 0, SEEK_END);
// Offset from the first to the last byte, or in other words, filesize
string_size = ftell(file);
// go back to the start of the file
rewind(file);
// Allocate a string that can hold it all
content = malloc((string_size + 1) * sizeof(char));
int i = 0;
while ((c = getc(file)) != EOF)
{
//printf("%c",(char) c);
content[i] = (char) c;
i++;
}
content[string_size] = '\0';
printf("content: %s",content);
fclose(file);
}
else
{
printf("not load\n");
}
}
Problem is if i read each carachter i've got the content of the file but if i do:
printf("content: %s",content);
I got just a symbol and not text whereas i need to pass the content var with correct text in argument of a json reply.
This is the first line of the file (CRC32):
�ex.txt k��X� ?xml version="1.0" encoding="utf-8"?
I compiled and ran the following code and it shows no major problem when executed.
The compilable version I used is (cmdline: gcc main.c -Wall -Wextra -o main):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
int c;
FILE *file;
int string_size;
file = fopen("plop", "r");
char * content;
if (file == NULL)
{
perror("fprintf");
return 1;
}
// Seek the last byte of the file
fseek(file, 0, SEEK_END);
// Offset from the first to the last byte, or in other words, filesize
string_size = ftell(file);
// go back to the start of the file
rewind(file);
// Allocate a string that can hold it all
content = malloc((string_size + 1) * sizeof(char));
int i = 0;
while ((c = getc(file)) != EOF)
{
//printf("%c",(char) c);
content[i] = (char) c;
i++;
}
content[string_size] = '\0';
printf("content: %s", content);
return 0;
}
Maybe your file has a binary content?
What is the symbol printed, that you mentioned?
I think you should use quotes "" around the content string:
printf("content: \"%s\"",content);

C File Reader from array

I can see the last printf output of y but the fpc turns null.
I suspected for double quotes in fopen function but not could not find a solution: how to fix it?
Part of the code ;
char *y = &arr_lines[1024*2];
FILE *fpc = fopen(y, "r");
if (fpc == NULL) {
printf("Error opening file.\n");
//return -1;
}
printf("TEST %s\n",y);
When I run the code;
Error opening file.
TEST /Users/lessons/AbstractLesson.java
Here is the full code;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define LINESIZE 1024
int main(void){
char *arr_lines, *line;
char buf_line[LINESIZE];
int num_lines = 0;
char buf[10240];
// open file
FILE *fp = fopen("/tmp/file", "r");
//FILE *fp1 = fopen(arr_lines, "r");
if (fp == NULL) {
printf("Error opening file.\n");
return -1;
}
// get number of lines; from http://stackoverflow.com/a/3837983
while (fgets(buf_line, LINESIZE, fp))
if (!(strlen(buf_line) == LINESIZE-1 && buf_line[LINESIZE-2] != '\n'))
num_lines++;
// allocate memory
arr_lines = (char*)malloc(num_lines * 1024 * sizeof(char));
// read lines
rewind(fp);
num_lines = 0;
line=arr_lines;
while (fgets(line, LINESIZE, fp))
if (!(strlen(line) == LINESIZE-1 && line[LINESIZE-2] != '\n'))
line += LINESIZE;
// print first four lines
char *y = &arr_lines[1024*2];
FILE *fpc = fopen(y, "r");
//FILE *fp1 = fopen(arr_lines, "r");
if (fpc == NULL) {
printf("Error opening file.\n");
//return -1;
}
printf("TEST [%s]\n",y);
//x = &arr_lines[1024*0];
// y = *x;
// finish
fclose(fp);
return 0;
}
Change printf("TEST %s\n", y) to printf("TEST \"%s\"\n", y) so we can see if you have any extra whitespace characters in the filename.
fgets() returns the new line, if it's there. I didn't see where your code clears the newline. Does your path string include the new line?
Beyond that, fopen() is almost certainly working correctly. The only options are 1) The path is not correct, 2) the path has whitespace or other invalid characters, or 3) the file is not available for reading.
If you don't have a new line in your path, then you simply haven't provided enough information to resolve this issue.
I suspect the path, /Users/lessons/AbstractLesson.java, is wrong. It looks like an OSX path and it might be missing the username between Users and lessons.

Resources