master ohmu/fastfetch-openbsd / src / detection / host / host_mac.c
ohmu  ·  2026-10-15
  1#include "host.h"
  2#include "common/strutil.h"
  3
  4const char* ffHostGetMacProductNameWithHwModel(const FFstrbuf* hwModel) {
  5    // Macbook Pro: https://support.apple.com/en-us/HT201300
  6    // Macbook Air: https://support.apple.com/en-us/HT201862
  7    // Mac mini:    https://support.apple.com/en-us/HT201894
  8    // iMac:        https://support.apple.com/en-us/HT201634
  9    // Mac Pro:     https://support.apple.com/en-us/HT202888
 10    // Mac Studio:  https://support.apple.com/en-us/HT213073
 11
 12    if (ffStrbufStartsWithS(hwModel, "MacBookPro")) {
 13        const char* version = hwModel->chars + strlen("MacBookPro");
 14        if (ffStrEquals(version, "18,3") ||
 15            ffStrEquals(version, "18,4")) {
 16            return "MacBook Pro (14-inch, 2021)";
 17        }
 18        if (ffStrEquals(version, "18,1") ||
 19            ffStrEquals(version, "18,2")) {
 20            return "MacBook Pro (16-inch, 2021)";
 21        }
 22        if (ffStrEquals(version, "17,1")) {
 23            return "MacBook Pro (13-inch, M1, 2020)";
 24        }
 25        if (ffStrEquals(version, "16,3")) {
 26            return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)";
 27        }
 28        if (ffStrEquals(version, "16,2")) {
 29            return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)";
 30        }
 31        if (ffStrEquals(version, "16,4") ||
 32            ffStrEquals(version, "16,1")) {
 33            return "MacBook Pro (16-inch, 2019)";
 34        }
 35        if (ffStrEquals(version, "15,4")) {
 36            return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)";
 37        }
 38        if (ffStrEquals(version, "15,3")) {
 39            return "MacBook Pro (15-inch, 2019)";
 40        }
 41        if (ffStrEquals(version, "15,2")) {
 42            return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)";
 43        }
 44        if (ffStrEquals(version, "15,1")) {
 45            return "MacBook Pro (15-inch, 2018/2019)";
 46        }
 47        if (ffStrEquals(version, "14,3")) {
 48            return "MacBook Pro (15-inch, 2017)";
 49        }
 50        if (ffStrEquals(version, "14,2")) {
 51            return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)";
 52        }
 53        if (ffStrEquals(version, "14,1")) {
 54            return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)";
 55        }
 56        if (ffStrEquals(version, "13,3")) {
 57            return "MacBook Pro (15-inch, 2016)";
 58        }
 59        if (ffStrEquals(version, "13,2")) {
 60            return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)";
 61        }
 62        if (ffStrEquals(version, "13,1")) {
 63            return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)";
 64        }
 65        if (ffStrEquals(version, "12,1")) {
 66            return "MacBook Pro (Retina, 13-inch, Early 2015)";
 67        }
 68        if (ffStrEquals(version, "11,4") ||
 69            ffStrEquals(version, "11,5")) {
 70            return "MacBook Pro (Retina, 15-inch, Mid 2015)";
 71        }
 72        if (ffStrEquals(version, "11,2") ||
 73            ffStrEquals(version, "11,3")) {
 74            return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)";
 75        }
 76        if (ffStrEquals(version, "11,1")) {
 77            return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)";
 78        }
 79        if (ffStrEquals(version, "10,2")) {
 80            return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)";
 81        }
 82        if (ffStrEquals(version, "10,1")) {
 83            return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)";
 84        }
 85        if (ffStrEquals(version, "9,2")) {
 86            return "MacBook Pro (13-inch, Mid 2012)";
 87        }
 88        if (ffStrEquals(version, "9,1")) {
 89            return "MacBook Pro (15-inch, Mid 2012)";
 90        }
 91        if (ffStrEquals(version, "8,3")) {
 92            return "MacBook Pro (17-inch, 2011)";
 93        }
 94        if (ffStrEquals(version, "8,2")) {
 95            return "MacBook Pro (15-inch, 2011)";
 96        }
 97        if (ffStrEquals(version, "8,1")) {
 98            return "MacBook Pro (13-inch, 2011)";
 99        }
100        if (ffStrEquals(version, "7,1")) {
101            return "MacBook Pro (13-inch, Mid 2010)";
102        }
103        if (ffStrEquals(version, "6,2")) {
104            return "MacBook Pro (15-inch, Mid 2010)";
105        }
106        if (ffStrEquals(version, "6,1")) {
107            return "MacBook Pro (17-inch, Mid 2010)";
108        }
109        if (ffStrEquals(version, "5,5")) {
110            return "MacBook Pro (13-inch, Mid 2009)";
111        }
112        if (ffStrEquals(version, "5,3")) {
113            return "MacBook Pro (15-inch, Mid 2009)";
114        }
115        if (ffStrEquals(version, "5,2")) {
116            return "MacBook Pro (17-inch, Mid/Early 2009)";
117        }
118        if (ffStrEquals(version, "5,1")) {
119            return "MacBook Pro (15-inch, Late 2008)";
120        }
121        if (ffStrEquals(version, "4,1")) {
122            return "MacBook Pro (17/15-inch, Early 2008)";
123        }
124    } else if (ffStrbufStartsWithS(hwModel, "MacBookAir")) {
125        const char* version = hwModel->chars + strlen("MacBookAir");
126        if (ffStrEquals(version, "10,1")) {
127            return "MacBook Air (M1, 2020)";
128        }
129        if (ffStrEquals(version, "9,1")) {
130            return "MacBook Air (Retina, 13-inch, 2020)";
131        }
132        if (ffStrEquals(version, "8,2")) {
133            return "MacBook Air (Retina, 13-inch, 2019)";
134        }
135        if (ffStrEquals(version, "8,1")) {
136            return "MacBook Air (Retina, 13-inch, 2018)";
137        }
138        if (ffStrEquals(version, "7,2")) {
139            return "MacBook Air (13-inch, Early 2015/2017)";
140        }
141        if (ffStrEquals(version, "7,1")) {
142            return "MacBook Air (11-inch, Early 2015)";
143        }
144        if (ffStrEquals(version, "6,2")) {
145            return "MacBook Air (13-inch, Mid 2013/Early 2014)";
146        }
147        if (ffStrEquals(version, "6,1")) {
148            return "MacBook Air (11-inch, Mid 2013/Early 2014)";
149        }
150        if (ffStrEquals(version, "5,2")) {
151            return "MacBook Air (13-inch, Mid 2012)";
152        }
153        if (ffStrEquals(version, "5,1")) {
154            return "MacBook Air (11-inch, Mid 2012)";
155        }
156        if (ffStrEquals(version, "4,2")) {
157            return "MacBook Air (13-inch, Mid 2011)";
158        }
159        if (ffStrEquals(version, "4,1")) {
160            return "MacBook Air (11-inch, Mid 2011)";
161        }
162        if (ffStrEquals(version, "3,2")) {
163            return "MacBook Air (13-inch, Late 2010)";
164        }
165        if (ffStrEquals(version, "3,1")) {
166            return "MacBook Air (11-inch, Late 2010)";
167        }
168        if (ffStrEquals(version, "2,1")) {
169            return "MacBook Air (Mid 2009)";
170        }
171    } else if (ffStrbufStartsWithS(hwModel, "Macmini")) {
172        const char* version = hwModel->chars + strlen("Macmini");
173        if (ffStrEquals(version, "9,1")) {
174            return "Mac mini (M1, 2020)";
175        }
176        if (ffStrEquals(version, "8,1")) {
177            return "Mac mini (2018)";
178        }
179        if (ffStrEquals(version, "7,1")) {
180            return "Mac mini (Mid 2014)";
181        }
182        if (ffStrEquals(version, "6,1") ||
183            ffStrEquals(version, "6,2")) {
184            return "Mac mini (Late 2012)";
185        }
186        if (ffStrEquals(version, "5,1") ||
187            ffStrEquals(version, "5,2")) {
188            return "Mac mini (Mid 2011)";
189        }
190        if (ffStrEquals(version, "4,1")) {
191            return "Mac mini (Mid 2010)";
192        }
193        if (ffStrEquals(version, "3,1")) {
194            return "Mac mini (Early/Late 2009)";
195        }
196    } else if (ffStrbufStartsWithS(hwModel, "MacBook")) {
197        const char* version = hwModel->chars + strlen("MacBook");
198        if (ffStrEquals(version, "10,1")) {
199            return "MacBook (Retina, 12-inch, 2017)";
200        }
201        if (ffStrEquals(version, "9,1")) {
202            return "MacBook (Retina, 12-inch, Early 2016)";
203        }
204        if (ffStrEquals(version, "8,1")) {
205            return "MacBook (Retina, 12-inch, Early 2015)";
206        }
207        if (ffStrEquals(version, "7,1")) {
208            return "MacBook (13-inch, Mid 2010)";
209        }
210        if (ffStrEquals(version, "6,1")) {
211            return "MacBook (13-inch, Late 2009)";
212        }
213        if (ffStrEquals(version, "5,2")) {
214            return "MacBook (13-inch, Early/Mid 2009)";
215        }
216    } else if (ffStrbufStartsWithS(hwModel, "MacPro")) {
217        const char* version = hwModel->chars + strlen("MacPro");
218        if (ffStrEquals(version, "7,1")) {
219            return "Mac Pro (2019)";
220        }
221        if (ffStrEquals(version, "6,1")) {
222            return "Mac Pro (Late 2013)";
223        }
224        if (ffStrEquals(version, "5,1")) {
225            return "Mac Pro (Mid 2010 - Mid 2012)";
226        }
227        if (ffStrEquals(version, "4,1")) {
228            return "Mac Pro (Early 2009)";
229        }
230    } else if (ffStrbufStartsWithS(hwModel, "Mac")) {
231        const char* version = hwModel->chars + strlen("Mac");
232        if (ffStrEquals(version, "18,5")) {
233            return "Mac Mini (M6, 2026)";
234        }
235        if (ffStrEquals(version, "17,16")) {
236            return "Mac Mini (M5 Pro, 2026)";
237        }
238        if (ffStrEquals(version, "17,15")) {
239            return "Mac Studio (M5 Ultra, 2026)";
240        }
241        if (ffStrEquals(version, "17,14")) {
242            return "Mac Studio (M5 Max, 2026)";
243        }
244        if (ffStrEquals(version, "17,9")) {
245            return "MacBook Pro (14-inch, M5 Pro, 2026)";
246        }
247        if (ffStrEquals(version, "17,8")) {
248            return "MacBook Pro (16-inch, M5 Pro, 2026)";
249        }
250        if (ffStrEquals(version, "17,7")) {
251            return "MacBook Pro (14-inch, M5 Max, 2026)";
252        }
253        if (ffStrEquals(version, "17,6")) {
254            return "MacBook Pro (16-inch, M5 Max, 2026)";
255        }
256        if (ffStrEquals(version, "17,5")) {
257            return "MacBook Neo (13-inch, A18 Pro, 2026)";
258        }
259        if (ffStrEquals(version, "17,4")) {
260            return "MacBook Air (15-inch, M5, 2026)";
261        }
262        if (ffStrEquals(version, "17,3")) {
263            return "MacBook Air (13-inch, M5, 2026)";
264        }
265        if (ffStrEquals(version, "17,2")) {
266            return "MacBook Pro (14-inch, M5, 2025)";
267        }
268        if (ffStrEquals(version, "16,13")) {
269            return "MacBook Air (15-inch, M4, 2025)";
270        }
271        if (ffStrEquals(version, "16,12")) {
272            return "MacBook Air (13-inch, M4, 2025)";
273        }
274        if (ffStrEquals(version, "16,11") ||
275            ffStrEquals(version, "16,10")) {
276            return "Mac Mini (2024)";
277        }
278        if (ffStrEquals(version, "16,9")) {
279            return "Mac Studio (M4 Max, 2025)";
280        }
281        if (ffStrEquals(version, "16,3")) {
282            return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)";
283        }
284        if (ffStrEquals(version, "16,2")) {
285            return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)";
286        }
287        if (ffStrEquals(version, "16,1")) {
288            return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)";
289        }
290        if (ffStrEquals(version, "16,6") ||
291            ffStrEquals(version, "16,8")) {
292            return "MacBook Pro (14-inch, 2024, Three Thunderbolt 5 ports)";
293        }
294        if (ffStrEquals(version, "16,7") ||
295            ffStrEquals(version, "16,5")) {
296            return "MacBook Pro (16-inch, 2024, Three Thunderbolt 5 ports)";
297        }
298        if (ffStrEquals(version, "15,14")) {
299            return "Mac Studio (M3 Ultra, 2025)";
300        }
301        if (ffStrEquals(version, "15,13")) {
302            return "MacBook Air (15-inch, M3, 2024)";
303        }
304        if (ffStrEquals(version, "15,12")) {
305            return "MacBook Air (13-inch, M3, 2024)";
306        }
307        if (ffStrEquals(version, "15,3")) {
308            return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)";
309        }
310        if (ffStrEquals(version, "15,4")) {
311            return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)";
312        }
313        if (ffStrEquals(version, "15,5")) {
314            return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
315        }
316        if (ffStrEquals(version, "15,6") ||
317            ffStrEquals(version, "15,8") ||
318            ffStrEquals(version, "15,10")) {
319            return "MacBook Pro (14-inch, Nov 2023, Three Thunderbolt 4 ports)";
320        }
321        if (ffStrEquals(version, "15,7") ||
322            ffStrEquals(version, "15,9") ||
323            ffStrEquals(version, "15,11")) {
324            return "MacBook Pro (16-inch, Nov 2023, Three Thunderbolt 4 ports)";
325        }
326        if (ffStrEquals(version, "14,15")) {
327            return "MacBook Air (15-inch, M2, 2023)";
328        }
329        if (ffStrEquals(version, "14,14")) {
330            return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)";
331        }
332        if (ffStrEquals(version, "14,13")) {
333            return "Mac Studio (M2 Max, 2023, Two USB-C front ports)";
334        }
335        if (ffStrEquals(version, "14,8")) {
336            return "Mac Pro (2023)";
337        }
338        if (ffStrEquals(version, "14,6") ||
339            ffStrEquals(version, "14,10")) {
340            return "MacBook Pro (16-inch, 2023)";
341        }
342        if (ffStrEquals(version, "14,5") ||
343            ffStrEquals(version, "14,9")) {
344            return "MacBook Pro (14-inch, 2023)";
345        }
346        if (ffStrEquals(version, "14,3")) {
347            return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)";
348        }
349        if (ffStrEquals(version, "14,12")) {
350            return "Mac mini (M2 Pro, 2023, Four Thunderbolt 4 ports)";
351        }
352        if (ffStrEquals(version, "14,7")) {
353            return "MacBook Pro (13-inch, M2, 2022)";
354        }
355        if (ffStrEquals(version, "14,2")) {
356            return "MacBook Air (M2, 2022)";
357        }
358        if (ffStrEquals(version, "13,1")) {
359            return "Mac Studio (M1 Max, 2022, Two USB-C front ports)";
360        }
361        if (ffStrEquals(version, "13,2")) {
362            return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)";
363        }
364    } else if (ffStrbufStartsWithS(hwModel, "iMac")) {
365        const char* version = hwModel->chars + strlen("iMac");
366        if (ffStrEquals(version, "21,1")) {
367            return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
368        }
369        if (ffStrEquals(version, "21,2")) {
370            return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)";
371        }
372        if (ffStrEquals(version, "20,1") ||
373            ffStrEquals(version, "20,2")) {
374            return "iMac (Retina 5K, 27-inch, 2020)";
375        }
376        if (ffStrEquals(version, "19,1")) {
377            return "iMac (Retina 5K, 27-inch, 2019)";
378        }
379        if (ffStrEquals(version, "19,2")) {
380            return "iMac (Retina 4K, 21.5-inch, 2019)";
381        }
382        if (ffStrEquals(version, "Pro1,1")) {
383            return "iMac Pro (2017)";
384        }
385        if (ffStrEquals(version, "18,3")) {
386            return "iMac (Retina 5K, 27-inch, 2017)";
387        }
388        if (ffStrEquals(version, "18,2")) {
389            return "iMac (Retina 4K, 21.5-inch, 2017)";
390        }
391        if (ffStrEquals(version, "18,1")) {
392            return "iMac (21.5-inch, 2017)";
393        }
394        if (ffStrEquals(version, "17,1")) {
395            return "iMac (Retina 5K, 27-inch, Late 2015)";
396        }
397        if (ffStrEquals(version, "16,2")) {
398            return "iMac (Retina 4K, 21.5-inch, Late 2015)";
399        }
400        if (ffStrEquals(version, "16,1")) {
401            return "iMac (21.5-inch, Late 2015)";
402        }
403        if (ffStrEquals(version, "15,1")) {
404            return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)";
405        }
406        if (ffStrEquals(version, "14,4")) {
407            return "iMac (21.5-inch, Mid 2014)";
408        }
409        if (ffStrEquals(version, "14,2")) {
410            return "iMac (27-inch, Late 2013)";
411        }
412        if (ffStrEquals(version, "14,1")) {
413            return "iMac (21.5-inch, Late 2013)";
414        }
415        if (ffStrEquals(version, "13,2")) {
416            return "iMac (27-inch, Late 2012)";
417        }
418        if (ffStrEquals(version, "13,1")) {
419            return "iMac (21.5-inch, Late 2012)";
420        }
421        if (ffStrEquals(version, "12,2")) {
422            return "iMac (27-inch, Mid 2011)";
423        }
424        if (ffStrEquals(version, "12,1")) {
425            return "iMac (21.5-inch, Mid 2011)";
426        }
427        if (ffStrEquals(version, "11,3")) {
428            return "iMac (27-inch, Mid 2010)";
429        }
430        if (ffStrEquals(version, "11,2")) {
431            return "iMac (21.5-inch, Mid 2010)";
432        }
433        if (ffStrEquals(version, "10,1")) {
434            return "iMac (27/21.5-inch, Late 2009)";
435        }
436        if (ffStrEquals(version, "9,1")) {
437            return "iMac (24/20-inch, Early 2009)";
438        }
439    }
440    return nullptr;
441}
442
443#ifdef __x86_64__
444bool ffHostDetectMac(FFHostResult* host) {
445    if (ffStrbufStartsWithS(&host->family, "Mac") && ffStrbufEqualS(&host->vendor, "Apple Inc.")) {
446        const char* productName = ffHostGetMacProductNameWithHwModel(&host->name);
447        if (productName) {
448            ffStrbufDestroy(&host->family);
449            ffStrbufInitMove(&host->family, &host->name);
450            ffStrbufSetStatic(&host->name, productName);
451            return true;
452        }
453    }
454    return false;
455}
456#endif