2 Bacula® - The Network Backup Solution
4 Copyright (C) 2004-2008 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * wxbDataParser, class that receives and analyses data
32 * Nicolas Boichat, April-July 2004
37 /* Windows debug builds set _DEBUG which is used by wxWidgets to select their
38 * debug memory allocator. Unfortunately it conflicts with Bacula's SmartAlloc.
39 * So we turn _DEBUG off since we aren't interested in things it enables.
46 #include "wxbmainframe.h"
48 #include "wxbtableparser.h"
50 /* A macro named Yield is defined under MinGW */
53 bool wxbUtils::inited = false;
55 wxString wxbUtils::ConvertToPrintable(wxString& str) {
56 /* FIXME : Unicode support should be added to fix this problem */
57 #if (wxUSE_UNICODE == 0) && __WXGTK20__
59 /* Convert the string to something printable without unicode */
60 for (unsigned int i = 0; i < strnew.Length(); i++) {
61 /* If the character is not ASCII, print a ? */
62 if (((unsigned char)strnew[i] > (unsigned char)127)) {
72 /* Sleeps during milliseconds (wrapper for wxUsleep (2.4) or wxMilliSleep (2.6)) */
73 void wxbUtils::MilliSleep(unsigned long milliseconds) {
74 #if wxCHECK_VERSION(2, 6, 0)
75 ::wxMilliSleep(milliseconds);
77 ::wxUsleep(milliseconds);
82 void wxbUtils::Init() {
87 void wxbUtils::Reset() {
91 /* Parse a table in tableParser */
92 wxbTableParser* wxbUtils::CreateAndWaitForParser(wxString cmd) {
93 wxbTableParser* tableParser = new wxbTableParser();
95 wxbMainFrame::GetInstance()->Send(cmd);
97 //time_t base = wxDateTime::Now().GetTicks();
98 while (!tableParser->hasFinished()) {
99 //innerThread->Yield();
100 wxTheApp->Yield(true);
101 wxbUtils::MilliSleep(100);
102 //if (base+15 < wxDateTime::Now().GetTicks()) break;
107 /* Run a command, and waits until prompt result is fully received,
108 * if keepresults is true, returns a valid pointer to a wxbPromptParser
109 * containing the data. */
110 wxbPromptParser* wxbUtils::WaitForPrompt(wxString cmd, bool keepresults) {
111 wxbPromptParser* promptParser = new wxbPromptParser();
113 wxbMainFrame::GetInstance()->Send(cmd);
115 //time_t base = wxDateTime::Now().GetTicks();
116 while (!promptParser->hasFinished()) {
117 //innerThread->Yield();
118 wxTheApp->Yield(true);
119 wxbUtils::MilliSleep(100);
120 //if (base+15 < wxDateTime::Now().GetTicks()) break;
132 /* Run a command, and waits until result is fully received. */
133 wxbDataTokenizer* wxbUtils::WaitForEnd(wxString cmd, bool keepresults, bool linebyline) {
134 wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
136 wxbMainFrame::GetInstance()->Send(cmd);
138 //wxbMainFrame::GetInstance()->Print("(<WFE)", CS_DEBUG);
140 //time_t base = wxDateTime::Now().GetTicks();
141 while (!datatokenizer->hasFinished()) {
142 //innerThread->Yield();
143 wxTheApp->Yield(true);
144 wxbUtils::MilliSleep(100);
145 //if (base+15 < wxDateTime::Now().GetTicks()) break;
148 //wxbMainFrame::GetInstance()->Print("(>WFE)", CS_DEBUG);
151 return datatokenizer;
154 delete datatokenizer;
160 /* Creates a new wxbDataParser, and register it in wxbMainFrame */
161 wxbDataParser::wxbDataParser(bool lineanalysis) {
162 wxbMainFrame::GetInstance()->Register(this);
163 this->lineanalysis = lineanalysis;
167 /* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
168 wxbDataParser::~wxbDataParser() {
169 wxbMainFrame::GetInstance()->Unregister(this);
173 * Receives director information, forwarded by wxbMainFrame, and sends it
174 * line by line to the virtual function Analyse.
176 bool wxbDataParser::Print(wxString str, int status) {
179 bool allnewline = true;
180 for (unsigned int i = 0; i < str.Length(); i++) {
181 if (!(allnewline = (str.GetChar(i) == '\n')))
186 ret = Analyse(buffer << wxT("\n"), CS_DATA);
188 for (unsigned int i = 1; i < str.Length(); i++) {
189 ret = Analyse(wxT("\n"), status);
193 wxStringTokenizer tkz(str, wxT("\n"),
194 (wxStringTokenizerMode)(wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL));
196 while ( tkz.HasMoreTokens() ) {
197 buffer << tkz.GetNextToken();
198 if (buffer.Length() != 0) {
199 if ((buffer.GetChar(buffer.Length()-1) == '\n') ||
200 (buffer.GetChar(buffer.Length()-1) == '\r')) {
201 ret = Analyse(buffer, status);
208 if (buffer == wxT("$ ")) { // Restore console
209 ret = Analyse(buffer, status);
213 if (status != CS_DATA) {
214 if (buffer.Length() != 0) {
215 ret = Analyse(buffer, CS_DATA);
218 ret = Analyse(wxT(""), status);
222 ret = Analyse(wxString(str), status);
227 /* Creates a new wxbDataTokenizer */
228 wxbDataTokenizer::wxbDataTokenizer(bool linebyline): wxbDataParser(linebyline), wxArrayString() {
232 /* Destroy a wxbDataTokenizer */
233 wxbDataTokenizer::~wxbDataTokenizer() {
238 * Receives director information, forwarded by wxbMainFrame.
240 bool wxbDataTokenizer::Analyse(wxString str, int status) {
241 finished = ((status == CS_END) || (status == CS_PROMPT) || (status == CS_DISCONNECTED));
243 if (str != wxT("")) {
249 /* Returns true if the last signal received was an end signal,
250 * indicating that no more data is available */
251 bool wxbDataTokenizer::hasFinished() {
255 /* Creates a new wxbDataTokenizer */
256 wxbPromptParser::wxbPromptParser(): wxbDataParser(false) {
262 questionStr = wxT("");
265 /* Destroy a wxbDataTokenizer */
266 wxbPromptParser::~wxbPromptParser() {
273 * Receives director information, forwarded by wxbMainFrame.
275 bool wxbPromptParser::Analyse(wxString str, int status) {
276 if (status == CS_DATA) {
277 if (finished || prompt) { /* New question */
285 questionStr = wxT("");
291 if (((i = str.Find(wxT(": "))) > 0) && (str.Mid(0, i).Trim(false).ToLong(&num))) { /* List element */
293 choices = new wxArrayString();
294 choices->Add(wxT("")); /* index 0 is never used by multiple choice questions */
298 if ((long)choices->GetCount() != num) { /* new choice has begun */
300 choices = new wxArrayString();
301 choices->Add(wxT(""), num); /* fill until this number */
305 choices->Add(str.Mid(i+2).RemoveLast());
307 else if (!choices) { /* Introduction, no list received yet */
308 introStr << questionStr;
309 questionStr = wxString(str);
311 else { /* List receveived, get the question now */
312 introStr << questionStr;
313 questionStr = wxString(str);
317 finished = ((status == CS_PROMPT) || (status == CS_END) || (status == CS_DISCONNECTED));
318 if (prompt = ((status == CS_PROMPT) && (questionStr != wxT("$ ")))) { // && (str.Find(": ") == str.Length())
319 if (introStr.Last() == '\n') {
320 introStr.RemoveLast();
322 if ((introStr != wxT("")) && (questionStr == wxT(""))) {
323 questionStr = introStr;
327 if ((!choices) && (questionStr.Find(wxT("(yes/mod/no)")) > -1)) {
328 choices = new wxArrayString();
329 choices->Add(wxT("yes"));
330 choices->Add(wxT("mod"));
331 choices->Add(wxT("no"));
336 else { /* ended or (dis)connected */
342 questionStr = wxT("");
349 /* Returns true if the last signal received was an prompt signal,
350 * indicating that the answer must be sent */
351 bool wxbPromptParser::hasFinished() {
355 /* Returns true if the last message received is a prompt message */
356 bool wxbPromptParser::isPrompt() {
360 /* Returns multiple choice question's introduction */
361 wxString wxbPromptParser::getIntroString() {
365 /* Returns question string */
366 wxString wxbPromptParser::getQuestionString() {
370 /* Returns a wxArrayString containing the indexed choices we have
371 * to answer the question, or NULL if this question is not a multiple
373 wxArrayString* wxbPromptParser::getChoices() {
377 /* Returns true if the expected answer to the choice list is a number,
378 * false if it is a string (for example yes/mod/no). */
379 bool wxbPromptParser::isNumericalChoice() {