1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 Kern Sibbald
5
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
8
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
13
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
16
17 Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20 * Main program for bat (qt-console)
21 *
22 * Written by Kern Sibbald, January MMVII
23 *
24 */
25
26
27 #include "bat.h"
28 #include <QApplication>
29 #include <QTranslator>
30
31 /*
32 * We need Qt version 4.8.4 or later to be able to comple correctly
33 */
34 #if QT_VERSION < 0x040804
35 #error "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
36 #error "You need Qt version 4.8.4 or later to build Bat"
37 #error "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
38 #endif
39
40 MainWin *mainWin;
41 QApplication *app;
42
43 /* Forward referenced functions */
44 void terminate_console(int sig);
45 static void usage();
46 static int check_resources();
47
48 extern bool parse_bat_config(CONFIG *config, const char *configfile, int exit_code);
49 extern void message_callback(int /* type */, char *msg);
50
51
52 #define CONFIG_FILE "bat.conf" /* default configuration file */
53
54 /* Static variables */
55 static CONFIG *config;
56 static char *configfile = NULL;
57
main(int argc,char * argv[])58 int main(int argc, char *argv[])
59 {
60 int ch;
61 bool no_signals = true;
62 bool test_config = false;
63
64
65 app = new QApplication(argc, argv);
66 app->setQuitOnLastWindowClosed(true);
67 #if QT_VERSION < 0x050000
68 app->setStyle(new QPlastiqueStyle());
69 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
70 #endif
71
72 QTranslator qtTranslator;
73 qtTranslator.load(QString("qt_") + QLocale::system().name(),QLibraryInfo::location(QLibraryInfo::TranslationsPath));
74 app->installTranslator(&qtTranslator);
75
76 QTranslator batTranslator;
77 batTranslator.load(QString("bat_") + QLocale::system().name(),QLibraryInfo::location(QLibraryInfo::TranslationsPath));
78 app->installTranslator(&batTranslator);
79
80 register_message_callback(message_callback);
81
82 #ifdef xENABLE_NLS
83 setlocale(LC_ALL, "");
84 bindtextdomain("bacula", LOCALEDIR);
85 textdomain("bacula");
86 #endif
87
88 #ifdef HAVE_WIN32
89 set_trace(true); /* output to trace file */
90 #endif
91
92 init_stack_dump();
93 my_name_is(argc, argv, "bat");
94 lmgr_init_thread();
95 init_msg(NULL, NULL);
96 working_directory = "/tmp";
97
98 #ifndef HAVE_WIN32
99 struct sigaction sigignore;
100 sigignore.sa_flags = 0;
101 sigignore.sa_handler = SIG_IGN;
102 sigfillset(&sigignore.sa_mask);
103 sigaction(SIGPIPE, &sigignore, NULL);
104 sigaction(SIGUSR2, &sigignore, NULL);
105 #endif
106
107 while ((ch = getopt(argc, argv, "bc:d:r:st?")) != -1) {
108 switch (ch) {
109 case 'c': /* configuration file */
110 if (configfile != NULL) {
111 free(configfile);
112 }
113 configfile = bstrdup(optarg);
114 break;
115
116 case 'd':
117 debug_level = atoi(optarg);
118 if (debug_level <= 0)
119 debug_level = 1;
120 break;
121
122 case 's': /* turn off signals */
123 no_signals = true;
124 break;
125
126 case 't':
127 test_config = true;
128 break;
129
130 case '?':
131 default:
132 usage();
133 }
134 }
135 argc -= optind;
136 argv += optind;
137
138
139 if (!no_signals) {
140 init_signals(terminate_console);
141 }
142
143 if (argc) {
144 usage();
145 }
146
147 OSDependentInit();
148 #ifdef HAVE_WIN32
149 WSA_Init(); /* Initialize Windows sockets */
150 #endif
151
152 if (configfile == NULL) {
153 configfile = bstrdup(CONFIG_FILE);
154 }
155
156 config = New(CONFIG());
157 parse_bat_config(config, configfile, M_ERROR_TERM);
158
159 if (init_crypto() != 0) {
160 Emsg0(M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
161 }
162
163 if (!check_resources()) {
164 Emsg1(M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
165 }
166 if (test_config) {
167 exit(0);
168 }
169
170 mainWin = new MainWin;
171 mainWin->show();
172
173 return app->exec();
174 }
175
terminate_console(int)176 void terminate_console(int /*sig*/)
177 {
178 #ifdef HAVE_WIN32
179 WSACleanup(); /* TODO: check when we have to call it */
180 #endif
181 exit(0);
182 }
183
usage()184 static void usage()
185 {
186 fprintf(stderr, _(
187 PROG_COPYRIGHT
188 "\n%sVersion: %s (%s) %s %s %s\n\n"
189 "Usage: bat [-s] [-c config_file] [-d debug_level] [config_file]\n"
190 " -c <file> set configuration file to file\n"
191 " -dnn set debug level to nn\n"
192 " -s no signals\n"
193 " -t test - read configuration and exit\n"
194 " -? print this message.\n"
195 "\n"), 2007, BDEMO, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
196
197 exit(1);
198 }
199
200 /*
201 * Make a quick check to see that we have all the
202 * resources needed.
203 */
check_resources()204 static int check_resources()
205 {
206 bool ok = true;
207 DIRRES *director;
208 int numdir;
209 bool tls_needed;
210
211 LockRes();
212
213 numdir = 0;
214 foreach_res(director, R_DIRECTOR) {
215 numdir++;
216 /* tls_require implies tls_enable */
217 if (director->tls_require) {
218 if (have_tls) {
219 director->tls_enable = true;
220 } else {
221 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
222 ok = false;
223 continue;
224 }
225 }
226 tls_needed = director->tls_enable || director->tls_authenticate;
227
228 if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed) {
229 Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
230 " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
231 " At least one CA certificate store is required.\n"),
232 director->hdr.name, configfile);
233 ok = false;
234 }
235 }
236
237 if (numdir == 0) {
238 Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n"
239 "Without that I don't how to speak to the Director :-(\n"), configfile);
240 ok = false;
241 }
242
243 CONRES *cons;
244 /* Loop over Consoles */
245 foreach_res(cons, R_CONSOLE) {
246 /* tls_require implies tls_enable */
247 if (cons->tls_require) {
248 if (have_tls) {
249 cons->tls_enable = true;
250 } else {
251 Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
252 ok = false;
253 continue;
254 }
255 }
256 tls_needed = cons->tls_enable || cons->tls_authenticate;
257
258 if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && tls_needed) {
259 Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
260 " or \"TLS CA Certificate Dir\" are defined for Console \"%s\" in %s.\n"),
261 cons->hdr.name, configfile);
262 ok = false;
263 }
264 }
265
266 UnlockRes();
267
268 return ok;
269 }
270