1.3 Automating patch creation
In this section we will discuss the script
'patchcreate'. It will generate a patch, which subsequently is embedded in a shell script using a shell here document. Running the shell script will apply the patch.
The unmodified script patches the file in the current directory, just like we did manually earlier on. After a test confirms the proper working, only a simple edit is needed to have the patch script work on the real actual file. In our case "/etc/mail/aliases".
For the impatient we will look at the generated patch script first.
Code:
$ cat -n _patcher
1 # ----------------------------------------------------------
2 echo
3 echo --- patch script for: aliases --- BEGIN
4
5 # --- edit the following line if needed
6 FILE=./aliases
7
8 patch -b -p0 ${FILE} <<END_OF_PATCH
9 --- ORIG/aliases Sat Jan 23 02:16:03 2010
10 +++ NEW/aliases Sat Jan 23 02:17:39 2010
11 @@ -64,9 +64,9 @@
12 sshd: /dev/null
13
14 # Well-known aliases -- these should be filled in!
15 -# root:
16 -# manager:
17 -# dumper:
18 +root: j65nko
19 +manager: j65nko
20 +dumper: j65nko
21
22 # RFC 2142: NETWORK OPERATIONS MAILBOX NAMES
23 abuse: root
24 @@ -74,11 +74,11 @@
25 security: root
26
27 # RFC 2142: SUPPORT MAILBOX NAMES FOR SPECIFIC INTERNET SERVICES
28 -# hostmaster: root
29 -# usenet: root
30 -# news: usenet
31 -# webmaster: root
32 -# ftp: root
33 +hostmaster: root
34 +usenet: root
35 +news: usenet
36 +webmaster: root
37 +ftp: root
38
39 # uncomment this for msgs:
40 # msgs: "|/usr/bin/msgs -s"
41 END_OF_PATCH
42
43 echo --- patch script for: aliases --- END
The FILE variable in line 6 defines the target of the patch. By changing it to
'/etc/mail/aliases' this file will be patched.
The patch command is on line 8, the end marker END_OF_PATCH of the here document at line 41.
An attentive reader may wonder why the typic shell shebang "#!/bin/sh" line is missing. The patch script is meant as component or a building block of a larger script. I use these kind of self-contained patch scripts in
'install.site' scripts used to customize an OpenBSD install. For details see
Customizing the install process.
Of course you can run it stand-alone with a simple
sh _patcher, e.g. as a post-install script for a FreeBSD or NetBSD system.
1.4 Using 'patchcreate' to create a 'sshd_config' patch
We will now see how the script automates the creation of a patch for the
'/etc/sshd_config' file. First we will extract this ssh configuration file from a
'etc46.tgz' file.
Code:
$ tar tvzf /home/j65nko/Snapshots/etc46.tgz | grep ssh
drwx------ 2 root wheel 0 Jan 19 23:44 ./etc/skel/.ssh
-rw------- 1 root wheel 0 Jan 19 23:44 ./etc/skel/.ssh/authorized_keys
drwxr-xr-x 2 root wheel 0 Jan 19 23:44 ./etc/ssh
-rw-r--r-- 1 root wheel 1555 Jan 19 23:44 ./etc/ssh/ssh_config
-rw-r--r-- 1 root wheel 2524 Jan 19 23:44 ./etc/ssh/sshd_config
$ tar xvzf /home/j65nko/Snapshots.old/etc46.tgz ./etc/ssh/sshd_config
./etc/ssh/sshd_config
$ ls -l etc/ssh/sshd_config
-rw-r--r-- 1 j65nko j65nko 2524 Jan 19 23:44 etc/ssh/sshd_config
$ cp etc/ssh/sshd_config .
$ ls -l sshd_config
-rw-r--r-- 1 j65nko wheel 2524 Jan 24 05:15 sshd_config
Having the file in our current directory, we can run
'patchcreate'
Code:
$ patchcreate sshd_config
Ok, found file sshd_config
Saving copy of sshd_config in directory ORIG
-rw-r--r-- 1 j65nko j65nko 2524 Jan 24 05:16 ORIG/sshd_config
Copy original sshd_config to directory NEW for editing
-rw-r--r-- 1 j65nko j65nko 2524 Jan 24 05:16 NEW/sshd_config
Press Enter to edit sshd_config
[snip vi session]
Copying original ORIG/sshd_config back to current dir to test <_patcher>
-rw-r--r-- 1 j65nko j65nko 630 Jan 24 05:20 _patcher
-rw-r--r-- 1 j65nko j65nko 2524 Jan 24 05:16 sshd_config
The generated patch script:
Code:
$ cat -n _patcher
1 # ----------------------------------------------------------
2 echo
3 echo --- patch script for: sshd_config --- BEGIN
4
5 # --- edit the following line if needed
6 FILE=./sshd_config
7
8 patch -b -p0 ${FILE} <<END_OF_PATCH
9 --- ORIG/sshd_config Sun Jan 24 05:16:30 2010
10 +++ NEW/sshd_config Sun Jan 24 05:20:26 2010
11 @@ -9,9 +9,11 @@
12 # default value.
13
14 #Port 22
15 -#AddressFamily any
16 -#ListenAddress 0.0.0.0
17 +AddressFamily inet
18 +ListenAddress 192.168.222.244
19 #ListenAddress ::
20 +
21 +AllowUsers j65nko robert
22
23 # The default requires explicit activation of protocol 1
24 #Protocol 2
25 END_OF_PATCH
26
27 echo --- patch script for: sshd_config --- END
Executing the script:
Code:
$ sh _patcher
--- patch script for: sshd_config --- BEGIN
Hmm... Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- ORIG/sshd_config Sun Jan 24 05:16:30 2010
|+++ NEW/sshd_config Sun Jan 24 05:20:26 2010
--------------------------
Patching file ./sshd_config using Plan A...
Hunk #1 succeeded at 9.
done
--- patch script for: sshd_config --- END
Code:
$ cat -n sshd_config
[snip]
9 # default value
10
11 #Port 22
12 AddressFamily inet
13 ListenAddress 192.168.222.244
14 #ListenAddress ::
15
16 AllowUsers j65nko robert
[snip]
17