Search code examples
cfilepermissionschmodstat

How to convert string permission to mode_t type


I am writing a program which changes file permissions. The permissions will be passed through a command line argument as a char * and then converted to mode_t type and given to chmod().

How could I change a string permission/mode to mode_t?

For example given a string 4777 aka rwsrwxrwx how could 4777 be changed to mode_t?


Solution

  • You can parse a string to extract an octal value by calling strtol and providing 8 as the base:

    int mode = strtol(str, NULL, 8);
    

    To be safe, you might want to do some additional sanity checks:

    // Extract file mode from a string, with sanity checks.
    // Returns non-zero on success. 
    int string_to_filemode(const char* str, mode_t* mode)
    {
        char* end = NULL;
        *mode = (mode_t)strtol(str, &end, 8);
        if (!end) return 0;
        while(isspace(*end)) end++;
        return *end == '\0' && (unsigned)*mode < 010000;
    }
    

    Here is an example using this:

    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <sys/stat.h>
    
    int string_to_filemode(const char* str, mode_t* mode)
    {
        char* end = NULL;
        *mode = (mode_t)strtol(str, &end, 8);
        if (!end) return 0;
        while(isspace(*end)) end++;
        return *end == '\0' && (unsigned)*mode < 010000;
    }
    
    int main(int argc, char *argv[])
    {
        for (int i = 1; i < argc; i++)
        {
            mode_t mode;
            if (string_to_filemode(argv[i], &mode))
                printf("Mode: str=%s val=%04o\n", argv[i], mode);
            else
                printf("Invalid mode: %s\n", argv[i]);
        }
        return 0;
    }
    

    Output, when invoked with command-line arguments 4777 644 1000 11232 91 abc -1:

    Mode: str=4777 val=4777
    Mode: str=644 val=0644
    Mode: str=1000 val=1000
    Invalid mode: 11232
    Invalid mode: 91
    Invalid mode: abc
    Invalid mode: -1
    

    Live demo: https://godbolt.org/z/4nhW9G9jM