Fix vim hang on xml files

The Syntastic syntax checking plugin validates xml files using xmllint.

You can pass custom arguments to xmllint to enable/disable functions that might be causing the hang.

For me it was the network access, which can be disabled with the –nonet option.

I added the following to my ~/.vimrc

let g:syntastic_xml_xmllint_args = "--xinclude --postvalid --nonet"

Convert AVI files for AppleTV

Once you’ve setup Home Sharing so you can play movies from iTunes on the AppleTV, you’ll notice that some movie types won’t play.

Handbrake is a free tool that can convert avi and other video type to mp4 movies that will play on the AppleTV.  But conversion of more than a few is tedious using the app.

It turns out there is a HandBrake CLI tool you can  download for doing batch conversions.

Change into the directory of files you want to convert. (It is okay if there are subdirectories you also want to process.)

cd /Volumes/Data/Movies

Here is the command I am using for the conversion*:

find . -type file
  -exec \
  /Volumes/HandBrake-0.10.5-MacOSX.6_CLI_x86_64/HandBrakeCLI \
  -i "{}" \
  -o "{}-AppleTV.mp4" \
  --preset="AppleTV" \;

That command will find all files and attempt to convert them using the ‘AppleTV’ preset.

It will output them in the same directory as the original with the suffix “-AppleTV.mp4”.

Of course if you only want to handle certain file types you can change or add to the options to the find command  (-name “*.avi” for example).

To clean up the original files after you are happy with the converted files:

IFS=$'\n';for orig in $(find . -name "*-AppleTV.mp4" | sed -e 's/-AppleTV.mp4//g'); do rm -i ${orig}; done

And finally you can rename the new converted files to remove the old file extension and “-AppleTV”:

IFS=$'\n';for new in $(find . -name "*-AppleTV.mp4"); do mv -i "$new" "$(echo $new | sed 's/\....-AppleTV.mp4/.mp4/g')"; done

*Use your own path to the HandBrakeCLI. I just dragged it into Terminal from the downloaded dmg.

dockutil 2.0.0 is out

It has been a long time coming, but I finally made time to attempt to get dockutil working better with cfprefsd.

I decided to use defaults rather than PyObjC.  Although in hindsight it probably doesn’t matter.  They both have quirks when running as root.

But defaults actually does handle paths correctly, and dockutil has always used paths to the dock plist, so that fits well.

At some point we will likely need to change dockutil to take users or domains rather than paths so it works better with CFPreferences.

But for now we can stay with paths to preserve compatibility with existing scripts using dockutil.

I expect some bugs, so please test and report them on github.

Launchd Tools Released

Launchd Tools are for reading and creating launchd jobs.

For example, to see info about all Apple LaunchAgents and LaunchDaemons.

launchd2cmd /System/Library/Launch*/*

Or to create your own launchd job from an existing command:

cmd2launchd /usr/local/bin/daemond -d --mode foreground

Check it out here: https://github.com/kcrawford/launchd_tools

10.9 Mavericks is your security update for 10.6 through 10.8.5

Mavericks is free.

Its system requirements are the same as for Mountain Lion

http://www.apple.com/osx/specs/

http://support.apple.com/kb/HT5444

It is also a security update:

http://support.apple.com/kb/HT1222

http://support.apple.com/kb/HT6011

I surmise that Apple does not intend to provide security updates for older OS versions.  At least not for 10.8.

If you want to get patched, start upgrading to 10.9…

Update: 10/4/2013

While it was fun to speculate about Apple forcing us to upgrade to 10.9.  It was just speculation.  I now believe I was wrong and I expect Apple to release updates for older versions similar to its past behavior.

 

Cursor Tracking Lag Caused by system_profiler

We’ve noticed problems with mouse cursor tracking, on Thunderbolt Macs attached to displays.

In the middle of moving the cursor with mouse or trackpad, the cursor jumps or skips making it difficult to control.

We tracked down the problem to background runs of system_profiler.  Specifically, when system_profiler queries the display for information.

Running system_profiler without flags or with the SPDisplaysDataType data type triggers the problem.

To reproduce the problem at its worst, run the following in Terminal on a Thunderbolt Mac attached to a display and attempt to use the tracking device:

while [ 1 ]; do system_profiler SPDisplaysDataType; done

Apple is aware of the issue, but has stated that this is expected behavior.

Many tools that rely on system_profiler trigger the issue including JAMF Casper Suite, Puppet, and Apple Remote Desktop.  These and other tools routinely inventory the Mac using system_profiler.

There is currently no workaround for getting display information such as Display serial number.  And the only way to avoid the trigger is to run system profiler with each data type excluding SPDisplaysDataType.

If you think Apple should address the issue, please let them know.

Load or Reload a LaunchAgent from installer script

Apple has some restrictions in place to prevent access to LaunchAgents running in a user session context.

But you may want to load or refresh a LaunchAgent as part of your install without requiring the user to log out and back in.

I prefer not to require logouts and reboots in my installation packages.  Where possible, I use munki’s unattended option so software installs silently and the user is not prompted.

After some experimentation, I came up with this hacky method of getting a LaunchAgent to load from a package being installed as root.  If you have a cleaner way to accomplish this, please let me know.  Update: Please see Per Olofsson’s comment for a much better method until I update this gist.


#!/bin/bash
# if someone is logged in
if who | grep -q console; then
# get the logged in user's uid
LOGGED_IN_UID=`ls -ln /dev/console | awk '{ print $3 }'`
# use the uid and pgrep to find the Finder process id
FINDER_PID=`pgrep -U ${LOGGED_IN_UID} Finder`
# use launchctl bsexec to run applescript code in the same Mach bootstrap namespace hierachy as the Finder
launchctl bsexec "${FINDER_PID}" osascript -e '
tell app "Finder"
do shell script "
launchctl unload -S Aqua /Library/LaunchAgents/com.company.agent.plist
launchctl load -S Aqua /Library/LaunchAgents/com.company.agent.plist
"
end tell
'
fi

view raw

gistfile1.sh

hosted with ❤ by GitHub

 

Triggering a shell script from MySQL

Sometimes you need to trigger a script when data changes in mysql.  Sometimes there just aren’t other hooks into the system and the database is your last resort.

It seems like this would be a common use case with a simple solution, but no.

MySQL does support triggers.

However what you can do inside a trigger is limited to what you can do in mysql.  This is good for security.

Using the following DOES NOT work!

\! /bin/ls >> /log/yourlog.txt

The !\ (bang or exclamation point + backslash) is a mysql console feature for running commands in the console.  These are ignored on the actual server.  Do not be fooled.  Since you are testing in the console, it will appear to work once, but the trigger will not cause your code to fire.

So you have two options:

1.) Polling

2.) MySQL UDF (plugin)

Polling

Yes, polling sucks.  But what you can do is still create a trigger that uses a separate (maybe in memory) table for capturing the changes.  Then your polling script only needs to look at that table to do its work.

So you could use something like this:

Create the temp_changes table (this example creates an in memory table):

CREATE TABLE temp_changes (changed_id INT, from_value VARCHAR(40), to_value VARCHAR(40)) ENGINE=MEMORY MAX_ROWS=500;

Create the mysql trigger:

DELIMITER $$
CREATE TRIGGER tg1 AFTER UPDATE ON `table_i_want_to_watch`
FOR EACH ROW
BEGIN
INSERT INTO temp_changes SET from_value = OLD.column_i_want_to_track, to_value = NEW.column_i_want_to_track, changed_id = NEW.id;
END $$
DELIMITER ;

The above will create a row in the temp_changes table with the old and new values and id of the column I want to track in the table I want to watch.  Substitute column_i_want_to_track and table_i_want_to_watch with your own table and column names.

Read the MySQL trigger documentation if you need to do something different.  This is just an example.

Now your external polling script can query only the temp_changes table without polling your whole database for changes.

MySQL UDF (plugin)

MySQL UDFs offer a powerful way to extend the functionality of your MySQL database.  But with great power comes great responsibility right?  (A. Yes.)

These plugins are written in C.  They need to be compiled and installed in your mysql plugins folder on the mysql server.

Plugins add custom functions you your mysql server.

Security is a major concern with this option because these functions run with the same privileges as the mysqlserver user.

There are a number of plugins published here including lib_mysqludf_sys, that will allow you to run shell commands.

Here is the justifiably scarey warning from that site:

Be very careful in deciding whether you need this function. UDFs are available to all database users – you cannot grant EXECUTE privileges for them. As the commandstring passed to sys_exec can do pretty much everything, exposing the function poses a very real security hazard.

Even for a benign user, it is possible to accidentally do a lot of damage with it. The call will be executed with the privileges of the os user that runs MySQL, so it is entirely feasible to delete MySQL’s data directory, or worse.

SQL injection takes on new meaning when the attacker can also run any command on your server.

So my recommendation is to download the source and modify it to hard code a specific path to the executable you want to run if you go this route. I was going to do this, but I’ve had to move on to other endeavors now.

Using the UDF plugin still involves using the mysql trigger functionality.  See Mike E’s solution on this stackoverflow post.