Browse Source

Manually convert a ton of broken code blocks

fml
pull/1/head
Adam Backstrom 6 years ago
parent
commit
cacc0865a1
66 changed files with 1069 additions and 648 deletions
  1. 35
    8
      content/1329-ubuntu-8-04-on-linode-cloning-and-upgrading-to-10-04.md
  2. 12
    13
      content/1402-running-gitweb-in-fastcgi-mode.md
  3. 43
    4
      content/1412-thinking-about-testability.md
  4. 44
    2
      content/1418-testable-factories.md
  5. 11
    1
      content/145-static-blogrolling.md
  6. 40
    6
      content/1458-locking-down-rsync-using-ssh.md
  7. 31
    9
      content/1486-migrating-to-php-5-3-call_user_func_array.md
  8. 14
    5
      content/150-flexibletype.md
  9. 12
    7
      content/1595-wordpress-mu-domain-mapping-patches.md
  10. 0
    155
      content/1603-arbitrary-siteurl-diff.md
  11. 0
    49
      content/1611-mu-plugins-url-diff.md
  12. 28
    23
      content/162-lock-your-doors.md
  13. 12
    4
      content/163-root.md
  14. 21
    6
      content/1679-better-local-dev-hostnames-with-dnsmasq.md
  15. 2
    2
      content/1690-installing-cpan-modules-without-root.md
  16. 6
    1
      content/1712-use-openssl-to-issue-raw-http-requests.md
  17. 55
    11
      content/173-bash-tips-testing-arguments.md
  18. 15
    6
      content/1799-jsrender-passing-variables-to-nested-templates.md
  19. 6
    1
      content/1955-git-subtree-merges-orphaned-branches-and-github.md
  20. 11
    4
      content/204-globbing.md
  21. 10
    7
      content/2066-mac-os-x-setup-guide.md
  22. 13
    14
      content/210-transparency.md
  23. 4
    30
      content/2143-two-factor-ssh-to-ubuntu-11-04-with-google-authenticator.md
  24. 5
    9
      content/215-scp.md
  25. 2
    29
      content/2153-adventures-in-git-move-commits-from-master-to-new-branch.md
  26. 15
    4
      content/226-filter.md
  27. 7
    15
      content/231-butcher.md
  28. 12
    3
      content/241-escaping.md
  29. 7
    11
      content/251-misc-2.md
  30. 4
    7
      content/255-itms.md
  31. 4
    24
      content/282-remote.md
  32. 15
    13
      content/291-labels.md
  33. 42
    24
      content/295-cdr.md
  34. 23
    1
      content/298-pkg.md
  35. 3
    5
      content/305-tape.md
  36. 11
    1
      content/307-calculator.md
  37. 13
    1
      content/328-taming.md
  38. 18
    11
      content/335-itunes.md
  39. 9
    3
      content/347-calendar-2.md
  40. 5
    2
      content/363-tooltips.md
  41. 23
    1
      content/364-sitemaps.md
  42. 3
    8
      content/367-e3.md
  43. 8
    3
      content/389-dns.md
  44. 2
    4
      content/398-downtime.md
  45. 2
    1
      content/400-merge.md
  46. 6
    4
      content/403-dos.md
  47. 25
    2
      content/406-days.md
  48. 159
    5
      content/421-filter-2.md
  49. 10
    7
      content/424-smtp-2.md
  50. 21
    5
      content/428-django.md
  51. 8
    2
      content/440-svn-4.md
  52. 14
    4
      content/451-screen.md
  53. 5
    3
      content/462-vi.md
  54. 7
    7
      content/512-smarter-parsing-with-smarty.md
  55. 4
    3
      content/554-bookmarklet.md
  56. 9
    5
      content/664-variable-variables-and-arrays.md
  57. 66
    22
      content/676-world-of-warcraft-tooltips-redux-phpbb-2-and-wowhead.md
  58. 15
    5
      content/730-local-documentation-php-django-jquery.md
  59. 3
    9
      content/776-a-vim-of-a-different-color.md
  60. 3
    3
      content/812-managing-money-with-buxfer.md
  61. 19
    6
      content/867-bash-completion.md
  62. 5
    3
      content/899-batterylog.md
  63. 2
    2
      content/934-removing-all-partitions-in-mac-os-x.md
  64. 17
    3
      content/942-tunneling-everything-through-socks5.md
  65. 6
    0
      themes/svbtle/static/css/style.css
  66. 7
    0
      themes/svbtle/static/css/style.less

+ 35
- 8
content/1329-ubuntu-8-04-on-linode-cloning-and-upgrading-to-10-04.md View File

@@ -32,19 +32,30 @@ some suggested `rsync` flags. I ran this several times throughout the
32 32
 process:
33 33
 
34 34
 
35
-    rsync -avzPH --numeric-ids --delete --delete-excluded --exclude-from=backup.lst root@server.example.com:/ /mnt/sda1/
35
+    rsync -avzPH --numeric-ids --delete --delete-excluded \
36
+        --exclude-from=backup.lst root@server.example.com:/ /mnt/sda1/
36 37
 
37 38
 
38 39
 Here's my `backup.lst` exclusion file:
39 40
 
40 41
 
41
-    + /dev/console+ /dev/initctl+ /dev/null+ /dev/zero- /dev/*- /proc/*- /sys/*- /tmp/*- *lost+found
42
-
42
+    + /dev/console
43
+    + /dev/initctl
44
+    + /dev/null
45
+    + /dev/zero
46
+    - /dev/*
47
+    - /proc/*
48
+    - /sys/*
49
+    - /tmp/*
50
+    - *lost+found
43 51
 
44 52
 After `rsync`, `chroot` to the cloned filesystem:
45 53
 
46 54
 
47
-    mount -R /proc /mnt/sda1/procmount -R /dev /mnt/sda1/devchroot /mnt/sda1 /bin/bashvi /etc/fstab # update mountpoints. change xvda to sda1, xvdb to sda2
55
+    mount -R /proc /mnt/sda1/proc
56
+    mount -R /dev /mnt/sda1/dev
57
+    chroot /mnt/sda1 /bin/bash
58
+    vi /etc/fstab # update mountpoints. change xvda to sda1, xvdb to sda2
48 59
 
49 60
 
50 61
 Install a bootloader. The Linode VPS is in Xen and doesn't normally boot
@@ -52,7 +63,12 @@ its own kernel. (I know next to nothing about Xen, but this is what I've
52 63
 gleaned.)
53 64
 
54 65
 
55
-    apt-get install grubmkdir -p /boot/grubcp -r /usr/lib/grub/i386-pc/{stage1,stage2,e2fs_stage1_5} /boot/grubapt-get install linuxecho defoptions=vga=791 >>/boot/grub/menu.lstupdate-grub
66
+    apt-get install grub
67
+    mkdir -p /boot/grub
68
+    cp -r /usr/lib/grub/i386-pc/{stage1,stage2,e2fs_stage1_5} /boot/grub
69
+    apt-get install linux
70
+    echo defoptions=vga=791 >>/boot/grub/menu.lst
71
+    update-grub
56 72
 
57 73
 
58 74
 Reboot. Make sure you kill your cron jobs while the VM is on, as many
@@ -70,7 +86,9 @@ I used a couple commands to update IP addresses on my backup so I could
70 86
 more accurately test services post-upgrade:
71 87
 
72 88
 
73
-    sudo ~/bin/ack --follow -al '207\.192\.74\.235' /etc | sudo xargs sed -i.bak 's/207\.192\.74\.235/172.16.226.130/g'sudo ~/bin/ack --follow -al '69\.164\.216\.5' /etc | sudo xargs sed -i.bak 's/69\.164\.216\.5/172.16.226.131/g'
89
+    sudo ~/bin/ack --follow -al '207\.192\.74\.235' /etc | sudo xargs sed -i.bak 's/207\.192\.74\.235/172.16.226.130/g'
90
+    sudo ~/bin/ack --follow -al '69\.164\.216\.5' /etc | sudo xargs sed -i.bak 's/69\.164\.216\.5/172.16.226.131/g'
91
+
74 92
 
75 93
 
76 94
 
@@ -93,7 +111,8 @@ by manually reinstalling before upgrade:
93 111
 Ensure the update manager is installed, and issue the upgrade command:
94 112
 
95 113
 
96
-    sudo apt-get install update-manager-coresudo do-release-upgrade
114
+    sudo apt-get install update-manager-core
115
+    sudo do-release-upgrade
97 116
 
98 117
 
99 118
 I encountered conflicts in the following packages, where I had modified
@@ -138,7 +157,15 @@ More about that error with `python-setuptools`: [this thread][] was
138 157
 helpful. From `/var/log/apt/term.log`:
139 158
 
140 159
 
141
-    Log started: 2010-10-06  08:35:15Setting up python-setuptools (0.6c9-0ubuntu1) ...pycentral: pycentral pkginstall: not overwriting local filespycentral pkginstall: not overwriting local filesdpkg: error processing python-setuptools (--configure): subprocess post-installation script returned error exit status 1Errors were encountered while processing: python-setuptoolsLog ended: 2010-10-06  08:35:15
160
+    Log started: 2010-10-06  08:35:15
161
+    Setting up python-setuptools (0.6c9-0ubuntu1) ...
162
+    pycentral: pycentral pkginstall: not overwriting local files
163
+    pycentral pkginstall: not overwriting local files
164
+    dpkg: error processing python-setuptools (--configure):
165
+     subprocess post-installation script returned error exit status 1
166
+    Errors were encountered while processing:
167
+     python-setuptools
168
+    Log ended: 2010-10-06  08:35:15
142 169
 
143 170
 
144 171
 Per the article, ran "apt-get remove python-setuptools" and "apt-get

+ 12
- 13
content/1402-running-gitweb-in-fastcgi-mode.md View File

@@ -7,15 +7,15 @@ Tags: Web, fastcgi, Git, gitweb, nginx
7 7
 WordPress-Post-ID: 1402
8 8
 WordPress-Post-Type: post
9 9
 
10
-[![][img]][img-big]Maybe my Google-fu is just failing me on this one, but I had a
10
+[![][img]][img-big]
11
+
12
+Maybe my Google-fu is just failing me on this one, but I had a
11 13
 hell of a time getting [gitweb][] to run in FastCGI mode. The key was
12
-combining gitweb's `--fastcgi` flag with the `FCGI_SOCKET_PATH`
14
+combining gitweb's `--fastcgi` flag with the [`FCGI_SOCKET_PATH`][FASTCGI_SOCKET_PATH]
13 15
 environment variable, in addition to a quick library install:
14 16
 
15
-
16 17
     apt-get install libcgi-fast-perl libfcgi-procmanager-perl
17 18
 
18
-
19 19
 Not complicated, but as a Perl novice it took some digging before I got
20 20
 the right combo of settings. Also, I didn't realize that a
21 21
 FastCGI-enabled script will run in CGI mode rather than listen for
@@ -28,26 +28,24 @@ Here's my final setup:
28 28
 /etc/init/gitweb-fcgi.conf
29 29
 --------------------------
30 30
 
31
-
32 31
 Here's an [Upstart][] script to start a gitweb wrapper under Ubuntu
33 32
 10.04. I'm using [gitolite][] and I want the script to run as my git
34 33
 user, hence the call to `su`.
35 34
 
35
+    start on startup
36
+    stop on shutdown
36 37
 
37
-    start on startupstop on shutdownexec su git -c /path/to/custom/gitweb.fcgirespawn
38
-
39
-
38
+    exec su git -c /path/to/custom/gitweb.fcgi
39
+    respawn
40 40
 
41 41
 gitweb.fcgi
42 42
 -----------
43 43
 
44
-
45 44
 And here's that custom gitweb wrapper:
46 45
 
47
-
48
-    #!/bin/shexport FCGI_SOCKET_PATH=127.0.0.1:9002/usr/local/share/gitweb/gitweb.cgi --fastcgi
49
-
50
-
46
+    #!/bin/sh
47
+    export FCGI_SOCKET_PATH=127.0.0.1:9002
48
+    /usr/local/share/gitweb/gitweb.cgi --fastcgi
51 49
 
52 50
 And you might as well install the [GitHub copycat theme][] while you're
53 51
 at it.
@@ -59,3 +57,4 @@ at it.
59 57
   [Upstart]: http://upstart.ubuntu.com/
60 58
   [gitolite]: https://github.com/sitaramc/gitolite/wiki/
61 59
   [GitHub copycat theme]: https://github.com/kogakure/gitweb-theme
60
+  [FASTCGI_SOCKET_PATH]: http://search.cpan.org/~lds/CGI.pm-3.50/lib/CGI/Fast.pm#FCGI_SOCKET_PATH

+ 43
- 4
content/1412-thinking-about-testability.md View File

@@ -17,7 +17,17 @@ In the past I may have written a user class which was very tightly
17 17
 coupled with a database:
18 18
 
19 19
 
20
-    class User {    public function __construct( $id ) {         global $db;         $sql = "SELECT * FROM users WHERE id = ?";         $user = $db->get( $sql, $id );         $this->id = $user->id;         $this->name = $user->name;    }}
20
+    class User {
21
+        public function __construct( $id ) {
22
+             global $db;
23
+
24
+             $sql = "SELECT * FROM users WHERE id = ?";
25
+             $user = $db->get( $sql, $id );
26
+
27
+             $this->id = $user->id;
28
+             $this->name = $user->name;
29
+        }
30
+    }
21 31
 
22 32
 
23 33
 It's easy to identify why this is hard to test: you need a database with
@@ -25,21 +35,50 @@ predictable data beneath to have any confidence that the code is working
25 35
 as it should. A testable alterative would use **Dependency Injection**:
26 36
 
27 37
 
28
-    class User {    public function __construct( $userstore ) {        $this->userstore = $userstore;    }    public function load( $id ) {        $userdata = $this->userstore->load( $id );        $this->id = $userdata->id;        $this->name = $userdata->name;    }}
38
+    class User {
39
+        public function __construct( $userstore ) {
40
+            $this->userstore = $userstore;
41
+        }
42
+
43
+        public function load( $id ) {
44
+            $userdata = $this->userstore->load( $id );
45
+
46
+            $this->id = $userdata->id;
47
+            $this->name = $userdata->name;
48
+        }
49
+    }
29 50
 
30 51
 
31 52
 Rather than instantiating a user with `new User(12)`, I would instead
32 53
 say:
33 54
 
34 55
 
35
-    $userstore = new UserStore_Database( DB_USER, DB_PASS ); // create db interface$user = new User( $userstore ); // create user object, connecting to db$user->load( 12 ); // load user #12
56
+    $userstore = new UserStore_Database( DB_USER, DB_PASS ); // create db interface
57
+    $user = new User( $userstore ); // create user object, connecting to db
58
+    $user->load( 12 ); // load user #12
36 59
 
37 60
 
38 61
 This is way more verbose, but factories can automatic the common use
39 62
 cases:
40 63
 
41 64
 
42
-    class User {    // __construct(), load(), plus:    public static function load_by_id( $id ) {        static $userstore = null;        // cache the database interface        if( $userstore === null ) {            $userstore = new UserStore_Database( DB_USER, DB_PASS );        }        $user = new User( $userstore );        $user->load( $id );        return $user;    }}
65
+    class User {
66
+        // __construct(), load(), plus:
67
+
68
+        public static function load_by_id( $id ) {
69
+            static $userstore = null;
70
+
71
+            // cache the database interface
72
+            if( $userstore === null ) {
73
+                $userstore = new UserStore_Database( DB_USER, DB_PASS );
74
+            }
75
+
76
+            $user = new User( $userstore );
77
+            $user->load( $id );
78
+
79
+            return $user;
80
+        }
81
+    }
43 82
 
44 83
 
45 84
 Our object is testable, but day-to-day code in production can still use

+ 44
- 2
content/1418-testable-factories.md View File

@@ -22,14 +22,56 @@ cached a reference to the database object using a static.)
22 22
 But what if the factory itself were its own class?
23 23
 
24 24
 
25
-    class UserFactory {    public static function userstore( $new_store = null ) {        static $userstore;        if( $new_store !== null ) {            $userstore = $new_store;        }        // default userstore if one wasn't provided        if( $userstore === null ) {            $userstore = new UserStore_Database( DB_USER, DB_PASS );        }        return $userstore;    }    public static function load_by_id( $id ) {        $user = new User( self::userstore() );        $user->load( $id );        return $user;    }}$dbstore = new UserStore_Database( DB_USER, DB_PASS );UserFactory::userstore( $dbstore );$user = UserFactory::load_by_id( 12 );
25
+    class UserFactory {
26
+        public static function userstore( $new_store = null ) {
27
+            static $userstore;
28
+
29
+            if( $new_store !== null ) {
30
+                $userstore = $new_store;
31
+            }
32
+
33
+            // default userstore if one wasn't provided
34
+            if( $userstore === null ) {
35
+                $userstore = new UserStore_Database( DB_USER, DB_PASS );
36
+            }
37
+
38
+            return $userstore;
39
+        }
40
+
41
+        public static function load_by_id( $id ) {
42
+            $user = new User( self::userstore() );
43
+            $user->load( $id );
44
+
45
+            return $user;
46
+        }
47
+    }
48
+
49
+    $dbstore = new UserStore_Database( DB_USER, DB_PASS );
50
+    UserFactory::userstore( $dbstore );
51
+    $user = UserFactory::load_by_id( 12 );
26 52
 
27 53
 
28 54
 Or maybe it's better to have the factory as an object rather than a
29 55
 collection of static methods:
30 56
 
57
+    class UserFactory {
58
+        public $userstore;
59
+
60
+        public function __construct( $userstore ) {
61
+            $this->userstore = $userstore;
62
+        }
63
+
64
+        public function load_by_id( $id ) {
65
+            $user = new User( $this->userstore );
66
+            $user->load( $id );
67
+
68
+            return $user;
69
+        }
70
+    }
31 71
 
32
-    class UserFactory {    public $userstore;    public function __construct( $userstore ) {        $this->userstore = $userstore;    }    public function load_by_id( $id ) {        $user = new User( $this->userstore );        $user->load( $id );        return $user;    }}$dbstore = new UserStore_Database( DB_USER, DB_PASS );$uf = new UserFactory( $dbstore );$user = $uf->load_by_id( 12 );
72
+    $dbstore = new UserStore_Database( DB_USER, DB_PASS );
73
+    $uf = new UserFactory( $dbstore );
74
+    $user = $uf->load_by_id( 12 );
33 75
 
34 76
 
35 77
 I'm not sure if one implementation is better than the other. The former

+ 11
- 1
content/145-static-blogrolling.md View File

@@ -14,9 +14,19 @@ who seems to be my most frequent visitor, second only to myself.
14 14
 
15 15
 Here's the script:
16 16
 
17
+    #!/bin/sh
17 18
 
18
-    #!/bin/shWEBDIR=/var/www/blogs.bwerp.net/htdocsURL="http://rpc.blogrolling.com/display_raw.php"ROLLID="r=11a89b51a86123178572ef64d4d87f02"/usr/bin/curl "${URL}?${ROLLID}" -s -o ${WEBDIR}/blogroll.html.newif [ $? -eq 0 ]; then  mv ${WEBDIR}/blogroll.html.new ${WEBDIR}/blogroll.htmlelse  echo "blogroll.sh failed: $?" 1>&2fi
19
+    WEBDIR=/var/www/blogs.bwerp.net/htdocs
20
+    URL="http://rpc.blogrolling.com/display_raw.php"
21
+    ROLLID="r=11a89b51a86123178572ef64d4d87f02"
19 22
 
23
+    /usr/bin/curl "${URL}?${ROLLID}" -s -o ${WEBDIR}/blogroll.html.new
24
+
25
+    if [ $? -eq 0 ]; then
26
+        mv ${WEBDIR}/blogroll.html.new ${WEBDIR}/blogroll.html
27
+    else
28
+        echo "blogroll.sh failed: $?" 1>&2
29
+    fi
20 30
 
21 31
 Cron runs this every fifteen minutes, so my blogroll is pretty
22 32
 up-to-date. Note that I don't replace blogroll.html right away. If

+ 40
- 6
content/1458-locking-down-rsync-using-ssh.md View File

@@ -17,7 +17,7 @@ OpenSSH while allowing scheduled syncing. First, my requirements:
17 17
 
18 18
 OpenSSH public/private keypairs and rsync over SSH was a logical
19 19
 starting point, but I was missing a piece to limit the rsync to specific
20
-files: the [`authorized_keys` `command="command"`][] option.
20
+files: the [`authorized_keys` `command="command"`][authorized_keys] option.
21 21
 
22 22
 The Setup
23 23
 ---------
@@ -37,7 +37,15 @@ work around a potential key conflict. Easy enough using `~/.ssh/config`
37 37
 on *penny*:
38 38
 
39 39
 
40
-    Host coriander    HostName coriander.example.com    User adam    IdentityFile ~/.ssh/id_dsaHost mysql-binlog    HostName coriander.example.com    User adam    IdentityFile ~/.ssh/mysql-binlog-key
40
+    Host coriander
41
+        HostName coriander.example.com
42
+        User adam
43
+        IdentityFile ~/.ssh/id_dsa
44
+
45
+    Host mysql-binlog
46
+        HostName coriander.example.com
47
+        User adam
48
+        IdentityFile ~/.ssh/mysql-binlog-key
41 49
 
42 50
 
43 51
 I run an ssh-agent, so I have to run things through `env -i` to prevent
@@ -72,13 +80,32 @@ when the user logs in over SSH:
72 80
 SSH to the host and see the output:
73 81
 
74 82
 
75
-    ambackstrom@fsck:~:0$ env -i ssh mysql-binlogSHELL=/bin/bashSSH_CLIENT=10.0.0.2 56490 22USER=adamPATH=/bin:/usr/binPWD=/home/adamSHLVL=1HOME=/home/adamSSH_CONNECTION=10.0.0.2 56490 10.0.0.1 22_=/usr/bin/env
83
+    ambackstrom@fsck:~:0$ env -i ssh mysql-binlog
84
+    SHELL=/bin/bash
85
+    SSH_CLIENT=10.0.0.2 56490 22
86
+    USER=adam
87
+    PATH=/bin:/usr/bin
88
+    PWD=/home/adam
89
+    SHLVL=1
90
+    HOME=/home/adam
91
+    SSH_CONNECTION=10.0.0.2 56490 10.0.0.1 22
92
+    _=/usr/bin/env
76 93
 
77 94
 
78 95
 Then once more, specifying a command to run on the server:
79 96
 
80 97
 
81
-    ambackstrom@fsck:~:0$ env -i ssh mysql-binlog 'ls -lAF'SHELL=/bin/bashSSH_CLIENT=10.0.0.2 56546 22USER=adamPATH=/bin:/usr/binPWD=/home/adamSHLVL=1HOME=/home/adamSSH_CONNECTION=10.0.0.2 56546 10.0.0.1 22SSH_ORIGINAL_COMMAND=ls -lAF_=/usr/bin/env
98
+    ambackstrom@fsck:~:0$ env -i ssh mysql-binlog 'ls -lAF'
99
+    SHELL=/bin/bash
100
+    SSH_CLIENT=10.0.0.2 56546 22
101
+    USER=adam
102
+    PATH=/bin:/usr/bin
103
+    PWD=/home/adam
104
+    SHLVL=1
105
+    HOME=/home/adam
106
+    SSH_CONNECTION=10.0.0.2 56546 10.0.0.1 22
107
+    SSH_ORIGINAL_COMMAND=ls -lAF
108
+    _=/usr/bin/env
82 109
 
83 110
 
84 111
 Our script becomes the middleman between the client and the requested
@@ -112,7 +139,14 @@ Within `~/rsync-control` we'll analyze the incoming command and take
112 139
 some action:
113 140
 
114 141
 
115
-    #!/bin/shif [ "$SSH_ORIGINAL_COMMAND" = "rsync --server --sender -vlogDtprz . logs/" ] ; then    rsync --server --sender -vlogDtprz . /var/lib/mysql/binlog/    exit $?fiexit 1
142
+    #!/bin/sh
143
+
144
+    if [ "$SSH_ORIGINAL_COMMAND" = "rsync --server --sender -vlogDtprz . logs/" ] ; then
145
+        rsync --server --sender -vlogDtprz . /var/lib/mysql/binlog/
146
+        exit $?
147
+    fi
148
+
149
+    exit 1
116 150
 
117 151
 
118 152
 What we've actually done here is obfuscated the real binary log
@@ -126,5 +160,5 @@ of git server like [gitolite][] that take advantage of this feature, and
126 160
 I'd love to find more.
127 161
 
128 162
   [rsync]: http://samba.anu.edu.au/rsync/
129
-  [`authorized_keys` `command="command"`]: http://www.openbsd.org/cgi-bin/man.cgi?query=sshd&sektion=8
163
+  [authorized_keys]: http://www.openbsd.org/cgi-bin/man.cgi?query=sshd&sektion=8
130 164
   [gitolite]: https://github.com/sitaramc/gitolite/wiki

+ 31
- 9
content/1486-migrating-to-php-5-3-call_user_func_array.md View File

@@ -8,7 +8,7 @@ WordPress-Post-ID: 1486
8 8
 WordPress-Post-Type: post
9 9
 
10 10
 I've been updating various old pieces of code after our PHP 5.3 upgrade
11
-yesterday afternoon. Today, [`call_user_func_array()`][] has been a
11
+yesterday afternoon. Today, [`call_user_func_array()`][call-user-func-array] has been a
12 12
 recurring theme. Notably, some older WordPress plugins have been causing
13 13
 issues, as the WordPress plugin API is heavily dependent on
14 14
 `call_user_func_array()`.
@@ -22,21 +22,30 @@ Let's first look what happens when we pass a non-array as the second
22 22
 argument to `call_user_func_array()`:
23 23
 
24 24
 
25
-    function foo() {    var_dump( func_get_args() );    return 7;}var_dump( call_user_func_array( 'foo', 3 ) );
25
+    function foo() {
26
+        var_dump( func_get_args() );
27
+        return 7;
28
+    }
26 29
 
30
+    var_dump( call_user_func_array( 'foo', 3 ) );
27 31
 
28 32
 
29 33
 Here's the output in PHP 5.2.17:
30 34
 
31 35
 
32
-    array(1) {  [0]=>  int(3)}int(7)
36
+    array(1) {
37
+      [0]=>
38
+      int(3)
39
+    }
40
+    int(7)
33 41
 
34 42
 
35 43
 
36 44
 And here's PHP 5.3.5:
37 45
 
38 46
 
39
-    PHP Warning:  call_user_func_array() expects parameter 2 to be array, integer given in /tmp/call_user_func_array.php on line 9NULL
47
+    PHP Warning:  call_user_func_array() expects parameter 2 to be array, integer given in /tmp/call_user_func_array.php on line 9
48
+    NULL
40 49
 
41 50
 
42 51
 
@@ -68,21 +77,29 @@ Passing by reference
68 77
 Let's try a callback that expects to get parameters by reference:
69 78
 
70 79
 
71
-    function foo( &$input ) {     var_dump( $input );    return 'goodbye'; }$args = array( 'hello' );var_dump( call_user_func_array( 'foo', $args ) );
80
+    function foo( &$input ) {
81
+        var_dump( $input );
82
+        return 'goodbye';
83
+    }
84
+
85
+    $args = array( 'hello' );
86
+    var_dump( call_user_func_array( 'foo', $args ) );
72 87
 
73 88
 
74 89
 
75 90
 The old PHP 5.2.17 behavior:
76 91
 
77 92
 
78
-    string(5) "hello"string(7) "goodbye"
93
+    string(5) "hello"
94
+    string(7) "goodbye"
79 95
 
80 96
 
81 97
 
82 98
 And now, in PHP 5.3.5:
83 99
 
84 100
 
85
-    PHP Warning:  Parameter 1 to foo() expected to be a reference, value given in /tmp/call_user_func_array.php on line 9NULL
101
+    PHP Warning:  Parameter 1 to foo() expected to be a reference, value given in /tmp/call_user_func_array.php on line 9
102
+    NULL
86 103
 
87 104
 
88 105
 
@@ -92,12 +109,17 @@ pass `$args` by reference, and remove the `&` from the function
92 109
 definition:
93 110
 
94 111
 
95
-    function foo( $input ) {    var_dump( $input );    return 'goodbye'; }$args = array( 'hello' );var_dump( call_user_func_array( 'foo', &$args ) );
112
+    function foo( $input ) {
113
+        var_dump( $input );
114
+        return 'goodbye'; 
115
+    }
96 116
 
117
+    $args = array( 'hello' );
118
+    var_dump( call_user_func_array( 'foo', &$args ) );
97 119
 
98 120
 
99 121
 Or if you don't really require pass by reference (you're not modifying
100 122
 the input) just remove the `&` from the function definition and be done
101 123
 with it.
102 124
 
103
-  [`call_user_func_array()`]: http://php.net/call-user-func-array
125
+  [call-user-func-array]: http://php.net/call-user-func-array

+ 14
- 5
content/150-flexibletype.md View File

@@ -15,19 +15,28 @@ mod\_rewrite? Very handy, when modifying [archive URLs][].
15 15
 Consider:
16 16
 
17 17
 
18
+    RewriteEngine on
18 19
 
19
-
20
-    RewriteEngine on<MTEntries lastn="99999">RewriteRule ^archives/<$MTEntryID pad="1"$>.php ¬       /archives/<$MTEntryDate format="%Y/%m/%d"$>/ ¬       <$MTEntryTitle dirify="1"$>.php [R=301]</MTEntries>
21
-
20
+    <MTEntries lastn="99999">
21
+    RewriteRule ^archives/<$MTEntryID pad="1"$>.php ¬
22
+           /archives/<$MTEntryDate format="%Y/%m/%d"$>/ ¬
23
+           <$MTEntryTitle dirify="1"$>.php [R=301]
24
+    </MTEntries>
22 25
 
23 26
 
24 27
 (Breaks added for readability.) Which produces this output:
25 28
 
29
+    RewriteEngine on
26 30
 
31
+    RewriteRule ^archives/000138.php ¬
32
+           /archives/2003/04/23/flexibletype.php [R=301]
33
+    RewriteRule ^archives/000137.php ¬
34
+           /archives/2003/04/22/tracking_comments.php [R=301]
35
+    RewriteRule ^archives/000135.php ¬
36
+           /archives/2003/04/22/thin_client_update.php [R=301]
37
+    ...
27 38
 
28 39
 
29
-    RewriteEngine onRewriteRule ^archives/000138.php ¬       /archives/2003/04/23/flexibletype.php [R=301]RewriteRule ^archives/000137.php ¬       /archives/2003/04/22/tracking_comments.php [R=301]RewriteRule ^archives/000135.php ¬       /archives/2003/04/22/thin_client_update.php [R=301]...
30
-
31 40
 
32 41
 
33 42
 Here's text files for the [.htaccess][] and [template][]. Go forth and

+ 12
- 7
content/1595-wordpress-mu-domain-mapping-patches.md View File

@@ -17,17 +17,22 @@ the domain mapping plugin.
17 17
 Domain Mapped siteurl()
18 18
 -----------------------
19 19
 
20
-
21
-`domain_mapping_siteurl()` is built to work only for the currently
22
-active blog. Here's a modification which allows a `$blog_id` parameter:
23
-
24
-[code name="arbitrary-siteurl.diff"]
20
+<script src="https://gist.github.com/abackstrom/5087996.js?file=arbitrary-siteurl.diff"></script>
25 21
 
26 22
 Here's the filter I'm using to apply this function to all `siteurl()`
27 23
 and `home()` calls:
28 24
 
29 25
 
30
-    function do_canonical_siteurl( $value, $blog_id ) {    // gotta do the remove/add dance to avoid recursion  remove_filter( 'blog_option_siteurl', __FUNCTION__, 10, 2 ); $url = domain_mapping_siteurl( 'siteurl', $blog_id );    add_filter( 'blog_option_siteurl', __FUNCTION__, 10, 2 ); return $url;}add_filter('blog_option_siteurl', 'do_canonical_siteurl', 10, 2);add_filter('blog_option_home', 'do_canonical_siteurl', 10, 2);
26
+    function do_canonical_siteurl( $value, $blog_id ) {
27
+        // gotta do the remove/add dance to avoid recursion
28
+        remove_filter( 'blog_option_siteurl', __FUNCTION__, 10, 2 );
29
+        $url = domain_mapping_siteurl( 'siteurl', $blog_id );
30
+        add_filter( 'blog_option_siteurl', __FUNCTION__, 10, 2 );
31
+
32
+        return $url;
33
+    }
34
+    add_filter('blog_option_siteurl', 'do_canonical_siteurl', 10, 2);
35
+    add_filter('blog_option_home', 'do_canonical_siteurl', 10, 2);
31 36
 
32 37
 
33 38
 
@@ -39,6 +44,6 @@ Plugin filters helpfully update the `PLUGINDIR` fragment in URLs, but
39 44
 does not know about `MUPLUGINDIR`. This patch makes the filter a bit
40 45
 more robust.
41 46
 
42
-[code name="mu-plugins-url.diff"]
47
+<script src="https://gist.github.com/abackstrom/5087996.js?file=mu-plugins-url.diff"></script>
43 48
 
44 49
   [WordPress MU Domain Mapping]: http://wordpress.org/extend/plugins/wordpress-mu-domain-mapping/

+ 0
- 155
content/1603-arbitrary-siteurl-diff.md View File

@@ -1,155 +0,0 @@
1
-Title: arbitrary-siteurl.diff
2
-Slug: 1603/arbitrary-siteurl-diff
3
-Date: 2011-09-27 22:56
4
-Author: Adam
5
-WordPress-Post-ID: 1603
6
-WordPress-Post-Type: sotcode
7
-Status: draft
8
-
9
-Index: domain\_mapping.php
10
-
11
-===================================================================
12
-
13
---- domain\_mapping.php (revision 9545)
14
-
15
-+++ domain\_mapping.php (revision 9553)
16
-
17
-@@ -515,27 +515,37 @@
18
-
19
-}
20
-
21
--function domain\_mapping\_siteurl( \$setting ) {
22
-
23
-- global \$wpdb, \$current\_blog;
24
-
25
-+function domain\_mapping\_siteurl( \$setting, \$blog\_id = 0 ) {
26
-
27
-+ global \$wpdb, \$current\_blog, \$switched;
28
-
29
-// To reduce the number of database queries, save the results the first
30
-time we encounter each blog ID.
31
-
32
-static \$return\_url = array();
33
-
34
-+ if( \$blog\_id == 0 ) {
35
-
36
-+ \$blog\_id = \$current\_blog-\>blog\_id;
37
-
38
-+ }
39
-
40
-+
41
-
42
-\$wpdb-\>dmtable = \$wpdb-\>base\_prefix . 'domain\_mapping';
43
-
44
-- if ( !isset( \$return\_url[ \$wpdb-\>blogid ] ) ) {
45
-
46
-+ if ( !isset( \$return\_url[ \$blog\_id ] ) ) {
47
-
48
-\$s = \$wpdb-\>suppress\_errors();
49
-
50
-- if ( get\_site\_option( 'dm\_no\_primary\_domain' ) == 1 ) {
51
-
52
-- \$domain = \$wpdb-\>get\_var( "SELECT domain FROM {\$wpdb-\>dmtable}
53
-WHERE blog\_id = '{\$wpdb-\>blogid}' AND domain = '" . \$wpdb-\>escape(
54
-\$\_SERVER[ 'HTTP\_HOST' ] ) . "' LIMIT 1" );
55
-
56
-+ if ( get\_site\_option( \$blog\_id, 'dm\_no\_primary\_domain' ) == 1 )
57
-{
58
-
59
-+ if ( \$switched === false ) {
60
-
61
-+ // Only filter using HTTP\_HOST if we haven't done switch\_to\_blog()
62
-
63
-+ \$domain = \$wpdb-\>get\_var( "SELECT domain FROM {\$wpdb-\>dmtable}
64
-WHERE blog\_id = '{\$blog\_id}' AND domain = '" . \$wpdb-\>escape(
65
-\$\_SERVER[ 'HTTP\_HOST' ] ) . "' LIMIT 1" );
66
-
67
-+ } else {
68
-
69
-+ \$domain = \$wpdb-\>get\_var( "SELECT domain FROM {\$wpdb-\>dmtable}
70
-WHERE blog\_id = '{\$blog\_id}' LIMIT 1" );
71
-
72
-+ }
73
-
74
-+
75
-
76
-if ( null == \$domain ) {
77
-
78
-- \$return\_url[ \$wpdb-\>blogid ] = untrailingslashit(
79
-get\_original\_url( "siteurl" ) );
80
-
81
-- return \$return\_url[ \$wpdb-\>blogid ];
82
-
83
-+ \$return\_url[ \$blog\_id ] = untrailingslashit( get\_original\_url(
84
-"siteurl", \$blog\_id ) );
85
-
86
-+ return \$return\_url[ \$blog\_id ];
87
-
88
-}
89
-
90
-} else {
91
-
92
-// get primary domain, if we don't have one then return original url.
93
-
94
-- \$domain = \$wpdb-\>get\_var( "SELECT domain FROM {\$wpdb-\>dmtable}
95
-WHERE blog\_id = '{\$wpdb-\>blogid}' AND active = 1 LIMIT 1" );
96
-
97
-+ \$domain = \$wpdb-\>get\_var( "SELECT domain FROM {\$wpdb-\>dmtable}
98
-WHERE blog\_id = '{\$blog\_id}' AND active = 1 LIMIT 1" );
99
-
100
-if ( null == \$domain ) {
101
-
102
-- \$return\_url[ \$wpdb-\>blogid ] = untrailingslashit(
103
-get\_original\_url( "siteurl" ) );
104
-
105
-- return \$return\_url[ \$wpdb-\>blogid ];
106
-
107
-+ \$return\_url[ \$blog\_id ] = untrailingslashit( get\_original\_url(
108
-"siteurl", \$blog\_id ) );
109
-
110
-+ return \$return\_url[ \$blog\_id ];
111
-
112
-}
113
-
114
-}
115
-
116
-@@ -546,11 +556,11 @@
117
-
118
-\$protocol = ( 'on' == strtolower( \$\_SERVER[ 'HTTPS' ] ) ) ?
119
-'https://' : 'http://';
120
-
121
-if ( \$domain ) {
122
-
123
-- \$return\_url[ \$wpdb-\>blogid ] = untrailingslashit( \$protocol .
124
-\$domain );
125
-
126
-- \$setting = \$return\_url[ \$wpdb-\>blogid ];
127
-
128
-- } else {
129
-
130
-- \$return\_url[ \$wpdb-\>blogid ] = false;
131
-
132
-- }
133
-
134
-- } elseif ( \$return\_url[ \$wpdb-\>blogid ] !== FALSE) {
135
-
136
-- \$setting = \$return\_url[ \$wpdb-\>blogid ];
137
-
138
-+ \$return\_url[ \$blog\_id ] = untrailingslashit( \$protocol . \$domain
139
-);
140
-
141
-+ \$setting = \$return\_url[ \$blog\_id ];
142
-
143
-+ } else {
144
-
145
-+ \$return\_url[ \$blog\_id ] = false;
146
-
147
-+ }
148
-
149
-+ } elseif ( \$return\_url[ \$blog\_id ] !== FALSE) {
150
-
151
-+ \$setting = \$return\_url[ \$blog\_id ];
152
-
153
-}
154
-
155
-

+ 0
- 49
content/1611-mu-plugins-url-diff.md View File

@@ -1,49 +0,0 @@
1
-Title: mu-plugins-url.diff
2
-Slug: 1611/mu-plugins-url-diff
3
-Date: 2011-09-27 23:44
4
-Author: Adam
5
-WordPress-Post-ID: 1611
6
-WordPress-Post-Type: sotcode
7
-Status: draft
8
-
9
-Index: domain\_mapping.php
10
-
11
-===================================================================
12
-
13
---- domain\_mapping.php (revision 9553)
14
-
15
-+++ domain\_mapping.php (revision 9554)
16
-
17
-@@ -660,5 +660,9 @@
18
-
19
-// fixes the plugins\_url
20
-
21
-function domain\_mapping\_plugins\_uri( \$full\_url, \$path=NULL,
22
-\$plugin=NULL ) {
23
-
24
-- return get\_option( 'siteurl' ) . substr( \$full\_url, stripos(
25
-\$full\_url, PLUGINDIR ) - 1 );
26
-
27
-+ if( false === ( \$pos = stripos( \$full\_url, PLUGINDIR ) ) ) {
28
-
29
-+ \$pos = stripos( \$full\_url, MUPLUGINDIR );
30
-
31
-+ }
32
-
33
-+
34
-
35
-+ return get\_option( 'siteurl' ) . substr( \$full\_url, \$pos - 1 );
36
-
37
-}
38
-
39
-@@ -668,5 +672,5 @@
40
-
41
-if ( defined( 'DOMAIN\_MAPPING' ) ) {
42
-
43
-- add\_filter( 'plugins\_url', 'domain\_mapping\_plugins\_uri', 1 );
44
-
45
-+ add\_filter( 'plugins\_url', 'domain\_mapping\_plugins\_uri', 1, 3 );
46
-
47
-add\_filter( 'theme\_root\_uri', 'domain\_mapping\_themes\_uri', 1 );
48
-
49
-add\_filter( 'pre\_option\_siteurl', 'domain\_mapping\_siteurl' );

+ 28
- 23
content/162-lock-your-doors.md View File

@@ -11,27 +11,40 @@ I'm overdue for a post, so I figured this was as interesting a thing as
11 11
 any. I checked out my [Apache][] logs a few minutes ago, and noticed
12 12
 this interesting line:
13 13
 
14
-
15
-
16
-
17
-    154.6.115.154 - - [26/Jun/2003:21:13:50 -0400] ¬     "CONNECT 1.3.3.7:1337 HTTP/1.0" 302 272 "-" "-"
18
-
19
-
14
+    154.6.115.154 - - [26/Jun/2003:21:13:50 -0400] ¬
15
+         "CONNECT 1.3.3.7:1337 HTTP/1.0" 302 272 "-" "-"
20 16
 
21 17
 Being the geek that I am, my curiosity was piqued. It appears that
22 18
 [CONNECT][] is used for tunneling proxy servers. Apparently, these
23 19
 proxies can be [used for spam][].
24 20
 
25
-
26
-
27 21
 I did a port scan, and lo and behold, both [SubSeven][] *and* [Back
28 22
 Orifice][] were running. Here's the output from a no-frills portscan:
29 23
 
30
-
31
-
32
-
33
-    Starting nmap V. 3.00 ( www.insecure.org/nmap/ )Interesting ports on mars.ritlogic.com (154.6.115.154):(The 1583 ports scanned but not shown below are in state: closed)Port       State       Service21/tcp     open        ftp25/tcp     open        smtp80/tcp     open        http135/tcp    open        loc-srv139/tcp    filtered    netbios-ssn443/tcp    open        https445/tcp    open        microsoft-ds1025/tcp   open        NFS-or-IIS1026/tcp   open        LSA-or-nterm1433/tcp   open        ms-sql-s1434/tcp   filtered    ms-sql-m3372/tcp   open        msdtc5800/tcp   open        vnc-http5900/tcp   open        vnc12345/tcp  filtered    NetBus12346/tcp  filtered    NetBus27374/tcp  filtered    subseven31337/tcp  filtered    EliteNmap run completed -- 1 IP address (1 host up) scanned in 10 seconds
34
-
24
+    Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
25
+    Interesting ports on mars.ritlogic.com (154.6.115.154):
26
+    (The 1583 ports scanned but not shown below are in state: closed)
27
+    Port       State       Service
28
+    21/tcp     open        ftp
29
+    25/tcp     open        smtp
30
+    80/tcp     open        http
31
+    135/tcp    open        loc-srv
32
+    139/tcp    filtered    netbios-ssn
33
+    443/tcp    open        https
34
+    445/tcp    open        microsoft-ds
35
+    1025/tcp   open        NFS-or-IIS
36
+    1026/tcp   open        LSA-or-nterm
37
+    1433/tcp   open        ms-sql-s
38
+    1434/tcp   filtered    ms-sql-m
39
+    3372/tcp   open        msdtc
40
+    5800/tcp   open        vnc-http
41
+    5900/tcp   open        vnc
42
+    12345/tcp  filtered    NetBus
43
+    12346/tcp  filtered    NetBus
44
+    27374/tcp  filtered    subseven
45
+    31337/tcp  filtered    Elite
46
+
47
+    Nmap run completed -- 1 IP address (1 host up) scanned in 10 seconds
35 48
 
36 49
 
37 50
 Futher investigation in my logs showed 68 CONNECT attempts from 23
@@ -39,29 +52,21 @@ different hosts. Here's [portscans for 14 of them][]. As expected, most
39 52
 are running Back Orifice and SubSeven. One is even running
40 53
 [pcAnywhere][], and [VNC][] shows up more than once.
41 54
 
42
-
43
-
44 55
 I might play around with Apache's settings and extensions and see if I
45 56
 can capture the CONNECT data. Might be interesting to see exactly what
46 57
 is coming throught the pipeline. In any case, let this be a lesson to my
47 58
 fellow webmasters: batton down the hatches, the 'net isn't a friendly
48 59
 place.
49 60
 
50
-
51
-
52 61
 (Oh, and don't be surprised if my blog page looks like hell in the near
53 62
 future. It needs a style update to fit with the [main site][], but
54 63
 mostly I need to see *a lot* less green.)
55 64
 
56
-
57
-
58
-<span class="update">Update:</span> Looking at my post, I realized that
65
+<ins>Update: Looking at my post, I realized that
59 66
 some of these ports (including Back Orifice and SubSeven) are actually
60 67
 filtered, not open. So, really, they might not be running those
61 68
 applications at all. But it still doesn't change the fact that some of
62
-these hosts tried to access 1.3.3.7:1337 through my box, so, eh.
63
-
64
-
69
+these hosts tried to access 1.3.3.7:1337 through my box, so, eh.</ins>
65 70
 
66 71
   [Apache]: http://httpd.apache.org
67 72
   [CONNECT]: http://asg.web.cmu.edu/rfc/rfc2616.html#sec-9.9

+ 12
- 4
content/163-root.md View File

@@ -10,9 +10,18 @@ WordPress-Post-Type: post
10 10
 I did some scripting for work yesterday, and came up with this little
11 11
 snippet to ensure important scripts will run as root:
12 12
 
13
+    #!/bin/sh
13 14
 
14
-    #!/bin/sh# check current userWHO=`whoami`# make sure we're superuserif [ $WHO != root ]; then   echo "Superuser privileges required, trying sudo."   exec sudo sh $0 "$@"fiecho "I'm the superuser."
15
+    # check current user
16
+    WHO=`whoami`
15 17
 
18
+    # make sure we're superuser
19
+    if [ $WHO != root ]; then
20
+        echo "Superuser privileges required, trying sudo."
21
+        exec sudo sh $0 "$@"
22
+    fi
23
+
24
+    echo "I'm the superuser."
16 25
 
17 26
 
18 27
 `whoami` is necessary because \$USER still holds the regular username
@@ -23,7 +32,6 @@ There is a disadvantage to this method: If you've sudo'd recently, you
23 32
 (or anyone else that happens across your terminal) won't be prompted for
24 33
 a password. Change `sudo sh $0` to `su -c $0` for some added security.
25 34
 (Though you may have to invoke your program differently, ie. with the
26
-path given if it's not already in your \$PATH.)
35
+path given if it's not already in your `$PATH`.)
27 36
 
28
-<ins datetime="2008-05-13T14:00:50-04:00"><span class="update">Update:</span>
29
-added "\$@" to exec line. Thanks, GX!</ins>
37
+<ins datetime="2008-05-13T14:00:50-04:00">Update: added `$@` to exec line. Thanks, GX!</ins>

+ 21
- 6
content/1679-better-local-dev-hostnames-with-dnsmasq.md View File

@@ -11,16 +11,29 @@ I use [ghost][] to configure development environment hostnames for all
11 11
 my local test sites. Some [DTrace tomfoolery][] showed me how ghost
12 12
 handles this config: each new hostname is saved to its own plist file.
13 13
 
14
-**Update:** for zero-configuration wildcard DNS, check out [xip.io][].
14
+**Update:** for zero-configuration wildcard DNS, check out [xip.io][]. {@class=update}
15 15
 
16
-
17
-
18
-[code name="ghost-plist"]
16
+    ambackstrom@fsck:~:1$ sudo cat /var/db/dslocal/nodes/Default/hosts/example.com.plist
17
+    Password:
18
+    <?xml version="1.0" encoding="UTF-8"?>
19
+    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
20
+    <plist version="1.0">
21
+    <dict>
22
+        <key>ip_address</key>
23
+        <array>
24
+            <string>127.0.0.1</string>
25
+        </array>
26
+        <key>name</key>
27
+        <array>
28
+            <string>example.com</string>
29
+        </array>
30
+    </dict>
31
+    </plist>
19 32
 
20 33
 There's filesystem caching going on behind the scenes and I expect the
21 34
 net impact is negligible, but I wondered if there wasn't a more robust
22 35
 solution that supported wildcards. Having just configured [dnsmasq][] on
23
-my [router][], I started with a `brew install dnsmasq` and was
36
+my [router][], I started with a [`brew`][homebrew]` install dnsmasq` and was
24 37
 pleasantly surprised to get a progress bar rather than "no available
25 38
 formula." Homebrew recommended a couple post-install actions for setting
26 39
 up a default config file and configuring `launchd` to keep dnsmasq
@@ -28,7 +41,8 @@ alive, which I dutifully ran. After that, I enabled my fake TLD in
28 41
 `dnsmasq.conf`:
29 42
 
30 43
 
31
-    # respond to *.zomg with 127.0.0.1address=/zomg/127.0.0.1
44
+    # respond to *.zomg with 127.0.0.1
45
+    address=/zomg/127.0.0.1
32 46
 
33 47
 
34 48
 By sheer luck I ended up on [this great serverfault.com post][]
@@ -49,3 +63,4 @@ front. Simple, clean, flexible.
49 63
   [dnsmasq]: http://thekelleys.org.uk/dnsmasq/doc.html
50 64
   [router]: http://www.polarcloud.com/tomato
51 65
   [this great serverfault.com post]: http://serverfault.com/questions/22419/set-dns-server-on-os-x-even-when-without-internet-connection
66
+  [homebrew]: http://mxcl.github.com/homebrew/

+ 2
- 2
content/1690-installing-cpan-modules-without-root.md View File

@@ -28,8 +28,8 @@ Resources
28 28
 
29 29
 
30 30
 
31
--   [Installing mod\_perl without superuser privileges][]
31
+-   [Installing mod_perl without superuser privileges][]
32 32
 
33 33
 
34 34
 
35
-  [Installing mod\_perl without superuser privileges]: http://www.perl.com/pub/2002/04/10/mod_perl.html?page=2
35
+  [Installing mod_perl without superuser privileges]: http://www.perl.com/pub/2002/04/10/mod_perl.html?page=2

+ 6
- 1
content/1712-use-openssl-to-issue-raw-http-requests.md View File

@@ -11,7 +11,12 @@ WordPress-Post-Type: post
11 11
 fails hard on HTTP over SSL:
12 12
 
13 13
 
14
-    ambackstrom@fsck:~:0$ telnet www.plymouth.edu 443Trying 158.136.1.105...Connected to algol.plymouth.edu.Escape character is '^]'.GET / HTTP/1.1Connection closed by foreign host.
14
+    ambackstrom@fsck:~:0$ telnet www.plymouth.edu 443
15
+    Trying 158.136.1.105...
16
+    Connected to algol.plymouth.edu.
17
+    Escape character is '^]'.
18
+    GET / HTTP/1.1
19
+    Connection closed by foreign host.
15 20
 
16 21
 
17 22
 Turns out `openssl` (which is a toolbox in its own right) [can step

+ 55
- 11
content/173-bash-tips-testing-arguments.md View File

@@ -10,21 +10,65 @@ WordPress-Post-Type: post
10 10
 Ever want to test command line arguments in bash, mixing arguments and
11 11
 execution options? I have. Here's one way to do it:
12 12
 
13
-
14
-
15
-
16
-    #!/bin/shfilelist=until [ -z "$1" ]; do # use a case statement to test vars. we always test  # test $1 and shift at the end of the for block. case $1 in       --home|-h )          # shift, so the string after --home becomes          # our new $1. then save the value.           shift            USERHOME=$1      ;;       --force|-f )         # set to 1 for later testing         FORCE=1      ;;       -- )         # set all the following arguments as files           shift            filelist="$filelist $@"          break        ;;       -* )         echo "Unrecognized option: $1"           exit 1       ;;       * )          filelist="$filelist $1"      ;;   esac  shift if [ "$#" = "0" ]; then      break    fidoneecho -n "Files:"for f in $filelist ; do echo -e "\t$f"doneecho "User home:" $USERHOMEecho "Forcing?" $FORCE
17
-
13
+    #!/bin/sh
14
+
15
+    filelist=
16
+
17
+    until [ -z "$1" ]; do
18
+        # use a case statement to test vars. we always test
19
+        # test $1 and shift at the end of the for block.
20
+        case $1 in
21
+            --home|-h )
22
+                # shift, so the string after --home becomes
23
+                # our new $1. then save the value.
24
+                shift
25
+                USERHOME=$1
26
+            ;;
27
+            --force|-f )
28
+                # set to 1 for later testing
29
+                FORCE=1
30
+            ;;
31
+            -- )
32
+                # set all the following arguments as files
33
+                shift
34
+                filelist="$filelist $@"
35
+                break
36
+            ;;
37
+            -* )
38
+                echo "Unrecognized option: $1"
39
+                exit 1
40
+            ;;
41
+            * )
42
+                filelist="$filelist $1"
43
+            ;;
44
+        esac
45
+
46
+        shift
47
+
48
+        if [ "$#" = "0" ]; then
49
+            break
50
+        fi
51
+    done
52
+
53
+    echo -n "Files:"
54
+
55
+    for f in $filelist ; do
56
+        echo -e "\t$f"
57
+    done
58
+
59
+    echo "User home:" $USERHOME
60
+    echo "Forcing?" $FORCE
18 61
 
19 62
 
20 63
 Here's some sample output:
21 64
 
22
-
23
-
24
-
25
-    adam@aziz:~/prog/argstest$ sh argstest.sh foo1 --home /home/adam foo2 -- --force foo3Files:  foo1 foo2 --force  foo3User home: /home/adamNot forcing.
26
-
27
-
65
+    adam@aziz:~/prog/argstest$ sh argstest.sh foo1 --home /home/adam foo2 -- --force foo3
66
+    Files:  foo1
67
+        foo2
68
+        --force
69
+        foo3
70
+    User home: /home/adam
71
+    Not forcing.
28 72
 
29 73
 As you can see, it works with long and short options, options that take
30 74
 values, and the "terminate option list" operator. All it needs is a man

+ 15
- 6
content/1799-jsrender-passing-variables-to-nested-templates.md View File

@@ -12,18 +12,27 @@ jsRender is the in-development successor to jQuery Templates
12 12
 a clean way to pass additional parameters to nested templates. What I've
13 13
 got so far:
14 14
 
15
-
16
-    <script id="t-parent" type="text/x-jquery-tmpl">    <h1>{{=section}}</h1>    <ul>        {{#each subsections}}            <li>{{=subsection}} in {{=$view.parent.parent.data.section}} AKA {{section_name}}</li>        {{/each}}    </ul></script>
17
-
18
-
15
+    <script id="t-parent" type="text/x-jquery-tmpl">
16
+        <h1>{{=section}}</h1>
17
+        <ul>
18
+            {{#each subsections}}
19
+                <li>{{=subsection}} in {{=$view.parent.parent.data.section}} AKA {{section_name}}</li>
20
+            {{/each}}
21
+        </ul>
22
+    </script>
19 23
 
20 24
 And the relevant JavaScript, including the `{{section_name}}` template
21 25
 tag:
22 26
 
27
+    $.views.registerTags({
28
+        section_name: function() {
29
+            return this._view.parent.parent.data.section;
30
+        }
31
+    });
23 32
 
24
-    $.views.registerTags({    section_name: function() {        return this._view.parent.parent.data.section;    }});var o = { section: "Sample", subsections: [ { subsection: "Skydiving"}, { subsection: "Skiing"} ] };$('#container').html($('#t-parent').render(o));
25
-
33
+    var o = { section: "Sample", subsections: [ { subsection: "Skydiving"}, { subsection: "Skiing"} ] };
26 34
 
35
+    $('#container').html($('#t-parent').render(o));
27 36
 
28 37
 I'm questioning `$view.parent.parent.data.section`. Seems a bit verbose,
29 38
 but I can't find a cleaner way to step out of the nested template and

+ 6
- 1
content/1955-git-subtree-merges-orphaned-branches-and-github.md View File

@@ -20,7 +20,12 @@ can manually [create an orphaned branch][] that shares no ancestors with
20 20
 your main project:
21 21
 
22 22
 
23
-    git symbolic-ref HEAD refs/heads/newbranch rm .git/index git clean -fdx <do work> git add your files git commit -m 'Initial commit'
23
+    git symbolic-ref HEAD refs/heads/newbranch
24
+    rm .git/index
25
+    git clean -fdx
26
+    <do work>
27
+    git add your files
28
+    git commit -m 'Initial commit'
24 29
 
25 30
 
26 31
 

+ 11
- 4
content/204-globbing.md View File

@@ -20,22 +20,29 @@ the question mark is pretty useful as well. It will match a single
20 20
 character, as opposed to any number of characters:
21 21
 
22 22
 
23
-    adam@aziz:~$ lsfile-index.txt    file1.txt  file3.jpg  file4.txt  file6.jpgfile-summary.txt  file2.jpg  file3.txt  file5.jpg  file6.txtfile1.jpg         file2.txt  file4.jpg  file5.txtadam@aziz:~$ ls file?.txtfile1.txt  file2.txt  file3.txt  file4.txt  file5.txt  file6.txt
23
+    adam@aziz:~$ ls
24
+    file-index.txt    file1.txt  file3.jpg  file4.txt  file6.jpg
25
+    file-summary.txt  file2.jpg  file3.txt  file5.jpg  file6.txt
26
+    file1.jpg         file2.txt  file4.jpg  file5.txt
27
+    adam@aziz:~$ ls file?.txt
28
+    file1.txt  file2.txt  file3.txt  file4.txt  file5.txt  file6.txt
24 29
 
25 30
 
26 31
 
27 32
 Pretty nice, but we can get even more explicit. What if we only want the
28 33
 first three text files?
29 34
 
30
-
31
-    adam@aziz:~$ ls file[1-3].txtfile1.txt  file2.txt  file3.txt
35
+    adam@aziz:~$ ls file[1-3].txt
36
+    file1.txt  file2.txt  file3.txt
32 37
 
33 38
 
34 39
 
35 40
 *Or* the first three text files and their corresponding images?
36 41
 
37 42
 
38
-    adam@aziz:~$ ls file[1-3].{txt,jpg}file1.jpg  file1.txt  file2.jpg  file2.txt  file3.jpg  file3.txt
43
+    adam@aziz:~$ ls file[1-3].{txt,jpg}
44
+    file1.jpg  file1.txt  file2.jpg  file2.txt  file3.jpg  file3.txt
45
+
39 46
 
40 47
 
41 48
 

+ 10
- 7
content/2066-mac-os-x-setup-guide.md View File

@@ -50,29 +50,32 @@ Settings
50 50
 
51 51
 Disable new window animation:
52 52
 
53
-`defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool NO`
53
+    defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool NO
54 54
 
55 55
 Expanded save dialogs:
56 56
 
57
-`defaults write -g NSNavPanelExpandedStateForSaveMode -bool YES`
57
+    defaults write -g NSNavPanelExpandedStateForSaveMode -bool YES
58 58
 
59 59
 Quicklook text selection:
60 60
 
61
-`defaults write com.apple.finder QLEnableTextSelection -bool TRUE; killall Finder`
61
+    defaults write com.apple.finder QLEnableTextSelection -bool TRUE; killall Finder
62 62
 
63 63
 Speed up sheets (Save…, Print…, etc.):
64 64
 
65
-`defaults write NSGlobalDomain NSWindowResizeTime .001`
65
+    defaults write NSGlobalDomain NSWindowResizeTime .001
66 66
 
67 67
 Hide Spotlight menu bar icon:
68 68
 
69
-`sudo chmod 600 /System/Library/CoreServices/Search.bundle/Contents/MacOS/Search && killall SystemUIServer`
69
+    sudo chmod 600 /System/Library/CoreServices/Search.bundle/Contents/MacOS/Search && killall SystemUIServer
70 70
 
71 71
 Other:
72 72
 
73 73
 
74
-    defaults write com.apple.finder FXEnableExtensionChangeWarning -bool falsedefaults write NSGlobalDomain NSQuitAlwaysKeepsWindows -bool falsedefaults write com.apple.finder _FXShowPosixPathInTitle 1defaults write NSGlobalDomain AppleFontSmoothing -int 2defaults write com.apple.screencapture type png && killall SystemUIServer
75
-
74
+    defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
75
+    defaults write NSGlobalDomain NSQuitAlwaysKeepsWindows -bool false
76
+    defaults write com.apple.finder _FXShowPosixPathInTitle 1
77
+    defaults write NSGlobalDomain AppleFontSmoothing -int 2
78
+    defaults write com.apple.screencapture type png && killall SystemUIServer
76 79
 
77 80
 
78 81
 Sources: [1][], [2][], others.

+ 13
- 14
content/210-transparency.md View File

@@ -12,30 +12,22 @@ mostly [Apache][]-related. I did some trickery with [AWStats][] page
12 12
 statistics files, VirtualHosts, and mod\_rewrite, and thought I would
13 13
 share.
14 14
 
15
-
16
-
17 15
 My Apache virtual hosts live in directories in `/var/www`, each named
18 16
 with their full domain name. Blogs live in `/var/www/blogs.bwerp.net/`,
19 17
 and so on. Each `/var/www/<domain>` directory contains at minimum an
20 18
 `htdocs` and `logs` directory, so web files and their corresponding logs
21 19
 are segmented from the other domains.
22 20
 
23
-
24
-
25 21
 I wanted to run AWStats on all these log files, and my first reaction
26 22
 was to create `/var/www/<domain>/stats` for each domain I wanted to
27 23
 analyze. This meant my number of tasks was high:
28 24
 
29
-
30
-
31 25
 1.  Create the `stats` directory for each domain.
32 26
 2.  Point the `awstats_buildstaticpages.pl` script to the correct
33 27
     destination directory.
34 28
 3.  Create an Apache Alias directive for each domain with stats, or
35 29
     suffer through a `stats` directory in each `htdocs` folder.
36 30
 
37
-
38
-
39 31
 My final solution was much more elegant than what I originally
40 32
 considered. AWStats creates static pages in the format
41 33
 `awstats.<domain>.<type>.html`, so each file implicitly "knows" what
@@ -43,12 +35,21 @@ domain it refers to. I created `/var/www/awstats-pages` to hold the
43 35
 static pages for every domain. Next, I created a global Alias that is
44 36
 applied to each VirtualHost:
45 37
 
38
+    #
39
+    # awstats generated pages
40
+    #
41
+    Alias /stats /var/www/awstats-pages
42
+    <Directory /var/www/awstats-pages>
43
+        Options FollowSymLinks
44
+        AllowOverride All
46 45
 
46
+        Order allow,deny
47
+        Allow from all
47 48
 
48
-
49
-    ## awstats generated pages#Alias /stats /var/www/awstats-pages<Directory /var/www/awstats-pages>    Options FollowSymLinks    AllowOverride All    Order allow,deny    Allow from all    RewriteEngine on    RewriteCond %{REQUEST_URI} ^/stats/$    RewriteRule ^(.*)$ /stats/awstats.%{SERVER_NAME}.html</Directory>
50
-
51
-
49
+        RewriteEngine on
50
+        RewriteCond %{REQUEST_URI} ^/stats/$
51
+        RewriteRule ^(.*)$ /stats/awstats.%{SERVER_NAME}.html
52
+    </Directory>
52 53
 
53 54
 When a user requests `http://<domain>/stats/`, they are transparently
54 55
 redirected to `awstats.<domain>.html` in the same directory. The links
@@ -57,7 +58,5 @@ necessary. One Alias, one stats directory, infinite domains, less
57 58
 changes in my scripts and the `httpd.conf` file, and transparency for
58 59
 the user. All good things.
59 60
 
60
-
61
-
62 61
   [Apache]: http://httpd.apache.org/
63 62
   [AWStats]: http://awstats.sourceforge.net/

+ 4
- 30
content/2143-two-factor-ssh-to-ubuntu-11-04-with-google-authenticator.md View File

@@ -25,30 +25,22 @@ your two-factor auth token. Even so, this gives you peace of mind when
25 25
 enabling password authentication, if you ever have to login on a machine
26 26
 that doesn't have your key.
27 27
 
28
-
29
-
30 28
 First, install `libqrencode3` so you don't have to manually type the
31 29
 resulting key.
32 30
 
33
-
34 31
     ~$ sudo apt-get install libqrencode3
35 32
 
36
-
37
-
38 33
 Next, download and install the [`google-authenticator` PAM module][]:
39 34
 
40
-
41
-    git clone https://code.google.com/p/google-authenticator/cd google-authenticator/libpam/makesudo make install
42
-
43
-
35
+    git clone https://code.google.com/p/google-authenticator/
36
+    cd google-authenticator/libpam/
37
+    make
38
+    sudo make install
44 39
 
45 40
 Run the binary to enable two-factor auth for your user account:
46 41
 
47
-
48 42
     ~$ google-authenticator
49 43
 
50
-
51
-
52 44
 Follow the prompts to customize your desired token lifetime window,
53 45
 whether or not tokens can be reused, and other settings. You'll get a
54 46
 sweet-as-hell ASCII art QR code which you can feed to your TOTP app's
@@ -57,48 +49,30 @@ Authenticator, or another TOTP app.
57 49
 
58 50
 Now add the Google authenticator to your PAM settings file for sshd:
59 51
 
60
-
61 52
     ~$ sudo vim /etc/pam.d/sshd
62 53
 
63
-
64
-
65 54
 Add the following line:
66 55
 
67
-
68 56
     auth required pam_google_authenticator.so
69 57
 
70
-
71
-
72 58
 You may also need to enable challenge/response authentication in sshd:
73 59
 
74
-
75 60
     $ sudo vim /etc/ssh/sshd_config
76 61
 
77
-
78
-
79 62
 Make sure you have this directive:
80 63
 
81
-
82 64
     ChallengeResponseAuthentication yes
83 65
 
84
-
85
-
86 66
 And restart sshd:
87 67
 
88
-
89 68
     sudo service ssh restart
90 69
 
91
-
92
-
93 70
 Key-based authentication will override token-based. If you usually use
94 71
 tokens, temporarily disable them in `sshd_config` before testing token
95 72
 logins:
96 73
 
97
-
98 74
     PubkeyAuthentication no
99 75
 
100
-
101
-
102 76
 You should be prompted for the token before being prompted for a
103 77
 password. Cheers! Your remote logins are now protected by two-factor
104 78
 auth.

+ 5
- 9
content/215-scp.md View File

@@ -14,7 +14,7 @@ error message during my remote copies:
14 14
 
15 15
 
16 16
 
17
-stderr is not a tty - where are you?
17
+    stderr is not a tty - where are you?
18 18
 
19 19
 
20 20
 
@@ -38,12 +38,10 @@ stdin, stdout, and stderr to be available, but it's obvious things
38 38
 aren't working 100% as expected. After some searching, it turns out it's
39 39
 fairly simple to alter `.bashrc` to cooperate with `scp`:
40 40
 
41
-
42
-
43
-
44
-    # only run if we have an interactive shellif [ $(expr index "$-" i) -eq 0 ]; then    returnfi
45
-
46
-
41
+    # only run if we have an interactive shell
42
+    if [ $(expr index "$-" i) -eq 0 ]; then
43
+        return
44
+    fi
47 45
 
48 46
 `bash` gets an environment variable "`$-`" that contains all its startup
49 47
 flags. If `$-` contains "i", the shell is interactive. Our `if` checks
@@ -52,6 +50,4 @@ I've put this at the top of my `.bashrc` for now, but at some point I
52 50
 will reorganize so important and non-harmful settings are still
53 51
 executed. (For example, `$CVSROOT`.)
54 52
 
55
-
56
-
57 53
   [OpenSSH]: http://www.openssh.com/

+ 2
- 29
content/2153-adventures-in-git-move-commits-from-master-to-new-branch.md View File

@@ -16,64 +16,37 @@ moment. Here's one way to move recent commits into a branch:
16 16
 Start with a clean master, based off origin/master:
17 17
 
18 18
 [git-commits]
19
-
20 19
 { hash: 'a' },
21
-
22 20
 { hash: 'b', },
23
-
24 21
 { hash: 'c', }
25
-
26 22
 [/git-commits]
27 23
 
28
-
29
-
30 24
 Make a few commits of your own:
31 25
 
32 26
 [git-commits]
33
-
34 27
 { hash: 'a' },
35
-
36 28
 { hash: 'b', },
37
-
38 29
 { hash: 'c', },
39
-
40 30
 { hash: 'd', },
41
-
42 31
 { hash: 'e', },
43
-
44 32
 { hash: 'f', }
45
-
46 33
 [/git-commits]
47 34
 
48
-
49
-
50 35
 Now, let's move these commits to a branch. Simply create a new branch at
51 36
 the current commit, then reset master back to the state of
52 37
 origin/master.
53 38
 
54
-
55
-    (master)$ git branch my-feature(master)$ git reset --hard origin/master
56
-
57
-
39
+    (master)$ git branch my-feature
40
+    (master)$ git reset --hard origin/master
58 41
 
59 42
 That's all. No `git rebase`, no `git cherry-pick`, just make your branch
60 43
 and reset master.
61 44
 
62 45
 [git-commits]
63
-
64 46
 { hash: 'a' },
65
-
66 47
 { hash: 'b', },
67
-
68 48
 { hash: 'c', },
69
-
70 49
 { hash: 'd', branch: 'feature' },
71
-
72 50
 { hash: 'e', branch: 'feature' },
73
-
74 51
 { hash: 'f', branch: 'feature' }
75
-
76 52
 [/git-commits]
77
-
78
-
79
-

+ 15
- 4
content/226-filter.md View File

@@ -1,6 +1,6 @@
1 1
 Title: Bash Tips: Giving Feedback
2 2
 Slug: 226/filter
3
-Summary: <p>Be nice to your users.</p>
3
+Summary: Be nice to your users.
4 4
 Date: 2004-06-24 11:00
5 5
 Author: Adam
6 6
 Tags: Scripting
@@ -24,12 +24,23 @@ out, as it improves readability.
24 24
 Here is the code I use to filter all status messages, nestled among
25 25
 example test code:
26 26
 
27
+    #!/bin/sh
27 28
 
29
+    function message() {
30
+        echo "$0[$$]: $@"
31
+    }
28 32
 
33
+    function error() {
34
+        message "$@" >/dev/stderr
35
+    }
29 36
 
30
-    #!/bin/shfunction message() {   echo "$0[$$]: $@"}function error() {    message "$@" >/dev/stderr}case "$1" in   '') echo "usage: $0 [-e|-m] [--] message" ; exit 1 ;;    -e) shift ; error "$@" ;;    -m|--) shift ; message "$@" ;;   -*) error "invalid argument: $1" ; exit 1 ;; *) message "$@" ;;esac
31
-
32
-
37
+    case "$1" in
38
+        '') echo "usage: $0 [-e|-m] [--] message" ; exit 1 ;;
39
+        -e) shift ; error "$@" ;;
40
+        -m|--) shift ; message "$@" ;;
41
+        -*) error "invalid argument: $1" ; exit 1 ;;
42
+        *) message "$@" ;;
43
+    esac
33 44
 
34 45
 Running this program will format message like so:
35 46
 

+ 7
- 15
content/231-butcher.md View File

@@ -14,33 +14,25 @@ not encourage semantic markup. It encourages table-based layouts and
14 14
 makes it easy to put arbitrary styles on elements. Consider this
15 15
 example:
16 16
 
17
-
18
-
19
-
20
-    <tr style='height:5.55pt'>   <td width="2%" valign=top style='width:2.66%;padding:0in 5.4pt 0in 5.4pt;     height:5.55pt'><a name="_Hlk67893959"></a>        <p class=Institution> </p>  </td>  <td style='border:none;padding:0in 0in 0in 0in' width="97%" colspan=2><p class='MsoNormal'> </td> </tr>
21
-
22
-
17
+    <tr style='height:5.55pt'>
18
+        <td width="2%" valign=top style='width:2.66%;padding:0in 5.4pt 0in 5.4pt;
19
+            height:5.55pt'><a name="_Hlk67893959"></a>
20
+            <p class=Institution> </p>
21
+        </td>
22
+        <td style='border:none;padding:0in 0in 0in 0in' width="97%" colspan=2><p class='MsoNormal'> </td>
23
+     </tr>
23 24
 
24 25
 For those of you unfamiliar with HTML, that code produces something
25 26
 similar to this:
26 27
 
27
-
28
-
29
-
30 28
      
31 29
 
32
-
33
-
34 30
 No, that's not a typo; it really creates a blank line on the page.
35 31
 
36
-
37
-
38 32
 It took me a couple hours over the course of a few days to hand-create
39 33
 Jen's resume. The end result is 10,000 characters and 370 lines shorter,
40 34
 much more semantic, and does not use the character "n" in a dingbats
41 35
 font to simulate list bullets. Thanks, Microsoft.
42 36
 
43
-
44
-
45 37
   [a resume]: http://www.jenniferkunz.com/
46 38
   [a butchered mockery of HTML]: http://www.jenniferkunz.com/resume/resume-1.5.html

+ 12
- 3
content/241-escaping.md View File

@@ -15,15 +15,24 @@ of time you have a snippet like this:
15 15
     <a href="#" onClick="doFunction('<?php echo $myVar; ?>')">
16 16
 
17 17
 
18
-Imagine all the possibilities: what if \$myVar contains a single quote
18
+Imagine all the possibilities: what if `$myVar` contains a single quote
19 19
 character? A double quote? A double quote, followed by some HTML tags?
20 20
 There are workarounds for escaping JavaScript using PHP, but mostly
21
-inside \<script\> tags.
21
+inside `<script>` tags.
22 22
 
23 23
 Well, here's a sure-fire PHP function to encode any ASCII string:
24 24
 
25
+    function javascript_escape($str) {
26
+        $new_str = '';
27
+
28
+        $str_len = strlen($str);
29
+        for($i = 0; $i < $str_len; $i++) {
30
+            $new_str .= '\\x' . dechex(ord(substr($str, $i, 1)));
31
+        }
32
+
33
+        return $new_str;
34
+    }
25 35
 
26
-    function javascript_escape($str) { $new_str = '';    $str_len = strlen($str); for($i = 0; $i < $str_len; $i++) {        $new_str .= '\\x' . dechex(ord(substr($str, $i, 1)));    } return $new_str;}
27 36
 
28 37
 
29 38
 So, let's use this function in our link:

+ 7
- 11
content/251-misc-2.md View File

@@ -38,28 +38,24 @@ methods:
38 38
 
39 39
 
40 40
 
41
-    >>> "foo".upper()'FOO'
41
+    >>> "foo".upper()
42
+    'FOO'
42 43
 
43 44
 
44 45
 
45 46
 Like Perl, the syntax deviates from the norm and gets a little
46 47
 Yoda-esque at times:
47 48
 
48
-
49
-
50
-
51
-    >>> def doFormat(str):...     return "%s a %s" % (str, str)...>>> print [doFormat(s) for s in ("a", "b", "c")]['a a a', 'b a b', 'c a c']
52
-
53
-
49
+    >>> def doFormat(str):
50
+    ...     return "%s a %s" % (str, str)
51
+    ...
52
+    >>> print [doFormat(s) for s in ("a", "b", "c")]
53
+    ['a a a', 'b a b', 'c a c']
54 54
 
55 55
 The flexibility is nice, it just takes some getting used to.
56 56
 
57
-
58
-
59 57
 That's enough randomness for now, I guess.
60 58
 
61
-
62
-
63 59
   [Jeremy]: http://www.jaharmi.com/
64 60
   [notable exceptions]: http://blogs.bwerp.net/~isaac/
65 61
   [Matt]: http://blogs.bwerp.net/matt/

+ 4
- 7
content/255-itms.md View File

@@ -1,6 +1,6 @@
1 1
 Title: Unlocking iTMS Tracks
2 2
 Slug: 255/itms
3
-Summary: <p>Much as I love their products, Apple has still failed me in one important regard: they have not released iTunes for Linux.</p>
3
+Summary: Much as I love their products, Apple has still failed me in one important regard: they have not released iTunes for Linux.
4 4
 Date: 2004-10-07 14:57
5 5
 Author: Adam
6 6
 Tags: Personal
@@ -21,12 +21,9 @@ when I got home. I did so, then used [hymn][] to clean the DRM filth off
21 21
 the .m4p files, leaving pure .m4a in their place. I copied the new files
22 22
 over to my Linux box and ran the following command:
23 23
 
24
-
25
-
26
-
27
-    for file in *.m4a ; do    mplayer -vo null "$file" -ao pcm -aofile "$file.wav"done
28
-
29
-
24
+    for file in *.m4a ; do
25
+        mplayer -vo null "$file" -ao pcm -aofile "$file.wav"
26
+    done
30 27
 
31 28
 My installation of MPlayer can handle any file format QuickTime
32 29
 understands, and I ended up with a bunch of WAV files ready for

+ 4
- 24
content/282-remote.md View File

@@ -14,49 +14,29 @@ B involves running `screen` locally and SSH'ing to DreamHost in every
14 14
 window, but I lose my tailored bash prompt. Normally, my prompt looks
15 15
 like this:
16 16
 
17
-
18
-
19
-
20 17
     adam@aziz[0]:~$
21 18
 
22
-
23
-
24 19
 I can immediately tell that `screen` is running, as well as my window
25 20
 number. This breaks down as soon as I SSH to DreamHost. I get a far more
26 21
 generic prompt:
27 22
 
28
-
29
-
30
-
31 23
     aestus@jezebel:~$
32 24
 
33
-
34
-
35 25
 So, what to do? Set a variable on the remote side, in a roundabout sort
36 26
 of way:
37 27
 
38
-
39
-
40
-
41
-    ssh -t jezebel.dreamhost.com 'export MYVAR=myvalue &&      exec /bin/bash --login'
42
-
43
-
28
+    ssh -t jezebel.dreamhost.com 'export MYVAR=myvalue &&
29
+        exec /bin/bash --login'
44 30
 
45 31
 It doesn't look like much. It took me an hour to assemble. SSH to the
46 32
 host, allocating a TTY with `-t`. Run `bash` on the remote side as a
47 33
 login shell, executing the specified command. Export a variable, and
48 34
 exec a sub-bash.
49 35
 
50
-
51
-
52 36
 Yeah, that's it.
53 37
 
54
-
55
-
56
-<span style="font-weight: bold">Update 12/15/2005:</span> Trimmed the
57
-command a bit: the outer /bin/bash call is unnecessary.
58
-
59
-
38
+<ins>Update 12/15/2005: Trimmed the
39
+command a bit: the outer /bin/bash call is unnecessary.{@class=update}</ins>
60 40
 
61 41
   [DreamHost]: http://www.dreamhost.com/
62 42
   [`screen`]: http://www.wlug.org.nz/Screen

+ 15
- 13
content/291-labels.md View File

@@ -8,22 +8,24 @@ WordPress-Post-ID: 291
8 8
 WordPress-Post-Type: post
9 9
 
10 10
 Maybe I'm the only one that missed this announcement, but [floated
11
-\<label\> tags disappear in Netscape 7.0][]. I use this code often:
11
+`<label>` tags disappear in Netscape 7.0][forms]. I use this code often:
12 12
 
13 13
 
14
-
15
-
16
-    <div class="formrow">    <label>Name:</label>    <input type="text" name="user_name"></div>
14
+    <div class="formrow">
15
+        <label>Name:</label>
16
+        <input type="text" name="user_name">
17
+    </div>
17 18
 
18 19
 
19 20
 
20 21
 With some CSS to style:
21 22
 
22
-
23
-
24
-
25
-    .formrow label {    width: 8em;    float: left;    text-align: right;    display: block;}
26
-
23
+    .formrow label {
24
+        width: 8em;
25
+        float: left;
26
+        text-align: right;
27
+        display: block;
28
+    }
27 29
 
28 30
 
29 31
 This code nicely aligns the form labels and edges of form inputs along a
@@ -31,7 +33,7 @@ line, as in the following screenshot:
31 33
 
32 34
 
33 35
 
34
-[![Screenshot of form from web browser.][]][]
36
+[![Screenshot of form from web browser.][thumb]][big]
35 37
 
36 38
 
37 39
 
@@ -60,6 +62,6 @@ That's it. Uh, thanks for reading.
60 62
 
61 63
 
62 64
 
63
-  [floated \<label\> tags disappear in Netscape 7.0]: http://tom.me.uk/html-to-css/forms.html
64
-  [Screenshot of form from web browser.]: http://blogs.bwerp.net/~adam/2005/01/26/form-labels_t.gif
65
-  [![Screenshot of form from web browser.][]]: http://blogs.bwerp.net/~adam/2005/01/26/form-labels.gif
65
+  [forms]: http://tom.me.uk/html-to-css/forms.html
66
+  [thumb]: http://blogs.bwerp.net/~adam/2005/01/26/form-labels_t.gif
67
+  [big]: http://blogs.bwerp.net/~adam/2005/01/26/form-labels.gif

+ 42
- 24
content/295-cdr.md View File

@@ -19,18 +19,23 @@ Memorex started out with a really great label design with a sort of
19 19
 matte finish. Here is what cdrecord has to say about this revision of
20 20
 the disc:
21 21
 
22
-
23
-
24
-
25
-    ATIP info from disk:  Indicated writing power: 4  Is not unrestricted  Is not erasable  Disk sub type: Medium Type A, low Beta category (A-) (2)  ATIP start of lead in:  -12508 (97:15/17)  ATIP start of lead out: 359848 (79:59/73)Disk type:    Short strategy type (Phthalocyanine or similar)Manuf. index: 22Manufacturer: Ritek Co.
26
-
22
+    ATIP info from disk:
23
+      Indicated writing power: 4
24
+      Is not unrestricted
25
+      Is not erasable
26
+      Disk sub type: Medium Type A, low Beta category (A-) (2)
27
+      ATIP start of lead in:  -12508 (97:15/17)
28
+      ATIP start of lead out: 359848 (79:59/73)
29
+    Disk type:    Short strategy type (Phthalocyanine or similar)
30
+    Manuf. index: 22
31
+    Manufacturer: Ritek Co.
27 32
 
28 33
 
29 34
 And the visual:
30 35
 
31 36
 
32 37
 
33
-[![Memorex Black CD-R with matte finish.][]][]
38
+[![Memorex Black CD-R with matte finish.][img1]][img1big]
34 39
 
35 40
 
36 41
 
@@ -38,9 +43,16 @@ Not bad. Plenty of writing surface to play with. They later changed the
38 43
 dye and altered the label to be a bit shinier. Disc info:
39 44
 
40 45
 
41
-
42
-
43
-    ATIP info from disk:  Indicated writing power: 4  Is unrestricted  Is not erasable  Disk sub type: Medium Type A, low Beta category (A-) (2)  ATIP start of lead in:  -11634 (97:26/66)  ATIP start of lead out: 359849 (79:59/74)Disk type:    Short strategy type (Phthalocyanine or similar)Manuf. index: 3Manufacturer: CMC Magnetics Corporation
46
+    ATIP info from disk:
47
+      Indicated writing power: 4
48
+      Is unrestricted
49
+      Is not erasable
50
+      Disk sub type: Medium Type A, low Beta category (A-) (2)
51
+      ATIP start of lead in:  -11634 (97:26/66)
52
+      ATIP start of lead out: 359849 (79:59/74)
53
+    Disk type:    Short strategy type (Phthalocyanine or similar)
54
+    Manuf. index: 3
55
+    Manufacturer: CMC Magnetics Corporation
44 56
 
45 57
 
46 58
 
@@ -48,17 +60,23 @@ And photo:
48 60
 
49 61
 
50 62
 
51
-[![Memorex Black CD-R with shiny finish.][]][]
63
+[![Memorex Black CD-R with shiny finish.][img2]][img2big]
52 64
 
53 65
 
54 66
 
55 67
 A few months later, somebody at Memorex took a hit off the ol' crack
56 68
 pipe. The disc info didn't change much:
57 69
 
58
-
59
-
60
-
61
-    ATIP info from disk:  Indicated writing power: 4  Is unrestricted  Is not erasable  Disk sub type: Medium Type A, low Beta category (A-) (2)  ATIP start of lead in:  -11634 (97:26/66)  ATIP start of lead out: 359849 (79:59/74)Disk type:    Short strategy type (Phthalocyanine or similar)Manuf. index: 3Manufacturer: CMC Magnetics Corporation
70
+    ATIP info from disk:
71
+      Indicated writing power: 4
72
+      Is unrestricted
73
+      Is not erasable
74
+      Disk sub type: Medium Type A, low Beta category (A-) (2)
75
+      ATIP start of lead in:  -11634 (97:26/66)
76
+      ATIP start of lead out: 359849 (79:59/74)
77
+    Disk type:    Short strategy type (Phthalocyanine or similar)
78
+    Manuf. index: 3
79
+    Manufacturer: CMC Magnetics Corporation
62 80
 
63 81
 
64 82
 
@@ -66,7 +84,7 @@ But the label took a turn for the worst:
66 84
 
67 85
 
68 86
 
69
-[![Memorex Black CD-R with hardly any writable surface.][]][]
87
+[![Memorex Black CD-R with hardly any writable surface.][img3]][img3big]
70 88
 
71 89
 
72 90
 
@@ -81,15 +99,15 @@ Here's a composite of the three discs, just for fun:
81 99
 
82 100
 
83 101
 
84
-[![Composite of three photographs, showing differences in label.][]][]
102
+[![Composite of three photographs, showing differences in label.][img4]][img4big]
85 103
 
86 104
 
87 105
 
88
-  [Memorex Black CD-R with matte finish.]: /~adam/2005/02/06/t_memorex-rev1.jpg
89
-  [![Memorex Black CD-R with matte finish.][]]: /~adam/2005/02/06/memorex-rev1.jpg
90
-  [Memorex Black CD-R with shiny finish.]: /~adam/2005/02/06/t_memorex-rev2.jpg
91
-  [![Memorex Black CD-R with shiny finish.][]]: /~adam/2005/02/06/memorex-rev2.jpg
92
-  [Memorex Black CD-R with hardly any writable surface.]: /~adam/2005/02/06/t_memorex-rev3.jpg
93
-  [![Memorex Black CD-R with hardly any writable surface.][]]: /~adam/2005/02/06/memorex-rev3.jpg
94
-  [Composite of three photographs, showing differences in label.]: /~adam/2005/02/06/t_composite.jpg
95
-  [![Composite of three photographs, showing differences in label.][]]: /~adam/2005/02/06/composite.jpg
106
+  [img1]: https://sixohthree.com/~adam/2005/02/06/t_memorex-rev1.jpg
107
+  [img1big]: https://sixohthree.com/~adam/2005/02/06/memorex-rev1.jpg
108
+  [img2]: https://sixohthree.com/~adam/2005/02/06/t_memorex-rev2.jpg
109
+  [img2big]: https://sixohthree.com/~adam/2005/02/06/memorex-rev2.jpg
110
+  [img3]: https://sixohthree.com/~adam/2005/02/06/t_memorex-rev3.jpg
111
+  [img3big]: https://sixohthree.com/~adam/2005/02/06/memorex-rev3.jpg
112
+  [img4]: https://sixohthree.com/~adam/2005/02/06/t_composite.jpg
113
+  [img4big]: https://sixohthree.com/~adam/2005/02/06/composite.jpg

+ 23
- 1
content/298-pkg.md View File

@@ -22,10 +22,32 @@ those packages. Firefox is available as a .tar.gz of files (as opposed
22 22
 to a graphical installer). The following script ([download version][])
23 23
 works nicely:
24 24
 
25
+    #!/bin/sh
25 26
 
27
+    CWD=`pwd`
28
+    PKG=/tmp/package-firefox
29
+    rm -rf $PKG
26 30
 
31
+    VERSION=1.0.2
32
+    ARCH=i686
33
+    BUILD=1
27 34
 
28
-    #!/bin/shCWD=`pwd`PKG=/tmp/package-firefoxrm -rf $PKGVERSION=1.0.2ARCH=i686BUILD=1mkdir -p $PKG/usr/lib $PKG/usr/bincd $PKG/usr/libtar xzfv $CWD/firefox-$VERSION.tar.gzcd $PKG/usr/binln -s ../lib/firefox/firefox ./firefoxmkdir -p $PKG/usr/share/pixmapscp $CWD/Firefox.png $PKG/usr/share/pixmaps/Firefox.pngchown -R root:root $PKGchown root.bin $PKG/usr/lib/firefox/firefox-bincd $PKGmakepkg -l y -c n ../firefox-$VERSION-$ARCH-$BUILD.tgz
35
+    mkdir -p $PKG/usr/lib $PKG/usr/bin
36
+    cd $PKG/usr/lib
37
+
38
+    tar xzfv $CWD/firefox-$VERSION.tar.gz
39
+
40
+    cd $PKG/usr/bin
41
+    ln -s ../lib/firefox/firefox ./firefox
42
+
43
+    mkdir -p $PKG/usr/share/pixmaps
44
+    cp $CWD/Firefox.png $PKG/usr/share/pixmaps/Firefox.png
45
+
46
+    chown -R root:root $PKG
47
+    chown root.bin $PKG/usr/lib/firefox/firefox-bin
48
+
49
+    cd $PKG
50
+    makepkg -l y -c n ../firefox-$VERSION-$ARCH-$BUILD.tgz
29 51
 
30 52
 
31 53
 

+ 3
- 5
content/305-tape.md View File

@@ -18,11 +18,9 @@ right. I backed up my 5.9GB /home partition with a
18 18
 Here's how long it took to pull off 59MB of data near the end of the
19 19
 tape:
20 20
 
21
-
22
-
23
-
24
-    real    109m38.125suser    0m1.230ssys     0m16.340s
25
-
21
+    real    109m38.125s
22
+    user    0m1.230s
23
+    sys     0m16.340s
26 24
 
27 25
 
28 26
 That's nearly two hours' time to perform under 20 seconds of work. Yay

+ 11
- 1
content/307-calculator.md View File

@@ -25,7 +25,17 @@ storing results in a variable. If you're handy with printf style
25 25
 statements, you can even format output to your liking. As an example:
26 26
 
27 27
 
28
-    adam@shed:~$ pythonPython 2.4 (#1, Jan  1 2005, 21:33:55)[GCC 3.3.4] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> 7 * 19133>>> 3 / 21.00.14285714285714285>>> print "%0.2f" % (81 / 2.1)38.57>>>
28
+    adam@shed:~$ python
29
+    Python 2.4 (#1, Jan  1 2005, 21:33:55)
30
+    [GCC 3.3.4] on linux2
31
+    Type "help", "copyright", "credits" or "license" for more information.
32
+    >>> 7 * 19
33
+    133
34
+    >>> 3 / 21.0
35
+    0.14285714285714285
36
+    >>> print "%0.2f" % (81 / 2.1)
37
+    38.57
38
+    >>>
29 39
 
30 40
 
31 41
 

+ 13
- 1
content/328-taming.md View File

@@ -22,10 +22,22 @@ content blocks, change colors and fonts, add text, or, drumroll: remove
22 22
 
23 23
 Here's the script:
24 24
 
25
+    // By Adam Backstrom <adam@sixohthree.com>
26
+    // Public Domain, 8 August, 2005.
27
+    // Block Google's data mining on search results.
25 28
 
29
+    // find all paragraph tags
30
+    thePs = document.getElementsByTagName("P");
26 31
 
32
+    for(var i = 0; i 
27 33
 
28
-    // By Adam Backstrom <adam@sixohthree.com>// Public Domain, 8 August, 2005.// Block Google's data mining on search results.// find all paragraph tagsthePs = document.getElementsByTagName("P");for(var i = 0; i     theP = thePs[i];    theLinks = theP.getElementsByTagName("A"); // find anchors    for(var j = 0; j < theLinks.length; j++) {        theLinks[j].removeAttribute("onmousedown");    }}
34
+        theP = thePs[i];
35
+        theLinks = theP.getElementsByTagName("A"); // find anchors
36
+
37
+        for(var j = 0; j < theLinks.length; j++) {
38
+            theLinks[j].removeAttribute("onmousedown");
39
+        }
40
+    }
29 41
 
30 42
 
31 43
 

+ 18
- 11
content/335-itunes.md View File

@@ -35,15 +35,30 @@ is a comparison of the files, filtered through `xxd(1)`. First, the old
35 35
 file:
36 36
 
37 37
 
38
-    0000ee0: 6f52 9e37 b977 527f 93c6 17e5 fce9 9212  oR.7.wR.........0000ef0: 8349 6b94 d4df a8fd 255d 57e2 3fa9 3fe9  .Ik.....%]W.?.?.0000f00: 8ac2 538e 23e5 5b7a 6779 6efc 5cdf 97b9  ..S.#.[zgyn.\...0000f10: 65ef 4aca e928 4748 fbf7 cfcd 7b9a f6bd  e.J..(GH....{...0000f20: a89c 483a 77c6 8952 8bd2 d56a f9bd ce5d  ..H:w..R...j...]0000f30: 41b5 307d b27f aece 4649 7522 ca3b a36a  A.0}....FIu".;.j0000f40: 7054 bd8d ba7f 3ab4 ac57 9237 a79c 7f3a  pT....:..W.7...:0000f50: 5324 d58b f054 f95d 5ad9 df4f 7115 743e  S$...T.]Z..Oq.t>0000f60: 49d7 9631 25e5 587a b0cc 6352 dd4b 5afb  I..1%.Xz..cR.KZ.
38
+    0000ee0: 6f52 9e37 b977 527f 93c6 17e5 fce9 9212  oR.7.wR.........
39
+    0000ef0: 8349 6b94 d4df a8fd 255d 57e2 3fa9 3fe9  .Ik.....%]W.?.?.
40
+    0000f00: 8ac2 538e 23e5 5b7a 6779 6efc 5cdf 97b9  ..S.#.[zgyn.\...
41
+    0000f10: 65ef 4aca e928 4748 fbf7 cfcd 7b9a f6bd  e.J..(GH....{...
42
+    0000f20: a89c 483a 77c6 8952 8bd2 d56a f9bd ce5d  ..H:w..R...j...]
43
+    0000f30: 41b5 307d b27f aece 4649 7522 ca3b a36a  A.0}....FIu".;.j
44
+    0000f40: 7054 bd8d ba7f 3ab4 ac57 9237 a79c 7f3a  pT....:..W.7...:
45
+    0000f50: 5324 d58b f054 f95d 5ad9 df4f 7115 743e  S$...T.]Z..Oq.t>
46
+    0000f60: 49d7 9631 25e5 587a b0cc 6352 dd4b 5afb  I..1%.Xz..cR.KZ.
39 47
 
40 48
 
41 49
 
42 50
 Next, the new:
43 51
 
44 52
 
45
-    0000ff0: e5fb 98a9 4ced c135 d746 32b3 de1b 7393  ....L..5.F2...s.0001000: 8396 5685 d5e9 8c1f 8a48 7bde 0a55 6bca  ..V......H{..Uk.0001010: f2bb 7ac3 9463 1d6d 9762 b117 b5b8 3bc8  ..z..c.m.b....;.0001020: 65ef 4aca e928 4748 fbf7 cfcd 7b9a f6bd  e.J..(GH....{...0001030: a89c 483a 77c6 8952 8bd2 d56a f9bd ce5d  ..H:w..R...j...]0001040: 41b5 307d b27f aece 4649 7522 ca3b a36a  A.0}....FIu".;.j0001050: 7054 bd8d ba7f 3ab4 ac57 9237 a79c 7f3a  pT....:..W.7...:0001060: 5324 d58b f054 f95d 5ad9 df4f 7115 743e  S$...T.]Z..Oq.t>0001070: 49d7 9631 25e5 587a b0cc 6352 dd4b 5afb  I..1%.Xz..cR.KZ.
46
-
53
+    0000ff0: e5fb 98a9 4ced c135 d746 32b3 de1b 7393  ....L..5.F2...s.
54
+    0001000: 8396 5685 d5e9 8c1f 8a48 7bde 0a55 6bca  ..V......H{..Uk.
55
+    0001010: f2bb 7ac3 9463 1d6d 9762 b117 b5b8 3bc8  ..z..c.m.b....;.
56
+    0001020: 65ef 4aca e928 4748 fbf7 cfcd 7b9a f6bd  e.J..(GH....{...
57
+    0001030: a89c 483a 77c6 8952 8bd2 d56a f9bd ce5d  ..H:w..R...j...]
58
+    0001040: 41b5 307d b27f aece 4649 7522 ca3b a36a  A.0}....FIu".;.j
59
+    0001050: 7054 bd8d ba7f 3ab4 ac57 9237 a79c 7f3a  pT....:..W.7...:
60
+    0001060: 5324 d58b f054 f95d 5ad9 df4f 7115 743e  S$...T.]Z..Oq.t>
61
+    0001070: 49d7 9631 25e5 587a b0cc 6352 dd4b 5afb  I..1%.Xz..cR.KZ.
47 62
 
48 63
 
49 64
 Notice how the data streams align midway through the pasted sections.
@@ -56,17 +71,9 @@ that needs modification.
56 71
 Next steps:
57 72
 
58 73
 1.  Do an additional comparison of old and new files.
59
-    </p>
60
-    <p>
61 74
 2.  Compare and old and new header for length and content.
62
-    </p>
63
-    <p>
64 75
 3.  Compare two old headers for length and content.
65
-    </p>
66
-    <p>
67 76
 4.  Compare two new headers for length and content.
68
-    </p>
69
-    <p>
70 77
 
71 78
 
72 79
 

+ 9
- 3
content/347-calendar-2.md View File

@@ -21,9 +21,15 @@ The whole mess can be seen at [BlackSheep:2005][]. The code to insert a
21 21
 calendar looks something like this:
22 22
 
23 23
 
24
-    == October =={{calmonth5|=   1 | | | | | | |2005-10-01|=   2 |2005-10-02| | | | | | |=   3 | | | | | | | |=   4 | | | | | | | |=   5 | | | | | | | |=}}
25
-
26
-
24
+    == October ==
25
+
26
+    {{calmonth5|=
27
+       1 | | | | | | |2005-10-01|=
28
+       2 |2005-10-02| | | | | | |=
29
+       3 | | | | | | | |=
30
+       4 | | | | | | | |=
31
+       5 | | | | | | | |=
32
+    }}
27 33
 
28 34
 As time goes on, Karl can manually add more items to the template call.
29 35
 

+ 5
- 2
content/363-tooltips.md View File

@@ -58,11 +58,14 @@ of our document on the fly, enabling us to update the tooltip for the
58 58
 current item and moving the tooltip to follow the cursor.
59 59
 
60 60
 Through Ajax, [large item tables][] become relatively painless. A custom
61
-MediaWiki plugin can create new wiki tags, such as the \<thottbot\> tag
61
+MediaWiki plugin can create new wiki tags, such as the `<thottbot>` tag
62 62
 used in the previous example:
63 63
 
64 64
 
65
-    *<thottbot rarity="legendary">Bindings of the Windseeker</thottbot> Keridwen*<thottbot rarity="epic">Arcanist Bindings</thottbot> Jackstroud*<thottbot rarity="epic">Felheart Belt</thottbot> Osynling*<thottbot rarity="epic">Felheart Shoulder Pads</thottbot> Dakkota
65
+    *<thottbot rarity="legendary">Bindings of the Windseeker</thottbot> Keridwen
66
+    *<thottbot rarity="epic">Arcanist Bindings</thottbot> Jackstroud
67
+    *<thottbot rarity="epic">Felheart Belt</thottbot> Osynling
68
+    *<thottbot rarity="epic">Felheart Shoulder Pads</thottbot> Dakkota
66 69
 
67 70
 
68 71
 The whole process becomes seamless. An author creates a link. A reader

+ 23
- 1
content/364-sitemaps.md View File

@@ -13,7 +13,29 @@ script that does not use [XML creation tools][] to be a hack. This is a
13 13
 hack.
14 14
 
15 15
 
16
-    <?phpheader("Content-type: application/xml");require_once( dirname(__FILE__) . '/wp-config.php'); // get the wordpress functions// sitemap headerecho '<'.'?xml version="1.0" encoding="UTF-8"?>';echo '<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">';// set upper limit to a sufficiently high number$posts = get_posts('numberposts=32767&order=ASC&orderby=post_date');// output all the postsforeach($posts as $post): setup_postdata($post);?>    <url>        <loc><?php the_permalink(); ?></loc>        <lastmod><?php echo get_post_modified_time('Y-m-d') ?></lastmod>    </url><?phpendforeach;echo '</urlset>';?>
16
+    <?php
17
+
18
+    header("Content-type: application/xml");
19
+    require_once( dirname(__FILE__) . '/wp-config.php'); // get the wordpress functions
20
+
21
+    // sitemap header
22
+    echo '<'.'?xml version="1.0" encoding="UTF-8"?>';
23
+    echo '<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">';
24
+
25
+    // set upper limit to a sufficiently high number
26
+    $posts = get_posts('numberposts=32767&order=ASC&orderby=post_date');
27
+
28
+    // output all the posts
29
+    foreach($posts as $post): setup_postdata($post);
30
+    ?>
31
+        <url>
32
+            <loc><?php the_permalink(); ?></loc>
33
+            <lastmod><?php echo get_post_modified_time('Y-m-d') ?></lastmod>
34
+        </url>
35
+    <?php
36
+
37
+    endforeach;
38
+    echo '</urlset>';
17 39
 
18 40
 
19 41
 

+ 3
- 8
content/367-e3.md View File

@@ -12,13 +12,9 @@ Select E3 links. Updated throughout the day.
12 12
 -   [Wii gameplay trailer][]
13 13
 -   [Sigil E3 blog][] (Developers of [Vanguard: Saga of Heroes][])
14 14
 -   [Joystiq][]: ongoing coverage
15
--   [Opera partners with Nintendo to put browser on the Wii™ game
16
-    console][]
15
+-   [Opera partners with Nintendo to put browser on the Wii™ game console][]
17 16
 -   [NY Times: The Burning Crusade][]. New Alliance race revealed.
18
--   [Vanguard: Saga of Heroes: I Want My Secret Sauce!][]. Housing,
19
-    weather, ships.
20
-    </p>
21
-    <p>
17
+-   [Vanguard: Saga of Heroes: I Want My Secret Sauce!][]. Housing, weather, ships.
22 18
 
23 19
 
24 20
 
@@ -26,7 +22,6 @@ Select E3 links. Updated throughout the day.
26 22
   [Sigil E3 blog]: http://www.sigilgames.com/e3.html
27 23
   [Vanguard: Saga of Heroes]: http://www.vanguardsoh.com/
28 24
   [Joystiq]: http://www.joystiq.com/
29
-  [Opera partners with Nintendo to put browser on the Wii™ game
30
-  console]: http://www.opera.com/pressreleases/en/2006/05/10/
25
+  [Opera partners with Nintendo to put browser on the Wii™ game console]: http://www.opera.com/pressreleases/en/2006/05/10/
31 26
   [NY Times: The Burning Crusade]: http://www.nytimes.com/2006/05/09/technology/10warcraft.web.html
32 27
   [Vanguard: Saga of Heroes: I Want My Secret Sauce!]: http://www.tentonhammer.com/index.php?module=ContentExpress&func=display&ceid=301

+ 8
- 3
content/389-dns.md View File

@@ -9,7 +9,7 @@ WordPress-Post-Type: post
9 9
 
10 10
 As I said in my [earlier post][], this server has been experiencing some
11 11
 slowness lately. I *believe* I've narrowed down the problem and finally
12
-fixed it after a little help from [mod\_status][].
12
+fixed it after a little help from [mod\_status][mod-status].
13 13
 
14 14
 Troubleshooting my server has always been a Catch-22. You can't fix
15 15
 something that isn't broken (like a server that is working flawlessly)
@@ -19,7 +19,12 @@ finally able to pull up my server status during a period of Apache
19 19
 slowness. My status looked like this:
20 20
 
21 21
 
22
-    40 requests currently being processed, 0 idle serversDWDDDWWDDWWDDWWDWKDWDDWDKDDWDDDKDDDDDWDW........................................................................................................................................................................................................................
22
+    40 requests currently being processed, 0 idle servers
23
+
24
+    DWDDDWWDDWWDDWWDWKDWDDWDKDDWDDDKDDDDDWDW........................
25
+    ................................................................
26
+    ................................................................
27
+    ................................................................
23 28
 
24 29
 
25 30
 
@@ -32,4 +37,4 @@ address. One changed line, and no more blocking due to DNS lookups.
32 37
 I'll have to keep an eye on things, but I feel good about this fix.
33 38
 
34 39
   [earlier post]: /archives/2006/12/14/spam
35
-  [mod\_status]: http://httpd.apache.org/docs/1.3/mod/mod_status.html
40
+  [mod-status]: http://httpd.apache.org/docs/1.3/mod/mod_status.html

+ 2
- 4
content/398-downtime.md View File

@@ -10,10 +10,8 @@ WordPress-Post-Type: post
10 10
 Firefox locked up Shed today. I got an uptime just before I lost
11 11
 keyboard access:
12 12
 
13
-
14
-    root@shed:~# uptime 13:13:36 up 265 days, 22:06,  2 users,  load average: 0.40, 1.23, 0.79
15
-
16
-
13
+    root@shed:~# uptime
14
+     13:13:36 up 265 days, 22:06,  2 users,  load average: 0.40, 1.23, 0.79
17 15
 
18 16
 265 days since I moved into my new apartment.
19 17
 

+ 2
- 1
content/400-merge.md View File

@@ -11,7 +11,8 @@ There are several free utilities for merging PDFs into one document. For
11 11
 a long time, Ghostscript was enough for me:
12 12
 
13 13
 
14
-    gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \\    -sOutputFile=collated.pdf file1.pdf file2.pdf
14
+    gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
15
+        -sOutputFile=collated.pdf file1.pdf file2.pdf
15 16
 
16 17
 
17 18
 

+ 6
- 4
content/403-dos.md View File

@@ -9,9 +9,11 @@ WordPress-Post-Type: post
9 9
 
10 10
 What's all this then?
11 11
 
12
-
13
-    UDP (46 bytes) from 76.187.107.238:26546 to 76.178.xxx.yyy:33273 on eth0UDP (46 bytes) from 76.173.19.250:53379 to 76.178.xxx.yyy:33273 on eth0UDP (46 bytes) from 75.31.97.247:28101 to 76.178.xxx.yyy:33273 on eth0UDP (46 bytes) from 76.170.130.124:32888 to 76.178.xxx.yyy:33273 on eth0UDP (46 bytes) from 70.105.249.4:49884 to 76.178.xxx.yyy:33273 on eth0UDP (46 bytes) from 69.31.210.146:23186 to 76.178.xxx.yyy:33273 on eth0
14
-
15
-
12
+    UDP (46 bytes) from 76.187.107.238:26546 to 76.178.xxx.yyy:33273 on eth0
13
+    UDP (46 bytes) from 76.173.19.250:53379 to 76.178.xxx.yyy:33273 on eth0
14
+    UDP (46 bytes) from 75.31.97.247:28101 to 76.178.xxx.yyy:33273 on eth0
15
+    UDP (46 bytes) from 76.170.130.124:32888 to 76.178.xxx.yyy:33273 on eth0
16
+    UDP (46 bytes) from 70.105.249.4:49884 to 76.178.xxx.yyy:33273 on eth0
17
+    UDP (46 bytes) from 69.31.210.146:23186 to 76.178.xxx.yyy:33273 on eth0
16 18
 
17 19
 /boggle. Hundreds of packets per minute.

+ 25
- 2
content/406-days.md View File

@@ -36,7 +36,18 @@ built-in autofill feature and drag this cell down the sheet to create
36 36
 your range of dates:
37 37
 
38 38
 
39
-    =A1+7/6=A2+7/6=A3+7/6=A4+7/6=A5+7/6=A6+7/6=A7+7/6=A8+7/6=A9+7/6=A10+7/6=A11+7/6=A12+7/6
39
+    =A1+7/6
40
+    =A2+7/6
41
+    =A3+7/6
42
+    =A4+7/6
43
+    =A5+7/6
44
+    =A6+7/6
45
+    =A7+7/6
46
+    =A8+7/6
47
+    =A9+7/6
48
+    =A10+7/6
49
+    =A11+7/6
50
+    =A12+7/6
40 51
 
41 52
 
42 53
 
@@ -52,7 +63,19 @@ By shifting the date value in the first cell we can make the skip come
52 63
 three days earlier, dropping Mondays from the list.
53 64
 
54 65
 
55
-    Thu, April 26, 2007Fri, April 27, 2007Sat, April 28, 2007Sun, April 29, 2007Tue, May 1, 2007Wed, May 2, 2007Thu, May 3, 2007Fri, May 4, 2007Sat, May 5, 2007Sun, May 6, 2007Tue, May 8, 2007Wed, May 9, 2007Thu, May 10, 2007
66
+    Thu, April 26, 2007
67
+    Fri, April 27, 2007
68
+    Sat, April 28, 2007
69
+    Sun, April 29, 2007
70
+    Tue, May 1, 2007
71
+    Wed, May 2, 2007
72
+    Thu, May 3, 2007
73
+    Fri, May 4, 2007
74
+    Sat, May 5, 2007
75
+    Sun, May 6, 2007
76
+    Tue, May 8, 2007
77
+    Wed, May 9, 2007
78
+    Thu, May 10, 2007
56 79
 
57 80
 
58 81
 

+ 159
- 5
content/421-filter-2.md View File

@@ -13,27 +13,181 @@ field after field as you dig down to the desired record set. After half
13 13
 a dozen filters, Alpha ends up with something like this:
14 14
 
15 15
 
16
-    Filter: ((((((ITMPRTCL="Fiber")) .AND. ((ITMPRTCL="Fiber")) .AND.(ITMFIL->ITMPRDCA"Product   ")) .AND. (((ITMPRTCL="Fiber")).AND.(ITMFIL->ITMPRDCA"Product   ")).AND.(ITMFIL->ITMPRDCA"Component ").AND.(ITMPRDCA="Bulk Cable")) .AND. ((((ITMPRTCL="Fiber")).AND.(ITMFIL->ITMPRDCA"Product   ")).AND.(ITMFIL->ITMPRDCA"Component ").AND.(ITMPRDCA="Bulk Cable")).AND.(ITMFIL->ITM_STATUS"Inactive            ")) .AND.(((((ITMPRTCL="Fiber")).AND.(ITMFIL->ITMPRDCA"Product   ")).AND.(ITMFIL->ITMPRDCA"Component ").AND.(ITMPRDCA="Bulk Cable")).AND.(ITMFIL->ITM_STATUS"Inactive            ")).AND.(PHMENG->F_JACKET"Outdoor Aerial      ")).AND. ((((((ITMPRTCL="Fiber")).AND.(ITMFIL->ITMPRDCA"Product   ")).AND.(ITMFIL->ITMPRDCA"Component ").AND.(ITMPRDCA="Bulk Cable")).AND.(ITMFIL->ITM_STATUS"Inactive            ")).AND.(PHMENG->F_JACKET"Outdoor Aerial      ")).AND.(PHMENG->F_JACKET"Indoor/Outdoor      ")
16
+    Filter: ((((((ITMPRTCL="Fiber")) .AND. ((ITMPRTCL="Fiber")) .AND.
17
+    (ITMFIL->ITMPRDCA"Product   ")) .AND. (((ITMPRTCL="Fiber")).AND.
18
+    (ITMFIL->ITMPRDCA"Product   ")).AND.(ITMFIL->ITMPRDCA"Component ").AND.
19
+    (ITMPRDCA="Bulk Cable")) .AND. ((((ITMPRTCL="Fiber")).AND.
20
+    (ITMFIL->ITMPRDCA"Product   ")).AND.(ITMFIL->ITMPRDCA"Component ").AND.
21
+    (ITMPRDCA="Bulk Cable")).AND.(ITMFIL->ITM_STATUS"Inactive            ")) .AND.
22
+    (((((ITMPRTCL="Fiber")).AND.(ITMFIL->ITMPRDCA"Product   ")).AND.
23
+    (ITMFIL->ITMPRDCA"Component ").AND.(ITMPRDCA="Bulk Cable")).AND.
24
+    (ITMFIL->ITM_STATUS"Inactive            ")).AND.
25
+    (PHMENG->F_JACKET"Outdoor Aerial      "))
26
+    .AND. ((((((ITMPRTCL="Fiber")).AND.(ITMFIL->ITMPRDCA"Product   ")).AND.
27
+    (ITMFIL->ITMPRDCA"Component ").AND.(ITMPRDCA="Bulk Cable")).AND.
28
+    (ITMFIL->ITM_STATUS"Inactive            ")).AND.
29
+    (PHMENG->F_JACKET"Outdoor Aerial      ")).AND.
30
+    (PHMENG->F_JACKET"Indoor/Outdoor      ")
17 31
 
18 32
 
19 33
 
20 34
 Some of you might prefer a more structured layout:
21 35
 
36
+    (
37
+        (
38
+            (
39
+                (
40
+                    (
41
+                        (
42
+                            ITMPRTCL="Fiber"
43
+                        )
44
+                    )
45
+                    .AND.
46
+                    (
47
+                        (
48
+                            ITMPRTCL="Fiber"
49
+                        )
50
+                    )
51
+                    .AND.
52
+                    (
53
+                        ITMFIL->ITMPRDCA"Product   "
54
+                    )
55
+                )
56
+                .AND.
57
+                (
58
+                    (
59
+                        (
60
+                            ITMPRTCL="Fiber"
61
+                        )
62
+                    )
63
+                    .AND.
64
+                    (
65
+                        ITMFIL->ITMPRDCA"Product   "
66
+                    )
67
+                )
68
+                .AND.
69
+                (
70
+                    ITMFIL->ITMPRDCA"Component "
71
+                )
72
+                .AND.
73
+                (
74
+                    ITMPRDCA="Bulk Cable"
75
+                )
76
+            )
77
+            .AND.
78
+            (
79
+                (
80
+                    (
81
+                        (
82
+                            ITMPRTCL="Fiber"
83
+                        )
84
+                    )
85
+                    .AND.
86
+                    (
87
+                        ITMFIL->ITMPRDCA"Product   "
88
+                    )
89
+                )
90
+                .AND.
91
+                (
92
+                    ITMFIL->ITMPRDCA"Component "
93
+                )
94
+                .AND.
95
+                (
96
+                    ITMPRDCA="Bulk Cable"
97
+                )
98
+            )
99
+            .AND.
100
+            (
101
+                ITMFIL->ITM_STATUS"Inactive            "
102
+            )
103
+        )
104
+        .AND.
105
+        (
106
+            (
107
+                (
108
+                    (
109
+                        (
110
+                            ITMPRTCL="Fiber"
111
+                        )
112
+                    )
113
+                    .AND.
114
+                    (
115
+                        ITMFIL->ITMPRDCA"Product   "
116
+                    )
117
+                )
118
+                .AND.
119
+                (
120
+                    ITMFIL->ITMPRDCA"Component "
121
+                )
122
+                .AND.
123
+                (
124
+                    ITMPRDCA="Bulk Cable"
125
+                )
126
+            )
127
+            .AND.
128
+            (
129
+                ITMFIL->ITM_STATUS"Inactive            "
130
+            )
131
+        )
132
+        .AND.
133
+        (
134
+            PHMENG->F_JACKET"Outdoor Aerial      "
135
+        )
136
+    )
137
+    .AND.
138
+    (
139
+        (
140
+            (
141
+                (
142
+                    (
143
+                        (
144
+                            ITMPRTCL="Fiber"
145
+                        )
146
+                    )
147
+                    .AND.
148
+                    (
149
+                        ITMFIL->ITMPRDCA"Product   "
150
+                    )
151
+                )
152
+                .AND.
153
+                (
154
+                    ITMFIL->ITMPRDCA"Component "
155
+                )
156
+                .AND.
157
+                (
158
+                    ITMPRDCA="Bulk Cable"
159
+                )
160
+            )
161
+            .AND.
162
+            (
163
+                ITMFIL->ITM_STATUS"Inactive            "
164
+            )
165
+        )
166
+        .AND.
167
+        (
168
+            PHMENG->F_JACKET"Outdoor Aerial      "
169
+        )
170
+    )
171
+    .AND.
172
+    (
173
+        PHMENG->F_JACKET"Indoor/Outdoor      "
174
+    )
22 175
 
23
-    (    (        (            (                (                    (                        ITMPRTCL="Fiber"                    )                )                .AND.                (                    (                        ITMPRTCL="Fiber"                    )                )                .AND.                (                    ITMFIL->ITMPRDCA"Product   "                )            )            .AND.            (                (                    (                        ITMPRTCL="Fiber"                    )                )                .AND.                (                    ITMFIL->ITMPRDCA"Product   "                )            )            .AND.            (                ITMFIL->ITMPRDCA"Component "            )            .AND.            (                ITMPRDCA="Bulk Cable"            )        )        .AND.        (            (                (                    (                        ITMPRTCL="Fiber"                    )                )                .AND.                (                    ITMFIL->ITMPRDCA"Product   "                )            )            .AND.            (                ITMFIL->ITMPRDCA"Component "            )            .AND.            (                ITMPRDCA="Bulk Cable"            )        )        .AND.        (            ITMFIL->ITM_STATUS"Inactive            "        )    )    .AND.    (        (            (                (                    (                        ITMPRTCL="Fiber"                    )                )                .AND.                (                    ITMFIL->ITMPRDCA"Product   "                )            )            .AND.            (                ITMFIL->ITMPRDCA"Component "            )            .AND.            (                ITMPRDCA="Bulk Cable"            )        )        .AND.        (            ITMFIL->ITM_STATUS"Inactive            "        )    )    .AND.    (        PHMENG->F_JACKET"Outdoor Aerial      "    )).AND.(    (        (            (                (                    (                        ITMPRTCL="Fiber"                    )                )                .AND.                (                    ITMFIL->ITMPRDCA"Product   "                )            )            .AND.            (                ITMFIL->ITMPRDCA"Component "            )            .AND.            (                ITMPRDCA="Bulk Cable"            )        )        .AND.        (            ITMFIL->ITM_STATUS"Inactive            "        )    )    .AND.    (        PHMENG->F_JACKET"Outdoor Aerial      "    )).AND.(    PHMENG->F_JACKET"Indoor/Outdoor      ")
24 176
 
25 177
 
26 178
 
27 179
 You may have noticed that some of the conditions are repeated several
28 180
 times. At times this will generate errors as the filter gets more and
29 181
 more complex. The Xbasic command
30
-[Expression\_Common\_Filter\_Eliminate][]() can trim these duplicate
182
+[Expression\_Common\_Filter\_Eliminate][ecfe]() can trim these duplicate
31 183
 query conditions, allowing you to add additional filters.
32 184
 
33 185
 
34
-    current_filter = topparent.filter_get()new_filter = expression_common_filter_eliminate(current_filter)topparent.queryrun(new_filter)
186
+    current_filter = topparent.filter_get()
187
+    new_filter = expression_common_filter_eliminate(current_filter)
188
+    topparent.queryrun(new_filter)
35 189
 
36 190
 
37 191
 
38 192
   [Alpha Five]: http://www.alphasoftware.com/AlphaFive/
39
-  [Expression\_Common\_Filter\_Eliminate]: http://support.alphasoftware.com/alphafivehelpv8/index.htm#Functions/EXPRESSION_COMMON_FILTER_ELIMINATE().HTM
193
+  [ecfe]: http://support.alphasoftware.com/alphafivehelpv8/index.htm#Functions/EXPRESSION_COMMON_FILTER_ELIMINATE().HTM

+ 10
- 7
content/424-smtp-2.md View File

@@ -11,9 +11,9 @@ I'm migrating e-mail servers, changing from Qmail to Postfix along the
11 11
 way. These settings have been necessary so far:
12 12
 
13 13
 
14
-    /etc/postfix/main.cf:   home_mailbox = Maildir/   recipient_delimiter = -
15
-
16
-
14
+    /etc/postfix/main.cf:
15
+       home_mailbox = Maildir/
16
+       recipient_delimiter = -
17 17
 
18 18
 The former sets up mail delivery for Maildirs (obviously), and the
19 19
 latter replaces the Postfix-style address separator of "+" (the plus
@@ -26,16 +26,19 @@ procmail will route these messages for me. First I uncommented the
26 26
 correct mailbox\_command:
27 27
 
28 28
 
29
-    /etc/postfix/main.cf:    mailbox_command = /usr/bin/procmail -a "$EXTENSION"
30
-
29
+    /etc/postfix/main.cf:
30
+        mailbox_command = /usr/bin/procmail -a "$EXTENSION"
31 31
 
32 32
 
33 33
 Then I updated my .procmailrc to handle extensions:
34 34
 
35 35
 
36
-    MAILDIR=$HOME/Maildir/EXTENSION=$1:0* EXTENSION ?? ^^sample^^$MAILDIR.SampleFolders/
37
-
36
+    MAILDIR=$HOME/Maildir/
37
+    EXTENSION=$1