summaryrefslogtreecommitdiff
path: root/navit/start_real.c
blob: fd631916f05052486a88c8428d69686ea52e7dc6 (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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/**
 * Navit, a modular navigation system.
 * Copyright (C) 2005-2008 Navit Team
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include "config.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
#include <XGetopt.h>
#endif
#include "config_.h"
#include "version.h"
#include "item.h"
#include "coord.h"
#include "main.h"
#include "route.h"
#include "navigation.h"
#include "track.h"
#include "debug.h"
#include "event.h"
#include "event_glib.h"
#include "xmlconfig.h"
#include "file.h"
#include "search.h"
#include "start_real.h"
#include "linguistics.h"
#include "navit_nls.h"
#include "atom.h"
#include "command.h"
#include "geom.h"
#ifdef HAVE_API_WIN32_CE
#include <windows.h>
#include <winbase.h>
#endif

char *version=PACKAGE_VERSION"+git:"GIT_VERSION""NAVIT_VARIANT;
int main_argc;
char * const* main_argv;

static void print_usage(void) {
    printf("%s",_("navit usage:\n"
                  "navit [options] [configfile]\n"
                  "\t-c <file>: use <file> as config file, instead of using the default file.\n"
                  "\t-d <n>: set the global debug output level to <n> (0=error, 1=warning, 2=info, 3=debug).\n"
                  "\tSettings from config file will still take effect where they set a higher level.\n"
                  "\t-h: print this usage info and exit.\n"
                  "\t-v: print the version and exit.\n"));
}


#ifndef USE_PLUGINS
extern void builtin_init(void);
#endif /* USE_PLUGINS*/

int main_real(int argc, char * const* argv) {
    xmlerror *error = NULL;
    char *config_file = NULL, *command=NULL, *startup_file=NULL;
    int opt;
    char *cp;
    struct attr navit, conf;

    GList *list = NULL, *li;
    main_argc=argc;
    main_argv=argv;

#ifdef HAVE_GLIB
    event_glib_init();
#else
    _g_slice_thread_init_nomessage();
#endif
    atom_init();
    main_init(argv[0]);
    navit_nls_main_init();
    debug_init(argv[0]);

    cp = getenv("NAVIT_LOGFILE");
    if (cp) {
        debug_set_logfile(cp);
    }
#ifdef HAVE_API_WIN32_CE
    else {
        debug_set_logfile("/Storage Card/navit.log");
    }
#endif
    file_init();
#ifndef USE_PLUGINS
    builtin_init();
#endif
    route_init();
    navigation_init();
    tracking_init();
    search_init();
    linguistics_init();
    geom_init();
    config_file=NULL;
#ifdef HAVE_GETOPT_H
    opterr=0;  //don't bomb out on errors.
#endif /* _MSC_VER */
    /* ingore iphone command line argument */
    if (argc == 2 && !strcmp(argv[1],"-RegisterForSystemEvents"))
        argc=1;
    if (argc > 1) {
        /* Don't forget to update the manpage if you modify theses options */
        while((opt = getopt(argc, argv, ":hvc:d:e:s:")) != -1) {
            switch(opt) {
            case 'h':
                print_usage();
                exit(0);
                break;
            case 'v':
                printf("%s %s\n", "navit", version);
                exit(0);
                break;
            case 'c':
                printf("config file n is set to `%s'\n", optarg);
                config_file = optarg;
                break;
            case 'd':
                debug_set_global_level(atoi(optarg), 1);
                break;
            case 'e':
                command=optarg;
                break;
            case 's':
                startup_file=optarg;
                break;
#ifdef HAVE_GETOPT_H
            case ':':
                fprintf(stderr, "navit: Error - Option `%c' needs a value\n", optopt);
                print_usage();
                exit(2);
                break;
            case '?':
                fprintf(stderr, "navit: Error - No such option: `%c'\n", optopt);
                print_usage();
                exit(3);
#endif
            }
        }
        // use 1st cmd line option that is left for the config file
        if (optind < argc) config_file = argv[optind];
    }

    // if config file is explicitely given only look for it, otherwise try std paths
    if (config_file) {
        list = g_list_append(list,g_strdup(config_file));
    } else {
        list = g_list_append(list,g_strjoin(NULL,getenv("NAVIT_USER_DATADIR"), "/navit.xml", NULL));
        list = g_list_append(list,g_strdup("navit.xml.local"));
        list = g_list_append(list,g_strdup("navit.xml"));
        list = g_list_append(list,g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml.local", NULL));
        list = g_list_append(list,g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml", NULL));
#ifndef _WIN32
        list = g_list_append(list,g_strdup("/etc/navit/navit.xml"));
#endif
    }
    li = list;
    for (;;) {
        if (li == NULL) {
            // We have not found an existing config file from all possibilities
            dbg(lvl_error, "%s", _("No config file navit.xml, navit.xml.local found"));
            return 4;
        }
        // Try the next config file possibility from the list
        config_file = li->data;
        dbg(lvl_debug,"trying %s",config_file);
        if (file_exists(config_file)) {
            break;
        }
        g_free(config_file);
        li = g_list_next(li);
    }

    dbg(lvl_debug,"Loading %s",config_file);
    if (!config_load(config_file, &error)) {
        dbg(lvl_error, _("Error parsing config file '%s': %s"), config_file, error ? error->message : "");
    } else {
        dbg(lvl_info, _("Using config file '%s'"), config_file);
    }
    if (! config) {
        dbg(lvl_error, _("Error: No configuration found in config file '%s'"), config_file);
    }
    while (li) {
        g_free(li->data);
        li = g_list_next(li);
    }
    g_list_free(list);
    if (! (config && config_get_attr(config, attr_navit, &navit, NULL))) {
        dbg(lvl_error, "%s", _("Internal initialization failed, exiting. Check previous error messages."));
        exit(5);
    }
    conf.type=attr_config;
    conf.u.config=config;
    if (startup_file) {
        FILE *f = fopen(startup_file,"r");
        if (f) {
            char buffer[4096];
            int fclose_ret;
            while(fgets(buffer, sizeof(buffer), f)) {
                command_evaluate(&conf, buffer);
            }
            fclose_ret = fclose(f);
            if (fclose_ret != 0) {
                dbg(lvl_error, "Could not close the specified startup file: %s", startup_file);
            }
        } else {
            dbg(lvl_error, "Could not open the specified startup file: %s", startup_file);
        }
    }
    if (command) {
        command_evaluate(&conf, command);
    }
    event_main_loop_run();

    /* TODO: Android actually has no event loop, so we can't free all allocated resources here. Have to find better place to
     *  free all allocations on program exit. And don't forget to free all the stuff allocated in the code above.
     */
#ifndef HAVE_API_ANDROID
    linguistics_free();
    debug_finished();
#endif
    return 0;
}