So I have been tackling the logfind project and I am running into a stumbling block. Probably because I am missing something essential in pointers (although I have gone and read it a few times). As the requirement states, Zed wants to search terms through logfiles. I started with a one line text file which is opened and read in my code. My idea is to read the file, identify when there is a new line and use that as a parameter to open the file specified by the string … for example — > Mr C Program open “log_file_list” then read the 1st line … take that line (in this case) /var/log/syslog … and then open that file and run all your other magic code from there. Here is my code … it fails because it says /var/log/syslog does not exist. It probably has to do with the fact of the string storage in memory. At this point I have read so many man pages and did more googling around that I more confused than before.
int main(int argc, char *argv[])
{
int size = 100; // size as required for fgets
char s[100]; // buffer as requred for fgets
FILE *my_text_file; // file to open and read (contains my log file name I want to use)
FILE *my_log_file; // name of the log file
my_text_file = fopen("log_files.txt", "r"); // opens the logfile
fgets(s, size, my_text_file); // gets the first line
printf("%s\n", s); // sanity checking -- yes it is /var/log/syslog
my_log_file = fopen(s, "r"); // reuse the s string to open another file ... this is where it fails fopen: No such file or dir
if (my_log_file == NULL) {
printf("%s\n", s);
perror("fopen");
exit(EXIT_FAILURE);
}
fclose(my_text_file);
fclose(my_log_file);
}
So, first thing I would do is make sure you can access /var/log/syslog normally. If you can’t do:
cat /var/log/syslog
Then that’s your main problem. If that fails then you’ll have to run this with sudo, but that can be dangerous while you’re doing development. What I’d do is either find a log file you can work with as a normal user, or make a copy of syslog to test with.
So a couple of notes here, 1. I had a hunch that my ‘s’ array was a bit big. - I made a change and only used an ‘int size’ and a char array size that would accommodate the size of the string. (It worked and opened) – so need to find a different way of doing that . 2. I figured there would be a permissions issue with /var/log/syslog … whenever something doesn’t work on Linux I go to file permissions. – I ran with sudo and it works … obviously this is not how I want things to work, so I need to come up with a better way.
Also, the prototype for fgets is … Why can’t use a pointer to ‘s’ I don’t want to have to initialize s to a size as I have it in my code.
char *fgets(char *s, int size, FILE *stream);
Notice how I changed the size to 16 … exactly the size …
int main(int argc, char *argv[])
{
int size = 16; // set to exactly what fgets expects to see as a size
char s[16]; // buffer is exactly the size of the characters
FILE *my_text_file; // file to open and read (contains my log file name I want to use)
FILE *my_log_file; // name of the log file
my_text_file = fopen("log_files.txt", "r"); // opens the logfile
fgets(s, size, my_text_file); // gets the first line
printf("%s\n", s); // sanity checking -- yes it is /var/log/syslog
my_log_file = fopen(s, "r"); // reuse the s string, doesn't fail
if (my_log_file != NULL) {
printf("%s\n", s);
perror("fopen");
exit(EXIT_FAILURE);
}
I solved my problem. When I ran it in GDB. I saw that fgets() was adding a “\n” to the end of the ‘got’ string (this was not printed in my sanity). So when it is placed in the buffer /var/log/syslog looks like “var/log/syslog\n” … obviously that causes problems. Here is my solution. - Works with no errors
int main(int argc, char *argv[])
{
int size = 60; // size as required for fgets
char s[60]; // buffer as requred for fgets
FILE *my_text_file; // file to open and read (contains my log file strings I want to use)
FILE *my_log_file; // name of the log file within my_text_file
my_text_file = fopen("log_files.txt", "r"); // opens the log file list
fgets(s, size, my_text_file); // gets the first line , sticks it in the 's' array
strtok(s, "\n"); // removes trailing carriage return from the 's' array
my_log_file = fopen(s, "r"); // Does not fail
if (my_log_file != NULL) {
printf("%s\n", s); // Prints the file name (sanity)
perror("fopen");
exit(EXIT_FAILURE);
}