master ohmu/fastfetch-openbsd / src / detection / os / os_apple.m
ohmu  ·  2026-10-15
  1#include "os.h"
  2#include "common/io.h"
  3#include "common/sysctl.h"
  4#include "common/strutil.h"
  5#include "common/mallocHelper.h"
  6
  7#include <stdlib.h>
  8#include <string.h>
  9#import <Foundation/Foundation.h>
 10
 11static bool parseSystemVersion(FFOSResult* os)
 12{
 13    NSError* error;
 14    NSString* fileName = @"file:///System/Library/CoreServices/SystemVersion.plist";
 15    NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
 16                                       error:&error];
 17    if(error)
 18        return false;
 19
 20    NSString* value;
 21
 22    if((value = dict[@"ProductName"]))
 23        ffStrbufInitS(&os->name, value.UTF8String);
 24    if((value = dict[@"ProductUserVisibleVersion"]))
 25        ffStrbufInitS(&os->version, value.UTF8String);
 26    if((value = dict[@"ProductBuildVersion"]))
 27        ffStrbufInitS(&os->buildID, value.UTF8String);
 28    if (ffStrbufStartsWithS(&os->version, "16."))
 29    {
 30        // macOS 26 Tahoe. #1809
 31        os->version.chars[0] = '2';
 32    }
 33
 34    return true;
 35}
 36
 37static bool detectOSCodeName(FFOSResult* os)
 38{
 39    // https://en.wikipedia.org/wiki/MacOS_version_history
 40    char* str_end;
 41    const char* version = os->version.chars;
 42    unsigned long num = strtoul(version, &str_end, 10);
 43    if (str_end == version) return false;
 44
 45    switch (num)
 46    {
 47        case 27: ffStrbufSetStatic(&os->codename, "Golden Gate"); return true;
 48        case 26:
 49        case 16: ffStrbufSetStatic(&os->codename, "Tahoe"); return true;
 50        case 15: ffStrbufSetStatic(&os->codename, "Sequoia"); return true;
 51        case 14: ffStrbufSetStatic(&os->codename, "Sonoma"); return true;
 52        case 13: ffStrbufSetStatic(&os->codename, "Ventura"); return true;
 53        case 12: ffStrbufSetStatic(&os->codename, "Monterey"); return true;
 54        case 11: ffStrbufSetStatic(&os->codename, "Big Sur"); return true;
 55        case 10: {
 56            version = str_end + 1;
 57            num = strtoul(version, &str_end, 10);
 58            if (str_end == version) return false;
 59
 60            switch (num)
 61            {
 62                case 16: ffStrbufSetStatic(&os->codename, "Big Sur"); return true;
 63                case 15: ffStrbufSetStatic(&os->codename, "Catalina"); return true;
 64                case 14: ffStrbufSetStatic(&os->codename, "Mojave"); return true;
 65                case 13: ffStrbufSetStatic(&os->codename, "High Sierra"); return true;
 66                case 12: ffStrbufSetStatic(&os->codename, "Sierra"); return true;
 67                case 11: ffStrbufSetStatic(&os->codename, "El Capitan"); return true;
 68                case 10: ffStrbufSetStatic(&os->codename, "Yosemite"); return true;
 69                case 9: ffStrbufSetStatic(&os->codename, "Mavericks"); return true;
 70                case 8: ffStrbufSetStatic(&os->codename, "Mountain Lion"); return true;
 71                case 7: ffStrbufSetStatic(&os->codename, "Lion"); return true;
 72                case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); return true;
 73                case 5: ffStrbufSetStatic(&os->codename, "Leopard"); return true;
 74                case 4: ffStrbufSetStatic(&os->codename, "Tiger"); return true;
 75                case 3: ffStrbufSetStatic(&os->codename, "Panther"); return true;
 76                case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); return true;
 77                case 1: ffStrbufSetStatic(&os->codename, "Puma"); return true;
 78                case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); return true;
 79            }
 80        }
 81    }
 82
 83    return false;
 84}
 85
 86void ffDetectOSImpl(FFOSResult* os)
 87{
 88    parseSystemVersion(os);
 89
 90    ffStrbufSetStatic(&os->id, "macos");
 91
 92    if(__builtin_expect(os->name.length == 0, 0))
 93        ffStrbufSetStatic(&os->name, "macOS");
 94
 95    if(__builtin_expect(os->version.length == 0, 0))
 96        ffSysctlGetString("kern.osproductversion", &os->version);
 97
 98    if(__builtin_expect(os->buildID.length == 0, 0))
 99        ffSysctlGetString("kern.osversion", &os->buildID);
100
101    ffStrbufAppend(&os->versionID, &os->version);
102
103    detectOSCodeName(os);
104
105    ffStrbufSetF(&os->prettyName, "%s %s %s (%s)", os->name.chars, os->codename.chars, os->version.chars, os->buildID.chars);
106}