Thread: Reading directory contents and getting access times, issues with struct stat

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    12

    Thumbs up Reading directory contents and getting access times, issues with struct stat

    So my code is supposed to take two inputs one being an int that will be representing a date in unix time, and the other is supposed to be a directory to search through. it then checks the files access time and if it is within a day of the inputted date it will print the file name and the date is was accessed. I apologize in advance for bad naming, my code:
    Code:
    /*Description: Takes a date in posix seconds and a directory as input and searches all files
    *and subdirectories for anything that has been accessed,modified, or created within
    *24 hours of the specified date.
    */
    #include <sys/stat.h>
    #include <dirent.h>
    #include <stdio.h>
    #include <time.h>
    #include <string.h>
    #include <stdlib.h> 
    /*
    *Description: takes the posix seconds value cal_time of type time_t and 
    *returns it as a string in the format of: month day hours:minutes.
    */
    char * format_time(time_t cal_time){ 
       struct tm *time_struct; 
       static char string[30]; 
       time_struct=localtime(&cal_time); 
       strftime(string, sizeof string, "%h %e %H:%M", time_struct); 
       return(string); 
    }// end format_time function
    
    int main(int argc, char *argv[]) {
    	int i;
       	struct stat buf;
       	char *fileType;
    	int date = atoi(argv[1]);
    
       	//checks input if the path given is in fact a directory
    	for (i=1; i<argc; i++) {
       	   printf("Times of %s:\n",argv[i]);
       	   if (lstat(argv[i], &buf) < 0) {
       	      printf("lstat error\n");
       	      continue;
       	   	}
    		//checks to see if path given is a directory, if it isnt the program throws an error and exits
    		if (!S_ISDIR(buf.st_mode)) {
    			printf("%s is not a directory\n",argv[2]);
    			exit(0);
    		}
    		
    	printf("Access time is %s\n", format_time(buf.st_atime)); 
    	printf("Modify time is %s\n", format_time(buf.st_mtime)); 
    	printf("I-node change time is %s\n", format_time(buf.st_ctime)); 
    	printf("\n");
    	}//end for loop	
    	tsSearch(date,argv[2]);
    }// end main function
    
    /*
    *Description: loops through the directory and checks all the files access/modified/i-node times *and prints out the files and those times if the time is within a day of the inputted "date", if the file being checked is a *directory the function is recursively called
    */
    
    void tsSearch(int date, char* path){
    	DIR *dp;
    	struct dirent	*dirp;
    	struct stat buf;
    	char* slash = "/\0";
    	char* temp = strcat(path,slash); //appends a slash to the directory
    	char* tmp;
    	char* filepath;
    	//int atime;
            //time_t a;
    	int k = strlen(temp);
    	//printf("%d\n", k);
    	
    	//checks to see if the path of the directory that is given is a valid directory, if not program throws an error and exits
    	if ((dp = opendir(path)) == NULL){
    		printf("can't open %s\n", path);
    		exit(0);
    	}	
    
    	while ((dirp = readdir(dp)) != NULL){
    		int j = strlen(dirp->d_name);
    		str_copy(temp,tmp);
    		fixtemp(tmp,k,j);
    		str_copy(temp,tmp);	
    		printf("%s\n",dirp->d_name);
    		filepath = strcat(tmp,dirp->d_name);
    		printf("%s\n",filepath);
    		//atime = getATime(filepath);
    		printf("%s, %s, Access\n", dirp->d_name, format_time(buf.st_atime));
    
    		/*if(S_ISDIR(filepath))
    			tsSearch(date, filepath);*/
    		//if(dirp->d_name == "." || dirp->d_name == ".."){}
    		/*if(atime > date-86400 && atime < date+86400)
    			printf("%s, %s, Accessed\n", dirp->d_name, format_time(atime));*/
    		fixtemp(tmp,k,j);
    		fixtemp(filepath,k,j);
    	}//end while loop
    	
    	closedir(dp);
    }// end tsSearch function
    
    void fixtemp(char* path, int i, int j){
    	int k = i;
    	for(;k<i+j;k++)
    		path[k] = '\0';
    }
    
    void str_copy(char *s, char *t){
    	for(;*s!='\0';s++){
    		*t = *s;
    		t++;
    }
    }//end strcopy function
    
    void str_cat(char *s, char *t){
    	str_copy(s,t+strlen(t));	
    }//end function strcat
    
    //gets the access time of the file at path
    int getATime(char* path){	
    	printf("%s\n", path);
    	struct stat buf;
    	//time_t tmp = buf.st_atime;
    	printf("Accessed: %s\n", format_time(buf.st_atime));
    	int t = 1;
    	return t;
    }// end getATime function
    This is the output:
    Code:
    jimmy@ubuntu:~/Desktop$ ./tsSearch2 1302757200 /home/jimmy/Desktop/herpderp
    Times of 1302757200:
    lstat error
    Times of /home/jimmy/Desktop/herpderp:
    Access time is Apr 18 21:09
    Modify time is Apr 18 21:09
    I-node change time is Apr 18 21:09
    
    18-SystemIO.ppt
    /home/jimmy/Desktop/herpderp/18-SystemIO.ppt
    Segmentation fault
    ive come to the conclusion through testing that my problem lies with the fixtemp function and the line "filepath = strcat(tmp,dirp->d_name);" because it causes an issue with struct stat for some reason. I was under the impression that if i gave a valid filepath struct stat would work.

    i have a section of code commented out, im kinda lookin for an opinion on it, would that recursive call to tsSearch work or would it just give me the same problem with the struct stat?

    Also i know it isnt wrapped around anything at the moment while it is commented out, but i was also having issues when checking for "." and "..", i tried srcmp as well but it didnt work.

    I'd appreciate any help.

  2. #2
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    You need to learn more about strings.
    Not sure why your write str_copy(), which does in fact have a bug when there are strcpy() and strcat() functions available in standard library.
    It is never advisable to modify argv[]. You are attempting to concatenate a "/". Instead you must copy argv[] to your own buffer and modify that.

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    I would suggest that you check your compiler settings to insure that warnings are emitted. When I compile this code these are the warnings I receive:
    main.c|15|warning: no previous declaration for ‘format_time’|
    main.c||In function ‘main’:|
    main.c|32|warning: implicit declaration of function ‘lstat’|
    main.c|47|warning: implicit declaration of function ‘tsSearch’|
    main.c|26|warning: unused variable ‘fileType’|
    main.c|54|warning: no previous declaration for ‘tsSearch’|
    main.c|54|warning: conflicting types for ‘tsSearch’|
    main.c|47|note: previous implicit declaration of ‘tsSearch’ was here|
    main.c||In function ‘tsSearch’:|
    main.c|75|warning: implicit declaration of function ‘str_copy’|
    main.c|76|warning: implicit declaration of function ‘fixtemp’|
    main.c|54|warning: unused parameter ‘date’|
    main.c|96|warning: no previous declaration for ‘fixtemp’|
    main.c|96|warning: conflicting types for ‘fixtemp’|
    main.c|76|note: previous implicit declaration of ‘fixtemp’ was here|
    main.c|102|warning: no previous declaration for ‘str_copy’|
    main.c|102|warning: conflicting types for ‘str_copy’|
    main.c|75|note: previous implicit declaration of ‘str_copy’ was here|
    main.c|109|warning: no previous declaration for ‘str_cat’|
    main.c|114|warning: no previous declaration for ‘getATime’|
    main.c||In function ‘tsSearch’:|
    main.c|75|warning: ‘tmp’ may be used uninitialized in this function|
    Also in your format_time() function you are returning the address of a local variable, this variable is destroyed when the function returns. You also seem to be using uninitialized memory in your tsSearch() function. You need to check your str_cat, and str_cpy functions to insure that they are placing the end of string character onto the end of the strings.

    Jim

  4. #4
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    I was going to mention that format_time()'s local variable string[] can not be relied upon persisting upon the function's exit. However, the way the pointer is immediately used, and knowing that stacked values are not being trashed as evidenced by the working example, I let it go. It is poor form though.

  5. #5
    Registered User
    Join Date
    Apr 2011
    Location
    Las Vegas
    Posts
    66
    Just a couple other things I see. In your getATime() function, the printf statement is attempting to print an undefined value, buf. You declare the variable buf two lines before, but fail to initialize it. You have a similar problem in your tsSearch() function. In the while loop, you attempt to copy tmp to temp, but tmp has not been initialized.

    What exactly is the purpose of fixtemp()? You don't need to fill a C string with null characters. The first null character encountered represents the end of the string. Anything following that first null character is never read, so it doesn't matter what characters may be there.

    I agree with nonoob - unless you have an overriding reason to recreate the wheel, I believe you should stick with the standard library functions (e.g. strcpy, strcat).

  6. #6
    Registered User
    Join Date
    Apr 2011
    Posts
    12
    Quote Originally Posted by nonoob View Post
    You need to learn more about strings.
    Not sure why your write str_copy(), which does in fact have a bug when there are strcpy() and strcat() functions available in standard library.
    It is never advisable to modify argv[]. You are attempting to concatenate a "/". Instead you must copy argv[] to your own buffer and modify that.
    when i use the given strcopy(), i get errors like these:
    tsSearch2.c.text+0x27c): undefined reference to `strcopy'

    so r u saying i should do a strcopy(path,temp) and then concatenate the "/" to temp? is this what was giving me the issues with struct stat? i was under the impression it was the '\0' characters that were causing that problem.

    Quote Originally Posted by jimblumberg View Post
    I would suggest that you check your compiler settings to insure that warnings are emitted. When I compile this code these are the warnings I receive:


    Also in your format_time() function you are returning the address of a local variable, this variable is destroyed when the function returns. You also seem to be using uninitialized memory in your tsSearch() function. You need to check your str_cat, and str_cpy functions to insure that they are placing the end of string character onto the end of the strings.

    Jim
    sry,i meant to delete the str_cat() function as it isnt even being used. i ignored those warnings of previous implicit declarations. i didnt think they were a problem since my previous homework gave me those warnings in which i was to code those string functions and it worked despite the warnings. and the format_time() code was given to us by the professor in a lecture, its not my code and im not entirely sure how it works, im just using it to change the unix time into a readable date.
    Last edited by Jimb0; 04-18-2011 at 09:37 PM. Reason: correction

  7. #7
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Sorry kmess. Your advice is flawed.
    getATime does not need a known buf. It is a parameter that's assigned within the function. Not that it's used.
    The tsSearch() function copies temp to tmp using the user written copy function which does source -> destination.

  8. #8
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    It's strcpy().

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    i ignored those warnings of previous implicit declarations. i didnt think they were a problem since my previous homework gave me those warnings in which i was to code those string functions and it worked despite the warnings.
    You should consider all warnings as errors. Your code should compile without any warnings or errors.
    main.c|96|warning: no previous declaration for ‘fixtemp’|
    main.c|96|warning: conflicting types for ‘fixtemp’|
    main.c|76|note: previous implicit declaration of ‘fixtemp’ was here|
    Look at these warnings closely. The compiler is actually telling you that you are not calling this function correctly (conflicting types).

    Jim

  10. #10
    Registered User
    Join Date
    Apr 2011
    Posts
    12
    Quote Originally Posted by nonoob View Post
    Sorry kmess. Your advice is flawed.
    getATime does not need a known buf. It is a parameter that's assigned within the function. Not that it's used.
    The tsSearch() function copies temp to tmp using the user written copy function which does source -> destination.
    i have it commented out at the moment but getATime() is supposed to take the file path i give it and give me the access time of that file. i was going to ask about that if i stil had problems after i got the issues that i mentioned in my opening post resolved.

  11. #11
    Registered User
    Join Date
    Apr 2011
    Posts
    12
    Quote Originally Posted by jimblumberg View Post
    You should consider all warnings as errors. Your code should compile without any warnings or errors.


    Look at these warnings closely. The compiler is actually telling you that you are not calling this function correctly (conflicting types).

    Jim
    here are my warnings:
    jimmy@ubuntu:~/Desktop$ gcc -o tsSearch2 tsSearch2.c
    tsSearch2.c:54: warning: conflicting types for ‘tsSearch’
    tsSearch2.c:47: note: previous implicit declaration of ‘tsSearch’ was here
    tsSearch2.c:96: warning: conflicting types for ‘fixtemp’
    tsSearch2.c:76: note: previous implicit declaration of ‘fixtemp’ was here
    tsSearch2.c:102: warning: conflicting types for ‘str_copy’
    tsSearch2.c:75: note: previous implicit declaration of ‘str_copy’ was here

    since it was only implcit declarations i ignored them.
    fixtemp() takes a string that is a directory path with a file name appended, and it removes the file name at the end of the string for the next loop.

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    fixtemp() takes a string
    The problem is that you are not sending a string you are sending a char *. Therefore you have the conflicting types warning message. You have never initialized your tmp variable or your filepath, or your temp variables.

    Jim

  13. #13
    Registered User
    Join Date
    Apr 2011
    Posts
    12
    Quote Originally Posted by jimblumberg View Post
    The problem is that you are not sending a string you are sending a char *. Therefore you have the conflicting types warning message. You have never initialized your tmp variable or your filepath, or your temp variables.

    Jim
    sry i meant char *, im not sure what you mean by i havent initialized my variables. strcopy doesnt initialize them? also doesn't struct stat just take a char* of a file path(my reason for passing it to the function getATime which intend to use eventually)?

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    You need to allocate memory for your pointers. Either statically tmp[100] or dynamically with malloc/free. I would suggest the static method for now. strcpy(), strcat() do not allocate memory, the destination variable must already have memory allocated that is large enough to hold the string.

    I think you need to study up on character arrays and pointers.

    Jim

  15. #15
    Registered User
    Join Date
    Apr 2011
    Location
    Las Vegas
    Posts
    66
    I'm the first to admit I make mistakes, but I'd appreciate you telling me exactly where buf is being initialized in getATime? I love being educated.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. struct stat
    By DarkRoom in forum C Programming
    Replies: 8
    Last Post: 09-15-2009, 05:26 AM
  2. On reading Directory contents and listing them.
    By Deathfrost in forum C Programming
    Replies: 9
    Last Post: 07-14-2009, 08:21 AM
  3. ls -l and st.size in stat struct
    By cljones81 in forum C Programming
    Replies: 7
    Last Post: 02-08-2008, 03:58 PM
  4. Using sys/stat.h and listing directory contents in C...
    By smoothdogg00 in forum C Programming
    Replies: 2
    Last Post: 03-14-2006, 02:11 AM
  5. reading the contents of a directory
    By Unregistered in forum C++ Programming
    Replies: 10
    Last Post: 04-15-2002, 10:19 AM