~ubuntu-branches/debian/wheezy/calibre/wheezy

« back to all changes in this revision

Viewing changes to setup/installer/osx/app/launcher.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-09-18 01:18:18 UTC
  • mto: (29.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20090918011818-2whiyzgvx59c7b7t
Tags: upstream-0.6.12+dfsg
ImportĀ upstreamĀ versionĀ 0.6.12+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdlib.h>
 
2
#include <strings.h>
 
3
#include <CoreFoundation/CoreFoundation.h>
 
4
#include <mach-o/dyld.h>
 
5
#include <Python.h>
 
6
 
 
7
static const char *ERR_UNKNOWNPYTHONEXCEPTION = "An uncaught exception was raised during execution of the main script, but its class or name could not be determined";
 
8
 
 
9
static int
 
10
report_error(const char *msg) {
 
11
    fprintf(stderr, msg);
 
12
    fprintf(stderr, "\n");
 
13
    fflush(stderr);
 
14
    return -1;
 
15
}
 
16
 
 
17
// These variable must be filled in before compiling
 
18
static const char *ENV_VARS[] = { /*ENV_VARS*/ NULL };
 
19
static const char *ENV_VAR_VALS[] = { /*ENV_VAR_VALS*/ NULL};
 
20
static char PROGRAM[] = "**PROGRAM**";
 
21
static const char MODULE[] = "**MODULE**";
 
22
 
 
23
#define EXE "@executable_path/.."
 
24
 
 
25
static void
 
26
set_env_vars(const char* exe_path, const char* rpath) {
 
27
    int i = 0;
 
28
    char buf[3*PATH_MAX];
 
29
    const char *env_var, *val;
 
30
 
 
31
    while(1) {
 
32
        env_var = ENV_VARS[i];
 
33
        if (env_var == NULL) break;
 
34
        val = ENV_VAR_VALS[i++];
 
35
        if (strstr(val, EXE) == val && strlen(val) >= strlen(EXE)+1) {
 
36
            strncpy(buf, exe_path, 3*PATH_MAX-150);
 
37
            strncpy(buf+strlen(exe_path), val+strlen(EXE), 150);
 
38
            setenv(env_var, buf, 1);
 
39
        } else
 
40
            setenv(env_var, val, 1);
 
41
    }
 
42
    setenv("CALIBRE_LAUNCH_MODULE", MODULE, 1);
 
43
    setenv("RESOURCEPATH", rpath, 1);
 
44
    return;
 
45
}
 
46
 
 
47
int 
 
48
main(int argc, char * const *argv, char * const *envp) {
 
49
    char *pathPtr = NULL;
 
50
    char buf[3*PATH_MAX];
 
51
    int ret, i;
 
52
 
 
53
    
 
54
    uint32_t buf_size = PATH_MAX+1;
 
55
    char *ebuf = calloc(buf_size, sizeof(char));
 
56
    ret = _NSGetExecutablePath(ebuf, &buf_size);
 
57
    if (ret == -1) {
 
58
        free(ebuf);
 
59
        ebuf = calloc(buf_size, sizeof(char));
 
60
        if (_NSGetExecutablePath(ebuf, &buf_size) != 0)
 
61
            return report_error("Failed to find real path of executable.");
 
62
    }
 
63
    pathPtr = realpath(ebuf, buf);
 
64
    if (pathPtr == NULL) {
 
65
        return report_error(strerror(errno));
 
66
    }
 
67
    char *t;
 
68
    for (i = 0; i < 3; i++) {
 
69
        t = rindex(pathPtr, '/');
 
70
        if (t == NULL) return report_error("Failed to determine bundle path.");
 
71
        *t = '\0';
 
72
    }
 
73
 
 
74
        
 
75
 
 
76
    char rpath[PATH_MAX+1];
 
77
    strncpy(rpath, pathPtr, strlen(pathPtr));
 
78
    strncat(rpath, "/Contents/Resources", 50);
 
79
    char exe_path[PATH_MAX+1];
 
80
    strncpy(exe_path, pathPtr, strlen(pathPtr));
 
81
    strncat(exe_path, "/Contents", 50);
 
82
    
 
83
    set_env_vars(exe_path, rpath);
 
84
 
 
85
    char main_script[PATH_MAX+1];
 
86
    strncpy(main_script, rpath, strlen(rpath));
 
87
    strncat(main_script, "/launcher.py", 20);
 
88
 
 
89
    Py_SetProgramName(PROGRAM);
 
90
 
 
91
    Py_Initialize();
 
92
    
 
93
    char **argv_new = calloc(argc+1, sizeof(char *));
 
94
    argv_new[argc] = NULL;
 
95
    argv_new[0] = main_script;
 
96
    memcpy(&argv_new[1], &argv[1], (argc - 1) * sizeof(char *));
 
97
    PySys_SetArgv(argc, argv_new);
 
98
 
 
99
    FILE *main_script_file = fopen(main_script, "r");
 
100
    int rval = PyRun_SimpleFileEx(main_script_file, main_script, 1);
 
101
 
 
102
    while (rval != 0) {
 
103
        PyObject *exc, *exceptionClassName, *v, *exceptionName;
 
104
        exc = PySys_GetObject("last_type");
 
105
 
 
106
        if ( !exc ) {
 
107
            rval = report_error(ERR_UNKNOWNPYTHONEXCEPTION);
 
108
            break;
 
109
        }
 
110
 
 
111
        exceptionClassName = PyObject_GetAttrString(exc, "__name__");
 
112
        if (!exceptionClassName) {
 
113
            rval = report_error(ERR_UNKNOWNPYTHONEXCEPTION);
 
114
            break;
 
115
        }
 
116
 
 
117
        v = PySys_GetObject("last_value");
 
118
        exceptionName = (v ? PyObject_Str(v) : NULL);
 
119
 
 
120
        char *class = PyString_AsString(exceptionClassName);
 
121
        char *exception = "";
 
122
        Py_DecRef(exceptionClassName);
 
123
        if (exceptionName) {
 
124
            exception = PyString_AsString(exceptionName);
 
125
            Py_DecRef(exceptionName);
 
126
        }
 
127
        char msg[2000];
 
128
        strncpy(msg, "An unexpected error occurred: ", 100);
 
129
        strncpy(msg, class, 500);
 
130
        strncpy(msg, " : ", 3);
 
131
        strncpy(msg, exception, 500);
 
132
        rval = report_error(msg);
 
133
        break;
 
134
 
 
135
    }
 
136
    Py_Finalize();
 
137
    return rval;
 
138
}