Search code examples
cmacosunixpermissionsxattr

How to get extended attributes of a file(UNIX/C)?


When I type ls -l in the command line, sometimes an @ or + symbol comes up alongside the file permissions(btw, I am on OS X), as shown below:

-rw-r-----@  1 john  staff      6731 Sep 28 01:10 mutations.txt
drwxr-xr-x+ 71 john  staff      2414 Mar 25 18:16 ..

I know how to get the permission bits using the stat structure, but I don't think these extended permission values are there. Can someone point me in the right direction as to how to obtain these values via a C or POSIX API?

EDIT:

I attempted the following:

#include <sys/types.h>
#include <sys/xattr.h>
#include <sys/types.h>

int main () {
    char  l[1024];
    listxattr("/Users/john/desktop/mutations.txt", l, 1024,  XATTR_SHOWCOMPRESSION);

    printf("%s\n", l);
}

and got as output:

com.apple.metadata:kMDItemWhereFroms

Still trying to understand how to convert this to an @ or +?


Solution

  • Following is some code I scraped off of the official implementation of ls given by Apple you will find here. The code is long so do CMD + F and search for "printlong".

    #include <sys/types.h>
    #include <sys/xattr.h>
    #include <sys/types.h>
    #include <sys/acl.h>
    #include <stdio.h>
    
    int main () {
        acl_t acl = NULL;
        acl_entry_t dummy;
        ssize_t xattr = 0;
        char chr;
        char * filename = "/Users/john/desktop/mutations.txt";
    
        acl = acl_get_link_np(filename, ACL_TYPE_EXTENDED);
        if (acl && acl_get_entry(acl, ACL_FIRST_ENTRY, &dummy) == -1) {
            acl_free(acl);
            acl = NULL;
        }
        xattr = listxattr(filename, NULL, 0, XATTR_NOFOLLOW);
        if (xattr < 0)
            xattr = 0;
    
        if (xattr > 0)
            chr = '@';
        else if (acl != NULL)
            chr = '+';
        else
            chr = ' ';
    
        printf("%c\n", chr);
     }
    

    Depending on the file used, the output will be a blank, @, or + in exactly the same manner ls -l displays it. Hope this helps !