Search code examples
c++cosx-maverickstaggingxattr

OSX Mavericks get tags of a file in c program


I need to get the usertags for a file in c program. I am aware of "mdls -name kMDItemUserTags FILENAME" command to get this details. But i need to do it in c code. Is there any way from which i can get the values directly instead of running this command and parsing.


Solution

  • You can do it via the NSURL Resource Key NSURLLabelColorKey which uses an NSColor to specify the colour.

    Therefore it cannot be done in C per se, however you can write an Objective-C implementation file with a C function entry point so it can be called from C (as noted by @Alex MDC in the comments you can use CoreFoundation and do it in C directly, but I would always favour Foundation where possible as it's easier to use when using ARC).

    Given NSColor is used to specify the colour, you'll need to create a struct to hold the RGB values and translate between that struct and NSColor yourself.

    Something like (untested):

    OSXFileLabelColour.h:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    typedef struct {
        int isSet;          // if 0 then no colour set
        float r;
        float g;
        float b;
    } LabelColour;
    
    /* Return 1 for success or 0 for failure */
    extern int getFileLabelColour(const char *filename, LabelColour *colour);
    
    #ifdef __cplusplus
    }    // extern "C"
    #endif
    

    OSXFileLabelColour.m:

    #import <Foundation/Foundation.h>
    #import "OSXFileLabelColour"
    
    int getFileLabelColour(const char *filename, LabelColour *colour)
    {
        int retval = 0;
        NSURL *url = [NSURL fileURLWithPath:@(filename)];
        if (url) {
            NSColor *nscolor = nil;
            NSError *error = nil;
            if ([url getResourceValue:&nscolor
                               forKey:NSURLLabelColorKey
                                error:&error]) {
                if (nscolor) {
                    CGFloat r, g, b, a;
                    [nscolor getRed:&r green:&g blue:&b alpha:&a];
                    colour->isSet = 1;
                    colour->r = r;
                    colour->g = g;
                    colour->b = b;
                } else {
                    colour->isSet = 0;
                }
                retval = 1;                
            } else {
                NSLog(@"Failed to get colour label for file '%s': %@", filename, [error localizedDescription]);
            }
        } else {
            NSLog(@"Failed to create URL for file '%s'", filename);
        }
        return retval;
    }