]> git.saurik.com Git - cydia.git/blobdiff - Cydia.mm
Checkpoint for LunaCy fork.
[cydia.git] / Cydia.mm
index e10a7d50c8fe52d3ff7c8227e9c0e909decd0e00..e069dd7f40d29a88605a173ab28982c9ef51fcd2 100644 (file)
--- a/Cydia.mm
+++ b/Cydia.mm
@@ -1,5 +1,5 @@
 /* Cydia - iPhone UIKit Front-End for Debian APT
- * Copyright (C) 2008  Jay Freeman (saurik)
+ * Copyright (C) 2008-2009  Jay Freeman (saurik)
 */
 
 /*
@@ -216,6 +216,11 @@ class _H {
     }
 
   public:
+    _finline _H(const This_ &rhs) :
+        value_(rhs.value_ == nil ? nil : [rhs.value_ retain])
+    {
+    }
+
     _finline _H(Type_ *value = NULL, bool mended = false) :
         value_(value)
     {
@@ -403,7 +408,7 @@ extern NSString * const kCAFilterNearest;
 
 #define lprintf(args...) fprintf(stderr, args)
 
-#define ForRelease 0
+#define ForRelease 1
 #define TraceLogging (1 && !ForRelease)
 #define HistogramInsertionSort (0 && !ForRelease)
 #define ProfileTimes (0 && !ForRelease)
@@ -764,8 +769,10 @@ class CYString {
     CFStringRef cache_;
 
     _finline void clear_() {
-        if (cache_ != nil)
+        if (cache_ != NULL) {
             CFRelease(cache_);
+            cache_ = NULL;
+        }
     }
 
   public:
@@ -789,7 +796,7 @@ class CYString {
     _finline CYString() :
         data_(0),
         size_(0),
-        cache_(nil)
+        cache_(NULL)
     {
     }
 
@@ -1044,7 +1051,6 @@ static const int ButtonBarHeight_ = 48;
 static const float KeyboardTime_ = 0.3f;
 
 #define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"
-#define SandboxTemplate_ "/usr/share/sandbox/SandboxTemplate.sb"
 #define NotifyConfig_ "/etc/notify.conf"
 
 static bool Queuing_;
@@ -1143,10 +1149,19 @@ static _finline CFStringRef CFCString(const char *value) {
     return CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(value), strlen(value), kCFStringEncodingUTF8, NO, kCFAllocatorNull);
 }
 
+const char *StripVersion_(const char *version) {
+    const char *colon(strchr(version, ':'));
+    if (colon != NULL)
+        version = colon + 1;
+    return version;
+}
+
 CFStringRef StripVersion(const char *version) {
     const char *colon(strchr(version, ':'));
     if (colon != NULL)
         version = colon + 1;
+    return CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const uint8_t *>(version), strlen(version), kCFStringEncodingUTF8, NO);
+    // XXX: performance
     return CFCString(version);
 }
 
@@ -1407,7 +1422,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 - (void) upgrade;
 - (void) update;
 
-- (void) updateWithStatus:(Status &)status;
+- (NSString *) updateWithStatus:(Status &)status;
 
 - (void) setDelegate:(id)delegate;
 - (Source *) getSource:(pkgCache::PkgFileIterator)file;
@@ -1416,6 +1431,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 
 /* Source Class {{{ */
 @interface Source : NSObject {
+    CYString depiction_;
     CYString description_;
     CYString label_;
     CYString origin_;
@@ -1438,6 +1454,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 
 - (NSComparisonResult) compareByNameAndType:(Source *)source;
 
+- (NSString *) depictionForPackage:(NSString *)package;
 - (NSString *) supportForPackage:(NSString *)package;
 
 - (NSDictionary *) record;
@@ -1469,6 +1486,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
     description_.clear();
     label_.clear();
     origin_.clear();
+    depiction_.clear();
     support_.clear();
     version_.clear();
     defaultIcon_.clear();
@@ -1512,30 +1530,35 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 
     debReleaseIndex *dindex(dynamic_cast<debReleaseIndex *>(index));
     if (dindex != NULL) {
-        FileFd fd(dindex->MetaIndexFile("Release"), FileFd::ReadOnly);
-        pkgTagFile tags(&fd);
+        FileFd fd;
+        if (!fd.Open(dindex->MetaIndexFile("Release"), FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            pkgTagFile tags(&fd);
 
-        pkgTagSection section;
-        tags.Step(section);
+            pkgTagSection section;
+            tags.Step(section);
 
-        struct {
-            const char *name_;
-            CYString *value_;
-        } names[] = {
-            {"default-icon", &defaultIcon_},
-            {"description", &description_},
-            {"label", &label_},
-            {"origin", &origin_},
-            {"support", &support_},
-            {"version", &version_},
-        };
-
-        for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
-            const char *start, *end;
+            struct {
+                const char *name_;
+                CYString *value_;
+            } names[] = {
+                {"default-icon", &defaultIcon_},
+                {"depiction", &depiction_},
+                {"description", &description_},
+                {"label", &label_},
+                {"origin", &origin_},
+                {"support", &support_},
+                {"version", &version_},
+            };
+
+            for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) {
+                const char *start, *end;
 
-            if (section.Find(names[i].name_, start, end)) {
-                CYString &value(*names[i].value_);
-                value.set(pool, start, end - start);
+                if (section.Find(names[i].name_, start, end)) {
+                    CYString &value(*names[i].value_);
+                    value.set(pool, start, end - start);
+                }
             }
         }
     }
@@ -1576,6 +1599,10 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
     return [lhs compare:rhs options:LaxCompareOptions_];
 }
 
+- (NSString *) depictionForPackage:(NSString *)package {
+    return depiction_.empty() ? nil : [depiction_ stringByReplacingOccurrencesOfString:@"*" withString:package];
+}
+
 - (NSString *) supportForPackage:(NSString *)package {
     return support_.empty() ? nil : [support_ stringByReplacingOccurrencesOfString:@"*" withString:package];
 }
@@ -1689,7 +1716,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
     bool visible_;
 
     NSString *latest_;
-    NSString *installed_;
+    CYString installed_;
 
     CYString id_;
     CYString name_;
@@ -1743,6 +1770,7 @@ typedef std::map< unsigned long, _H<Source> > SourceMap;
 
 - (NSString *) latest;
 - (NSString *) installed;
+- (BOOL) uninstalled;
 
 - (BOOL) valid;
 - (BOOL) upgradableAndEssential:(BOOL)essential;
@@ -1934,8 +1962,6 @@ struct PackageNameOrdering :
 
     if (latest_ != nil)
         [latest_ release];
-    if (installed_ != nil)
-        [installed_ release];
 
     if (sponsor$_ != nil)
         [sponsor$_ release];
@@ -2059,7 +2085,7 @@ struct PackageNameOrdering :
         _profile(Package$initWithVersion$Versions)
             current = iterator_.CurrentVer();
             if (!current.end())
-                installed_ = (NSString *) StripVersion(current.VerStr());
+                installed_.set(pool_, StripVersion_(current.VerStr()));
 
             if (!version_.end())
                 file_ = version_.FileList();
@@ -2083,6 +2109,8 @@ struct PackageNameOrdering :
             _end
         }
 
+        visible_ = true;
+
         _profile(Package$initWithVersion$Tags)
             pkgCache::TagIterator tag(iterator_.TagList());
             if (!tag.end()) {
@@ -2090,8 +2118,12 @@ struct PackageNameOrdering :
                 do {
                     const char *name(tag.Name());
                     [tags_ addObject:(NSString *)CFCString(name)];
-                    if (role_ == nil && strncmp(name, "role::", 6) == 0)
+                    if (role_ == nil && strncmp(name, "role::", 6) == 0 /*&& strcmp(name, "role::leaper") != 0*/)
                         role_ = (NSString *) CFCString(name + 6);
+                    if (visible_ && strncmp(name, "require::", 9) == 0 && (
+                        true
+                    ))
+                        visible_ = false;
                     ++tag;
                 } while (!tag.end());
             }
@@ -2130,12 +2162,13 @@ struct PackageNameOrdering :
                 if (version == nil) {
                     [metadata_ setObject:latest_ forKey:@"LastVersion"];
                     changed = true;
-                } else if (![version isEqualToString:latest_]) {
+                } else {
+                if (![version isEqualToString:latest_]) {
                     [metadata_ setObject:latest_ forKey:@"LastVersion"];
                     lastSeen_ = now_;
                     [metadata_ setObject:lastSeen_ forKey:@"LastSeen"];
                     changed = true;
-                }
+                } }
             }
 
             metadata_ = [metadata_ retain];
@@ -2151,7 +2184,7 @@ struct PackageNameOrdering :
         _end
 
         essential_ = ((iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES) || [self hasTag:@"cydia::essential"];
-        visible_ = [self hasSupportingRole] && [self unfiltered];
+        visible_ = visible_ && [self hasSupportingRole] && [self unfiltered];
     } _end } return self;
 }
 
@@ -2204,7 +2237,7 @@ struct PackageNameOrdering :
 }
 
 - (NSString *) longSection {
-    return LocalizeSection(section_);
+    return LocalizeSection([self section]);
 }
 
 - (NSString *) shortSection {
@@ -2302,6 +2335,10 @@ struct PackageNameOrdering :
     return installed_;
 }
 
+- (BOOL) uninstalled {
+    return installed_.empty();
+}
+
 - (BOOL) valid {
     return !version_.end();
 }
@@ -2417,7 +2454,7 @@ struct PackageNameOrdering :
 }
 
 - (NSString *) depiction {
-    return depiction_;
+    return !depiction_.empty() ? depiction_ : [[self source] depictionForPackage:id_];
 }
 
 - (Address *) sponsor {
@@ -2706,7 +2743,7 @@ struct PackageNameOrdering :
 }
 
 - (bool) isInstalledAndVisible:(NSNumber *)number {
-    return (![number boolValue] || [self visible]) && [self installed] != nil;
+    return (![number boolValue] || [self visible]) && ![self uninstalled];
 }
 
 - (bool) isVisiblyUninstalledInSection:(NSString *)name {
@@ -2714,7 +2751,7 @@ struct PackageNameOrdering :
 
     return
         [self visible] &&
-        [self installed] == nil && (
+        [self uninstalled] && (
             name == nil ||
             section == nil && [name length] == 0 ||
             [name isEqualToString:section]
@@ -3320,6 +3357,8 @@ static NSArray *Finishes_;
     for (pkgAcquire::ItemIterator item = fetcher_->ItemsBegin(); item != fetcher_->ItemsEnd(); item++) {
         if ((*item)->Status == pkgAcquire::Item::StatDone && (*item)->Complete)
             continue;
+        if ((*item)->Status == pkgAcquire::Item::StatIdle)
+            continue;
 
         std::string uri = (*item)->DescURI();
         std::string error = (*item)->ErrorText;
@@ -3377,13 +3416,20 @@ static NSArray *Finishes_;
     [self updateWithStatus:status_];
 }
 
-- (void) updateWithStatus:(Status &)status {
+- (NSString *) updateWithStatus:(Status &)status {
     pkgSourceList list;
     _assert(list.ReadMainList());
 
     FileFd lock;
     lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
-    _assert(!_error->PendingError());
+
+    if (_error->PendingError()) {
+        std::string error;
+        if (!_error->PopMessage(error))
+            _assert(false);
+        _error->Discard();
+        return [NSString stringWithUTF8String:error.c_str()];
+    }
 
     pkgAcquire fetcher(&status);
     _assert(list.GetIndexes(&fetcher));
@@ -3404,6 +3450,8 @@ static NSArray *Finishes_;
         [Metadata_ setObject:[NSDate date] forKey:@"LastUpdate"];
         Changed_ = true;
     }
+
+    return nil;
 }
 
 - (void) setDelegate:(id)delegate {
@@ -3413,7 +3461,8 @@ static NSArray *Finishes_;
 }
 
 - (Source *) getSource:(pkgCache::PkgFileIterator)file {
-    return sources_[file->ID];
+    SourceMap::const_iterator i(sources_.find(file->ID));
+    return i == sources_.end() ? nil : i->second;
 }
 
 @end
@@ -3970,92 +4019,52 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [transition_ transition:6 toView:view_];
 }
 
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    NSString *context([sheet context]);
-
-    if ([context isEqualToString:@"error"])
-        [sheet dismiss];
-    else if ([context isEqualToString:@"conffile"]) {
-        FILE *input = [database_ input];
-
-        switch (button) {
-            case 1:
-                fprintf(input, "N\n");
-                fflush(input);
-                break;
-            case 2:
-                fprintf(input, "Y\n");
-                fflush(input);
-                break;
-            default:
-                _assert(false);
-        }
-
-        [sheet dismiss];
-    }
-}
-
-- (void) closeButtonPushed {
-    running_ = NO;
-
-    switch (Finish_) {
-        case 0:
-            [self resetView];
-        break;
-
-        case 1:
-            [delegate_ suspendWithAnimation:YES];
-        break;
+- (void) _checkError {
+    if (_error->PendingError()) {
+        std::string error;
+        if (!_error->PopMessage(error))
+            _assert(false);
 
-        case 2:
-            system("launchctl stop com.apple.SpringBoard");
-        break;
+        UIActionSheet *sheet = [[[UIActionSheet alloc]
+            initWithTitle:CYLocalize("ERROR")
+            buttons:[NSArray arrayWithObjects:CYLocalize("OKAY"), nil]
+            defaultButtonIndex:0
+            delegate:self
+            context:@"_error"
+        ] autorelease];
 
-        case 3:
-            system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
-        break;
+        [sheet setBodyText:[NSString stringWithUTF8String:error.c_str()]];
+        [sheet popupAlertAnimated:YES];
 
-        case 4:
-            system("reboot");
-        break;
+        return;
     }
-}
-
-- (void) _retachThread {
-    UINavigationItem *item = [navbar_ topItem];
-    [item setTitle:CYLocalize("COMPLETE")];
-
-    [overlay_ addSubview:close_];
-    [progress_ removeFromSuperview];
-    [status_ removeFromSuperview];
 
     [delegate_ progressViewIsComplete:self];
 
     if (Finish_ < 4) {
-        FileFd file(SandboxTemplate_, FileFd::ReadOnly);
-        MMap mmap(file, MMap::ReadOnly);
-        SHA1Summation sha1;
-        sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-        if (!(sandplate_ == sha1.Result()))
-            Finish_ = 4;
-    }
-
-    if (Finish_ < 4) {
-        FileFd file(NotifyConfig_, FileFd::ReadOnly);
-        MMap mmap(file, MMap::ReadOnly);
-        SHA1Summation sha1;
-        sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-        if (!(notifyconf_ == sha1.Result()))
-            Finish_ = 4;
+        FileFd file;
+        if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            MMap mmap(file, MMap::ReadOnly);
+            SHA1Summation sha1;
+            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+            if (!(notifyconf_ == sha1.Result()))
+                Finish_ = 4;
+        }
     }
 
     if (Finish_ < 3) {
-        FileFd file(SpringBoard_, FileFd::ReadOnly);
-        MMap mmap(file, MMap::ReadOnly);
-        SHA1Summation sha1;
-        sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-        if (!(springlist_ == sha1.Result()))
-            Finish_ = 3;
+        FileFd file;
+        if (!file.Open(SpringBoard_, FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            MMap mmap(file, MMap::ReadOnly);
+            SHA1Summation sha1;
+            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+            if (!(springlist_ == sha1.Result()))
+                Finish_ = 3;
+        }
     }
 
     switch (Finish_) {
@@ -4116,6 +4125,71 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [delegate_ setStatusBarShowsProgress:NO];
 }
 
+- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
+    NSString *context([sheet context]);
+
+    if ([context isEqualToString:@"error"])
+        [sheet dismiss];
+    else if ([context isEqualToString:@"_error"]) {
+        [sheet dismiss];
+        [self _checkError];
+    } else if ([context isEqualToString:@"conffile"]) {
+        FILE *input = [database_ input];
+
+        switch (button) {
+            case 1:
+                fprintf(input, "N\n");
+                fflush(input);
+                break;
+            case 2:
+                fprintf(input, "Y\n");
+                fflush(input);
+                break;
+            default:
+                _assert(false);
+        }
+
+        [sheet dismiss];
+    }
+}
+
+- (void) closeButtonPushed {
+    running_ = NO;
+
+    switch (Finish_) {
+        case 0:
+            [self resetView];
+        break;
+
+        case 1:
+            [delegate_ suspendWithAnimation:YES];
+        break;
+
+        case 2:
+            system("launchctl stop com.apple.SpringBoard");
+        break;
+
+        case 3:
+            system("launchctl unload "SpringBoard_"; launchctl load "SpringBoard_);
+        break;
+
+        case 4:
+            system("reboot");
+        break;
+    }
+}
+
+- (void) _retachThread {
+    UINavigationItem *item = [navbar_ topItem];
+    [item setTitle:CYLocalize("COMPLETE")];
+
+    [overlay_ addSubview:close_];
+    [progress_ removeFromSuperview];
+    [status_ removeFromSuperview];
+
+    [self _checkError];
+}
+
 - (void) _detachNewThreadData:(ProgressData *)data { _pooled
     [[data target] performSelector:[data selector] withObject:[data object]];
     [data release];
@@ -4139,27 +4213,27 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     running_ = YES;
 
     {
-        FileFd file(SandboxTemplate_, FileFd::ReadOnly);
-        MMap mmap(file, MMap::ReadOnly);
-        SHA1Summation sha1;
-        sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-        sandplate_ = sha1.Result();
-    }
-
-    {
-        FileFd file(NotifyConfig_, FileFd::ReadOnly);
-        MMap mmap(file, MMap::ReadOnly);
-        SHA1Summation sha1;
-        sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-        notifyconf_ = sha1.Result();
+        FileFd file;
+        if (!file.Open(NotifyConfig_, FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            MMap mmap(file, MMap::ReadOnly);
+            SHA1Summation sha1;
+            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+            notifyconf_ = sha1.Result();
+        }
     }
 
     {
-        FileFd file(SpringBoard_, FileFd::ReadOnly);
-        MMap mmap(file, MMap::ReadOnly);
-        SHA1Summation sha1;
-        sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
-        springlist_ = sha1.Result();
+        FileFd file;
+        if (!file.Open(SpringBoard_, FileFd::ReadOnly))
+            _error->Discard();
+        else {
+            MMap mmap(file, MMap::ReadOnly);
+            SHA1Summation sha1;
+            sha1.Add(reinterpret_cast<uint8_t *>(mmap.Data()), mmap.Size());
+            springlist_ = sha1.Result();
+        }
     }
 
     [transition_ transition:6 toView:overlay_];
@@ -4580,7 +4654,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         section_ = [section localized];
         if (section_ != nil)
             section_ = [section_ retain];
-        name_  = [(section_ == nil ? CYLocalize("NO_SECTION") : section_) retain];
+        name_  = [(section_ == nil || [section_ length] == 0 ? CYLocalize("NO_SECTION") : section_) retain];
         count_ = [[NSString stringWithFormat:@"%d", [section count]] retain];
 
         if (editing_)
@@ -4892,11 +4966,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         if ([package_ source] == nil);
         else if ([package_ upgradableAndEssential:NO])
             [buttons_ addObject:CYLocalize("UPGRADE")];
-        else if ([package_ installed] == nil)
+        else if ([package_ uninstalled])
             [buttons_ addObject:CYLocalize("INSTALL")];
         else
             [buttons_ addObject:CYLocalize("REINSTALL")];
-        if ([package_ installed] != nil)
+        if (![package_ uninstalled])
             [buttons_ addObject:CYLocalize("REMOVE")];
 
         if (special_ != NULL) {
@@ -5939,7 +6013,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     ];
 }
 
-- (void) _update_ {
+- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
+    NSString *context([sheet context]);
+
+    if ([context isEqualToString:@"refresh"])
+        [sheet dismiss];
+}
+
+- (void) _update_:(NSString *)error {
     updating_ = false;
 
     [indicator_ stopAnimation];
@@ -5961,7 +6042,24 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     [UIView commitAnimations];
 
-    [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
+    if (error == nil)
+        [delegate_ performSelector:@selector(reloadData) withObject:nil afterDelay:0];
+    else {
+        UIActionSheet *sheet = [[[UIActionSheet alloc]
+            initWithTitle:[NSString stringWithFormat:CYLocalize("COLON_DELIMITED"), CYLocalize("ERROR"), CYLocalize("REFRESH")]
+            buttons:[NSArray arrayWithObjects:
+                CYLocalize("OK"),
+            nil]
+            defaultButtonIndex:0
+            delegate:self
+            context:@"refresh"
+        ] autorelease];
+
+        [sheet setBodyText:error];
+        [sheet popupAlertAnimated:YES];
+
+        [self reloadButtons];
+    }
 }
 
 - (id) initWithFrame:(CGRect)frame database:(Database *)database {
@@ -6050,11 +6148,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     Status status;
     status.setDelegate(self);
 
-    [database_ updateWithStatus:status];
+    NSString *error([database_ updateWithStatus:status]);
 
     [self
-        performSelectorOnMainThread:@selector(_update_)
-        withObject:nil
+        performSelectorOnMainThread:@selector(_update_:)
+        withObject:error
         waitUntilDone:NO
     ];
 }
@@ -6094,10 +6192,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return !updating_;
 }
 
-- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    [sheet dismiss];
-}
-
 - (void) _setProgressTitle:(NSString *)title {
     [prompt_ setText:title];
 }
@@ -6373,7 +6467,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [*section addToCount];
 
         _profile(SectionsView$reloadData$Filter)
-            if (![package valid] || [package installed] != nil || ![package visible])
+            if (![package valid] || ![package uninstalled] || ![package visible])
                 continue;
         _end
 
@@ -6394,7 +6488,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [section addToCount];
 
         _profile(SectionsView$reloadData$Filter)
-            if (![package valid] || [package installed] != nil || ![package visible])
+            if (![package valid] || ![package uninstalled] || ![package visible])
                 continue;
         _end
 
@@ -6585,7 +6679,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     _trace();
     for (Package *package in packages)
         if (
-            [package installed] == nil && [package valid] && [package visible] ||
+            [package uninstalled] && [package valid] && [package visible] ||
             [package upgradableAndEssential:YES]
         )
             [packages_ addObject:package];
@@ -7844,12 +7938,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         Changed_ = true;
 
+        [sheet dismiss];
+
         if (reset)
             [self updateData];
         else
             [self finish];
-
-        [sheet dismiss];
     } else if ([context isEqualToString:@"upgrade"]) {
         switch (button) {
             case 1:
@@ -8037,8 +8131,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     if (
         readlink("/Applications", NULL, 0) == -1 && errno == EINVAL ||
         readlink("/Library/Ringtones", NULL, 0) == -1 && errno == EINVAL ||
-        readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/Library/Wallpaper", NULL, 0) == -1 && errno == EINVAL /*||
+        readlink("/usr/bin", NULL, 0) == -1 && errno == EINVAL*/ ||
         readlink("/usr/include", NULL, 0) == -1 && errno == EINVAL ||
+        readlink("/usr/lib/pam", NULL, 0) == -1 && errno == EINVAL ||
         readlink("/usr/libexec", NULL, 0) == -1 && errno == EINVAL ||
         readlink("/usr/share", NULL, 0) == -1 && errno == EINVAL /*||
         readlink("/var/lib", NULL, 0) == -1 && errno == EINVAL*/