CentOS vs Ubuntu

CentOS and Ubuntu both are Linux distros. Below are some major differences between them.

1. CentOS is based on RHEL (Red Hat Enterprise Linux), while Ubuntu has its roots in Debian.

2. On an Ubuntu system the root password is randomly generated which is not known to the administrator. You will have to use ‘sudo command’ to get root-privileges.

3. Repositories of Ubuntu contain fresher packages than CentOS, it tends to be less conservative than CentOS, whereas CentOS packages focuses only on security patches.

4. CentOS uses YUM package manager with RPM packages whereas Ubuntu uses apt with DEB packages.

5. Ubuntu cleanly upgrades between major versions, CentOS is not so good to do that (needs a reinstall often). [via: Liz Quilty]

Know some more differences? Please put them in the comment box, I will add them in the post.

Recommended reading: “CentOS vs Ubuntu

Protect your web server with SSL certificate

If you are a system administrator who is running a web server then you may want to protect it so that no one can hack into it and misuse the important data. Networks by themseleves are not secure enough, you will have to find other ways to make your server more secure. Here in this article we will examine ways in which you can help guard your important data.

Nowadays all the E-commerce applications (banking and online shopping for example) are encrypted using either SSL or TLS specifications. SSL stands for Secure Socket Layer and TLS means Transport Layer Security. Actually TLS is based on SSL 3.0 hence they are very similar in nature. For secure web connections first of all the SSL connection is established and then the HTTP communication is “tunneled” through it.

Note: Since name-based virtual hosting occurs at HTTP layer and as I said that SSL gets established before any HTTP communication, it causes problems with name-based virtual hosting. In short name-based virtual hosting does not work easily with SSL.

To verify the identities and for establishing session parameters along with a session key, asymmetric cryptography is used during connection establishment between an SSL client and SSL server. Then a symmetric encryption algorithm (DES or RC4) is used with the negotiated key to encrypt all the data which is being transmitted during the session. This means that asymmetric encryption (during the handshaking phase) provides safe communication whereas symmetric encryption works on the session data (for faster and more practical use).

For the client to verify the identity of the server, the server must have a private key and a certificate (which contains the public key and information about the server). The client also contains a public key, which it uses to verify the certificate of the server (matches public key of client with the public key of server which is mentioned in the certificate).

Certificates are generally digitally signed by third-party certificate authorities (CA) which have verified the identities of the requester and the validity of the requests to have the certificate signed. In most of the cases CA is a company which contacts with vendors of web browsers to have its own certificate installed and trusted by default client installations. Then certificate authorities earn by charging server operators for its services.

There are many commercial certificate authorities which differ in features, price but as people say “Price is not always an indication of quality“. VeriSign, InstantSSL and Thawte are some popular CAs.

Instead of going for certificate authorities you can create self-signed certificates, but those should be used only for testing if the number of people who will be accessing your server are less.

Another option is to run your own certificate authority but we are not going to cover that in this article.

Generating SSL keys

Delete the old key and certificate

 rm /etc/pki/tls/private/localhost.key
 rm /etc/pki/tls/certs/localhost.crt

Create your own key

 cd /etc/pki/tls/certs
 make genkey
umask 77 ; \
	/usr/bin/openssl genrsa -aes128 2048 > /etc/pki/tls/private/localhost.key
Generating RSA private key, 2048 bit long modulus
e is 65537 (0x10001)
Enter pass phrase:
Verifying - Enter pass phrase:

Creating self-signed certificate

 make testcert
umask 77 ; \
	/usr/bin/openssl req -utf8 -new -key /etc/pki/tls/private/localhost.key -x509 -days 365 -out /etc/pki/tls/certs/localhost.crt -set_serial 0
Enter pass phrase for /etc/pki/tls/private/localhost.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [XX]:IN
State or Province Name (full name) []:Rajasthan
Locality Name (eg, city) [Default City]:Jaipur
Organization Name (eg, company) [Default Company Ltd]:Linux Stall
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:www.linuxstall.com
Email Address []:[email protected]

This is how it looked on my server:

ssl certificate linux

This will create a file localhost.crt in /etc/pki/tls/certs/. Now open the file ssl.conf which is located at /etc/httpd/conf.d/ and edit it with the content given below:

SSLCertificateFile /etc/pki/tls/certs/localhost.crt

Restart your web server

 service httpd restart

Now you’re done. Open your browser and use httpd in front of each URL instead of http. You can ignore the certification validation message which your web browser may prompt.

Removing password encryption on private key

You will notice that whenever you restart your server it asks for certificate password. This is for security purpose so that no one can break into your server and steal your private key. You are safe in the knowledge that the private key is a jumbled mess. The cracker will not be able to make use of it but without such protection, a cracker could get your private key and easily masquerade as you, appearing to be legitimate in all cases.

If you are willing to accept the risk and cannot stand having to enter the password every time your server starts, you can remove the password encryption on private key by entering the command given below:

 cd /etc/pki/tls/private
 /usr/bin/openssl rsa -in localhost.key -out localhost.key
Enter pass phrase for localhost.key: *******

Now you will be able to restart the server without entering a pass phrase.


Following tips will help if you are having problems with your SSL certificate:

  • You should know that only one SSL certificate can be used for one IP. If you want to add more than one web site (SSL enabled) to your server, you must bind another IP address to the network interface.
  • Don’t block port 443 on your server. All https request come on port 443. If this port is blocked then you will not be able to get secure pages.
  • The certificate expires after one year. Don’t forget to renew your certificate with your CA before expiration.
  • mod_ssl package should be installed on your server. If it is not then you will not be able to serve any SSL-enabled traffic.

Reference in Perl

Reference in Perl


References are the most important feature of Perl which helps in creating complex data structures. This tutorial is aimed for a complete newbie in Perl. We will start with What references are? What are their benefits? How to use them? Their syntax and examples. Wasting no more time just dive into it!

What is a reference?

If you are familiar with C language then you can consider a reference as a pointer (not literally, because there are no pointers in Perl like C language). A variable can store a reference to some variable/value/array or hash.

Reference to a variable

+----------\\       +----------\\
|     x     >      |     y     >
+----------/       +----------/
      |                  |
+-----------+      +-----------+
|     O-----+----->|   54321   |
+-----------+      +-----------+

Here the variable $x has a reference which points to the value of variable $y (which is 54321).

To create a reference to a value we use the backslash operator (\\). For example:

use warnings;
my $y = 54321;
my $x = \$y;     # $x is a reference to the value of variable $y.
print "$y\n";    # 54321
print "$x\n";    # will print the address where the value 54321 is stored like SCALAR(0x13dcac0)
print "${$x}\n"; # 54321 (dereferencing a scalar variable)
print "$$x";     # 54321 (same as above)

Reference to an array

@a		@{$aref}		# An array
reverse @a	reverse @{$aref}	# Reverse the array
$a[3]		${$aref}[3]		# An element of the array
$a[3] = 17;	${$aref}[3] = 17	# Assigning an element
|     x     >      +----------\\
+----------/       |     y     >
      |            +----------/
+-----------+            |
|     O-----+----->+###########+
+-----------+      +"""""""""""+
                   |    Foo    |
+----------\\       +-----------+
|     z     >      |    ABC    |
+----------/       +-----------+
      |            |    BUZ    |
+-----------+      +-----------+
|     O-----+----->|    VIZ    |
+-----------+      +-----------+

Here the refernce $x is pointing to the array @y, reference $z is pointing to the 4th element of array @y i.e. $y[4].

use warnings;
my @y = ("Foo", "ABC", "BUZ", "VIZ");
my $x = \\@y;         # creating reference of an array
print "$x\\n";        # ARRAY(0x189faf0)
print "@y\\n";        # Foo ABC BUZ VIZ
print "@{$x}\\n";     # Foo ABC BUZ VIZ (dereferencing)
print "@$x\\n";       # Foo ABC BUZ VIZ (You may omit curly brace here)
print "${$x}[1]\\n";  # ABC  (Accessing element at position 1 of array using reference variable)
print "$$x[1]\\n";    # ABC  (Another way of doing the same)
print "$x->[1]";     # ABC  (You can use -> operator too)

Reference to a hash

You can make a reference to hash in the similar way as you created from scalar variables and array.

%h		%{$href}	      # A hash
keys %h		keys %{$href}	      # Get the keys from the hash
$h{'red'}	${$href}{'red'}	      # An element of the hash
$h{'red'} = 17	${$href}{'red'} = 17  # Assigning an element

Loop over an array or hash using reference

If you want to loop over an array then

for my $element (@array) {

If you want to loop over an array using reference then

for my $element (@{$aref}) {

If you want to loop over a hash then

for my $key (keys %hash) {
          print "$key -> $hash{$key}\\n";

If you want to loop over a hash using reference then

for my $key (keys %{$href}) {
          print "$key => ${$href}{$key}\\n";


${$aref}[3] is too hard to read, so you can write $aref->[3] instead.
${$href}{red} is too hard to read, so you can write $href->{red} instead.

If $aref holds a reference to an array, then $aref->[3] is the fourth element of the array. Don’t confuse this with $aref[3], which is the fourth element of a totally different array, one deceptively named @aref. $aref and @aref are unrelated the same way that $item and @item are.

Similarly, $href->{‘red’} is part of the hash referred to by the scalar variable $href, perhaps even one with no name. $href{‘red’} is part of the deceptively named %href hash.

It’s easy to forget to leave out the ->, and if you do, you’ll get bizarre results when your program gets array and hash elements out of totally unexpected hashes and arrays that weren’t the ones you wanted to use.

With the help of references you can construct complex datastructures as:

1) A reference to a list containing references to several lists

|     x     >                      +-->+###########+
+----------/                       |   +"""""""""""+
      |                            |   |    Foo    |
+-----------+                      |   +-----------+
|     O-----+----->+###########+   |   |    ABC    |
+-----------+      +"""""""""""+   |   +-----------+
                   |     O-----+---+
                   |     O-----+------>+###########+
                   +-----------+       +"""""""""""+
                   |     O-----+---+   |    BUZ    |
                   +-----------+   |   +-----------+
                                   |   |    VIZ    |
                                   |   +-----------+
                                       |    BUZ    |

2) A hash containing references to lists

|     x     >                 +-->+###########+
+----------/                  |   +"""""""""""+
      |                       |   |    Foo    |
+#########################+   |   +-----------+
+"""""""""""""""""""""""""+   |   |    ABC    |
+-----------\\ +-----------+   |   +-----------+
|    aaa     >|     O-----+---+
+-----------< +-----------+
|    bbb     >|     O-----+------>+###########+
+-----------< +-----------+       +"""""""""""+
|    ccc     >|     O-----+---+   |    BUZ    |
+-----------/ +-----------+   |   +-----------+
                              |   |    VIZ    |
                              |   +-----------+
                                  |    BUZ    |

Creating reference to an anonymous array

To create an anonymous array [ ] brackets are used. For example:

$x = [1, 2, 3];

Here $x is a reference to an anonymous array.

Creating reference to an anonymous hash

To create an anonymous hash curly braces { } are used. For example:

$x = {Name => 'Chankey', Email => '[email protected]'};

Creating reference to an anonymous subroutine

For this just assign subroutine to a scalar variable (reference variable in our case).

$x = sub { print "Welcome to Linux Stall\n" };

Some notations

Consider the example given below

@a = ( [1, 2, 3],
               [4, 5, 6],
	       [7, 8, 9]

@a is an array with three elements, and each one is a reference to another array. $a[1] is one of these references. It refers to an array, the array containing (4, 5, 6), and because it is a reference to an array, we can write $a[1]->[2] to get the third element from that array. $a[1]->[2] is the 6. Similarly, $a[0]->[1] is the 2. What we have here is like a two-dimensional array; you can write $a[ROW]->[COLUMN] to get or set the element in any row and any column of the array.

The notation still looks a little cumbersome, so there’s one more abbreviation:

In between two subscripts, the arrow is optional i.e. instead of $a[1]->[2], we can write $a[1][2]; it means the same thing. Instead of $a[0]->[1] = 23, we can write $a[0][1] = 23 ; it means the same thing. Now it really looks like two-dimensional arrays! You can see why the arrows are important. Without them, we would have had to write ${$a[1]}[2] instead of $a[1][2]. For three-dimensional arrays, they let us write $x[2][3][5] instead of the unreadable ${${$x[2]}[3]}[5].

This is all what a newbie should know about reference in Perl.

Android Tethering: Using Android to access internet on your Linux machine

Android tethering Linux

What is Android Tethering?

Android Tethering is a way to access internet on your computer with the help of your Android smartphone. USB and Wi-Fi access point tethering is natively supported from Android Froyo 2.2.

Android tethering Linux

USB tethering

For USB tethering you must have root access to the phone and a USB cable to connect your phone to computer.

Step 1: First of all you will have to enable USB debugging on your Android. Go to Settings -> Applications -> Development -> USB debugging and enable it. After enabling just reboot your phone.

Step 2: Connect your phone to computer using USB cable.

Step 3: Now enable tethering option from your phone. For this go to Settings -> Wireless & Networks -> Internet tethering and enable it.

Step 4: Open up terminal on your computer and run the command given below

 ifconfig -a

The output will be like:

eth0      Link encap:Ethernet  HWaddr 40:61:86:B1:E9:33
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

lo        Link encap:Local Loopback
          inet addr:  Mask:
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:480 (480.0 b)  TX bytes:480 (480.0 b)

usb0      Link encap:Ethernet  HWaddr C2:5A:11:8D:43:F5
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

usb0 is denoting your Android device. If you don’t see it then you will have to load the usbnet module and you can do that using modprobe command as:

 modprobe usbnet

Step 5: Now to configure new network device via DHCP use the command given below:

 ifconfig usb0 up && dhcpcd usb0

For configuring the new network device using iproute toolkit the command is:

 ip link set usb0 up && dhcpcd usb0

For stopping the network sharing the command is:

 dhcpcd -x usb0



You can use Netcfg to configure USB tethering, for that just add a static ethernet configuration like:


DESCRIPTION='A basic dhcp ethernet connection using iproute'

How to install Linux Mint’s Cinnamon Desktop on Ubuntu

full cinnamon desktop

full cinnamon desktop

Recently Linux Mint’s developer team released Cinnamon for Linux Mint 13 which is the new desktop environment, it follows the layout of traditional desktops. If you want to try out Cinnamon but you don’t have Linux Mint installed on your system and you are using Ubuntu instead, then you can use the method given below to install it on your Ubuntu machine.

Cinnamon is available in a PPA (personal package archive) for Ubuntu. First of all open the terminal and run the following command:

 sudo add-apt-repository ppa:merlwiz79/cinnamon-ppa


ubuntu terminal

Press Enter when it prompts you. After that update the available packages list by running the command given below:

 sudo apt-get update

Now you can install Cinnamon with this command:

 sudo apt-get install cinnamon cinnamon-session cinnamon-settings

Press Y and Enter when it prompts you.

ubuntu terminal 2

If you are not using Ubuntu then you can go to Cinnamon’s official page to find instructions on how to install cinnamon on your distribution.

Starting Cinnamon

Installing Cinnamon will not replace your default Ubuntu desktop environment. It will just add an option of Cinnamon at your login screen. To enable Cinnamon log out from your current session and from the login screen select Cinnamon and log back in.

starting cinnamon

What you see now is Cinnamon. Start playing with it and check out its features.

set Cinnamon as the default desktop environment

If autologin is enabled in your system then every time the system gets rebooted it will come up with unity by default, then you will have to logout each time you want to switch back to Cinnamon. It will be better to make Cinnamon your default desktop environment, here’s how to do that.

 sudo /usr/lib/lightdm/lightdm-set-defaults -s cinnamon

Removing global menu of Ubuntu

menu bar ubuntu

You will see Ubuntu’s global menu bar is still there (at the top of the screen). If you want to remove it then run the command given below, log out and log back in:

 sudo apt-get remove appmenu-gtk3 appmenu-gtk appmenu-qt

If you want to get it back then use the same command by replacing “remove” with “install”

sudo apt-get install appmenu-gtk3 appmenu-gtk appmenu-qt

Linux Mint 13 featuring Cinnamon to seduce its users by enhanced user interfaces


Now a days developers are focusing on improving the user interfaces of almost all devices, therefore, so many experiments are going on desktop interfaces designing too. Developers of Linux Mint are following the same trend and they are designing a new user interface for Linux Mint 13.

The older versions of Linux Mint were using Gnome environment but the upcoming versions will include Cinnamon whose version 1.2 was released 5 days ago.

We’re hoping Cinnamon will seduce most Linux Mint users, whether they’re coming from Gnome 2, Gnome Shell or other desktops. -Clement Lefebvre (Linux Mint creator)

Cinnamon seems to be a good conservative design which can compete with Gnome and KDE but still we will have to wait for the public response to see which one they like the most? Recently KDE 4.8 was also released. So at the moment there are 2 new desktop environments.

Lefebvre made Linux Mint after reviewing all the the other Linux distributions which were available in the open-source market and from that review he got some new ideas about what features should a ideal distribution should have? Then he made Linux Mint specifically for those folks who want a desktop operating system which is easy to use and require no or very little maintenance.

He said:

We expect much more from our desktop than other distributions. We look at common use cases and if they fail to work out of the box or if they’re too complicated for the user, we identify it as a problem that needs fixing.

Last year Ubuntu desktop were changed from Gnome to Unity interface by Canonical because they didn’t like unnecessary features of Gnome. Unity is an overlay for Gnome 3. Canonical is planning to advance its user interface even more by using “Head-Up Display” technology in the next release of Ubuntu.

While Canonical is constantly improving its interfaces, Linux Mint remains steadfastly committed to the traditional desktop. Desktop market is still ruled by Microsoft and Apple. Linux has much work to do to reach to that place.

Lefebvre said:

Microsoft Windows and Apple Mac OS dominate the desktop market with inferior products. There’s a huge potential for growth for Linux on the desktop market. Our core expertise is on the desktop, we’re not interested in smartphones, tablets and mobile devices.

Since Linux Mint is based on Ubuntu (which itself is based on Debian), so it is possible that Linux Mint would use Unity. This is not the case, however.

So far Unity is only used by one other distribution. It doesn’t look particularly interesting to us and there’s no demand for it. -Lefebvre

It is clear that Linux Mint team don’t want to continue to use Gnome 3. Gnome 3 asks folks to change the way they use their computers. It requires users to think about using the computer in terms of the applications they want to use rather than the tasks they want to complete. Nor does it multitask well. Linus Torvalds has already called Gnome 3 “an unholy mess“.

Cinnamon follows traditional notions of how the desktop interfaces should look like. The interface has a slim panel which contains icons for applications, operational status report and basic commands. Users are allowed to place this icon panel along the top, or on the bottom, or you can have two panels for both the top and bottom.

In the upcoming versions the users will be allowed to place this panel anywhere they want (on the desktop obviously). This approach is a notable contrast from Unity, the icon panel for which is affixed to the left-hand side of the screen.

Users can customize the look and feel of the desktop from “Cinnamon Settings”. They can choose different themes, desktop effects, can add new applets and extensions etc. Which is quite same as Gnome.

Other than Cinnamon, Linux Mint 13 will feature Mate (another desktop), which puts a shell over Gnome 3 that presents an interface that replicates the experience of using Gnome 2.0. It is for those people who are used to the old interface or don’t have the enough system resources to run Cinnamon.

Below are some screenshots of Cinnamon, to see full size image just click on it:




cinnamon theme


Which desktop environment is the best according to you?

View Results

Loading ... Loading ...

Not using Linux Mint? You can install Cinnamon on any distribution, check out this post.

SOPA and PIPA are dead

SOPA and PIPA are dead

Check out this statement by House Judiciary Committee Chairman Lamar Smith (R-Texas).

I have heard from the critics and I take seriously their concerns regarding proposed legislation to address the problem of online piracy. It is clear that we need to revisit the approach on how best to address the problem of foreign thieves that steal and sell American inventions and products.

It means that SOPA and PIPA are almost dead but still there are many actors behind the scene who are supporting this. They are not ready to give up right now. Let’s see what happens! Till then keep protesting against SOPA & PIPA.

How to block a country using iptables?

If you are an admin of a website and you see a lot of bogus traffic coming from some countries which give no profit to you, and you want to block those countries from accessing your website then you can use the bash script given below.

There are two ways to block countries. First is to configure your Apache server and second is to set iptables commands. We will do this using iptables. First of all download the list of IP zone files of the country which you want to block from here.

[Warning]The script will not work if people of that country are using any proxy server or they have spoofed their IP address.[/Warning]

### Block all traffic from AFGHANISTAN (af) and CHINA (CN). Use ISO code ###
ISO="af cn"
### Set PATH ###
### No editing below ###
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
# create a dir
[ ! -d $ZONEROOT ] &amp;&amp; /bin/mkdir -p $ZONEROOT
# clean old rules
# create a new iptables list
for c  in $ISO
	# local zone file
	# get fresh zone file
	$WGET -O $tDB $DLROOT/$c.zone
	# country specific log message
	SPAMDROPMSG="$c Country Drop"
	# get
	BADIPS=$(egrep -v "^#|^$" $tDB)
	for ipblock in $BADIPS
	   $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
	   $IPT -A $SPAMLIST -s $ipblock -j DROP
# Drop everything
# call your other iptable script
# /path/to/other/iptables.sh
exit 0

You must be logged in as a ‘root’ user to run this script. Mention the country names which you want to block in ‘ISO’.

To run the script

# /path/block_country.sh

You can add this script to crontab so that it will run automatically.

@weekly /path/block_country.sh

Below is an another script which does the same work:

wget -c --output-document=iptables-blocklist.txt http://blogama.org/country_query.php?country=$COUNTRIES
if [ -f iptables-blocklist.txt ]; then
  iptables -F
  IPS=$(grep -Ev "^#" $BLOCKDB)
  for i in $IPS
    iptables -A INPUT -s $i -j DROP
    iptables -A OUTPUT -d $i -j DROP
rm $WORKDIR/iptables-blocklist.txt

No big useless shortcuts in Unity Dash of Ubuntu 12.04

If you don’t like those 8 big shortcuts in Unity Dash then this is a good news for you. There will be no big shortcuts in Unity Dash of Ubuntu 12.04. The reason of removing these is that they are useless, yes useless! Ask yourself how many times do you use them? Do they help you? If your answer is no then you should be happy now.

Old look of Unity Dash

The Unity Dash of Ubuntu 12.04 will consist of 3 sections:

1. Recent Apps: This section will display the recently used applications.

2. Recent Files: This section will display recently accessed files.

3. Downloads: This section will display the items of your ‘Downloads’ folder.

Here is how it will look:

New look of Unity Dash

Isn’t this cool? You can get access to your recently used Apps, files and downloaded items from just one place. I think this is a good and necessary decision which Ubuntu 12.04 developers have taken.

How to delete spaces from file name in Linux?

If your file name has spaces in it and there are many such files that it is not possible for you to rename each file’s name manually then you may use the command given below. It will rename all the file names which have spaces by replacing the spaces with an underscore ( _ ).

for FILE in *; do mv "$FILE" "$(echo "$FILE"|tr ' ' '_')"; done


for file in *; do mv "$file" `echo $file | sed -e 's/ */_/g' -e 's/_-_/-/g'`; done

I had two files named a b c.txt and x y z.txt in my directory. I used the command given above to delete spaces from file name. It changed the file names to a_b_c.txt and x_y_z.txt respectively. See the screenshot below: