Thread: stat() -> how to find out if file has S_IROTH

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    14

    stat() -> how to find out if file has S_IROTH

    Thats my program which is doing BFS(for that purpose i am using single linked list instead of FIFO) on directories, and is writing all files it found. I would like to ask you how to find out if the file is read only for Others.
    Actaully its tested on my windows tommorow morning I will test it on unix and I want to write only the files with the S_IROTH.
    If you can give me some advice or something I would be gratefull. Thanks
    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <dirent.h>
    #include <string.h>
    #include <sys/stat.h>
    //#include "listHelper.h"
    
    
    int isDir(const char* name){
            char* pName = malloc (strlen(name)+1 * sizeof(char));
            strcpy(pName,name);
            char* help = pName + strlen(name)-3;
    
    
            if (strchr(help,'.')!=NULL){
                free(pName);
                return 2;
            }
                free(pName);
                DIR* p_look_dir= opendir(name);
    
    
                if (p_look_dir!=NULL ){
    
    
                 closedir(p_look_dir);
                 return 1;
                }
    
    
             return 0;
        }
    
    
    typedef struct listItem{
                struct listItem* next;
                char* tableName;
            } listItem;
    
    
        listItem* prev;
        listItem* cur;
        listItem* list = NULL;
    
    
        void add(const char* name, listItem** list){
            listItem *newItem = malloc(sizeof(listItem));
    
    
            char* pArray = malloc(strlen(name)+1*sizeof(char));
            newItem->tableName = strcpy(pArray,name);
    
    
            newItem->next = *list;
            *list = newItem;
    
    
        }
    
    
        void scan(listItem** list){
    
    
         prev = *list;
         if (prev->next==NULL) {
            cur = prev;
           // prev = NULL;
         }else {
             cur = prev->next;
    
    
         }
    
    
            if (prev!=NULL){
                while (cur->next != NULL){
                    prev=cur;
                    cur= cur->next;
                }
            }
    
    
            if (*list == NULL ){
                cur= NULL;
                prev= NULL;
            }
        }
    
    
    
    
    
    
    
    
    
    
        void deleteList (){
           free(cur->tableName);
           free(cur);
    
    
    
    
           if (prev!=NULL)
            prev->next =NULL;
    
    
    
    
    
    
           }
    int main()
    {
    
    
    
    
        add("C:/Users/Ivo/Downloads/IVOVI JAVA/",&list);
    
    
    
    
        DIR *directory = NULL;
    
    
        struct dirent *pFile = NULL;
        do{
            scan(&list);
            directory = opendir(cur->tableName);
            while (pFile=readdir(directory)){
                char* predlzCestuODir = malloc(strlen(pFile->d_name)+ strlen(cur->tableName)+2 * sizeof(char));
                strcpy(predlzCestuODir,cur->tableName);
                strcat(predlzCestuODir,pFile->d_name);
                strcat(predlzCestuODir,"/");
    
    
                    int flag = isDir(predlzCestuODir);
    
    
                    if (flag==1){
                        add(predlzCestuODir,&list);
                    }
                   /**
                   *This if test if it is no a directory, if it isnt it will write               *the route to that file, and i guess this is the right spot for the *I_SROTH testing
                   */ 
                   if (flag==0)
                        printf("%s\n",predlzCestuODir);
    
    
                free(predlzCestuODir);
            }
            closedir(directory);
            scan(&list);
            deleteList ();
    
    
        }while(cur!=prev);
    
    
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Well, when you get to that Unix machine tomorrow, fire up a console and type "man 2 stat". Read all about the function, and read the part about S_IROTH. Then read over the example. Note that the S_IROTH flag is part of a bit field. If you aren't too clear on what that is, look in your C textbook or class notes for the bitwise-AND operator (&).

  3. #3
    Registered User
    Join Date
    Nov 2011
    Posts
    14

    Address is 0 bytes inside a block of size 16 free'd

    Hi, I have some memory issues, somehow I am freeing already freed memory but I really cant find it after staring at it for quite long while, valgrind is writing sth like this... btw program works how it should but i have to deal with those 16 bytes...
    I would be gratefull for any help. thanks


    Code:
    ==3200== Invalid write of size 8==3200==    at 0x400B88: deleteList (in /home/xnovak11/Downloads/C/hwDirectories/main)
    ==3200==    by 0x400D4C: mainFunc (in /home/xnovak11/Downloads/C/hwDirectories/main)
    ==3200==    by 0x400E87: main (in /home/xnovak11/Downloads/C/hwDirectories/main)
    ==3200==  Address 0x51d4840 is 0 bytes inside a block of size 16 free'd
    ==3200==    at 0x4C2695D: free (vg_replace_malloc.c:366)
    ==3200==    by 0x400B74: deleteList (in /home/xnovak11/Downloads/C/hwDirectories/main)
    ==3200==    by 0x400D4C: mainFunc (in /home/xnovak11/Downloads/C/hwDirectories/main)
    ==3200==    by 0x400E87: main (in /home/xnovak11/Downloads/C/hwDirectories/main)
    ==3200==
    ==3200==
    ==3200== HEAP SUMMARY:
    ==3200==     in use at exit: 0 bytes in 0 blocks
    ==3200==   total heap usage: 35 allocs, 35 frees, 165,099 bytes allocated
    ==3200==
    ==3200== All heap blocks were freed -- no leaks are possible
    ==3200==
    ==3200== For counts of detected and suppressed errors, rerun with: -v
    ==3200== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <dirent.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include "correctperms.h"
    
    
    int corrected=0;
    int isDir(const char* name){
            char* pName = malloc (strlen(name)+1 * sizeof(char));
            strcpy(pName,name);
            char* help = pName + strlen(name)-3;
    
    
            if (strlen(pName)>126) {
                    free(pName);
                    fprintf(stderr,"dlha cesta\n");
                return 2;
            }
            if (strchr(help,'.')!=NULL){
                free(pName);
                return 2;
            }
    
    
                DIR* p_look_dir= opendir(pName);
                free(pName);
                if (p_look_dir!=NULL ){
    
    
                 closedir(p_look_dir);
                 return 1;
                }
    
    
             return 0;
        }
    
    
    
    
    
    
        listItem* prev;
        listItem* cur;
        listItem* list = NULL;
        int prechod;
    
    
        void add(const char* name, listItem** list){
            listItem *newItem = malloc(sizeof(listItem));
    
    
             newItem->tableName  = malloc(strlen(name)+1*sizeof(char));
              strcpy(newItem->tableName,name);
    
    
    
    
            newItem->next = *list;
            *list = newItem;
    
    
        }
    
    
        void scan(listItem** list){
    
    
         prev = *list;
         if (prev->next==NULL) {
            cur = prev;
            prechod=0;
         }else {
             cur = prev->next;
             prechod=1;
         }
    
    
            if (prev!=NULL){
                while (cur->next != NULL){
                    prev=cur;
                    cur= cur->next;
                }
            }
    
    
            if (*list == NULL ){
                cur= NULL;
                prev= NULL;
            }
        }
    
    
            void deleteList (){
                    if(cur->tableName!=NULL)
                            free(cur->tableName);
    
    
                    if (cur)
                            free(cur);
    
    
    
    
                    if (prev!=NULL)
                            prev->next =NULL;
            }
    
    
    int mainFunc(const char* buffer){
    
    
         add(buffer,&list);
    
    
    
    
        DIR *directory = NULL;
        struct stat sb;
        struct dirent *pFile = NULL;
        do{
            scan(&list);
            directory = opendir(cur->tableName);
            pFile=readdir(directory);
            while (pFile!=NULL){
    
    
    
    
    
    
               char* predlzCestuODir = malloc(strlen(pFile->d_name)+ strlen(cur->tableName)+2 * sizeof(char));
                strcpy(predlzCestuODir,cur->tableName);
                strcat(predlzCestuODir,pFile->d_name);
    
    
    
    
                    int flag = isDir(predlzCestuODir);
    
    
                    if (flag==1){
    
    
                            strcat(predlzCestuODir,"/");
                            add(predlzCestuODir,&list);
                    }
                    if (flag==0){
    
    
                            if (stat(predlzCestuODir, &sb) == -1) {
                                perror("stat");
                                exit(EXIT_FAILURE);
                           }
    
    
                            if (sb.st_mode & S_IROTH){
                                    corrected++;
                                    printf("%s\n",predlzCestuODir);
                             }
                    printf("%s",predlzCestuODir);
                    }
                free(predlzCestuODir);
                pFile=readdir(directory);
            }
        closedir(directory);
            scan(&list);
            deleteList ();
    
    
        }while(prechod==1);
    
    
        return corrected;
    }
    Code:
    #ifndef CORRECTPERMS_H_INCLUDED#define CORRECTPERMS_H_INCLUDED
    typedef struct listItem{
                struct listItem* next;
                char* tableName;
            } listItem;
    
    
    void deleteList ();
    
    
    void scan(listItem** list);
    
    
    void add(const char* name, listItem** list);
    
    
    int isDir(const char* name);
    
    
    int mainFunc(const char* buffer);
    
    
    
    
    
    
    #endif // CORRECTPERMS_H_INCLUDED
    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <dirent.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    
    #include "correctperms.h"
    
    
    int main(int argc,char *argv[])
    {
      // if (argc!=1){
    //      fprintf(stderr,"error: could not open file\n");
    //       return -1;
    //      }
    
    
            int i;
           
    
    
    
    
                     char* lomitko = malloc (strlen(argv[1])+1 * sizeof(char));
                    strcpy (lomitko,argv[1]);
                    char* help = lomitko +strlen(lomitko)-1;
    
    
    
    
    
    
                    if (*help=='/'){
                            free(lomitko);
                            i=mainFunc(argv[1]);
                            printf("Corrected %d files.\n",i);
                    }else{
                            free(lomitko);
                            lomitko = malloc (strlen(argv[1])+2 * sizeof(char));
                            strcpy(lomitko,argv[1]);
                            strcat (lomitko,"/");
                            i=mainFunc(lomitko);
                            free(lomitko);
                            printf("Corrected %d files.\n",i);
                    }
        return 0;
    }

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    In function isDir you call free three times; why do you think the last time is valid?

    Tim S.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    A couple of hundred lines of code needs better indentation.
    SourceForge.net: Indentation - cpwiki
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Nov 2011
    Posts
    14
    Because if the condition is true I am returning value immidiatelly so before that I freeing my pointer, and if the condition were both false so I have to free the pointer or he will be forgotten.
    I may be wrong, I am not sure.

    I have been playing with those pointers but they were fine, if I changed sth Valgrind started showing leaks.

    But thank you for your time.

  7. #7
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by flegmik View Post
    Because if the condition is true I am returning value immidiatelly so before that I freeing my pointer, and if the condition were both false so I have to free the pointer or he will be forgotten.
    I missed the returns; you are right should not cause problems because of returns.

    Tim S.

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    I think you code is poorly indent and I have no idea what deleteList is supposed to do; So, I can not help you.
    Note: If it is supposed to delete all the elements in a link list; I consider it very unlikely that one can write a function doing that without a loop or recursion.

    Tim S.

  9. #9
    Registered User
    Join Date
    Nov 2011
    Posts
    14
    deleteList will delete the first list in my linked list.
    it works like this-> I get some way to some file like /home/xnovak/directory/ and I am supposed to write all files which are readable for all, and if I found a directory I should search in him too, so when I find a directory I put it at the end of my linked list for further search...

    I will try to make my code more readable, cause it is very important homework for me and i get 0 points if I have just 1 bytenot freed or sth.

    K I tried my best to make it pretty, I put here only the correctperms.c where is everything happening
    Hope someone will look at it...

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <dirent.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include "correctperms.h"
    
    
    int corrected=0;
    
    
    /**
    *param is way to the file, so for example /home/xuser/directory/file.dat
    * or it can be /home/xuser/directory/ and function returns wheather it is/isnt a directory/file
    *
    *return 0 = its a file
    *return 1 = its directory
    *return 2 = if it is . or .. like way up, cause readdir returns way up
    *return 2 = if the way is longer then 127 characters
    *
    * so the point is that when we return 2 we dont care about that file/directory 
    */
    int isDir(const char* name){
            
            char* pName = malloc (strlen(name)+1 * sizeof(char));
            strcpy(pName,name);
            // help will be at last 3 characters of the sentance mostly to dont have /home/xuser/directory/./   that dot
            char* help = pName + strlen(name)-3;
            
            //decides if the way isnt too long, if true STDERR, return 2, and we dont care about this way anymore
            if (strlen(pName)>126) {
                    free(pName);
                    fprintf(stderr,"dlha cesta\n");
                return 2;
            }
            
            //decides if the way up, cause readdir can return . or .. it means directory above, 
            //my searching way, we return 2 and dont care about them anymore
            if (strchr(help,'.')!=NULL){
                free(pName);
                return 2;
            }
            
            //decides if it is Directory or File, so we try to open it throug opendir
            // if opendir returns a pointer it is directory and we return 1
            // and we will put it into our single linked list -> its elsewhere
            DIR* p_look_dir= opendir(pName);
            free(pName);
                
            if (p_look_dir!=NULL ){
                closedir(p_look_dir);
            return 1;
            }
                
            //if it a File return 0;
             return 0;
        }
    
    
    
    
    
    
        
        listItem* prev; // void scan sets this pointer to be pointing on second list in our single linked list
        listItem* cur;  // void scan sets this pointer to be pointing on first list in our single linked list
        listItem* list = NULL; //pointer to the last list in our single linked list
        int prechod;        // something I use later in while loop to decide wheather end it or not
        /**
        *param name = way to the file for example /home/xuser/directory/another_directory/
        * list = is pointing on the last list in my single linked list
        *
        * so my new created list is last in my single linked list and is pointing on the previous last listItem          
        */
        void add(const char* name, listItem** list){
            listItem *newItem = malloc(sizeof(listItem));
    
    
            newItem->tableName  = malloc(strlen(name)+1*sizeof(char));
            strcpy(newItem->tableName,name);
    
    
    
    
            newItem->next = *list;
            *list = newItem;
    
    
        }
        
        /**
        *param= pointer to list, so I give him pointer to last list in my single linked list struct
        * and sets pointer cur to point at first list in my linked list struct
        * and sets pointer prev to point at second list in my linked list struct    
        */
        void scan(listItem** list){
            //sets previous on last list in our single linked list 
            prev = *list;
            
            //if previous->next ==NULL, it means it is the last list and we set our first item to be the last
            // prechod sets on 0 to know we are at the last list in our linked list 
            if (prev->next==NULL) {
                cur = prev;
                prechod=0;
            }else{
                cur = prev->next;
                prechod=1;
            }
            
            // here we are looking for the first list, if we find him we set cur to point at him
            // and set prev to point at second list
            if (prev!=NULL){
                while (cur->next != NULL){
                    prev=cur;
                    cur= cur->next;
                }
            }
        }
            /**
            *deletes and free the memory of the first list in my single linked list
            *and second list becomes first and points at NULL  which will means that it is first     
            */
            void deleteList (){
                    //firstly freeing the memory allocated insade struct
                    if(cur->tableName)
                            free(cur->tableName);
                    
                    //freeing that struct
                    if (cur)
                            free(cur);
                    //setting second list to become first list
                    if (prev!=NULL)
                            prev->next =NULL;
            }
    
    
    /**
    *param is way to the directory which I will be searching throug, so for example /home/xuser/directory/
    *
    * returns number of found files with S_IROTH
    */
    int mainFunc(const char* buffer){
        
        //so we put our way to the first list in our linked list, he is there alone now
        add(buffer,&list);
    
    
        //initizing needed variables
        DIR *directory = NULL;
        struct stat sb;
        struct dirent *pFile = NULL;
        
        do{
            //sets pointers at first and second item
            scan(&list);
            // open directory from the first list in our linked list 
            directory = opendir(cur->tableName);
            // read first file in it
            pFile=readdir(directory);
            // do it until you have sth to read in that directory
            while (pFile!=NULL){
                //predlzCestuODir allocate memory for the way we already have like /home/xuser/directory/
                // and strcat the name of the file returned by readdir for example readdir returns program.c
                // so we allocate enough space to make sentance /home/xuser/directory/program.c and let one more space to put a slasher later
                //thats why its +2
                char* predlzCestuODir = malloc(strlen(pFile->d_name)+ strlen(cur->tableName)+2 * sizeof(char));
                strcpy(predlzCestuODir,cur->tableName);
                strcat(predlzCestuODir,pFile->d_name);
                
                //sets flag on 0,1,2 read the isDir comments
                int flag = isDir(predlzCestuODir);
                //if it is a directory, put slacsher at the end a put list at the end of 
                //our linked list with the way to another directory that should be searched
                if (flag==1){
                    strcat(predlzCestuODir,"/");
                    add(predlzCestuODir,&list);
                }
                //if it is a file, get the information S_IROTH and if it is printf the way to that file and increments variable corrected
                if (flag==0){
                    if (stat(predlzCestuODir, &sb) == -1) {
                        perror("stat");
                        exit(EXIT_FAILURE);
                        }
    
    
                        if (sb.st_mode & S_IROTH){
                        //says how many file are S_IROTH
                        corrected++;
                        printf("%s\n",predlzCestuODir);
                        }
                }
                     
                free(predlzCestuODir);
                pFile=readdir(directory);
            }
        //when there is nothing more to read in that directory, i will close him
        closedir(directory);
        //i look for the first and second list in our linked list, if we have only one list it means the final last list prechod will be set to 1
        scan(&list);
         //deleteing the first list and setting second list to become first list
        deleteList ();
        // condition=if it was the last list and he was removed end of cycle and return corrected
        }while(prechod==1);
    
    
        return corrected;
    }
    Last edited by flegmik; 12-08-2011 at 06:00 PM. Reason: adding my pretty code

  10. #10
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Tip: Unless you're in a very limited stack environment, then if you find yourself using malloc/free on the same variable within a function, chances are you can remove the dynamic allocation and simply use an automatic buffer. Much of your code could be replace with

    Code:
    char path[MAX_PATH];
    placed at the start of your function, and using that instead of malloc/free. You're working with file paths, which will not exceed the length of MAX_PATH. This change also has the added benefit of improved performance, as dynamic memory allocation is expensive.

    Actually, your isDir does lots of unnecessary stuff. here's your isDir() rewritten:

    Code:
    int isDir(const char* name){
            // help will be at last 3 characters of the sentance mostly to dont have /home/xuser/directory/./   that dot
            const char* help = name + strlen(name)-3;
            
            //decides if the way isnt too long, if true STDERR, return 2, and we dont care about this way anymore
            if (strlen(name)>126) {
                fprintf(stderr,"dlha cesta\n");
                return 2;
            }
            
            //decides if the way up, cause readdir can return . or .. it means directory above, 
            //my searching way, we return 2 and dont care about them anymore
            if (strchr(help,'.')!=NULL){
                return 2;
            }
            
            //decides if it is Directory or File, so we try to open it throug opendir
            // if opendir returns a pointer it is directory and we return 1
            // and we will put it into our single linked list -> its elsewhere
            DIR* p_look_dir= opendir(name);
                
            if (p_look_dir!=NULL ){
                closedir(p_look_dir);
                return 1;
            }
                
            //if it a File return 0;
             return 0;
        }
    That should work for that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Distinguish symbolic link from file (stat function)
    By mario++ in forum C Programming
    Replies: 10
    Last Post: 05-07-2010, 04:26 PM
  2. Problems with stat() <sys/stat.h>
    By headbr in forum C Programming
    Replies: 9
    Last Post: 07-27-2008, 08:49 PM
  3. Replies: 1
    Last Post: 09-06-2007, 04:17 AM
  4. help with my mIRC log file stat generator.
    By TravisS in forum C Programming
    Replies: 3
    Last Post: 06-13-2002, 09:28 PM
  5. Capturing file stat information
    By Sue Paterniti in forum C Programming
    Replies: 3
    Last Post: 04-15-2002, 05:47 AM