summaryrefslogtreecommitdiff
path: root/exec.mm
blob: 751a84ab190f78614695aeebf29a02a12d37f952 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <Foundation/Foundation.h>
#include <CoreFoundation/CoreFoundation.h>

#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>

const char *Firmware_ = NULL;

unsigned Major_;
unsigned Minor_;
unsigned BugFix_;

#define FW_LEAST(major, minor, bugfix) \
    (major < Major_ || major == Major_ && \
        (minor < Minor_ || minor == Minor_ && \
            bugfix <= BugFix_))

int main(int argc, char *argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    if (NSDictionary *sysver = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]) {
        if (NSString *prover = [sysver valueForKey:@"ProductVersion"]) {
            Firmware_ = strdup([prover cString]);
            NSArray *versions = [prover componentsSeparatedByString:@"."];
            int count = [versions count];
            Major_ = count > 0 ? [[versions objectAtIndex:0] intValue] : 0;
            Minor_ = count > 1 ? [[versions objectAtIndex:1] intValue] : 0;
            BugFix_ = count > 2 ? [[versions objectAtIndex:2] intValue] : 0;
        }
    }

    [pool release];

    const char *user;
    if (FW_LEAST(1,1,3))
        user = "mobile";
    else
        user = "root";

    if (argc == 1)
        printf("%s\n", user);
    else {
        struct passwd *passwd = getpwnam(user);

        if (setreuid(passwd->pw_uid, 0) == -1) {
            perror("setreuid");
            exit(1);
        }

        if (setregid(passwd->pw_gid, 0) == -1) {
            perror("setregid");
            exit(1);
        }

        if (execvp(argv[1], argv + 1) == -1) {
            perror("execvp");
            exit(1);
        }
    }

    return 0;
}