diff options
Diffstat (limited to 'rbutil/rbutil.cpp')
-rw-r--r-- | rbutil/rbutil.cpp | 783 |
1 files changed, 0 insertions, 783 deletions
diff --git a/rbutil/rbutil.cpp b/rbutil/rbutil.cpp deleted file mode 100644 index 058ca10a27..0000000000 --- a/rbutil/rbutil.cpp +++ /dev/null | |||
@@ -1,783 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * Module: rbutil | ||
9 | * File: rbutil.cpp | ||
10 | * | ||
11 | * Copyright (C) 2005 Christi Alice Scarborough | ||
12 | * | ||
13 | * All files in this archive are subject to the GNU General Public License. | ||
14 | * See the file COPYING in the source tree root for full license agreement. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | |||
21 | #include "rbutil.h" | ||
22 | #include "installlog.h" | ||
23 | |||
24 | /* this function gets a Bitmap from embedded memory */ | ||
25 | wxBitmap wxGetBitmapFromMemory(const unsigned char *data,int length) | ||
26 | { | ||
27 | wxMemoryInputStream istream( data,length); | ||
28 | return wxBitmap(wxImage(istream, wxBITMAP_TYPE_ANY, -1), -1); | ||
29 | } | ||
30 | |||
31 | // This class allows us to return directories as well as files to | ||
32 | // wxDir::Traverse | ||
33 | class wxDirTraverserIncludeDirs : public wxDirTraverser | ||
34 | { | ||
35 | public: | ||
36 | wxDirTraverserIncludeDirs(wxArrayString& files) : m_files(files) { } | ||
37 | |||
38 | virtual wxDirTraverseResult OnFile(const wxString& filename) | ||
39 | { | ||
40 | m_files.Add(filename); | ||
41 | return wxDIR_CONTINUE; | ||
42 | } | ||
43 | |||
44 | virtual wxDirTraverseResult OnDir(const wxString& dirname) | ||
45 | { | ||
46 | m_files.Add(dirname); | ||
47 | return wxDIR_CONTINUE; | ||
48 | } | ||
49 | |||
50 | private: | ||
51 | wxArrayString& m_files; | ||
52 | }; | ||
53 | |||
54 | wxDEFINE_SCOPED_PTR_TYPE(wxZipEntry); | ||
55 | |||
56 | const wxChar* _rootmatch[] = { | ||
57 | wxT("rockbox.*"), | ||
58 | wxT("ajbrec.ajz"), | ||
59 | wxT("archos.mod"), | ||
60 | wxT(".scrobbler.*"), | ||
61 | wxT("battery_bench.txt"), | ||
62 | wxT("battery.dummy"), | ||
63 | }; | ||
64 | const wxArrayString* rootmatch = new wxArrayString( | ||
65 | (size_t) (sizeof(_rootmatch) / sizeof(wxChar*)), _rootmatch); | ||
66 | |||
67 | bool InstallTheme(wxString Themesrc) | ||
68 | { | ||
69 | wxString dest,src,err; | ||
70 | |||
71 | int pos = Themesrc.Find('/',true); | ||
72 | wxString themename = Themesrc.SubString(pos+1,Themesrc.Length()); | ||
73 | |||
74 | src = gv->themes_url + wxT("/") + Themesrc; | ||
75 | dest = gv->stdpaths->GetUserDataDir() | ||
76 | + wxT("" PATH_SEP "download" PATH_SEP) + themename; | ||
77 | if( DownloadURL(src, dest) ) | ||
78 | { | ||
79 | wxRemoveFile(dest); | ||
80 | ERR_DIALOG(wxT("Unable to download ") + src, wxT("Install Theme")); | ||
81 | return false; | ||
82 | } | ||
83 | |||
84 | if(!checkZip(dest)) | ||
85 | { | ||
86 | ERR_DIALOG(wxT("The Zip ") + dest | ||
87 | + wxT(" does not contain the correct dir structure"), | ||
88 | wxT("Install Theme")); | ||
89 | return false; | ||
90 | } | ||
91 | |||
92 | if(UnzipFile(dest,gv->curdestdir, true)) | ||
93 | { | ||
94 | ERR_DIALOG(wxT("Unable to unzip ") + dest + wxT(" to ") | ||
95 | + gv->curdestdir, wxT("Install Theme")); | ||
96 | return false; | ||
97 | } | ||
98 | |||
99 | return true; | ||
100 | } | ||
101 | |||
102 | bool checkZip(wxString zipname) | ||
103 | { | ||
104 | |||
105 | wxZipEntryPtr entry; | ||
106 | |||
107 | wxFFileInputStream* in_file = new wxFFileInputStream(zipname); | ||
108 | wxZipInputStream* in_zip = new wxZipInputStream(*in_file); | ||
109 | |||
110 | entry.reset(in_zip->GetNextEntry()); | ||
111 | |||
112 | wxString name = entry->GetName(); | ||
113 | if(entry->IsDir()) | ||
114 | { | ||
115 | if( 0==name.Cmp(wxT(".rockbox")) | ||
116 | || 0==name.Cmp(wxT(".rockbox\\")) | ||
117 | || 0==name.Cmp(wxT(".rockbox/")) ) | ||
118 | return true; | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | if( name.StartsWith(wxT(".rockbox/")) | ||
123 | || name.StartsWith(wxT(".rockbox\\")) ) | ||
124 | return true; | ||
125 | } | ||
126 | |||
127 | return false; | ||
128 | |||
129 | } | ||
130 | |||
131 | int DownloadURL(wxString src, wxString dest) | ||
132 | { | ||
133 | int input, errnum = 0, success = false; | ||
134 | wxString buf, errstr; | ||
135 | wxLogVerbose(wxT("=== begin DownloadURL(%s,%s)"), src.c_str(), | ||
136 | dest.c_str()); | ||
137 | |||
138 | buf = wxT("Fetching ") + src; | ||
139 | wxProgressDialog* progress = new wxProgressDialog(wxT("Downloading"), | ||
140 | buf, 100, NULL, wxPD_APP_MODAL | | ||
141 | wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_ELAPSED_TIME | | ||
142 | wxPD_REMAINING_TIME | wxPD_CAN_ABORT); | ||
143 | progress->SetSize(500,200); | ||
144 | progress->Update(0); | ||
145 | |||
146 | |||
147 | input = true; | ||
148 | wxURL* in_http = new wxURL(src); | ||
149 | |||
150 | if(gv->proxy_url != wxT("")) | ||
151 | in_http->SetProxy(gv->proxy_url); | ||
152 | |||
153 | if (in_http->GetError() == wxURL_NOERR) | ||
154 | { | ||
155 | |||
156 | wxFFileOutputStream* os = new wxFFileOutputStream(dest); | ||
157 | input = false; | ||
158 | if (os->IsOk()) | ||
159 | { | ||
160 | wxInputStream* is = in_http->GetInputStream(); | ||
161 | input = true; | ||
162 | if (is) | ||
163 | { | ||
164 | size_t filesize = is->GetSize(); | ||
165 | input = true; | ||
166 | if (is->IsOk()) | ||
167 | { | ||
168 | char buffer[FILE_BUFFER_SIZE + 1]; | ||
169 | size_t current = 0; | ||
170 | |||
171 | while (! is->Eof()) | ||
172 | { | ||
173 | is->Read(buffer, FILE_BUFFER_SIZE); | ||
174 | input = true; | ||
175 | if (is->LastRead() ) | ||
176 | { | ||
177 | os->Write(buffer, is->LastRead()); | ||
178 | input = false; | ||
179 | if (os->IsOk()) | ||
180 | { | ||
181 | current += os->LastWrite(); | ||
182 | if (!progress->Update(current * 100 / filesize)) | ||
183 | { | ||
184 | errstr = wxT("Download aborted by user"); | ||
185 | errnum = 1000; | ||
186 | break; | ||
187 | } | ||
188 | |||
189 | } else | ||
190 | { | ||
191 | errnum = os->GetLastError(); | ||
192 | errstr = wxT("Can't write to output stream (") | ||
193 | + stream_err_str(errnum) + wxT(")"); | ||
194 | |||
195 | break; | ||
196 | } | ||
197 | |||
198 | } else | ||
199 | { | ||
200 | errnum = is->GetLastError(); | ||
201 | if (errnum == wxSTREAM_EOF) | ||
202 | { | ||
203 | errnum = 0; | ||
204 | break; | ||
205 | } | ||
206 | errstr = wxT("Can't read from input stream (") | ||
207 | + stream_err_str(errnum) + wxT(")"); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | os->Close(); | ||
212 | if (! errnum) | ||
213 | { | ||
214 | errnum = os->GetLastError(); | ||
215 | errstr = wxT("Can't close output file (") | ||
216 | + stream_err_str(errnum) + wxT(")"); | ||
217 | |||
218 | input = false; | ||
219 | } | ||
220 | |||
221 | if (! errnum) success = true; | ||
222 | |||
223 | } else | ||
224 | { | ||
225 | errnum = is->GetLastError(); | ||
226 | errstr = wxT("Can't get input stream size (") | ||
227 | + stream_err_str(errnum) + wxT(")"); | ||
228 | } | ||
229 | } else | ||
230 | { | ||
231 | errnum = in_http->GetError(); | ||
232 | errstr.Printf(wxT("Can't get input stream (%d)"), errnum); | ||
233 | } | ||
234 | delete is; | ||
235 | } else | ||
236 | { | ||
237 | errnum = os->GetLastError(); | ||
238 | errstr = wxT("Can't create output stream (") | ||
239 | + stream_err_str(errnum) + wxT(")"); | ||
240 | } | ||
241 | delete os; | ||
242 | } else | ||
243 | { | ||
244 | errstr.Printf(wxT("Can't open URL %s (%d)"), src.c_str(), | ||
245 | in_http->GetError() ); | ||
246 | errnum = 100; | ||
247 | } | ||
248 | |||
249 | delete in_http; | ||
250 | delete progress; | ||
251 | |||
252 | if (!success) | ||
253 | { | ||
254 | if (errnum == 0) errnum = 999; | ||
255 | if (input) | ||
256 | { | ||
257 | ERR_DIALOG(errstr + wxT(" reading\n") + src, wxT("Download URL")); | ||
258 | } else | ||
259 | { | ||
260 | ERR_DIALOG(errstr + wxT("writing to download\n/") + dest, | ||
261 | wxT("Download URL")); | ||
262 | } | ||
263 | |||
264 | } | ||
265 | |||
266 | wxLogVerbose(wxT("=== end DownloadURL")); | ||
267 | return errnum; | ||
268 | } | ||
269 | |||
270 | int UnzipFile(wxString src, wxString destdir, bool isInstall) | ||
271 | { | ||
272 | |||
273 | wxZipEntryPtr entry; | ||
274 | wxString in_str, progress_msg, buf,subdir; | ||
275 | int errnum = 0, curfile = 0, totalfiles = 0; | ||
276 | InstallLog* log = NULL; | ||
277 | |||
278 | wxLogVerbose(wxT("===begin UnzipFile(%s,%s,%i)"), | ||
279 | src.c_str(), destdir.c_str(), isInstall); | ||
280 | |||
281 | wxFFileInputStream* in_file = new wxFFileInputStream(src); | ||
282 | wxZipInputStream* in_zip = new wxZipInputStream(*in_file); | ||
283 | if (in_file->Ok() ) | ||
284 | { | ||
285 | if (! in_zip->IsOk() ) | ||
286 | { | ||
287 | errnum = in_zip->GetLastError(); | ||
288 | ERR_DIALOG(wxT("Can't open ZIP stream ") + src | ||
289 | + wxT(" for reading (") + stream_err_str(errnum) | ||
290 | + wxT(")"), wxT("Unzip File") ); | ||
291 | delete in_zip; | ||
292 | delete in_file; | ||
293 | return true; | ||
294 | } | ||
295 | |||
296 | totalfiles = in_zip->GetTotalEntries(); | ||
297 | if (! in_zip->IsOk() ) | ||
298 | { | ||
299 | errnum = in_zip->GetLastError(); | ||
300 | ERR_DIALOG( wxT("Error Getting total ZIP entries for ") | ||
301 | + src + wxT(" (") + stream_err_str(errnum) + wxT(")"), | ||
302 | wxT("Unzip File") ); | ||
303 | delete in_zip; | ||
304 | delete in_file; | ||
305 | return true; | ||
306 | } | ||
307 | } else | ||
308 | { | ||
309 | errnum = in_file->GetLastError(); | ||
310 | ERR_DIALOG(wxT("Can't open ") + src + wxT(" (") | ||
311 | + stream_err_str(errnum) + wxT(")"), wxT("Unzip File") ); | ||
312 | delete in_zip; | ||
313 | delete in_file; | ||
314 | return true; | ||
315 | } | ||
316 | |||
317 | wxProgressDialog* progress = new wxProgressDialog(wxT("Unpacking archive"), | ||
318 | wxT("Preparing to unpack the downloaded files to your audio" | ||
319 | "device"), totalfiles, NULL, wxPD_APP_MODAL | | ||
320 | wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_ELAPSED_TIME | | ||
321 | wxPD_REMAINING_TIME | wxPD_CAN_ABORT); | ||
322 | progress->Update(0); | ||
323 | |||
324 | // We're not overly worried if the logging fails | ||
325 | if (isInstall) | ||
326 | { | ||
327 | log = new InstallLog(destdir + wxT("" PATH_SEP UNINSTALL_FILE)); | ||
328 | } | ||
329 | |||
330 | while (! errnum && | ||
331 | (entry.reset(in_zip->GetNextEntry()), entry.get() != NULL) ) | ||
332 | { | ||
333 | |||
334 | |||
335 | curfile++; | ||
336 | wxString name = entry->GetName(); | ||
337 | // set progress | ||
338 | progress_msg = wxT("Unpacking ") + name; | ||
339 | if (! progress->Update(curfile, progress_msg) ) | ||
340 | { | ||
341 | MESG_DIALOG(wxT("Unpacking cancelled by user")); | ||
342 | errnum = 1000; | ||
343 | break; | ||
344 | } | ||
345 | |||
346 | in_str = destdir + wxT("" PATH_SEP) + name; | ||
347 | |||
348 | subdir = wxPathOnly(in_str); | ||
349 | if(!(wxDirExists(subdir))) | ||
350 | { | ||
351 | if (! wxMkdir(subdir, 0777) ) | ||
352 | { | ||
353 | buf = wxT("Unable to create directory ") + subdir; | ||
354 | errnum = 100; | ||
355 | break; | ||
356 | } | ||
357 | log->WriteFile(subdir, true); // Directory | ||
358 | } | ||
359 | |||
360 | if(entry->IsDir()) | ||
361 | { | ||
362 | if(!wxDirExists(name)) | ||
363 | { | ||
364 | if(!wxMkdir(name, 0777) ) | ||
365 | { | ||
366 | buf = wxT("Unable to create directory ") + name; | ||
367 | errnum = 100; | ||
368 | break; | ||
369 | } | ||
370 | } | ||
371 | log->WriteFile(name, true); // Directory | ||
372 | continue; // this is just a directory, nothing else to do | ||
373 | } | ||
374 | |||
375 | // its a file, copy it | ||
376 | wxFFileOutputStream* out = new wxFFileOutputStream(in_str); | ||
377 | if (! out->IsOk() ) | ||
378 | { | ||
379 | buf = wxT("Can't open file ") + in_str + wxT(" for writing"); | ||
380 | delete out; | ||
381 | errnum = 100; | ||
382 | break; | ||
383 | } else if (isInstall) | ||
384 | { | ||
385 | log->WriteFile(name); | ||
386 | } | ||
387 | |||
388 | in_zip->Read(*out); | ||
389 | if (! out->IsOk()) { | ||
390 | buf.Printf(wxT("Can't write to %s (%d)"), in_str.c_str(), | ||
391 | errnum = out->GetLastError() ); | ||
392 | } | ||
393 | |||
394 | if (!in_zip->IsOk() && ! in_file->GetLastError() == wxSTREAM_EOF) | ||
395 | { | ||
396 | buf.Printf(wxT("Can't read from %s (%d)"), src.c_str(), | ||
397 | errnum = in_file->GetLastError() ); | ||
398 | } | ||
399 | |||
400 | if (! out->Close() && errnum == 0) | ||
401 | { | ||
402 | buf.Printf(wxT("Unable to close %s (%d)"), in_str.c_str(), | ||
403 | errnum = out->GetLastError() ); | ||
404 | |||
405 | } | ||
406 | |||
407 | delete out; | ||
408 | |||
409 | } | ||
410 | |||
411 | delete in_zip; delete in_file; delete progress; | ||
412 | |||
413 | if (errnum) | ||
414 | { | ||
415 | ERR_DIALOG(buf, wxT("Unzip File")); | ||
416 | } | ||
417 | |||
418 | if (log) delete log; | ||
419 | wxLogVerbose(wxT("=== end UnzipFile")); | ||
420 | return(errnum); | ||
421 | |||
422 | } | ||
423 | |||
424 | int Uninstall(const wxString dir, bool isFullUninstall) { | ||
425 | wxString buf, uninst; | ||
426 | unsigned int i; | ||
427 | bool errflag = false; | ||
428 | InstallLog *log = NULL; | ||
429 | wxArrayString* FilesToRemove = NULL; | ||
430 | |||
431 | wxLogVerbose(wxT("=== begin Uninstall(%s,%i)"), dir.c_str(), isFullUninstall); | ||
432 | |||
433 | wxProgressDialog* progress = new wxProgressDialog(wxT("Uninstalling"), | ||
434 | wxT("Reading uninstall data from jukebox"), 100, NULL, | ||
435 | wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_SMOOTH | | ||
436 | wxPD_ELAPSED_TIME | wxPD_REMAINING_TIME | wxPD_CAN_ABORT); | ||
437 | progress->Update(0); | ||
438 | |||
439 | if (! isFullUninstall) | ||
440 | { | ||
441 | |||
442 | buf = dir + wxT("" PATH_SEP UNINSTALL_FILE); | ||
443 | log = new InstallLog(buf, false); // Don't create the log | ||
444 | FilesToRemove = log->GetInstalledFiles(); | ||
445 | if (log) delete log; | ||
446 | |||
447 | if (FilesToRemove == NULL || FilesToRemove->GetCount() < 1) { | ||
448 | wxLogNull lognull; | ||
449 | if ( wxMessageDialog(NULL, | ||
450 | wxT("Rockbox Utility can't find any uninstall data on this " | ||
451 | "jukebox.\n" | ||
452 | "Would you like to attempt a full uninstall?\n" | ||
453 | "(WARNING: A full uninstall removes all files in your Rockbox " | ||
454 | "folder)"), | ||
455 | wxT("Standard uninstall not possible"), | ||
456 | wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT).ShowModal() | ||
457 | == wxID_YES) | ||
458 | { | ||
459 | isFullUninstall = true; | ||
460 | } | ||
461 | else { | ||
462 | MESG_DIALOG(wxT("Uninstall cancelled by user")); | ||
463 | delete progress; | ||
464 | return 1000; | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | |||
469 | if (isFullUninstall ) | ||
470 | { | ||
471 | buf = dir + wxT("" PATH_SEP ".rockbox"); | ||
472 | if (rm_rf(buf) ) | ||
473 | { | ||
474 | WARN_DIALOG(wxT("Unable to completely remove Rockbox directory"), | ||
475 | wxT("Full uninstall") ); | ||
476 | errflag = true; | ||
477 | } | ||
478 | |||
479 | wxDir* root = new wxDir(dir); | ||
480 | wxArrayString* special = new wxArrayString(); | ||
481 | // Search for files for deletion in the jukebox root | ||
482 | for (i = 0; i < rootmatch->GetCount(); i++) | ||
483 | { | ||
484 | const wxString match = (*rootmatch)[i]; | ||
485 | root->GetAllFiles(dir, special, match, wxDIR_FILES); | ||
486 | } | ||
487 | delete root; | ||
488 | |||
489 | // Sort in reverse order so we get directories last | ||
490 | special->Sort(true); | ||
491 | |||
492 | for (i = 0; i < special->GetCount(); i++) | ||
493 | { | ||
494 | |||
495 | if (wxDirExists((*special)[i]) ) | ||
496 | { | ||
497 | // We don't check the return code since we don't want non | ||
498 | // empty dirs disappearing. | ||
499 | wxRmdir((*special)[i]); | ||
500 | |||
501 | } else if (wxFileExists((*special)[i]) ) | ||
502 | { | ||
503 | if (! wxRemoveFile((*special)[i]) ) | ||
504 | { | ||
505 | WARN_DIALOG(wxT("Can't delete ") + (*special)[i], | ||
506 | wxT("Full uninstall")); | ||
507 | errflag = true; | ||
508 | } | ||
509 | } | ||
510 | // Otherwise there isn't anything there, so we don't have to worry. | ||
511 | } | ||
512 | delete special; | ||
513 | } else | ||
514 | { | ||
515 | wxString instplat, this_path_sep; | ||
516 | unsigned int totalfiles, rc; | ||
517 | totalfiles = FilesToRemove->GetCount(); | ||
518 | FilesToRemove->Sort(true); // Reverse alphabetical ie dirs after files | ||
519 | |||
520 | for (i = 0; i < totalfiles; i++) | ||
521 | { | ||
522 | // If we're running on the device, let's not delete our own | ||
523 | // installation, eh? | ||
524 | if (gv->portable && | ||
525 | FilesToRemove->Item(i).StartsWith(PATH_SEP | ||
526 | wxT("RockboxUtility")) ) | ||
527 | { | ||
528 | continue; | ||
529 | } | ||
530 | |||
531 | wxString* buf2 = new wxString; | ||
532 | buf = dir + FilesToRemove->Item(i); | ||
533 | buf2->Format(wxT("Deleting %s"), buf.c_str()); | ||
534 | |||
535 | if (! progress->Update((i + 1) * 100 / totalfiles, *buf2) ) | ||
536 | { | ||
537 | WARN_DIALOG(wxT("Cancelled by user"), wxT("Normal Uninstall")); | ||
538 | delete progress; | ||
539 | return true; | ||
540 | } | ||
541 | |||
542 | if (wxDirExists(buf) ) | ||
543 | { | ||
544 | // If we're about to attempt to remove .rockbox. delete | ||
545 | // install data first | ||
546 | *buf2 = dir + wxT("" PATH_SEP ".rockbox"); | ||
547 | if ( buf.IsSameAs(buf2->c_str()) ) | ||
548 | { | ||
549 | *buf2 = dir +wxT("" PATH_SEP UNINSTALL_FILE); | ||
550 | wxRemoveFile(*buf2); | ||
551 | } | ||
552 | |||
553 | if ( (rc = ! wxRmdir(buf)) ) | ||
554 | { | ||
555 | buf = buf.Format(wxT("Can't remove directory %s"), | ||
556 | buf.c_str()); | ||
557 | errflag = true; | ||
558 | WARN_DIALOG(buf.c_str(), wxT("Standard uninstall")); | ||
559 | } | ||
560 | } else if (wxFileExists(buf) ) | ||
561 | { | ||
562 | if ( (rc = ! wxRemoveFile(buf)) ) | ||
563 | { | ||
564 | buf = buf.Format(wxT("Can't delete file %s"), | ||
565 | buf.c_str()); | ||
566 | errflag = true; | ||
567 | WARN_DIALOG(buf.c_str(), wxT("Standard uninstall")); | ||
568 | } | ||
569 | } else | ||
570 | { | ||
571 | errflag = true; | ||
572 | buf = buf.Format(wxT("Can't find file or directory %s"), | ||
573 | buf.c_str() ); | ||
574 | WARN_DIALOG(buf.c_str(), wxT("Standard uninstall") ); | ||
575 | } | ||
576 | |||
577 | uninst = uninst.AfterFirst('\n'); | ||
578 | } | ||
579 | if (errflag) | ||
580 | { | ||
581 | ERR_DIALOG(wxT("Unable to remove some files"), | ||
582 | wxT("Standard uninstall")) ; | ||
583 | } | ||
584 | |||
585 | if (FilesToRemove != NULL) delete FilesToRemove; | ||
586 | } | ||
587 | |||
588 | delete progress; | ||
589 | wxLogVerbose(wxT("=== end Uninstall")); | ||
590 | return errflag; | ||
591 | } | ||
592 | |||
593 | |||
594 | wxString stream_err_str(int errnum) | ||
595 | { | ||
596 | wxString out; | ||
597 | |||
598 | switch (errnum) { | ||
599 | case wxSTREAM_NO_ERROR: | ||
600 | out = wxT("wxSTREAM_NO_ERROR"); | ||
601 | break; | ||
602 | case wxSTREAM_EOF: | ||
603 | out = wxT("wxSTREAM_EOF"); | ||
604 | break; | ||
605 | case wxSTREAM_WRITE_ERROR: | ||
606 | out = wxT("wxSTREAM_WRITE_ERROR"); | ||
607 | break; | ||
608 | case wxSTREAM_READ_ERROR: | ||
609 | out = wxT("wxSTREAM_READ_ERROR"); | ||
610 | break; | ||
611 | default: | ||
612 | out = wxT("UNKNOWN"); | ||
613 | break; | ||
614 | } | ||
615 | return out; | ||
616 | } | ||
617 | |||
618 | bool InstallRbutil(wxString dest) | ||
619 | { | ||
620 | wxArrayString filestocopy; | ||
621 | wxString str, buf, dstr, localpath, destdir; | ||
622 | unsigned int i; | ||
623 | wxDir dir; | ||
624 | bool copied_exe = false, made_rbdir = false; | ||
625 | InstallLog* log; | ||
626 | |||
627 | buf = dest + wxT("" PATH_SEP ".rockbox"); | ||
628 | |||
629 | if (! wxDirExists(buf) ) | ||
630 | { | ||
631 | wxMkdir(buf); | ||
632 | made_rbdir = true; | ||
633 | } | ||
634 | |||
635 | buf = dest + wxT("" PATH_SEP UNINSTALL_FILE); | ||
636 | log = new InstallLog(buf); | ||
637 | if (made_rbdir) log->WriteFile(wxT(".rockbox"), true); | ||
638 | |||
639 | destdir = dest + wxT("" PATH_SEP "RockboxUtility"); | ||
640 | if (! wxDirExists(destdir) ) | ||
641 | { | ||
642 | if (! wxMkdir(destdir, 0777) ) | ||
643 | { | ||
644 | WARN_DIALOG( wxT("Unable to create directory for installer (") | ||
645 | + destdir + wxT(")"), wxT("Portable install") ); | ||
646 | return false; | ||
647 | } | ||
648 | log->WriteFile(wxT("RockboxUtility"), true); | ||
649 | } | ||
650 | |||
651 | dir.GetAllFiles(gv->ResourceDir, &filestocopy, wxT("*"), | ||
652 | wxDIR_FILES); | ||
653 | if (filestocopy.GetCount() < 1) | ||
654 | { | ||
655 | WARN_DIALOG(wxT("No files to copy"), wxT("Portable install") ); | ||
656 | return false; | ||
657 | } | ||
658 | |||
659 | // Copy the contents of the program directory | ||
660 | for (i = 0; i < filestocopy.GetCount(); i++) | ||
661 | { | ||
662 | if (filestocopy[i].AfterLast(PATH_SEP_CHR) == EXE_NAME) | ||
663 | { | ||
664 | copied_exe = true; | ||
665 | } | ||
666 | |||
667 | dstr = destdir + wxT("" PATH_SEP) | ||
668 | + filestocopy[i].AfterLast(PATH_SEP_CHR); | ||
669 | if (! wxCopyFile(filestocopy[i], dstr) ) | ||
670 | { | ||
671 | WARN_DIALOG( wxT("Error copying file (") | ||
672 | + filestocopy[i].c_str() + wxT(" -> ") | ||
673 | + dstr + wxT(")"), wxT("Portable Install") ); | ||
674 | return false; | ||
675 | } | ||
676 | buf = dstr; | ||
677 | buf.Replace(dest, wxEmptyString, false); | ||
678 | log->WriteFile(buf); | ||
679 | } | ||
680 | |||
681 | if (! copied_exe) | ||
682 | { | ||
683 | str = gv->AppDir + wxT("" PATH_SEP EXE_NAME); | ||
684 | dstr = destdir + wxT("" PATH_SEP EXE_NAME); | ||
685 | if (! wxCopyFile(str, dstr) ) | ||
686 | { | ||
687 | WARN_DIALOG(wxT("Can't copy program binary ") | ||
688 | + str + wxT(" -> ") + dstr, wxT("Portable Install") ); | ||
689 | return false; | ||
690 | } | ||
691 | buf = dstr; | ||
692 | buf.Replace(dest, wxEmptyString, false); | ||
693 | log->WriteFile(buf); | ||
694 | } | ||
695 | |||
696 | // Copy the local ini file so that it knows that it's a portable copy | ||
697 | gv->UserConfig->Flush(); | ||
698 | dstr = destdir + wxT("" PATH_SEP "RockboxUtility.cfg"); | ||
699 | if (! wxCopyFile(gv->UserConfigFile, dstr) ) | ||
700 | { | ||
701 | WARN_DIALOG(wxT("Unable to install user config file (") | ||
702 | + gv->UserConfigFile + wxT(" -> ") + dstr + wxT(")"), | ||
703 | wxT("Portable Install") ); | ||
704 | return false; | ||
705 | } | ||
706 | buf = dstr; | ||
707 | buf.Replace(dest, wxEmptyString, false); | ||
708 | log->WriteFile(buf); | ||
709 | |||
710 | delete log; | ||
711 | return true; | ||
712 | } | ||
713 | |||
714 | bool rm_rf(wxString file) | ||
715 | { | ||
716 | wxLogVerbose(wxT("=== begin rm-rf(%s)"), file.c_str() ); | ||
717 | |||
718 | wxString buf; | ||
719 | wxArrayString selected; | ||
720 | wxDirTraverserIncludeDirs wxdtid(selected); | ||
721 | unsigned int rc = 0, i; | ||
722 | bool errflag = false; | ||
723 | |||
724 | if (wxFileExists(file) ) | ||
725 | { | ||
726 | rc = ! wxRemoveFile(file); | ||
727 | } else if (wxDirExists(file) ) | ||
728 | { | ||
729 | wxDir* dir = new wxDir(file);; | ||
730 | dir->Traverse(wxdtid); | ||
731 | delete dir; | ||
732 | // Sort into reverse alphabetical order for deletion in correct order | ||
733 | // (directories after files) | ||
734 | selected.Sort(true); | ||
735 | selected.Add(file); | ||
736 | |||
737 | wxProgressDialog* progress = new wxProgressDialog(wxT("Removing files"), | ||
738 | wxT("Deleting files"), selected.GetCount(), NULL, | ||
739 | wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_SMOOTH | | ||
740 | wxPD_ELAPSED_TIME | wxPD_REMAINING_TIME | wxPD_CAN_ABORT); | ||
741 | |||
742 | for (i = 0; i < selected.GetCount(); i++) | ||
743 | { | ||
744 | wxLogVerbose(selected[i]); | ||
745 | if (progress != NULL) | ||
746 | { | ||
747 | buf = wxT("Deleting ") + selected[i]; | ||
748 | if (! progress->Update(i, buf)) | ||
749 | { | ||
750 | WARN_DIALOG(wxT("Cancelled by user"), wxT("Erase Files")); | ||
751 | delete progress; | ||
752 | return true; | ||
753 | } | ||
754 | } | ||
755 | |||
756 | if (wxDirExists(selected[i]) ) | ||
757 | { | ||
758 | if ((rc = ! wxRmdir(selected[i])) ) | ||
759 | { | ||
760 | errflag = true; | ||
761 | WARN_DIALOG(wxT("Can't remove directory ") + selected[i], | ||
762 | wxT("Erase files")); | ||
763 | } | ||
764 | } else if ((rc = ! wxRemoveFile(selected[i])) ) | ||
765 | { | ||
766 | errflag = true; | ||
767 | WARN_DIALOG(wxT("Error deleting file ") + selected[i], | ||
768 | wxT("Erase files")); | ||
769 | } | ||
770 | } | ||
771 | delete progress; | ||
772 | } else | ||
773 | { | ||
774 | WARN_DIALOG(wxT("Can't find expected file ") + file, | ||
775 | wxT("Erase files")); | ||
776 | return true; | ||
777 | } | ||
778 | |||
779 | wxLogVerbose(wxT("=== end rm-rf")); | ||
780 | return rc ? true : false; | ||
781 | } | ||
782 | |||
783 | |||