2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
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.
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.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 #include "tray-monitor.h"
22 #include <QFileDialog>
24 extern char *configfile; // defined in tray-monitor.cpp
25 extern RES_TABLE resources[];
26 extern int32_t r_first;
27 extern int32_t r_last;
28 extern int32_t res_all_size;
31 bool Conf::parse_config()
34 config = New(CONFIG());
35 config->encode_password(false);
36 config->init(configfile, NULL, M_ERROR, (void *)&res_all, res_all_size,
37 r_first, r_last, resources, &rhead);
38 ret = config->parse_config();
42 /* Check for \ at the end */
43 static char *is_str_valid(POOLMEM **buf, const char *p)
49 p1 = *buf = check_pool_memory_size(*buf, (strlen(p) + 1));
54 } else if (*p == '"') {
65 /* The .toUtf8().data() function can be called only one time at a time */
68 POOLMEM *buf = get_pool_memory(PM_FNAME);
69 POOL_MEM tmp, tmp2, name;
71 const char *restype=NULL, *p=NULL, *pname;
79 Mmsg(tmp, "%s.temp", configfile);
80 fp = fopen(tmp.c_str(), "w");
83 display_error("Unable to open %s to write the new configuration file. ERR=%s\n", tmp.c_str(), be.bstrerror());
86 str = UIConf.editName->text();
87 p = is_str_valid(&buf, str.toUtf8().data());
89 display_error(_("The Name of the Monitor should be set"));
94 fprintf(fp, "Monitor {\n Name=\"%s\"\n", p);
96 n = UIConf.spinRefresh->value();
97 fprintf(fp, " Refresh Interval = %d\n", n);
99 if (UIConf.cbDspAdvanced->isChecked()) {
100 fprintf(fp, " Display Advanced Options = yes\n");
103 str = UIConf.editCommandDir->text();
104 p = is_str_valid(&buf, str.toUtf8().data());
105 if (p) { // TODO: Check for \ at the end of the string
106 fprintf(fp, " Command Directory = \"%s\"\n", p);
111 for (int i = 1; i < UIConf.tabWidget->count() ; i++) {
112 ConfTab *t = (ConfTab *) UIConf.tabWidget->widget(i);
113 if (t->isEnabled() == false) {
114 continue; // This one was deleted
116 for(int i = 0; resources[i].name ; i++) {
117 if (resources[i].rcode == t->res->type) {
118 restype = resources[i].name;
126 str = t->ui.editName->text();
127 pname = is_str_valid(&buf, str.toUtf8().data());
129 display_error(_("The name of the Resource should be set"));
133 pm_strcpy(name, pname);
135 str = t->ui.editAddress->text();
136 p = is_str_valid(&buf, str.toUtf8().data());
138 display_error(_("The address of the Resource should be set for resource %s"), name.c_str());
142 fprintf(fp, "%s {\n Name = \"%s\"\n Address = \"%s\"\n", restype, name.c_str(), p);
144 str = t->ui.editPassword->text();
145 p = is_str_valid(&buf, str.toUtf8().data());
147 display_error(_("The Password of should be set for resource %s"), name.c_str());
151 fprintf(fp, " Password = \"%s\"\n", p);
153 str = t->ui.editDescription->text();
154 p = is_str_valid(&buf, str.toUtf8().data());
156 fprintf(fp, " Description = \"%s\"\n", p);
158 n = t->ui.editPort->text().toInt(&ok, 10);
159 if (ok && n > 0 && n < 65636) {
160 fprintf(fp, " Port = %d\n", n);
162 n = t->ui.editTimeout->text().toInt(&ok, 10);
164 fprintf(fp, " Connect Timeout = %d\n", n);
167 str = t->ui.editCaCertificateFile->text();
168 p = is_str_valid(&buf, str.toUtf8().data());
170 if (stat(p, &sp) != 0 || !S_ISREG(sp.st_mode)) {
171 display_error(_("The TLS CA Certificate File should be a PEM file for resource %s"), name.c_str());
175 fprintf(fp, " TLSCaCertificateFile = \"%s\"\n", p);
178 str = t->ui.editCaCertificateDir->text();
179 p = is_str_valid(&buf, str.toUtf8().data());
181 if (stat(p, &sp) != 0 || !S_ISDIR(sp.st_mode)) {
182 display_error(_("The TLS CA Certificate Directory should be a directory for resource %s"), name.c_str());
186 fprintf(fp, " TLSCaCertificateDir = \"%s\"\n", p);
189 str = t->ui.editCertificate->text();
190 p = is_str_valid(&buf, str.toUtf8().data());
192 if (stat(p, &sp) != 0 || !S_ISREG(sp.st_mode)) {
193 display_error(_("The TLS Certificate File should be a file for resource %s"), name.c_str());
197 fprintf(fp, " TLSCertificate = \"%s\"\n", p);
200 str = t->ui.editKey->text();
201 p = is_str_valid(&buf, str.toUtf8().data());
203 if (stat(p, &sp) != 0 || !S_ISREG(sp.st_mode)) {
204 display_error(_("The TLS Key File should be a file for resource %s"), name.c_str());
208 fprintf(fp, " TLSKey = \"%s\"\n", p);
210 if (t->ui.cbTLSEnabled->isChecked()) {
211 fprintf(fp, " TLS Enable = yes\n");
213 if (strcmp(restype, "client") == 0 && t->ui.cbRemote->isChecked()) {
214 fprintf(fp, " Remote = yes\n");
216 if (strcmp(restype, "director") == 0 && t->ui.cbUseSetIp->isChecked()) {
217 fprintf(fp, " UseSetIp = yes\n");
219 if (t->ui.cbMonitor->isChecked()) {
220 fprintf(fp, " Monitor = yes\n");
225 // Save the configuration file
231 // TODO: We probably need to load the configuration file to see if it works
233 if (rename(tmp.c_str(), configfile) == 0) {
238 display_error("Unable to write to the configuration file %s ERR=%s\n", configfile, be.bstrerror());
254 Conf::Conf(): QDialog()
261 UIConf.setupUi(this);
262 if (parse_config()) {
263 for(res=NULL; (res=(RESMON *)GetNextRes(rhead, R_CLIENT, (RES*)res));) {
264 addResource(res, res->hdr.name);
266 for(res=NULL; (res=(RESMON *)GetNextRes(rhead, R_DIRECTOR, (RES*)res));) {
267 addResource(res, res->hdr.name);
269 for(res=NULL; (res=(RESMON *)GetNextRes(rhead, R_STORAGE, (RES*)res));) {
270 addResource(res, res->hdr.name);
272 mon = (MONITOR *)GetNextRes(rhead, R_MONITOR, NULL);
273 UIConf.editName->setText(QString(mon->hdr.name));
274 UIConf.spinRefresh->setValue(mon->RefreshInterval);
275 UIConf.editCommandDir->setText(QString(NPRTB(mon->command_dir)));
277 if (mon->display_advanced_options) {
278 UIConf.cbDspAdvanced->setChecked(true);
281 setAttribute(Qt::WA_DeleteOnClose, true);
285 void Conf::addResource(RESMON *res, const char *title)
288 ConfTab *w = new ConfTab(res);
289 w->ui.editName->setText(QString(res->hdr.name));
291 w->ui.editPassword->setText(QString(res->password));
293 if (res->type != R_CLIENT) {
294 w->ui.cbRemote->hide();
295 w->ui.labelRemote->hide();
297 } else if (res->use_remote) {
298 w->ui.cbRemote->setChecked(true);
301 if (res->type != R_DIRECTOR) {
302 w->ui.cbUseSetIp->hide();
303 w->ui.labelSetIp->hide();
305 } else if (res->use_setip) {
306 w->ui.cbUseSetIp->setChecked(true);
309 if (res->use_monitor) {
310 w->ui.cbMonitor->setChecked(true);
312 w->ui.editAddress->setText(QString(res->address));
313 w->ui.editPort->setText(QString(edit_uint64(res->port, ed1)));
314 w->ui.editTimeout->setText(QString(edit_uint64(res->connect_timeout, ed1)));
315 if (!res->tls_enable) {
316 if (w->ui.cbTLSEnabled->isChecked()) {
317 emit w->ui.cbTLSEnabled->click();
320 if (res->tls_ca_certfile) {
321 w->ui.editCaCertificateFile->setText(QString(res->tls_ca_certfile));
323 if (res->tls_ca_certdir) {
324 w->ui.editCaCertificateDir->setText(QString(res->tls_ca_certdir));
326 if (res->tls_certfile) {
327 w->ui.editCertificate->setText(QString(res->tls_certfile));
329 if (res->tls_keyfile) {
330 w->ui.editKey->setText(QString(res->tls_keyfile));
333 UIConf.tabWidget->addTab(w, QString(title));
337 void Conf::addRes(int type, const char *title)
339 RESMON *res = (RESMON *) malloc(sizeof(RESMON));
340 init_resource(config, type, res);
341 res->type = type; // Not sure it's set by init_resource
342 res->new_resource = true; // We want to free this resource with the ConfTab
343 addResource(res, title);
348 addRes(R_DIRECTOR, "New Director");
351 void Conf::addStore()
353 addRes(R_STORAGE, "New Storage");
356 void Conf::addClient()
358 addRes(R_CLIENT, "New Client");
361 void Conf::togglePassword()
363 if (passtype == QLineEdit::Normal) {
364 passtype = QLineEdit::PasswordEchoOnEdit;
366 passtype = QLineEdit::Normal;
368 for (int i = 1; i < UIConf.tabWidget->count() ; i++) {
369 ConfTab *tab = (ConfTab *) UIConf.tabWidget->widget(i);
370 tab->ui.editPassword->setEchoMode(passtype);
374 void Conf::selectCommandDir()
376 QString directory = QFileDialog::getExistingDirectory(this,
377 tr("Select Command Directory"),
378 QDir::currentPath());
379 UIConf.editCommandDir->setText(directory);
382 void ConfTab::selectCaCertificateFile()
384 QString directory = QFileDialog::getOpenFileName(this,
385 tr("Select CA Certificate File PEM file"),
386 QDir::currentPath());
387 ui.editCaCertificateFile->setText(directory);
390 void ConfTab::selectCaCertificateDir()
392 QString directory = QFileDialog::getExistingDirectory(this,
393 tr("Select CA Certificate Directory"),
394 QDir::currentPath());
395 ui.editCaCertificateDir->setText(directory);
398 void ConfTab::selectCertificate()
400 QString file = QFileDialog::getOpenFileName(this,
401 tr("Select TLS Certificate File"),
402 QDir::currentPath());
403 ui.editCertificate->setText(file);
406 void ConfTab::selectKey()
408 QString file = QFileDialog::getOpenFileName(this,
409 tr("Select TLS Certificate File"),
410 QDir::currentPath());
411 ui.editKey->setText(file);