Category: OS X

  • Praise and a warning about using Gemini II and CleanMyMac X to clean up old merged backups

    Time to clean up!

    Earlier this year, my company, in its push to get things squared away for an IPO at some point (note to the SEC: I know nothing about IPO plans, I am not suggesting anyone invest in anything, I’m just this guy, you know?), installed a remote management tool for MacOS. Initially, I was concerned that we might end up being monitored as to what was on our machines, and non-work use might be frowned upon – plus I learned the hard way at WhiteHat that if you’re going to get laid off or fired, no one’s going to give you a day or two to back up anything personal on your machine. (I lost, and later managed to partially recover, all the patches for my Radio Free Krakatau album.)

    IT and upper management, after a couple of days of general consternation and concern about keylogging, etc., formally told us, “no, we don’t care what you do on your laptop, just don’t do anything illegal,” but by that point I’d scoured off the personal files and data and moved them to iCloud, Dropbox, or a spare 2012 MacBook Pro I had.

    The 2012 MBP was the last one that allowed upgrading by the end user. It could accept up to 16GB of memory, had a lot of ports (including a DisplayPort, native Ethernet, and FireWire), and had an internal disk that could be swapped to an SSD.

    I picked up a 2TB Crucial SSD, pulled the old disk, installed the new one, and used Carbon Copy Cloner to copy the old internal disk back on to the SSD. I also pulled in several older backup spinny disks into a folder called “Backups to Clean Up”. This was a superfund site of duplicates, junk, and accumulated files. I took a first cut at cleaning it up right away — deleting old stuff I knew I didn’t care about anymore, like partial iPhoto/Aperture/Photos libraries and old iTunes folders — but I was left with a considerable stash of data that I knew contained duplicates. At the time I was busy and decided I’d work out the rest later. I had removed my Adobe apps and music apps and data from my work laptop, and at the time I just didn’t have any time to work on those.

    Diving in with Gemini II

    Last weekend, I decided it was time to do the cleanup. I had bought Gemini II a couple years ago in a MacHeist bundle, and had tried it a little, but found it too slow on a spinny disk to to be useful. I decided that the job was big enough that I really needed to have some help, so I tried it again. I fired it up on Wednesday afternoon, and pointed it at my home directory on the MBP, and said go get ’em.

    Friday morning (I neglected to exclude Dropbox from the duplicate check, resulting in a lot of “download the file, check it” for the 200 or so GB or data in there, slowing things down considerably), I had a complete comparison. I spent the better part of Friday evening and Saturday and a chunk of Sunday looking at the recommendations and clearing duplicates. In general Gemini had made good choices as to which files to keep and which were duplicates, and this got rid of almost 200GB of duplicates. I did a couple rescans and found another hundred or so that I could clean up.

    Gemini recommended I try CleanMyMac X to help with getting rid of extra junk on the disk, and being in a cleaning mood, I decided to try it. I signed up for a month, and only after I’d done that did I see a “30% off if you own one of our other products”, despite being signed in. MacPaw was very kind and extended my CleanMyMac X subscription for three months to compensate.

    On the initial run, CleanMyMac X was very useful. It cleared a bunch of old caches, got rid of unused languages, etc., and helped me cleanly delete some old apps that were cluttering up ~/Library. It installed a very attractive cleanup and virus checking monitor, and I thought nothing of it at the time.

    Problems surface

    I continued working with Gemini II, and the monitor was solicitously clearing the trash when it got full, and so on. I then tried to use Gemini to just dedup my Music folder, and here’s where the fun started.

    It ran for an hour or so and then I got a “You are out of memory” warning; Gemini II apparently had 69GB of memory allocated. I shut some stuff down, but I ran out of memory again. And again. And again. Quit Gemini. Tried to run Ableton Live; the cursor was sluggish, sound was breaking up, and trying to select a patch in plugins was causing outright crashes. And the laptop was so hot I couldn’t leave it on my legs.

    This was not going to do at all. I wanted to use this machine for music, and it wasn’t able to handle it anymore. Was I going to need a new laptop? It was late. I went to bed.

    The solution

    In the morning, after some time spent with Activity Monitor, I twigged to the problem: CleanMyMac X had installed a lot of startup items. Like four. And Gemini had installed some too. This was not going to get any better with those hanging around. I decided that I was going to have to remove them, and the easiest way was to have CleanMyMac X do it. All credit to MacPaw: it simply warned me that it would shut down all the monitoring if I removed CleanMyMac X, did I want to do that? I did.

    And now the machine is running fine. I’m able to keep a couple of instances of Arturia’s 2600 emulator open and running with Live actively generating sound, and I can tweak the settings without significant effort or the sound breaking up. I ended up using Song Sergeant to do the Music Library cleanup; I can recommend it as doing a good job of finding duplicates, even in different formats.

    Conclusions

    The machine is slimmed down by about 250GB total and running fine; if I decide to do a similar cleanup again, I will probably use both Gemini II and CleanMyMac X to get the cleanup work done, but without being able to easily say no to the monitoring they install, I’ll probably delete them again as soon as I finish. MacPaw, if you’re reading this: make it optional to install the startup items, and give us an easy way to turn them off. If I had those I’d leave the two apps installed, but I just can’t and get any work done.

  • iTunes Ringtone UI Surprise

    You cannot drag and drop .m3r files into the Tones tab in iTunes. They must be pasted.

    Find your .m3r files in the Finder, select them all, File > Copy, click on the Tones tab in the iTunes sidebar, and File > Paste.

    No, it does not make any sense that drag and drop does not work. But it absolutely does not.

  • High Sierra Wifi Poor Performance Fix for 2010 MacBook Pro

    I’ve been working remotely at an AirBNB this week and was having a really frustrating time of it. The 2010-vintage MacBook Pro I have would connect to the Wifi, go for awhile — sometimes a half-hour, sometimes not more than a minute, — and then drop the connection. Shutting off wireless and reinstating it would restart the connection, but it would be unstable and drop again. The length of time it would stay connected was completely unpredictable, and whether or not it would reconnect, and how long it would take was also completely random.

    I was getting speed test results of 0.15 MB/s up and 0.18 down. This was unusable, and I fell back on my hotspot for any sustained connection. Weirdly, I could connect fine with the Amazon Dot I’d brought along – flawlessly, in fact. What was going on?

    Late Friday evening, after a particularly frustrating session attempting to get Netflix to work (I really wanted to see Disenchantment — great show, by the way!), I started doing some research and came across an article that recommended reducing the MTU for the wireless device to 1453 (from the default somewhere in the 1500’s). Really? Okay…

    Magic. It has now been solid for several hours, including streaming video. If you’re having any trouble at all, I’d recommend at least trying it. The article shows you how to set up a separate “location” with the different MTU, so it’s simple to switch it on or off as you choose.

    Update: 12 hours later, I’m getting terrible performance again. A little more searching turned up a tutorial on readjusting the MTU to optimum with ping. Reset your MTU size to default, then starting at your 1500, try the following commad (replacing mtusize with the actual number!):

    ping -D -s mtusize -c 2 google.com

    If you get “message too long” in the ping output, drop the MTU size a bit a try again. If you have no idea what MTU size is good, start at 1500, which will be too big, and go down by 100s until you start seeing “xxxx bytes from google.com:…” messages, which let you know your ping is getting through. You can then go up by tens until you get “message too long” again, then back down by 1’s until you find the maximum MTU size that doesn’t get “message too long”.

    I had to reduce my MTU size further to 1425, and I’m near 10 megabits/second again.

  • A quick note on Mac malware

    The most recent bit of OS X malware making the rounds is a fake file converter program that installs a PHP backdoor accessible via Tor, allowing some rando to rummage around on your machine. As is usual, you, the victim, have to download the software, and run it, and allow the program to install its backdoor code.

    If you want to protect yourself from malware on your Mac, there are three principal things you can do.

    1. Don’t download software if you’re not 100% sure of its provenance, function, and dependability. Just because it’s on MacUpdate doesn’t mean it’s okay.
    2. If you do accidentally download something – say you’re using one of those dodgy file-sharing sites with fifteen ads masquerading as the real download button – don’t run it. Just delete it.
    3. If, despite all this, you did download something and run it, under no circumstances enter your administrator password when it asks to install “support software” or the like unless you know exactly what’s going to happen if you do.

    You still have the backstop that nothing is going to get installed as a persistent backdoor if you don’t enter your administrator password when prompted, but it’s trivially easy to build a backdoor that runs only when the software is running. Don’t run random programs you aren’t sure you can trust. Find a trusted third party that knows for certain that the program is safe.

    If you insist on living dangerously, there are a couple utilities I’ll mention below that will allow you to try to prevent the damage, and I emphasize try. They are no guarantee of safety; if you download pirated software or random things to “try them out” or “see if they work”, you’re sooner or later going to mess yourself up. These monitors are counting on your personal software sophistication to protect yourself from harm. They are only useful if you understand what they are telling you.

    I run the programs I mention below not because they magically keep me safe from bad programs, but because I like to know what’s going on behind the scenes on my Mac. If you aren’t certain you know what ~/Library/LaunchAgents does, or what a connection over port 443 means, you may not want to try using these programs, because they will confuse you; if you try to use them by simply blocking everything, you’ll find that things that are actually supposed to make outgoing connections (like Mail) will stop working, and that software that really needs to install agents, like Dropbox, will break. Conversely, if you just say “yes” to everything, things like the fake file converter mentioned above will get to install their hooks and they will allow who knows who to read your mail and download your naked selfies.

    If I haven’t lost you at this point – you understand OS x/Unix well enough to understand what connections are good and what ones are bad, and you know what a file in ~/Library/LaunchAgents is for:

    • Little Snitch is a program that sits in the background and alerts you whenever your machine tries to make a network connection, whether incoming our outgoing. If you don’t respond, the connection is automatically blocked. You can add rules to automatically allow or automatically block connections. This utility will let you know if someone is actively trying to connect to your machine, or if your machine is trying to make an unexpected outgoing connection.
    • BlockBlock is a utility that monitors attempts to install long-running processes like the one that constitutes the Tor/PHP backdoor and reports them to you with the option to block them. In the case of EasyDoc Converter, it’d be pretty easy to spot that the software was up to no good, as it’s attempting to install stuff named “dropbox” in an attempt to hide their nasty software as part of good software.

    As helpful and useful as these monitors are – I run them, and I like them – they’re still not going to 100% protect you from what happens if you run random things you download from the Internet, especially if you say “sure, why not?” when they ask for your administrator password.

    Just avoid the off-the-wall random links and wait until someone reputable has said, “yeah, that’s good” before trying it.

  • Note on Vagrant UID conflicts

    If you’ve restored from backup on OS X and are seeing this message when you issue vagrant up:

    The VirtualBox VM was created with a user that doesn't match the
    current user running Vagrant. VirtualBox requires that the same
    user be used to manage the VM that was created. Please re-run 
    Vagrant with that user. This is not a Vagrant issue.
    
    The UID used to create the VM was: 503
    
    Your UID is: 2612
    

    Vagrant is lying. There’s a file in the directory where you’re trying to start the Vagrant box named .vagrant/machines/default/virtualbox/creator_uid; the UID of the creator is in that file. Change it to your current UID and everything will be fine again.

  • CrashPlan folder date recovery

    The situation: a friend had a MacBook Air whose motherboard went poof. Fortunately she had backups (almost up-to-date) in CrashPlan, so she did a restore of her home directory, which worked fine in that she had her files, but not so fine in that all the folder last-changed dates now ran from the current date to a couple days previous (it takes a couple days to recover ~60GB of data).

    This was a problem for her, because she partly uses the last-changed date on her folders to help her keep organized. “When was the last time I did anything on project X?” (I should note: she uses Microsoft Word and a couple different photo library managers, so git or the equivalent doesn’t work well for her workflow. She is considering git or the like now for her future text-based work…)

    A check with CrashPlan let us know that they did not track folder update dates and couldn’t restore them. We therefore needed to come up with a way to re-establish as best we could what the dates were before the crash.

    My original thought was simply to start at the bottom and recursively restore the folder last-used dates using touch -t, taking the most-recently-updated file in the folder as the folder’s last-updated date. Some research (read: trying it) and thought turned up the following:

    • Updating a file updated the folder’s last-updated date.
    • Updating a folder did not update the containing folder’s last-updated date.

    This meant that we couldn’t precisely guarantee that the folder’s last-updated date would accurately reflect the last update of its contents. We decided in the end that the best strategy for her was to “bubble up” the last-updated dates by checking both files and folders contained in a subject folder. This way, if a file deep in the hierarchy is updated, but the files and folders above it have not been, the file’s last-updated date is applied to its containing folder, and subsequently is applied also to each containing folder (since we’re checking both files and folders, and there’s always a folder that has the last-updated date that corresponds to the one on the deeply-nested file). This seemed like the better choice for her as she had no other records of what had been worked on when, and runs a very nested set of folders.

    If you were running a flatter hierarchy, only updating the folders to the last-updated date of the files might be a better choice.  Since I was writing a script to do this anyway, it seemed reasonable to go ahead and implement it so that you could choose to bubble up or not as you liked, and to also allow you to selectively bubble-up or not in a single directory.

    This was the genesis of date-fixer.pl. Here’s the script. A more detailed example of why neither approach to restoring the folder dates is perfect is contained in the POD.

    use strict;
    use warnings;
    use 5.010;
    
    =head1 NAME
    
    date-fixer.pl - update folder dates to match newest contained file
    
    =head1 SYNOPSIS
    
    date-fixer.pl --directory top_dir_to_fix
                 [--commit]
                 [--verbose]
                 [--includefolders]
                 [--single]
    
    =head1 DESCRIPTION
    
    date-fixer.pl is meant to be used after you've used something like CrashPlan to restore your files. The restore process will put the files back with their proper dates, but the folders containing those files will be updated to the current date (the last time any operation was done in this folder - specifically, putting the files back).
    
    date-fixer.pl's default operation is to tell you what it would do; if you want it to actually do anything, you need to add the --commit argument to force it to actually execute the commands that change the folder dates.
    
    If you supply the --verbose argument, date-fixer.pl will print all the commands it is about to execute (and if you didn't specify --includefolders, warn you about younger contained folders - see below). You can capture these from STDOUT and further process them if you like.
    
    =head2 Younger contained folders and --includefolders
    
    Consider the following:
    
        folder1           (created January 2010 - date is April 2011)
            veryoldfile 1 (updated March 2011)
            oldfile2      (updated April 2011)
            folder2       (created June 2012 - date is July 2012)
                newfile   (updated July 2012)
    
    If we update folder1 to only match the files within it, we won't catch that folder2's date could actually be much more recent that that of either of the files directly contained by folder1. However, if we use contained folder dates as well as contained file dates to calculate the "last updated" date of the current folder, we may make the date of the current folder considerably more recent than it may actually have been.
    
    Example: veryoldfile1 and oldfile2 were updated in March and April 2011.
    Folder2 was updated in June 2012, and newfile was added to in in July 2012. The creation of folder2 updates the last-updated date of folder1 to June 2012; the addition of newfile updates folder2's last-updated date to that date -- but the last-updated date of folder1 does not change - it remains June 2012.
    
    If we restore all the files and try to determine the "right" dates to set the folder update dates to, we discover that there is no unambiguous way to decide what the "right" dates are. If we use the file dates, alone, we'll miss that folder2 was created in June (causing folder1 to update to June); if we use both file and folder dates, we update folder1 to July 2012, which is not accurate either.
    
    date-fixer.pl takes a cautious middle road, defaulting to only using the files within a folder to update that folder's last-modified date. If you prefer to ensure that the newest date buried in a folder hierarchy always "bubbles up" to the top, add the --includefolders option to the command.
    
    date-fixer will, in verbose mode, print a warning for every folder that
    contains a folder younger than itself; you may choose to go back and adjust the dates on those folders with
    
    date-fixer.pl --directory fixthisone --includefolders --single
    
    This will, for this one folder, adjust the folder's last-updated date to the most recent date of any of the items contained in it.
    
    =head1 USAGE
    
    To fix all the dates in a directory and all directories below it, "bubbling up" dates from later files:
    
        date-fixer.pl --directory dir --commit --includefolders
    
    To fix the dates in just one directory based on only the files in it and
    ignoring the dates on any directories it contains:
    
        date-fixer.pl --directory dir --commit --single
    
    To see in detail what date-fixer is doing while recursively fixing dates, "bubbling up" folder dates:
    
        date-fixer.pl --directory dir --commit --verbose --includefolders
    
    =head1 NOTES
    
    "Why didn't you use File::Find?"
    
    I conceived the code as a simple recursion; it seemed much easier to go ahead and read the directories myself than to go through the mental exercise of transforming the treewalk into an iteration such as I
    would need to use File::Find instead.
    
    =head1 AUTHOR
    
    Joe McMahon, mcmahon@cpan.org
    
    =head1 LICENSE
    
    This code is licensed under the same terms as Perl itself.
    
    =cut
    
    use Getopt::Long;
    use Date::Format;
    
    my($commit, $start_dir, $verbose, $includefolders, $single);
    GetOptions(
        'commit' => \$commit,
        'directory=s' => \$start_dir,
        'verbose|v' => \$verbose,
        'includefolders' => \$includefolders,
        'single' => \$single,
    );
    
    $start_dir or die "Must specify --directory\n";
    
    set_date_from_contained_files($start_dir);
    
    sub set_date_from_contained_files {
        my($directory) = @_;
        return unless defined $directory;
    
        opendir my $dirhandle, $directory
            or die "Can't read $directory: $!\n";
        my @contents;
        push @contents, $_ while readdir($dirhandle);
        closedir $dirhandle;
    
        @contents = grep { !/\.$|\.\.$/ } @contents;
        my @dirs = grep { -d "$directory/$_" } @contents;
    
        my %dirmap;
        @dirmap{@{[@dirs]}} = ();
    
        my @files = grep { !exists $dirmap{$_}} @contents;
    
        # Recursively apply the same update criteria unless --single is on.
        unless ($single) {
            foreach my $dir (@dirs) {
                set_date_from_contained_files("$directory/$dir");
            }
        }
    
        my $most_recent_date;
        if (! $includefolders) {
             $most_recent_date = most_recent_date($directory, @files);
             my $most_recent_folder = most_recent_date($directory, @dirs);
             warn "Folders in $directory are more recent ($most_recent_folder) than the most-recent file ($most_recent_date)\n";
        }
        else {
             $most_recent_date = most_recent_date($directory, @files, @dirs);
        }
    
        if (defined $most_recent_date) {
            (my $requoted = $directory) =~ s/'/\\'/g;
            my @command = (qw(touch -t), $most_recent_date, $directory);
            print "@command\n" if $verbose;
            system @command if $commit;
        }
        else {
            warn "$directory unchanged because it is empty\n" if $verbose;
        }
    }
    
    sub most_recent_date {
        my ($directory, @items) = @_;
        my @dates =     map  { (stat "$directory/$_")[9] } @items;
        my @formatted = map  { time2str("%Y%m%d%H%M.%S", $_) } @dates;
        my @ordered =   sort { $a lt $b } @formatted;
        return $ordered[0];
    }