7 Patch Command Examples to Apply Diff Patch Files in Linux

When there is a security fix available for a particular software, we typically do a binary upgrade using the package management tools like yum or apt-get.
But, there might be situation where you have installed a software by compiling it from the source code.
In those situation, how do you apply the security fix to the software?
The answer is to download the security patch and apply it to the original source code and re-compile the software.
This tutorial explains how to create a patch file using diff, and apply it using patch command.

A patch file is a text file which contains the differences between two versions of the same file (or same source-tree). Patch file is created by using diff command.

1. Create a Patch File using diff

To understand this, let us create a small C program named hello.c
#include <stdio.h> 

int main() {
printf("Hello World\n");
}
Now, copy the hello.c to hello_new.c
$ cp hello.c hello_new.c
Edit the hello_new.c as shown below to make some small changes:
#include <stdio.h>

int main(int argc, char *argv[]) {
printf("Hello World\n");
return 0;
}
Finally, create the patch file using diff command as shown below:
$ diff -u hello.c hello_new.c > hello.patch
The above command will create a patch file named “hello.patch”.
--- hello.c 2014-10-07 18:17:49.000000000 +0530
+++ hello_new.c 2014-10-07 18:17:54.000000000 +0530
@@ -1,5 +1,6 @@
 #include <stdio.h>
 
-int main() {
+int main(int argc, char *argv[]) {
  printf("Hello World\n");
+ return 0;
 }

2. Apply Patch File using Patch Command

The “patch” command takes a patch file as input and apply the differences to one or more original file(s), producing patched versions.
patch -p[num] < patchfile
patch [options] originalfile patchfile 
Use the patch command as shown below to apply the hello.patch to the original hello.c source code.
$ patch < hello.patch
patching file hello.c
The hello.patch file contains the name of the file to be patched. Once the file is patched, both hello.c and hello_new.c will have the content.

3. Create a Patch From a Source Tree

The above example was so simple that it works only with one file. We will see how to create and apply patch for a complete source tree by taking “openvpn” source code as example.
I’ve downloaded 2 version of openvpn, openvpn-2.3.2 and openvpn-2.3.4.
tar -xvzf openvpn-2.3.2.tar.gz

tar -xvzf openvpn-2.3.4.tar.gz
Now we will create the patch using the following command.
diff -Naur /usr/src/openvpn-2.3.2 /usr/src/openvpn-2.3.4 > openvpn.patch
The above command will operate recursively and find the differences, and place those differences in the patch file.

4. Apply Patch File to a Source Code Tree

The following patch commands can be used to apply the patch to source tree.
# patch -p3 < /root/openvpn.patch
patching file openvpn-2.3.2/aclocal.m4
patching file openvpn-2.3.2/build/Makefile.in
patching file openvpn-2.3.2/build/msvc/Makefile.in
...
Please note that we are executing the command from /usr/src/. The patch file contains all the filenames in absolute path format( from root ). So when we execute from /usr/src, without the “-p” option, it will not work properly.
-p3 tells the patch command to skip 3 leading slashes from the filenames present in the patch file. In our case, the filename in patch file is “/usr/src/openvpn-2.3.2/aclocal.m4″, since you have given “-p3″, 3 leading slashes, i.e. until /usr/src/ is ignored.

5. Take a Backup before Applying the Patch using -b

You can take a backup of the original file before applying the patch command using the -b option as shown below.
$ patch -b < hello.patch
patching file hello.c
Now you will have a file name “hello.c.orig”, which is the backup of the original hello.c.
You can also use -V to decide the backup filename format as shown below. Now you will have a file name “hello.c.~1~”.
$ patch -b -V numbered < hello.patch
patching file hello.c

6. Validate the Patch without Applying (Dry-run Patch File)

You can dry run the patch command to see if you are getting any errors, without patching the file using –dry-run option as shown below.
$ patch --dry-run < hello.patch
patching file hello.c
You can see that hello.c is not modified at all.

7. Reverse a Patch that is Already Applied (Undo a Patch)

You can use the -R option to reverse a patch which is applied already.
$ patch < hello.patch
patching file hello.c

$ ls -l hello.c
-rw-r--r-- 1 lakshmanan users  94 2014-10-07 20:05 hello.c

$ patch -R < hello.patch
patching file hello.c

$ ls -l hello.c
-rw-r--r-- 1 lakshmanan users  62 2014-10-07 20:04 hello.c
You can notice from the filesize, that the patch, which is applied already is reversed when we used the -R option.

12 CUPS lpadmin Command Examples to Setup Printers on Linux

CUPS stands for Common UNIX Printing System.
lpadmin is a command line tool used to configure printer and class queues provided by CUPS.
A system running CUPS is a host that can accept print jobs from client computers, process them, and send them to the appropriate printer. It can also be used to set the server default printer or class.
This tutorial explains how to add a new printer, setup printer options, and manage printers on Linux environment using lpadmin command examples.

1. Adding a New Printer

To add a new network printer with the name “HPLaserJetP3015” use the lpadmin command with -p option as shown below:
# lpadmin -p HPLaserJetP3015 -v socket://19.86.82.172 -P 
/usr/share/cups/model/HP/LaserJet_P3005-Postscript.ppd

# lpstat -v
device for HPLaserJetP3015: socket://19.86.82.172
To verify if the printer is configured currently, you can use the command as shown in the below example:
# lpstat -p HPLaserJetP3015 -l
printer HPLaserJetP3015 is idle.  enabled since Sun Jan 11 16:11:41 2015

2. PPD and Log Files

In the above example, PPD files (is also known as PostScript Printer Description) are created by vendors to describe the entire set of features and capabilities available for their PostScript printers and they are usually located under /usr/share/cups/model/ directory.
If you have any problems with configuring the printer, then please verify the logs at the below location for any error messages. This location may change depending upon the different distribution of Linux.
# ls -l /var/log/cups/*
-rw-r--r-- 1 root lp  6851 Jan 11 16:19 /var/log/cups/access_log
-rw-r--r-- 1 root lp 13207 Jan 11 16:19 /var/log/cups/error_log

3. Configure Printer on Parallel Port

In order to configure the printer on the parallel port (/dev/lp0), use the lpadmin command as shown in this example:
# lpadmin -p HPDESKJET882 -v parallel:/dev/lp0 -m 
/usr/share/cups/model/HP/DeskJet_882C-cdj880.ppd

4. View All Available Ports for Printer Setup

Also to list all the available ports or interfaces available to configure the printer can be displayed using lpinfo command,
# lpinfo -v
network socket
direct hp
network http
network ipp
network lpd
direct parallel:/dev/lp0
direct scsi
network tpvmgp
network tpvmlp
network smb

5. Multiple Printer Classes

CUPS always checks for an available printer in the order in which printers were added to a class.
You can add 1 or more printers to a class and when one of the printers becomes unavailable, the other printer defined in the class handles the print job requests.
It is not mandatory to add printers in classes. One printer class can themselves be members of other classes so it is possible for you to define printer classes for high availability for printing.
Once you configure the printer class, you can print to the printer class in the same way that you point to a single printer.
For example, If you have 2 Laserjet printers and 2 deskjet printers. you can create a class known as “Class-Laserjet”consisting 2 Laserjet Printers, and create another class known as “Class-Deskjet” printers and then create another class containing these 2 classes.
This way even if both the laserjet or deskjet printers go down, the other class serves the printing jobs.

6. Add Printer to a Class

To add a printer to the class, use the below command.
# lpadmin -h localhost -p HPLaserJetP3015 -c myclass
To verify whether the printers are in printer class:
# lpstat -c myclass
members of class myclass:
        HPLaserJetP3015

7. Remove Printer from a Class

To remove a printer from the class you can use the lpadmin command as shown in the below example:
in this example, myclass has two printers:
# lpstat -c myclass
members of class myclass:
        HPLaserJetP3015
        HPDESKJET882
Remove the HPDESKJET882 printer from myclass as shown below:
# lpadmin -p HPDESKJET882 -r myclass
Once you remove it, you’ll see only the HP Laser Jet Printer:
# lpstat -c myclass
members of class myclass:
        HPLaserJetP3015

8. Remove a Whole Printer Class

Using the -x option, you can remove the class. as shown below.
# lpstat -c myclass
members of class myclass:
        HPLaserJetP3015

# lpadmin -x myclass

# lpstat -c myclass
lpstat: Unknown destination "myclass"!
Please note that the printer configuration still exists even if you removed the class.

9. Change Printing Option

To change the printing options for the printer, you can execute the below commands.
List all the available options for the printer using lpoptions command as shown below.
In this example, you will see all the activated options is prefixed with asterisk symbol. If there is no asterisk is present, then it uses default settings.
# lpoptions -p HPLaserJetP3015 -l

PageSize/Page Size: *A4 Letter 11x17 A3 A5 B5 Env10 EnvC5 EnvDL EnvISOB5 
EnvMonarch Executive Legal
PageRegion/PageRegion: A4 Letter 11x17 A3 A5 B5 Env10 EnvC5 EnvDL EnvISOB5 
EnvMonarch Executive Legal
Resolution/Resolution: 150x150dpi 300x300dpi *600x600dpi 1200x1200dpi
InputSlot/Media Source: *Default Tray1 Tray2 Tray3 Manual
Duplex/Double-Sided Printing: DuplexNoTumble DuplexTumble *None

10. Change Printer Resolution

To change the resolution of the printer to 300x300dpi, you can use the lpadmin command as shown below:
# lpadmin -p HPLaserJetP3015 -o Resolution=300x300dpi

# lpoptions -p HPLaserJetP3015 -l
Here are the other options you can set for any printer using lpadmin with –o option as described in above example,
  • job-k-limit=value – Sets the kilobyte limit for per-user quotas. The value is an integer number of kilobytes.
  • job-page-limit=value – Sets the page limit for per-user quotas. The value is the integer number of pages that can be printed; double-sided pages are counted as two pages.
  • job-quota-period=value – Sets the accounting period for per-user quotas. The value is an integer number of seconds.
  • job-sheets-default=banner – Sets the default banner pages to use for print jobs.
  • name=value – Sets a PPD option for the printer. PPD options can be listed using the -l option with the lpoptions(1) command.
  • name-default=value – Sets a default server-side option for the printer.
  • port-monitor=name – The specified port monitor must be listed in the printer’s PPD file.
  • printer-error-policy=name – Sets the error policy to be used when the printer backend is unable to send the job to the printer.
  • printer-is-shared=true/false – Sets the printer to shared/published or unshared/unpublished.
  • printer-op-policy=name – Sets the IPP operation policy associated with the printer. The name must be defined in the cupsd.conf in a Policy section. The default operation policy is “default”.

11. Remove Printer from Configuration File

To remove a CUPS printer from the printer configuration file, you can use the -x option as shown below:
# lpstat -v
device for HPLaserJetP3015: socket://19.86.82.172

# lpadmin -x HPLaserJetP3015

# lpstat -v
lpstat: No destinations added.

12. Allow/Deny User or Groups to Configure Printer Options

You can allow the individual users or group to configure the printer options using lpadmin commands.
The following command will allow the user karthik to configure the printer option on HPLaserJetP3015 printer:
# lpadmin -p HPLaserJetP3015 -u allow:karthik
You can also block the user from changing the settings/options or configure printer using the below command.
The following command will deny the user karthik to configure the printer option on HPLaserJetP3015 printer:
# lpadmin -p HPLaserJetP3015 -u deny:karthik
If there is a group that needs to be allowed access, you can use the group name preceding with @ symbol. Multiple user names or groups can be given separated by commas.
For example, the following will allow users from sysadmin group to configure printer options.
# lpadmin -p HPLaserJetP3015 -u allow:@sysadmin
The following will deny users from developer group to configure printer options.
# lpadmin -p HPLaserJetP3015 -u deny:@developer

7 Steps to Build a RPM Package from Source on CentOS / RedHat

Sometimes you might have access to an open source application source code but might not have the RPM file to install it on your system.
In that situation, you can either compile the source code and install the application from source code, or build a RPM file from source code yourself, and use the RPM file to install the application.
There might also be a situation where you want to build a custom RPM package for the application that you developed.
This tutorial explains how to build a RPM package from the source code.

In order to build RPMs, you will need source code, which usually means a compressed tar file that also includes the SPEC file.
The SPEC file typically contains instructions on how to build RPM, what files are part of package and where it should be installed.
The RPM performs the following tasks during the build process.
  1. Executes the commands and macros mentioned in the prep section of the spec file.
  2. Checks the content of the file list
  3. Executes the commands and macros in the build section of the spec file. Macros from the file list is also executed at this step.
  4. Creates the binary package file
  5. Creates the source package file
Once the RPM executes the above steps, it creates the binary package file and source package file.
The binary package file consists of all source files along with any additional information to install or uninstall the package.
It is usually enabled with all the options for installing the package that are platform specific. Binary package file contain complete applications or libraries of functions compiled for a particular architecture. The source package usually consists of the original compressed tar file, spec file and the patches which are required to create the binary package file.
Let us see how to create a simple source and BIN RPM packages using a tar file.
If you are new to rpm package, you may first want to understand how to use rpm command to install, upgrade and remove packages on CentOS or RedHat.

1. Install rpm-build Package

To build an rpm file based on the spec file that we just created, we need to use rpmbuild command.
rpmbuild command is part of rpm-build package. Install it as shown show below.
# yum install rpm-build
rpm-build is dependent on the following package. If you don’t have these installed already, yum will automatically install these dependencies for you.
elfutils-libelf
rpm
rpm-libs
rpm-python

2. RPM Build Directories

rpm-build will automatically create the following directory structures that will be used during the RPM build.
# ls -lF /root/rpmbuild/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 BUILD/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 BUILDROOT/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 RPMS/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 SOURCES/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 SPECS/
drwxr-xr-x. 2 root root 4096 Feb  4 12:21 SRPMS/
Note: The above directory structure is for both CentOS and RedHat when using rpmbuild package. You can also use /usr/src/redhat directory, but you need to change the topdir parameter accordingly during the rpm build. If you are doing this on SuSE Enterprise Linux, use /usr/src/packages directory.
If you want to use your own directory structure instead of the /root/rpmbuild, you can use one of the following option:
  • Use –buildroot option and specify the custom directory during the rpmbuild
  • Specify the topdir parameter in the rpmrc file or rpmmacros file.

3. Download Source Tar File

Next, download the source tar file for the package that you want to build and save it under SOURCES directory.
For this example, I’ve used the source code of icecase open source application, which is a server software for streaming multi-media. But, the steps are exactly the same for building RPM for any other application. You just have to download the corresponding source code for the RPM that you are trying to build.
# cd /root/rpmbuild/SOURCES/

# wget http://downloads.xiph.org/releases/icecast/icecast-2.3.3.tar.gz

# ls -l
-rw-r--r--. 1 root root 1161774 Jun 11  2012 icecast-2.3.3.tar.gz

4. Create the SPEC File

In this step, we direct RPM in the build process by creating a spec file. The spec file usually consists of the following eight different sections:
  1. Preamble – The preamble section contains information about the package being built and define any dependencies to the package. In general, the preamble consists of entries, one per line, that start with a tag followed by a colon, and then some information.
  2. %prep – In this section, we prepare the software for building process. Any previous builds are removed during this process and the source file(.tar) file is expanded, etc.
  3. One more key thing is to understand there are pre-defined macros available to perform various shortcut options to build rpm. You may be using this macros when you try to build any complex packages. In the below example, I have used a macro called %setup which removes any previous builds, untar the source files and changes the ownership of the files. You can also use sh scripts under %prep section to perform this action but %setup macro simplifies the process by using predefined sh scripts.
  4. %description – the description section usually contains description about the package.
  5. %build – This is the section that is responsible for performing the build. Usually the %build section is an sh script.
  6. %install – the % install section is also executed as sh script just like %prep and %build. This is the step that is used for the installation.
  7. %files – This section contains the list of files that are part of the package. If the files are not part of the %files section then it wont be available in the package. Complete paths are required and you can set the attributes and ownership of the files in this section.
  8. %clean – This section instructs the RPM to clean up any files that are not part of the application’s normal build area. Lets say for an example, If the application creates a temporary directory structure in /tmp/ as part of its build, it will not be removed. By adding a sh script in %clean section, the directory can be removed after the build process is completed.
Here is the SPEC file that I created for the icecast application to build an RPM file.
# cat /root/rpmbuild/SPECS/icecast.spec
Name:           icecast
Version:        2.3.3
Release:        0
Summary:        Xiph Streaming media server that supports multiple formats.
Group:          Applications/Multimedia
License:        GPL
URL:            http://www.icecast.org/
Vendor:         Xiph.org Foundation team@icecast.org
Source:         http://downloads.us.xiph.org/releases/icecast/%{name}-%{version}.tar.gz
Prefix:         %{_prefix}
Packager:  Karthik
BuildRoot:      %{_tmppath}/%{name}-root

%description
Icecast is a streaming media server which currently supports Ogg Vorbis
and MP3 audio streams. It can be used to create an Internet radio
station or a privately running jukebox and many things in between.
It is very versatile in that new formats can be added relatively
easily and supports open standards for commuincation and interaction.

%prep
%setup -q -n %{name}-%{version}

%build
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix} --mandir=%{_mandir} --sysconfdir=/etc

make

%install
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT

make DESTDIR=$RPM_BUILD_ROOT install
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/%{name}

%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root)
%doc README AUTHORS COPYING NEWS TODO ChangeLog
%doc doc/*.html
%doc doc/*.jpg
%doc doc/*.css
%config(noreplace) /etc/%{name}.xml
%{_bindir}/icecast
%{_prefix}/share/icecast/*

%changelog

In this file, under % prep section you may noticed the macro “%setup -q -n %{name}-%{version}”. This macro executes the following command in the background.

cd /usr/src/redhat/BUILD
rm -rf icecast
gzip -dc /usr/src/redhat/SOURCES/icecast-2.3.3.tar.gz | tar -xvvf -
if [ $? -ne 0 ]; then
  exit $?
fi
cd icecast
cd /usr/src/redhat/BUILD/icecast
chown -R root.root .
chmod -R a+rX,g-w,o-w .
In %build section, you will see the CFLAGS with configure options that defines the options that can be using during RPM installation and the prefix option , mandatory directory to be present for the installation and sysconfig directory under which the system files needs to be copied over.
Below that line, you will see the make utility which determines the list of files needs to be compiled and compiles them appropriately.
In % install section, the line below the %install that says “make install” is used to take the binaries compiled from the previous step and installs or copies them to the appropriate locations so they can be accessed.

5. Create the RPM File using rpmbuild

Once the SPEC file is ready, you can start building your rpm with rpm –b command. The –b option is used to perform all the phases of the build process. If you see any errors during this phase, then you need to resolve it before re-attempting again. The errors will be usually of library dependencies and you can download and install it as necessary.
# cd /root/rpmbuild/SPECS

# rpmbuild -ba icecast.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.Kohe4t
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd /root/rpmbuild/BUILD
+ rm -rf icecast-2.3.3
+ /usr/bin/gzip -dc /root/rpmbuild/SOURCES/icecast-2.3.3.tar.gz
+ /bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd icecast-2.3.3
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.ynm7H7
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd icecast-2.3.3
+ CFLAGS='-O2 -g'
+ ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether to enable maintainer-specific portions of Makefiles... no
checking for gcc... gcc
..
..
..
Wrote: /root/rpmbuild/SRPMS/icecast-2.3.3-0.src.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/icecast-2.3.3-0.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.dzahrv
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd icecast-2.3.3
+ '[' /root/rpmbuild/BUILDROOT/icecast-2.3.3-0.x86_64 '!=' / ']'
+ rm -rf /root/rpmbuild/BUILDROOT/icecast-2.3.3-0.x86_64
+ exit 0
Note: If you are using SuSE Linux, if rpmbuild is not available, try using “rpm -ba” to build the rpm package.
During the above rpmbuild install, you might notice the following error messages:
Error 1: XSLT configuration could not be found
checking for xslt-config... no
configure: error: XSLT configuration could not be found
error: Bad exit status from /var/tmp/rpm-tmp.8J0ynG (%build)
RPM build errors:
    Bad exit status from /var/tmp/rpm-tmp.8J0ynG (%build)
Solution 1: Install libxstl-devel
For the xslt-config, you need to install libxstl-devel package as shown below.
yum install libxstl-devel
This will also install the following dependencies:
  • libgcrypt
  • libgcrypt-devel
  • libgpg-error-devel
Error 2: libvorbis Error
checking for libvorbis... configure: error: must have Ogg Vorbis v1.0 or above installed
error: Bad exit status from /var/tmp/rpm-tmp.m4Gk3f (%build)
Solution 2: Install libvorbis-devel
For the Ogg Vorbis v1.0, install the libvorbis-devel package as shown below:
yum install libvorbis-devel
This will also install the following dependencies:
  • libogg
  • libogg-devel
  • libvorbis

6. Verify the Source and Binary RPM Files

Once the rpmbuild is completed, you can verify the source rpm and binary rpm is created in the below directories.
# ls -l /root/rpmbuild/SRPMS/
-rw-r--r-- 1 root root 1162483 Aug 25 15:46 icecast-2.3.3-0.src.rpm

# ls -l /root/rpmbuild/RPMS/x86_64/
-rw-r--r--. 1 root root 349181 Feb  4 12:54 icecast-2.3.3-0.x86_64.rpm

7. Install the RPM File to Verify

As a final step, you can install the binary rpm to verify that it installs successfully and all the dependencies are resolved.
# rpm -ivvh /root/rpmbuild/RPMS/x86_64/icecast-2.3.3-0.x86_64.rpm
D: ============== /root/rpmbuild/RPMS/x86_64/icecast-2.3.3-0.x86_64.rpm
D: loading keyring from pubkeys in /var/lib/rpm/pubkeys/*.key
D: couldn't find any keys in /var/lib/rpm/pubkeys/*.key
D: loading keyring from rpmdb
D: opening  db environment /var/lib/rpm cdb:mpool:joinenv
D: opening  db index       /var/lib/rpm/Packages rdonly mode=0x0
D:  read h#     210 Header sanity check: OK
D: added key gpg-pubkey-c105b9de-4e0fd3a3 to keyring
D: Using legacy gpg-pubkey(s) from rpmdb
D: Expected size:       349181 = lead(96)+sigs(180)+pad(4)+data(348901)
D:   Actual size:       349181
D: ========== relocations
D:      added binary package [0]
D: found 0 source and 1 binary packages
D: ========== +++ icecast-2.3.3-0 x86_64/linux 0x2
..
..
After the above installation, you can verify that your custom created rpm file was installed successfully as shown below.
# rpm -qa icecast
icecast-2.3.3-0.x86_64