|
22 | 22 | * Contributor(s):
|
23 | 23 | * Darin Fisher <darin@meer.net>
|
24 | 24 | * Ben Turner <mozilla@songbirdnest.com>
|
| 25 | + * Robert Strong <robert.bugzilla@gmail.com> |
25 | 26 | *
|
26 | 27 | * Alternatively, the contents of this file may be used under the terms of
|
27 | 28 | * either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
51 | 52 | #include "nsPrintfCString.h"
|
52 | 53 | #include "prproces.h"
|
53 | 54 | #include "prlog.h"
|
| 55 | +#include "nsVersionComparator.h" |
54 | 56 |
|
55 | 57 | #ifdef XP_MACOSX
|
56 | 58 | #include "nsILocalFileMac.h"
|
@@ -222,16 +224,16 @@ GetFile(nsIFile *dir, const nsCSubstring &name, nsCOMPtr<nsILocalFile> &result)
|
222 | 224 | {
|
223 | 225 | nsresult rv;
|
224 | 226 |
|
225 |
| - nsCOMPtr<nsIFile> statusFile; |
226 |
| - rv = dir->Clone(getter_AddRefs(statusFile)); |
| 227 | + nsCOMPtr<nsIFile> file; |
| 228 | + rv = dir->Clone(getter_AddRefs(file)); |
227 | 229 | if (NS_FAILED(rv))
|
228 | 230 | return PR_FALSE;
|
229 | 231 |
|
230 |
| - rv = statusFile->AppendNative(name); |
| 232 | + rv = file->AppendNative(name); |
231 | 233 | if (NS_FAILED(rv))
|
232 | 234 | return PR_FALSE;
|
233 | 235 |
|
234 |
| - result = do_QueryInterface(statusFile, &rv); |
| 236 | + result = do_QueryInterface(file, &rv); |
235 | 237 | return NS_SUCCEEDED(rv);
|
236 | 238 | }
|
237 | 239 |
|
@@ -274,6 +276,42 @@ SetStatus(nsILocalFile *statusFile, const char *status)
|
274 | 276 | return PR_TRUE;
|
275 | 277 | }
|
276 | 278 |
|
| 279 | +static PRBool |
| 280 | +GetVersionFile(nsIFile *dir, nsCOMPtr<nsILocalFile> &result) |
| 281 | +{ |
| 282 | + return GetFile(dir, NS_LITERAL_CSTRING("update.version"), result); |
| 283 | +} |
| 284 | + |
| 285 | +// Compares the current application version with the update's application |
| 286 | +// version. |
| 287 | +static PRBool |
| 288 | +IsOlderVersion(nsILocalFile *versionFile, const char *&appVersion) |
| 289 | +{ |
| 290 | + nsresult rv; |
| 291 | + |
| 292 | + FILE *fp; |
| 293 | + rv = versionFile->OpenANSIFileDesc("r", &fp); |
| 294 | + if (NS_FAILED(rv)) |
| 295 | + return PR_TRUE; |
| 296 | + |
| 297 | + char buf[32]; |
| 298 | + char *result = fgets(buf, sizeof(buf), fp); |
| 299 | + fclose(fp); |
| 300 | + if (!result) |
| 301 | + return PR_TRUE; |
| 302 | + |
| 303 | + // If the update xml doesn't provide the application version the file will |
| 304 | + // contain the string "null" and it is assumed that the update is not older. |
| 305 | + const char kNull[] = "null"; |
| 306 | + if (strncmp(buf, kNull, sizeof(kNull) - 1) == 0) |
| 307 | + return PR_FALSE; |
| 308 | + |
| 309 | + if (NS_CompareVersions(appVersion, result) > 0) |
| 310 | + return PR_TRUE; |
| 311 | + |
| 312 | + return PR_FALSE; |
| 313 | +} |
| 314 | + |
277 | 315 | static PRBool
|
278 | 316 | CopyFileIntoUpdateDir(nsIFile *parentDir, const char *leafName, nsIFile *updateDir)
|
279 | 317 | {
|
@@ -505,7 +543,7 @@ ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsILocalFile *statusFile,
|
505 | 543 |
|
506 | 544 | nsresult
|
507 | 545 | ProcessUpdates(nsIFile *greDir, nsIFile *appDir, nsIFile *updRootDir,
|
508 |
| - int argc, char **argv) |
| 546 | + int argc, char **argv, const char *&appVersion) |
509 | 547 | {
|
510 | 548 | nsresult rv;
|
511 | 549 |
|
@@ -533,6 +571,16 @@ ProcessUpdates(nsIFile *greDir, nsIFile *appDir, nsIFile *updRootDir,
|
533 | 571 | for (int i = 0; i < dirEntries.Count(); ++i) {
|
534 | 572 | nsCOMPtr<nsILocalFile> statusFile;
|
535 | 573 | if (GetStatusFile(dirEntries[i], statusFile) && IsPending(statusFile)) {
|
| 574 | + nsCOMPtr<nsILocalFile> versionFile; |
| 575 | + // Remove the update if the update application version file doesn't exist |
| 576 | + // or if the update's application version is less than the current |
| 577 | + // application version. |
| 578 | + if (!GetVersionFile(dirEntries[i], versionFile) || |
| 579 | + IsOlderVersion(versionFile, appVersion)) { |
| 580 | + dirEntries[i]->Remove(PR_TRUE); |
| 581 | + continue; |
| 582 | + } |
| 583 | + |
536 | 584 | ApplyUpdate(greDir, dirEntries[i], statusFile, appDir, argc, argv);
|
537 | 585 | break;
|
538 | 586 | }
|
|
0 commit comments