Vidalia  0.3.1
ServicePage.cpp
Go to the documentation of this file.
1 /*
2 ** This file is part of Vidalia, and is subject to the license terms in the
3 ** LICENSE file, found in the top level directory of this distribution. If you
4 ** did not receive the LICENSE file with this file, you may obtain it from the
5 ** Vidalia source package distributed by the Vidalia Project at
6 ** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7 ** including this file, may be copied, modified, propagated, or distributed
8 ** except according to the terms described in the LICENSE file.
9 */
10 
11 #include "ServicePage.h"
12 #include "Service.h"
13 #include "ServiceList.h"
14 #include "VMessageBox.h"
15 #include "ConfigDialog.h"
16 #include "IpValidator.h"
17 #include "DomainValidator.h"
18 #include "Vidalia.h"
19 
20 #include "stringutil.h"
21 #include "file.h"
22 
23 #include <QHeaderView>
24 #include <QClipboard>
25 #include <QFile>
26 #include <QTextStream>
27 
28 
29 /** Constructor */
30 ServicePage::ServicePage(QWidget *parent)
31 : ConfigPage(parent, "Services")
32 {
33  /* Invoke the Qt Designer generated object setup routine */
34  ui.setupUi(this);
35  /* A QMap, mapping from the row number to the Entity for
36  * all services */
37  _services = new QMap<int, Service>();
38  /* A QMap, mapping from the directory path to the Entity for
39  * all Tor services */
40  _torServices = new QMap<QString, Service>();
41 
42  ui.serviceWidget->horizontalHeader()->resizeSection(0, 150);
43  ui.serviceWidget->horizontalHeader()->resizeSection(1, 89);
44  ui.serviceWidget->horizontalHeader()->resizeSection(2, 100);
45  ui.serviceWidget->horizontalHeader()->resizeSection(3, 120);
46  ui.serviceWidget->horizontalHeader()->resizeSection(4, 60);
47  ui.serviceWidget->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
48  ui.serviceWidget->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
49  ui.serviceWidget->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
50  ui.serviceWidget->horizontalHeader()->setResizeMode(3, QHeaderView::Stretch);
51  ui.serviceWidget->verticalHeader()->hide();
52 
53  connect(ui.addButton, SIGNAL(clicked()), this, SLOT(addService()));
54  connect(ui.removeButton, SIGNAL(clicked()), this, SLOT(removeService()));
55  connect(ui.copyButton, SIGNAL(clicked()), this, SLOT(copyToClipboard()));
56  connect(ui.browseButton, SIGNAL(clicked()), this, SLOT(browseDirectory()));
57  connect(ui.serviceWidget, SIGNAL(itemClicked(QTableWidgetItem*)),
58  this, SLOT(serviceSelectionChanged()));
59  connect(ui.serviceWidget, SIGNAL(itemChanged(QTableWidgetItem*)),
60  this, SLOT(valueChanged()));
61 }
62 
63 /** Destructor */
65 {
66  delete _services;
67  delete _torServices;
68 }
69 
70 /** Called when the user changes the UI translation. */
71 void
73 {
74  ui.retranslateUi(this);
75 }
76 
77 /** Saves changes made to settings on the Server settings page. */
78 bool
79 ServicePage::save(QString &errmsg)
80 {
81  ServiceSettings serviceSettings(Vidalia::torControl());
82  QList<Service> serviceList;
83  QList<Service> publishedServices;
84  int index = 0;
85 
86  while(index < ui.serviceWidget->rowCount()) {
87  QString address = ui.serviceWidget->item(index,0)->text();
88  QString virtualPort = ui.serviceWidget->item(index,1)->text();
89  QString physicalAddress = ui.serviceWidget->item(index,2)->text();
90  QString directoryPath = ui.serviceWidget->item(index,3)->text();
91  bool enabled = _services->value(index).enabled();
92  Service temp(address, virtualPort, physicalAddress, directoryPath,
93  enabled);
95  _services->value(ui.serviceWidget->currentRow()).additionalServiceOptions());
96  serviceList.push_back(temp);
97  if(enabled) {
98  publishedServices.push_back(temp);
99  }
100  index++;
101  }
102 
103  bool save = checkBeforeSaving(serviceList);
104  if(save) {
105  ServiceList sList;
106  if(serviceList.size() > 0) {
107  sList.setServices(serviceList);
108  } else {
109  _services = new QMap<int, Service>();
110  sList.setServices(_services->values());
111  }
112  serviceSettings.setServices(sList);
113  if(publishedServices.size() > 0) {
114  startServicesInTor(publishedServices);
115  } else {
116  QString errmsg1 = tr("Error while trying to unpublish all services");
117  QString &errmsg = errmsg1;
118  serviceSettings.unpublishAllServices(&errmsg);
119  }
120  return true;
121  } else {
122  errmsg = tr("Please configure at least a service directory and a virtual "
123  "port for each service you want to save. Remove the other ones.");
124  return false;
125  }
126 }
127 
128 /** this method checks if either all services have minimal
129  * configuration or not */
130 bool
131 ServicePage::checkBeforeSaving(QList<Service> serviceList)
132 {
133  bool result = true;
134  foreach(Service s, serviceList) {
135  if(s.serviceDirectory().isEmpty() || s.virtualPort().isEmpty()) {
136  result = false;
137  break;
138  }
139  }
140  return result;
141 }
142 
143 /** this method generates the configuration string for a list of services */
144 void
145 ServicePage::startServicesInTor(QList<Service> services)
146 {
147  ServiceSettings serviceSettings(Vidalia::torControl());
148  QString serviceConfString;
149  QString errmsg = "Error while trying to publish services.";
150  QListIterator<Service> it(services);
151 
152  while(it.hasNext()) {
153  Service temp = it.next();
154  serviceConfString.append("hiddenservicedir=" +
155  string_escape(temp.serviceDirectory()) + " ");
156  serviceConfString.append("hiddenserviceport=" +
157  string_escape(temp.virtualPort() +
158  (temp.physicalAddressPort().isEmpty() ? "" : " " +
159  temp.physicalAddressPort())));
160  serviceConfString.append(" " + temp.additionalServiceOptions());
161  }
162  serviceSettings.applyServices(serviceConfString, &errmsg);
163 }
164 
165 /** Loads previously saved settings */
166 void
168 {
169  ServiceSettings serviceSettings(Vidalia::torControl());
170  QList<Service> torServiceList;
171 
172  ui.removeButton->setEnabled(false);
173  ui.copyButton->setEnabled(false);
174  ui.browseButton->setEnabled(false);
175  // get all services
176  _services->clear();
177  _torServices->clear();
178 
179  QString torConfigurationString = serviceSettings.getHiddenServiceDirectories();
180  torServiceList = extractSingleServices(torConfigurationString);
181  QList<Service> completeList = torServiceList;
182  // the services stored with vidalia
183  ServiceList serviceList = serviceSettings.getServices();
184  QList<Service> serviceSettingsList = serviceList.services();
185  QListIterator<Service> it(serviceSettingsList);
186  // check whether a service is already in the list because he is published
187  while(it.hasNext()) {
188  Service temp = it.next();
189  if(isServicePublished(temp, torServiceList) == false) {
190  completeList.push_back(temp);
191  }
192  }
193  // generate the _services data structure used during vidalia session
194  QListIterator<Service> it2(completeList);
195  int index = 0;
196  while (it2.hasNext()) {
197  Service tempService = it2.next();
198  _services->insert(index, tempService);
199  index++;
200  }
202 }
203 
204 /** this method returns a list of services by parsing the configuration
205  * string given by the tor controller */
206 QList<Service>
208 {
209  QList<Service> list;
210  QStringList strList = conf.split("250 HiddenServiceDir");
211  strList.removeFirst();
212  QListIterator<QString> it(strList);
213  //for each service directory splitted string = service
214  while(it.hasNext()) {
215  QString temp = it.next();
216  list.push_back(generateService(temp));
217  }
218  return list;
219 }
220 
221 /** this return a Service by parseing the configuration string
222  * of Tor and storeing its values into the object */
223 Service
225 {
226  QString additionalOptions = s;
227  // remove directory
228  int index = additionalOptions.indexOf("250",1);
229  additionalOptions.remove(0, index+4);
230  // remove the first appearance of the port
231  int startindex = additionalOptions.indexOf("hiddenserviceport", 0,
232  Qt::CaseInsensitive);
233  int endindex = additionalOptions.indexOf("250", startindex);
234  if(endindex != -1) {
235  additionalOptions.remove(startindex, (endindex-startindex)+4);
236  //remove all appearances of "250"
237  while(additionalOptions.contains("250")) {
238  int i = additionalOptions.indexOf("250", 0);
239  additionalOptions.remove(i, 4);
240  }
241  // prepare for correct quotation
242  if (!additionalOptions.endsWith('\n')) {
243  additionalOptions.append("\n");
244  }
245  //quote the values
246  int j = additionalOptions.indexOf("=", 0);
247  while(j != -1) {
248  additionalOptions.insert(j+1, "\"");
249  int end = additionalOptions.indexOf("\n", j);
250  additionalOptions.insert(end, "\"");
251  j = additionalOptions.indexOf("=", end);
252  }
253  //replace the line brakes with a space and create one single line
254  additionalOptions.replace(QString("\n"), QString(" "));
255  } else {
256  additionalOptions = "";
257  }
258 
259  QString address, virtualPort, physAddressPort, serviceDir;
260  // service directory
261  QStringList strList = s.split("\n");
262  QString tempServiceDir = strList.first().trimmed();
263  serviceDir = tempServiceDir.remove(0, 1);
264  //virtual port
265  QStringList strList2 = s.split("HiddenServicePort");
266  strList2.removeFirst();
267  QStringList strList3 = strList2.first().split("\n");
268  QStringList strList4 = strList3.first().split(" ");
269  if(strList4.size() > 0) {
270  QString tempVirtualPort = strList4.first();
271  virtualPort = tempVirtualPort.remove(0, 1);
272  strList4.removeFirst();
273  //physical address:port
274  if(!strList4.isEmpty()) {
275  physAddressPort = strList4.first().trimmed();
276  }
277  } else {
278  QString tempVirtualPort = strList3.first();
279  virtualPort = tempVirtualPort.remove(0, 1);
280  }
281  //get .onion address
282  QString serviceHostnameDir = serviceDir;
283  serviceHostnameDir.append("/");
284  serviceHostnameDir.append("hostname");
285  QFile file(serviceHostnameDir);
286  if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
287  address = "[Directory not found]";
288  } else {
289  QTextStream in(&file);
290  QString hostname;
291  while (!in.atEnd()) {
292  hostname.append(in.readLine());
293  }
294  address = hostname;
295  }
296  Service service(address, virtualPort, physAddressPort, serviceDir, true);
297  service.setAdditionalServiceOptions(additionalOptions);
298  _torServices->insert(serviceDir, service);
299  return service;
300 }
301 
302 /** this method checks either a service is published or not */
303 bool
304 ServicePage::isServicePublished(Service service, QList<Service> torServices)
305 {
306  QListIterator<Service> it(torServices);
307  while(it.hasNext()) {
308  Service temp = it.next();
309  if(temp.serviceDirectory().compare(service.serviceDirectory()) == 0) {
310  return true;
311  }
312  }
313  return false;
314 }
315 
316 /** this method creates/displays the values for each service
317  * shown in the service listing */
318 void
319 ServicePage::initServiceTable(QMap<int, Service>* services)
320 {
321  // clean the widget
322  int rows = ui.serviceWidget->rowCount();
323  for(int i = 0; i < rows; i++) {
324  ui.serviceWidget->removeRow(0);
325  }
326  //for each service
327  int index = 0;
328  while(index < services->size()) {
329  Service tempService = services->value(index);
330  ui.serviceWidget->insertRow(index);
331  QTableWidgetItem *cboxitem = new QTableWidgetItem();
332  cboxitem->setFlags(Qt::ItemIsSelectable);
333  QTableWidgetItem *addressitem = new QTableWidgetItem();
334  addressitem->setFlags(Qt::ItemIsSelectable);
335  if(tempService.serviceAddress().length() < 0) {
336  addressitem->setText(tempService.serviceAddress());
337  } else {
338  QString serviceHostnameDir = tempService.serviceDirectory();
339  serviceHostnameDir.append("/");
340  serviceHostnameDir.append("hostname");
341  QFile file(serviceHostnameDir);
342  if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
343  addressitem->setText("[Directory not found]");
344  } else {
345  QTextStream in(&file);
346  QString hostname;
347  while (!in.atEnd()) {
348  hostname.append(in.readLine());
349  }
350  addressitem->setText(hostname);
351  tempService.setServiceAddress(hostname);
352  }
353  }
354  addressitem->setData(32, addressitem->text());
355  QTableWidgetItem *serviceDir =
356  new QTableWidgetItem(tempService.serviceDirectory(), 0);
357  serviceDir->setData(32, tempService.serviceDirectory());
358  QTableWidgetItem* virtualportitem =
359  new QTableWidgetItem(tempService.virtualPort(), 0);
360  virtualportitem->setData(32, tempService.virtualPort());
361  QTableWidgetItem* targetitem =
362  new QTableWidgetItem(tempService.physicalAddressPort(),0);
363  targetitem->setData(32, tempService.physicalAddressPort());
364  if(tempService.enabled()) {
365  cboxitem->setCheckState(Qt::Checked);
366  serviceDir->setFlags(Qt::ItemIsSelectable);
367  } else {
368  cboxitem->setCheckState(Qt::Unchecked);
369  }
370  cboxitem->setTextAlignment(Qt::AlignCenter);
371  ui.serviceWidget->setItem(index, 0, addressitem);
372  ui.serviceWidget->setItem(index, 1, virtualportitem);
373  ui.serviceWidget->setItem(index, 2, targetitem);
374  ui.serviceWidget->setItem(index, 3, serviceDir);
375  ui.serviceWidget->setItem(index, 4, cboxitem);
376  index++;
377  }
378 }
379 
380 /** this method is called when the user clicks the "Add"-Button
381  * it generates a new empty table entrie(row) */
382 void
384 {
385  int rows = ui.serviceWidget->rowCount();
386  ui.serviceWidget->insertRow(rows);
387  QTableWidgetItem *address = new QTableWidgetItem("["+tr("Created by Tor")+"]");
388  address->setFlags(Qt::ItemIsSelectable);
389  QTableWidgetItem *dummy = new QTableWidgetItem();
390  QTableWidgetItem *dummy2 = new QTableWidgetItem();
391  QTableWidgetItem *dummy3 = new QTableWidgetItem();
392  QTableWidgetItem *cboxitem = new QTableWidgetItem();
393  cboxitem->setFlags(Qt::ItemIsSelectable);
394  cboxitem->setCheckState(Qt::Checked);
395  ui.serviceWidget->setItem(rows, 0, address);
396  ui.serviceWidget->setItem(rows, 1, dummy);
397  ui.serviceWidget->setItem(rows, 2, dummy2);
398  ui.serviceWidget->setItem(rows, 3, dummy3);
399  ui.serviceWidget->setItem(rows, 4, cboxitem);
400  Service s;
401  s.setEnabled(true);
402  _services->insert(rows, s);
403 }
404 
405 /** this method is called when the user clicks the "Remove"-Button
406  * it removes a service/row of the service listing */
407 void
409 {
410  int rows = ui.serviceWidget->rowCount();
411  int selrow = ui.serviceWidget->currentRow();
412  if(selrow < 0 || selrow >= _services->size()) {
413  VMessageBox::warning(this, tr("Error"), tr("Please select a Service."),
415  return;
416  } else {
417  ui.serviceWidget->removeRow(selrow);
418  //decrease all other service keys
419  for(int i = 0; i < (rows-selrow-1); i++) {
420  int index = i+selrow;
421  Service s = _services->take(index+1);
422  _services->insert(index, s);
423  }
424  }
426 }
427 
428 /** this method is called when the user clicks on the "Copy"-Button, it
429  * copies the .onion-Address of the selected service into the clipboard */
430 void
432 {
433  int selrow = ui.serviceWidget->currentRow();
434  if(selrow < 0 || selrow >= _services->size()) {
435  VMessageBox::warning(this, tr("Error"), tr("Please select a Service."),
437  return;
438  } else {
439  QString onionAddress = ui.serviceWidget->item(selrow,0)->text();
440  QClipboard *clipboard = QApplication::clipboard();
441  QString clipboardText;
442  QTableWidgetItem* selectedItem = ui.serviceWidget->item(selrow,0);
443  clipboardText.append(selectedItem->text());
444  clipboard->setText(clipboardText);
445  }
446 }
447 
448 /** this method is called when the user clicks on the "Brows"-Button it opens
449  * a QFileDialog to choose a service directory */
450 void
452 {
453  int selrow = ui.serviceWidget->currentRow();
454  if(selrow < 0 || selrow >= _services->size()) {
455  VMessageBox::warning(this, tr("Error"), tr("Please select a Service."),
457  return;
458  } else {
459  QString dirname =
460  QFileDialog::getExistingDirectory(this,
461  tr("Select Service Directory"), "",
462  QFileDialog::ShowDirsOnly
463  | QFileDialog::DontResolveSymlinks);
464 
465  if (dirname.isEmpty()) {
466  return;
467  }
468  ui.serviceWidget->item(selrow,3)->setText(dirname);
469  Service s = _services->take(selrow);
470  s.setServiceDirectory(dirname);
471  _services->insert(selrow, s);
472  }
473 }
474 
475 /** this method is called when the selects an other tablewidgetitem */
476 void
478 {
479  bool emptyTable = false;
480  if(ui.serviceWidget->rowCount() > 0) {
481  ui.removeButton->setEnabled(true);
482  ui.copyButton->setEnabled(true);
483  ui.browseButton->setEnabled(true);
484  } else {
485  ui.removeButton->setEnabled(false);
486  ui.copyButton->setEnabled(false);
487  ui.browseButton->setEnabled(false);
488  emptyTable = true;
489  }
490  int currentRow = ui.serviceWidget->currentRow();
491  if(emptyTable == false) {
492  QTableWidgetItem* item = ui.serviceWidget->item(currentRow, 0);
493  if(item != NULL) {
494  bool b = item->text().contains(".onion");
495  ui.copyButton->setEnabled(b);
496  }
497  }
498 
499  QString selDir = _services->value(ui.serviceWidget->currentRow()).
500  serviceDirectory();
501  QList<QString> strList = _torServices->keys();
502  if(selDir.length() > 0) {
503  QListIterator<QString> it(strList);
504  while(it.hasNext()) {
505  QString temp = it.next();
506  if(selDir.compare(temp) == 0) {
507  ui.browseButton->setEnabled(false);
508  break;
509  }
510  }
511  }
512  // if the user has clicked on the checkbox cell
513  if(ui.serviceWidget->currentColumn() == 4) {
514  Service service = _services->take(currentRow);
515  QTableWidgetItem* item = ui.serviceWidget->item(currentRow,4);
516  if(service.enabled()) {
517  item->setCheckState(Qt::Unchecked);
518  service.setEnabled(false);
519  } else {
520  item->setCheckState(Qt::Checked);
521  service.setEnabled(true);
522  }
523  _services->insert(currentRow, service);
524  }
525 }
526 
527 /** this method is called when the user finished editing a cell and it provides
528  * that only valid values are set */
529 void
531 {
532  int pos = 0;
533  QIntValidator* portValidator = new QIntValidator(1, 65535, this);
534  DomainValidator* domainValidator = new DomainValidator(this);
535  IpValidator* ipValidator = new IpValidator(this);
536  QTableWidgetItem* item = ui.serviceWidget->currentItem();
537  if (item == NULL || item->text() == NULL || item->text().length() == 0) {
538  // nothing to validate here
539  return;
540  }
541  QString text = item->text();
542  switch (item->column()) {
543  case 1: // virtual port
544  if(portValidator->validate(text, pos) == QValidator::Acceptable) {
545  // correct data; buffer value in user role 32
546  item->setData(32, text);
547  } else {
548  //incorrect data; restore value from user role 32
549  VMessageBox::warning(this, tr("Error"),
550  tr("Virtual Port may only contain valid port numbers [1..65535]."),
552  item->setText(item->data(32).toString());
553  }
554  break;
555  case 2: // target
556  if(text.contains(":")) {
557  // check for <address>:<port>
558  QStringList strList = text.split(":");
559  if (strList.size() != 2) {
560  goto invalid;
561  }
562  QString address = strList.at(0);
563  QString port = strList.at(1);
564  if((address.compare("localhost") != 0 &&
565  ipValidator->validate(address, pos) != QValidator::Acceptable &&
566  domainValidator->validate(address, pos) != QValidator::Acceptable) ||
567  portValidator->validate(port, pos) != QValidator::Acceptable) {
568  goto invalid;
569  }
570  } else { // either <address> or <port>
571  if (text.compare("localhost") != 0 &&
572  ipValidator->validate(text, pos) != QValidator::Acceptable &&
573  domainValidator->validate(text, pos) != QValidator::Acceptable &&
574  portValidator->validate(text, pos) != QValidator::Acceptable) {
575  goto invalid;
576  }
577  }
578  goto valid;
579  invalid:
580  VMessageBox::warning(this, tr("Error"),
581  tr("Target may only contain address:port, address, or port."),
583  item->setText(item->data(32).toString());
584  break;
585  valid:
586  item->setData(32, text);
587  break;
588  case 3: // service directory
589  // compare with directories of other enabled services
590  for (int index = 0; index < ui.serviceWidget->rowCount(); index++) {
591  // skip own row
592  if(index == item->row()) {
593  continue;
594  }
595  QTableWidgetItem* compareWith = ui.serviceWidget->item(index, 3);
596  if(compareWith != NULL) {
597  QString actualDir = compareWith->text();
598  if(actualDir.length() > 0 && text.compare(actualDir) == 0) {
599  // service directory already in use
600  VMessageBox::warning(this, tr("Error"),
601  tr("Directory already in use by another service."),
603  item->setText(item->data(32).toString());
604  return;
605  }
606  }
607  }
608  // correct data; buffer value in user role 32
609  item->setData(32, text);
610  break;
611  }
612 }
613 
ServiceSettings
Definition: ServiceSettings.h:22
ServicePage::ServicePage
ServicePage(QWidget *parent=0)
Definition: ServicePage.cpp:30
string_escape
QString string_escape(const QString &str)
Definition: stringutil.cpp:131
VMessageBox.h
ServicePage::isServicePublished
bool isServicePublished(Service service, QList< Service > torServices)
Definition: ServicePage.cpp:304
ServicePage::initServiceTable
void initServiceTable(QMap< int, Service > *_services)
Definition: ServicePage.cpp:319
Service::setServiceAddress
void setServiceAddress(QString serviceAddress)
Definition: Service.cpp:42
IpValidator.h
Service::serviceAddress
QString serviceAddress() const
Definition: Service.h:30
ServiceSettings::setServices
void setServices(ServiceList services)
Definition: ServiceSettings.cpp:37
i
QString i(QString str)
Definition: html.cpp:32
DomainValidator
Definition: DomainValidator.h:22
ServiceSettings::unpublishAllServices
void unpublishAllServices(QString *errmsg)
Definition: ServiceSettings.cpp:162
IpValidator::validate
QValidator::State validate(QString &input) const
Definition: IpValidator.cpp:45
DomainValidator.h
Service::setServiceDirectory
void setServiceDirectory(QString serviceDirectory)
Definition: Service.cpp:60
ServiceList::services
QList< Service > services() const
Definition: ServiceList.h:32
ServiceSettings::applyServices
void applyServices(QString value, QString *errmsg)
Definition: ServiceSettings.cpp:154
Vidalia.h
Vidalia::torControl
static TorControl * torControl()
Definition: Vidalia.h:76
Service::setAdditionalServiceOptions
void setAdditionalServiceOptions(QString options)
Definition: Service.cpp:66
VMessageBox::warning
static int warning(QWidget *parent, QString caption, QString text, int button0, int button1=NoButton, int button2=NoButton)
Definition: VMessageBox.cpp:187
Service
Definition: Service.h:19
ServicePage.h
ServiceList::setServices
void setServices(QList< Service > services)
Definition: ServiceList.cpp:31
ServicePage::checkBeforeSaving
bool checkBeforeSaving(QList< Service > services)
Definition: ServicePage.cpp:131
IpValidator
Definition: IpValidator.h:22
VMessageBox::Ok
@ Ok
Definition: VMessageBox.h:33
ServicePage::retranslateUi
virtual void retranslateUi()
Definition: ServicePage.cpp:72
ServicePage::extractSingleServices
QList< Service > extractSingleServices(QString conf)
Definition: ServicePage.cpp:207
stringutil.h
Service::physicalAddressPort
QString physicalAddressPort() const
Definition: Service.h:34
ServiceSettings::getHiddenServiceDirectories
QString getHiddenServiceDirectories()
Definition: ServiceSettings.cpp:143
connect
stop errmsg connect(const QHostAddress &address, quint16 port)
ServicePage::browseDirectory
void browseDirectory()
Definition: ServicePage.cpp:451
ServicePage::ui
Ui::ServicePage ui
Definition: ServicePage.h:75
ConfigPage
Definition: ConfigPage.h:22
ServicePage::load
void load()
Definition: ServicePage.cpp:167
ServicePage::copyToClipboard
void copyToClipboard()
Definition: ServicePage.cpp:431
b
QString b(QString str)
Definition: html.cpp:39
ServicePage::valueChanged
void valueChanged()
Definition: ServicePage.cpp:530
Service::enabled
bool enabled() const
Definition: Service.h:38
Service.h
ServicePage::serviceSelectionChanged
void serviceSelectionChanged()
Definition: ServicePage.cpp:477
ServiceList.h
ServicePage::startServicesInTor
void startServicesInTor(QList< Service > services)
Definition: ServicePage.cpp:145
Service::virtualPort
QString virtualPort() const
Definition: Service.h:32
ServicePage::_services
QMap< int, Service > * _services
Definition: ServicePage.h:70
ServiceSettings::getServices
ServiceList getServices()
Definition: ServiceSettings.cpp:51
ServicePage::save
bool save(QString &errmsg)
Definition: ServicePage.cpp:79
ServicePage::removeService
void removeService()
Definition: ServicePage.cpp:408
file.h
ServicePage::~ServicePage
~ServicePage()
Definition: ServicePage.cpp:64
ServicePage::generateService
Service generateService(QString serviceString)
Definition: ServicePage.cpp:224
Service::additionalServiceOptions
QString additionalServiceOptions() const
Definition: Service.h:40
ServiceList
Definition: ServiceList.h:19
Service::setEnabled
void setEnabled(bool enabled)
Definition: Service.cpp:36
Service::serviceDirectory
QString serviceDirectory() const
Definition: Service.h:36
ServicePage::_torServices
QMap< QString, Service > * _torServices
Definition: ServicePage.h:72
ConfigDialog.h
ServicePage::addService
void addService()
Definition: ServicePage.cpp:383