Sunday, October 25, 2009

Squid Setup a transparent

My Server Setup:

i) Server: Xeon CPU system with 8 GB RAM .
ii) Eth0: IP:192.168.1.1
iii) Eth1: IP: 192.168.2.1 (192.168.2.0/24 network)
iv) Red Hat Enterprise Linux 5.0

Eth0 connected to internet and eth1 connected to local lan i.e. system act as router.
Server Configuration

* Step #1 : Squid configuration so that it will act as a transparent proxy
* Step #2 : Iptables configuration
o a) Configure system as router
o b) Forward all http requests to 3128 (DNAT)
* Step #3: Run scripts and start squid service

First, Squid server installed (use up2date squid) and configured by adding following directives to file:
# vi /etc/squid/squid.conf

Modify or add following squid directives:
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
acl lan src 192.168.1.1 192.168.2.0/24
http_access allow localhost
http_access allow lan

Where,

* httpd_accel_host virtual: Squid as an httpd accelerator
* httpd_accel_port 80: 80 is port you want to act as a proxy
* httpd_accel_with_proxy on: Squid act as both a local httpd accelerator and as a proxy.
* httpd_accel_uses_host_header on: Header is turned on which is the hostname from the URL.
* acl lan src 192.168.1.1 192.168.2.0/24: Access control list, only allow LAN computers to use squid
* http_access allow localhost: Squid access to LAN and localhost ACL only
* http_access allow lan: -- same as above --

Here is the complete listing of squid.conf for your reference (grep will remove all comments and sed will remove all empty lines, thanks to David Klein for quick hint ):
# grep -v "^#" /etc/squid/squid.conf | sed -e '/^$/d'

OR, try out sed
# cat /etc/squid/squid.conf | sed '/ *#/d; /^ *$/d'

Output:
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY
hosts_file /etc/hosts
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern . 0 20% 4320
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl purge method PURGE
acl CONNECT method CONNECT
cache_mem 1024 MB
http_access allow manager localhost
http_access deny manager
http_access allow purge localhost
http_access deny purge
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
acl lan src 192.168.1.1 192.168.2.0/24
http_access allow localhost
http_access allow lan
http_access deny all
http_reply_access allow all
icp_access allow all
visible_hostname myclient.hostname.com
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
coredump_dir /var/spool/squid
Iptables configuration

Next, I had added following rules to forward all http requests (coming to port 80) to the Squid server port 3128 :
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 192.168.1.1:3128
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

Here is complete shell script. Script first configure Linux system as router and forwards all http request to port 3128
#!/bin/sh
# squid server IP
SQUID_SERVER="192.168.1.1"
# Interface connected to Internet
INTERNET="eth0"
# Interface connected to LAN
LAN_IN="eth1"
# Squid port
SQUID_PORT="3128"
# DO NOT MODIFY BELOW
# Clean old firewall
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# Load IPTABLES modules for NAT and IP conntrack support
modprobe ip_conntrack
modprobe ip_conntrack_ftp
# For win xp ftp client
#modprobe ip_nat_ftp
echo 1 > /proc/sys/net/ipv4/ip_forward
# Setting default filter policy
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
# Unlimited access to loop back
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow UDP, DNS and Passive FTP
iptables -A INPUT -i $INTERNET -m state --state ESTABLISHED,RELATED -j ACCEPT
# set this system as a router for Rest of LAN
iptables --table nat --append POSTROUTING --out-interface $INTERNET -j MASQUERADE
iptables --append FORWARD --in-interface $LAN_IN -j ACCEPT
# unlimited access to LAN
iptables -A INPUT -i $LAN_IN -j ACCEPT
iptables -A OUTPUT -o $LAN_IN -j ACCEPT
# DNAT port 80 request comming from LAN systems to squid 3128 ($SQUID_PORT) aka transparent proxy
iptables -t nat -A PREROUTING -i $LAN_IN -p tcp --dport 80 -j DNAT --to $SQUID_SERVER:$SQUID_PORT
# if it is same system
iptables -t nat -A PREROUTING -i $INTERNET -p tcp --dport 80 -j REDIRECT --to-port $SQUID_PORT
# DROP everything and Log it
iptables -A INPUT -j LOG
iptables -A INPUT -j DROP

Save shell script. Execute script so that system will act as a router and forward the ports:
# chmod +x /etc/fw.proxy
# /etc/fw.proxy
# service iptables save
# chkconfig iptables on

Start or Restart the squid:
# /etc/init.d/squid restart
# chkconfig squid on
Desktop / Client computer configuration

Point all desktop clients to your eth1 IP address (192.168.2.1) as Router/Gateway (use DHCP to distribute this information). You do not have to setup up individual browsers to work with proxies.
How do I test my squid proxy is working correctly?

See access log file /var/log/squid/access.log:
# tail -f /var/log/squid/access.log

Above command will monitor all incoming request and log them to /var/log/squid/access_log file. Now if somebody accessing a website through browser, squid will log information.
Problems and solutions
(a) Windows XP FTP Client

All Desktop client FTP session request ended with an error:
Illegal PORT command.

I had loaded the ip_nat_ftp kernel module. Just type the following command press Enter and voila!
# modprobe ip_nat_ftp

Please note that modprobe command is already added to a shell script (above).
(b) Port 443 redirection

I had block out all connection request from our router settings except for our proxy (192.168.1.1) server. So all ports including 443 (https/ssl) request denied. You cannot redirect port 443, from debian mailing list, "Long answer: SSL is specifically designed to prevent "man in the middle" attacks, and setting up squid in such a way would be the same as such a "man in the middle" attack. You might be able to successfully achive this, but not without breaking the encryption and certification that is the point behind SSL".

Therefore, I had quickly reopen port 443 (router firewall) for all my LAN computers and problem was solved.
(c) Squid Proxy authentication in a transparent mode

You cannot use Squid authentication with a transparently intercepting proxy.

Thursday, October 15, 2009

Linux NIC Bonding

vim /etc/sysconfig/network-scripts/ifcfg-bond0

DEVICE=bond0
IPADDR=10.5.1.76
NETMASK=
GATEWAY=10.5.1.93
ONBOOT=yes
BOOTPROTO=static
USERCLT=no
BONDING_OPTS="miimon=100 mode=1"

edit vim /etc/sysconfig/network-scripts/ifcfg-eth0

# Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet
DEVICE=eth0
HWADDR=00:26:55:7D:38:00
USERCTL=no
ONBOOT=yes
MASTER=bond0
SLAVE=yes
BOOTPROTO=none

edit vim /etc/sysconfig/network-scripts/ifcfg-eth1

# Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet
DEVICE=eth1
USERCTL=no
ONBOOT=yes
HWADDR=00:26:55:7D:38:01
MASTER=bond0
SLAVE=yes
BOOTPROTO=none

edit vim /etc/modprobe.conf

alias eth0 bnx2
alias eth1 bnx2
alias bond0 bonding
alias scsi_hostadapter megaraid_sas
alias scsi_hostadapter1 ata_piix
alias scsi_hostadapter2 qla2xxx

#modprobe bonding

http://www.cisco.com/en/US/tech/tk389/tk213/technologies_configuration_example09186a0080094470.shtml Since I don't know the model of your switch

#service network restart

# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.4.0 (October 7, 2008)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth2
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth2
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:26:55:19:4a:18

Slave Interface: eth3
MII Status: up
Link Failure Count: 2
Permanent HW addr: 00:26:55:19:4a:1c

add following lines to file
#vim /etc/sysctl.conf
# Gigabit tuning
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# net.core.wmem_max = 8388608
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 2096 65535 16777216

net.ipv4.tcp_mem = 98304 131072 196608
net.core.netdev_max_backlog = 250000
net.ipv4.tcp_timestamps = 1
net.ipv4.ip_local_port_range = 1025 61000

# VM pressure fixes
vm.swappiness = 100
vm.inactive_clean_percent = 100

vm.pagecache = 200 10 20
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5


# Security tweaks
net.ipv4.tcp_synack_retries = 3
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_max_syn_backlog = 10240
net.ipv4.tcp_fin_timeout = 30

net.ipv4.tcp_keepalive_time = 1200


What is bonding?
Bonding is the same as port trunking. In the following I will use the word bonding because practically we will bond interfaces as one.

But still...what is bonding?
Bonding allows you to aggregate multiple ports into a single group, effectively combining the bandwidth into a single connection. Bonding also allows you to create multi-gigabit pipes to transport traffic through the highest traffic areas of your network. For example, you can aggregate three megabits ports (1 mb each) into a three-megabits trunk port. That is equivalent with having one interface with three megabits speed.

Where should I use bonding?
You can use it wherever you need redundant links, fault tolerance or load balancing networks. It is the best way to have a high availability network segment. A very useful way to use bonding is to use it in connection with 802.1q VLAN support (your network equipment must have 802.1q protocol implemented).

The best documentation is on the Linux Channel Bonding Project page
I strongly recommend to read it for more details.

Credits: Linux Channel Bonding Project page , Thea

This small howto will try to cover the most used bonding types. The following script (the gray area) will configure a bond interface (bond0) using two ethernet interface (eth0 and eth1). You can place it onto your on file and run it at boot time..

#!/bin/bash

modprobe bonding mode=0 miimon=100 # load bonding module

ifconfig eth0 down # putting down the eth0 interface
ifconfig eth1 down # putting down the eth1 interface

ifconfig bond0 hw ether 00:11:22:33:44:55 # changing the MAC address of the bond0 interface
ifconfig bond0 192.168.55.55 up # to set ethX interfaces as slave the bond0 must have an ip.

ifenslave bond0 eth0 # putting the eth0 interface in the slave mod for bond0
ifenslave bond0 eth1 # putting the eth1 interface in the slave mod for bond0

You can set up your bond interface according to your needs. Changing one parameters (mode=X) you can have the following bonding types:
mode=0 (balance-rr)
Round-robin policy: Transmit packets in sequential order from the first available slave through the last. This mode provides load balancing and fault tolerance.

mode=1 (active-backup)
Active-backup policy: Only one slave in the bond is active. A different slave becomes active if, and only if, the active slave fails. The bond's MAC address is externally visible on only one port (network adapter) to avoid confusing the switch. This mode provides fault tolerance. The primary option affects the behavior of this mode.

mode=2 (balance-xor)
XOR policy: Transmit based on [(source MAC address XOR'd with destination MAC address) modulo slave count]. This selects the same slave for each destination MAC address. This mode provides load balancing and fault tolerance.

mode=3 (broadcast)
Broadcast policy: transmits everything on all slave interfaces. This mode provides fault tolerance.

mode=4 (802.3ad)
IEEE 802.3ad Dynamic link aggregation. Creates aggregation groups that share the same speed and duplex settings. Utilizes all slaves in the active aggregator according to the 802.3ad specification.

Pre-requisites:
1. Ethtool support in the base drivers for retrieving
the speed and duplex of each slave.
2. A switch that supports IEEE 802.3ad Dynamic link
aggregation.
Most switches will require some type of configuration
to enable 802.3ad mode.

mode=5 (balance-tlb)
Adaptive transmit load balancing: channel bonding that does not require any special switch support. The outgoing traffic is distributed according to the current load (computed relative to the speed) on each slave. Incoming traffic is received by the current slave. If the receiving slave fails, another slave takes over the MAC address of the failed receiving slave.

Prerequisite:
Ethtool support in the base drivers for retrieving the
speed of each slave.

mode=6 (balance-alb)
Adaptive load balancing: includes balance-tlb plus receive load balancing (rlb) for IPV4 traffic, and does not require any special switch support. The receive load balancing is achieved by ARP negotiation. The bonding driver intercepts the ARP Replies sent by the local system on their way out and overwrites the source hardware address with the unique hardware address of one of the slaves in the bond such that different peers use different hardware addresses for the server.

The most used are the first four mode types...

Also you can use multiple bond interface but for that you must load the bonding module as many as you need.
Presuming that you want two bond interface you must configure the /etc/modules.conf as follow:

alias bond0 bonding
options bond0 -o bond0 mode=0 miimon=100
alias bond1 bonding
options bond1 -o bond1 mode=1 miimon=100

Notes:

* To restore your slaves MAC addresses, you need to detach them from the bond (`ifenslave -d bond0 eth0'). The bonding driver will then restore the MAC addresses that the slaves had before they were enslaved.
* The bond MAC address will be the taken from its first slave device.
* Promiscous mode: According to your bond type, when you put the bond interface in the promiscous mode it will propogates the setting to the slave devices as follow:
o for mode=0,2,3 and 4 the promiscuous mode setting is propogated to all slaves.
o for mode=1,5 and 6 the promiscuous mode setting is propogated only to the active slave.
For balance-tlb mode the active slave is the slave currently receiving inbound traffic, for balance-alb mode the active slave is the slave used as a "primary." and for the active-backup, balance-tlb and balance-alb modes, when the active slave changes (e.g., due to a link failure), the promiscuous setting will be propogated to the new active slave.

How to Setup Fedora Directory Server with Postfix Mail Server

Set hostname of the computer
#hostname mail.taashee.com
Install Fedora Directory Server
#yum install fedora-ds
Create a new user and group named fds. This account will be used to run the fds
service.
#useradd fds
Type in setup-ds-admin.pl in a terminal window to setup Fedora Directory Server.
#setup-ds-admin.pl
=====================================================
This program will set up the Fedora Directory and Administration Servers.
It is recommended that you have "root" privilege to set up the software.
Tips for using this program:
- Press "Enter" to choose the default and go to the next screen
- Type "Control-B" then "Enter" to go back to the previous screen
- Type "Control-C" to cancel the setup program
Would you like to continue with set up? [yes]: ↵
=====================================================
BY SETTING UP AND USING THIS SOFTWARE YOU ARE CONSENTING TO BE BOUND BY
AND ARE BECOMING A PARTY TO THE AGREEMENT FOUND IN THE
LICENSE.TXT FILE. IF YOU DO NOT AGREE TO ALL OF THE TERMS
OF THIS AGREEMENT, PLEASE DO NOT SET UP OR USE THIS SOFTWARE.
Do you agree to the license terms? [no]: yes
====================================================
Your system has been scanned for potential problems, missing patches,
etc. The following output is a report of the items found that need to
be addressed before running this software in a production
environment.
Fedora Directory Server system tuning analysis version 10-AUGUST-2007.
NOTICE : System is i686-unknown-linux2.6.18-92.el5 (1 processor).
WARNING: 494MB of physical memory is available on the system. 1024MB is recommended for
best performance on large production system.
NOTICE : The net.ipv4.tcp_keepalive_time is set to 7200000 milliseconds
(120 minutes). This may cause temporary server congestion from lost
client connections.
WARNING: There are only 1024 file descriptors (hard limit) available, which
limit the number of simultaneous connections.
WARNING: There are only 1024 file descriptors (soft limit) available, which
limit the number of simultaneous connections.
Would you like to continue? [no]: yes
===================================================
Choose a setup type:
1. Express
Allows you to quickly set up the servers using the most
common options and pre-defined defaults. Useful for quick
evaluation of the products.
2. Typical
Allows you to specify common defaults and options.
3. Custom
Allows you to specify more advanced options. This is
recommended for experienced server administrators only.
To accept the default shown in brackets, press the Enter key.
Choose a setup type [2]: ↵
=====================================================
Enter the fully qualified domain name of the computer
on which you're setting up server software. Using the form
.
Example: eros.example.com.
To accept the default shown in brackets, press the Enter key.
Computer name [mail.taashee.com]: ↵
=====================================================
The servers must run as a specific user in a specific group.
It is strongly recommended that this user should have no privileges
on the computer (i.e. a non-root user). The setup procedure
will give this user/group some permissions in specific paths/files
to perform server-specific operations.
If you have not yet created a user and group for the servers,
create this user and group using your native operating
system utilities.
System User [nobody]: fds
System Group [nobody]: fds
=====================================================
Server information is stored in the configuration directory server.
This information is used by the console and administration server to
configure and manage your servers. If you have already set up a
configuration directory server, you should register any servers you
set up or create with the configuration server. To do so, the
following information about the configuration server is required: the
fully qualified host name of the form
.(e.g. hostname.example.com), the port number
(default 389), the suffix, the DN and password of a user having
permission to write the configuration information, usually the
configuration directory administrator, and if you are using security
(TLS/SSL). If you are using TLS/SSL, specify the TLS/SSL (LDAPS) port
number (default 636) instead of the regular LDAP port number, and
provide the CA certificate (in PEM/ASCII format).
If you do not yet have a configuration directory server, enter 'No' to
be prompted to set up one.
Do you want to register this software with an existing
configuration directory server? [no]: ↵
=====================================================
Please enter the administrator ID for the configuration directory
server. This is the ID typically used to log in to the console. You
will also be prompted for the password.
Configuration directory server
administrator ID [admin]: ↵
Password:
Password (confirm):
====================================================
The information stored in the configuration directory server can be
separated into different Administration Domains. If you are managing
multiple software releases at the same time, or managing information
about multiple domains, you may use the Administration Domain to keep
them separate.
If you are not using administrative domains, press Enter to select the
default. Otherwise, enter some descriptive, unique name for the
administration domain, such as the name of the organization
responsible for managing the domain.
Administration Domain [taashee.com]: ↵
=====================================================
The standard directory server network port number is 389. However, if
you are not logged as the superuser, or port 389 is in use, the
default value will be a random unused port number greater than 1024.
If you want to use port 389, make sure that you are logged in as the
superuser, that port 389 is not in use.
Directory server network port [389]: ↵
=====================================================
Each instance of a directory server requires a unique identifier.
This identifier is used to name the various
instance specific files and directories in the file system,
as well as for other uses as a server instance identifier.
Directory server identifier [mail]: ↵
=====================================================
The suffix is the root of your directory tree. The suffix must be a valid DN.
It is recommended that you use the dc=domaincomponent suffix convention.
For example, if your domain is example.com,
you should use dc=example,dc=com for your suffix.
Setup will create this initial suffix for you,
but you may have more than one suffix.
Use the directory server utilities to create additional suffixes.
Suffix [dc=taashee, dc=com]: ↵
=====================================================
Certain directory server operations require an administrative user.
This user is referred to as the Directory Manager and typically has a
bind Distinguished Name (DN) of cn=Directory Manager.
You will also be prompted for the password for this user. The password must
be at least 8 characters long, and contain no spaces.
Directory Manager DN [cn=Directory Manager]: ↵
Password:
Password (confirm):
=====================================================
The Administration Server is separate from any of your web or application
servers since it listens to a different port and access to it is
restricted.
Pick a port number between 1024 and 65535 to run your Administration
Server on. You should NOT use a port number which you plan to
run a web or application server on, rather, select a number which you
will remember and which will not be used for anything else.
Administration port [9830]: ↵
=====================================================
The interactive phase is complete. The script will now set up your
servers. Enter No or go Back if you want to change something.
Are you ready to set up your servers? [yes]: ↵
Creating directory server . . .
Your new DS instance 'mail' was successfully created.
Creating the configuration directory server . . .
Beginning Admin Server creation . . .
Creating Admin Server files and directories . . .
Updating adm.conf . . .
Updating admpw . . .
Registering admin server with the configuration directory server . . .
Updating adm.conf with information from configuration directory server . . .
Updating the configuration for the httpd engine . . .
Starting admin server . . .
The admin server was successfully started.
Admin server was successfully created, configured, and started.
Exiting . . .
Log file is '/tmp/setupcT78dr.log'
Restart the dirsrv, dirsrv-admin and httpd service.
#service httpd restart
#service dirsrv restart
#service dirsrv-admin restart
Now launch the Fedora Console Login window.
#fedora-idm-console
Provide following details if you have default setup
User ID: cn=directory manager
Password: ******
Administration URL: localhost:9830
Create user on Fedora Directory server using following screen shots.


You have to enable POSIX User and fill the details if you want to authenticate a user from linux
box. You will have to create Home directory of users manually.

Setup LDAP Client (RHEL/Fedora Box).
#system-config-authentication


Add required LDAP details.
Now, check on client whether you are able to sync the ldap database using following
command.
# getent passwd
This document is only meant to make use of Fedora Directory Server as LDAP Server for Central
Authentication of users.

http://i36.tinypic.com/i1jjuo.jpg
http://i34.tinypic.com/33o1xj7.jpg
http://i38.tinypic.com/13zqwdu.jpg
http://i34.tinypic.com/wb9wfq.jpg
http://i33.tinypic.com/2rr55yv.jpg
http://i38.tinypic.com/2rgp1yg.jpg

Postfix Server

POSTFIX HOWTO
First check postfix is install or not. ( You need to require basic repository to be setup )
[root@mail ~]# yum list postfix
Loading "security" plugin
Loading "rhnplugin" plugin
Loading "installonlyn" plugin
This system is not registered with RHN.
RHN support will be disabled.
Setting up repositories
Reading repository metadata in from local files
Available Packages
postfix.i386 2:2.3.3-2 rhel
[root@mail ~]#
Now install postfix
[root@mail ~]# yum install postfix
Loading "security" plugin
Loading "rhnplugin" plugin
Loading "installonlyn" plugin
This system is not registered with RHN.
RHN support will be disabled.
Setting up Install Process
Setting up repositories
Reading repository metadata in from local files
Parsing package install arguments
Resolving Dependencies
--> Populating transaction set with selected packages. Please wait.
---> Downloading header for postfix to pack into transaction set.
postfix-2.3.3-2.i386.rpm 100% |=========================| 41 kB 00:00
---> Package postfix.i386 2:2.3.3-2 set to be updated
--> Running transaction check
Dependencies Resolved
================================================================
Package Arch Version Repository Size
================================================================
Installing:
postfix i386 2:2.3.3-2 rhel 3.6 M
Transaction Summary
================================================================
Install 1 Package(s)
Update 0 Package(s)
Remove 0 Package(s)
Total download size: 3.6 M
Is this ok [y/N]: y
Downloading Packages:
(1/1): postfix-2.3.3-2.i3 100% |=========================| 3.6 MB 00:00
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing: postfix ######################### [1/1]
Installed: postfix.i386 2:2.3.3-2
Complete!
[root@mail ~]#
Let us make postfix default mta
[root@mail ~]# alternatives --display mta
mta - status is auto.
link currently points to /usr/sbin/sendmail.sendmail
/usr/sbin/sendmail.sendmail - priority 90
slave mta-pam: /etc/pam.d/smtp.sendmail
slave mta-mailq: /usr/bin/mailq.sendmail
slave mta-newaliases: /usr/bin/newaliases.sendmail
slave mta-rmail: /usr/bin/rmail.sendmail
slave mta-sendmail: /usr/lib/sendmail.sendmail
slave mta-mailqman: /usr/share/man/man1/mailq.sendmail.1.gz
slave mta-newaliasesman: /usr/share/man/man1/newaliases.sendmail.1.gz
slave mta-aliasesman: /usr/share/man/man5/aliases.sendmail.5.gz
slave mta-sendmailman: /usr/share/man/man8/sendmail.sendmail.8.gz
/usr/sbin/sendmail.postfix - priority 30
slave mta-pam: /etc/pam.d/smtp.postfix
slave mta-mailq: /usr/bin/mailq.postfix
slave mta-newaliases: /usr/bin/newaliases.postfix
slave mta-rmail: /usr/bin/rmail.postfix
slave mta-sendmail: /usr/lib/sendmail.postfix
slave mta-mailqman: /usr/share/man/man1/mailq.postfix.1.gz
slave mta-newaliasesman: /usr/share/man/man1/newaliases.postfix.1.gz
slave mta-aliasesman: /usr/share/man/man5/aliases.postfix.5.gz
slave mta-sendmailman: /usr/share/man/man1/sendmail.postfix.1.gz
Current `best' version is /usr/sbin/sendmail.sendmail.
[root@mail ~]#
[root@mail ~]# alternatives --config mta
There are 2 programs which provide 'mta'.
Selection Command
-----------------------------------------------
*+ 1 /usr/sbin/sendmail.sendmail
2 /usr/sbin/sendmail.postfix
Enter to keep the current selection[+], or type selection number: 2
[root@mail ~]#
Stop sendmail
[root@mail ~]# service sendmail stop
Shutting down sm-client: [ OK ]
Shutting down sendmail: [ OK ]
[root@mail ~]# chkconfig sendmail off
Start Postfix
[root@mail ~]# chkconfig postfix on
[root@mail ~]# service postfix start
Starting postfix: [ OK ]
[root@mail ~]#
CHECK POSTFIX LISTING ON .
[root@mail ~]# netstat -tlpn | grep ':25'
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 5108/master
[root@mail ~]#
As it is listing on localhost onle need to enabled it listen to all address.
[root@mail postfix]# postconf -n | grep interfaces
inet_interfaces = localhost
[root@mail postfix]#
FROM OTHER HOST 192.168.0.101
[root@mail postfix]# postconf -n | grep interfaces
inet_interfaces = localhost
[root@mail postfix]#
FROM LOCALHOST
[root@mail postfix]# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 mail.taashee.com ESMTP Postfix
SO LET IT LISTION TO ALL PORTS
[root@mail postfix]# grep inet_interfaces main.cf
# The inet_interfaces parameter specifies the network interface
#inet_interfaces = all
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
inet_interfaces = localhost
# the address list specified with the inet_interfaces parameter.
# receives mail on (see the inet_interfaces parameter).
# to $mydestination, $inet_interfaces or $proxy_interfaces.
# - destinations that match $inet_interfaces or $proxy_interfaces,
# unknown@[$inet_interfaces] or unknown@[$proxy_interfaces] is returned
[root@mail postfix]#
[root@mail postfix]# postconf inet_interfaces
inet_interfaces = localhost
[root@mail postfix]# postconf -e "inet_interfaces = all"
[root@mail postfix]# postconf inet_interfaces
inet_interfaces = all
[root@mail postfix]#
[root@mail postfix]# service postfix restart
Shutting down postfix: [ OK ]
Starting postfix: [ OK ]
[root@mail postfix]#
NOW CHECKING FROM OTHER HOST
[root@vhost ~]# telnet 192.168.0.253 25
Trying 192.168.0.253...
telnet: connect to address 192.168.0.253: No route to host
telnet: Unable to connect to remote host: No route to host
STILL REFUSING CONNECTION, CHECK FIREWALL AND ADD FOLLOWING RULES.
[root@mail postfix]# iptables -I INPUT -p tcp --dport 25 -m state --state NEW -j ACCEPT
[root@vhost ~]# telnet 192.168.0.253 25
Trying 192.168.0.253...
Connected to mail.taashee.com (192.168.0.253).
Escape character is '^]'.
220 mail.taashee.com ESMTP Postfix
check the trusted network.
[root@mail postfix]# postconf mynetworks
mynetworks = 127.0.0.0/8 192.168.122.0/24 192.168.0.0/24
FROM POSTFIX main.cf
# TRUST AND RELAY CONTROL
# The mynetworks parameter specifies the list of "trusted" SMTP
# clients that have more privileges than "strangers".
#
# In particular, "trusted" SMTP clients are allowed to relay mail
# through Postfix. See the smtpd_recipient_restrictions parameter
# in postconf(5).
#
# You can specify the list of "trusted" network addresses by hand
# or you can let Postfix do it for you (which is the default).
#
# By default (mynetworks_style = subnet), Postfix "trusts" SMTP
# clients in the same IP subnetworks as the local machine.
# On Linux, this does works correctly only with interfaces specified
# with the "ifconfig" command.
#
# Specify "mynetworks_style = class" when Postfix should "trust" SMTP
# clients in the same IP class A/B/C networks as the local machine.
# Don't do this with a dialup site - it would cause Postfix to "trust"
# your entire provider's network. Instead, specify an explicit
# mynetworks list by hand, as described below.
#
# Specify "mynetworks_style = host" when Postfix should "trust"
# only the local machine.
Check defaults and current parameters.
[root@mail postfix]# postconf mynetworks_style
mynetworks_style = subnet
[root@mail postfix]# postconf -d mynetworks_style
mynetworks_style = subnet
checking myhostname parameters
[root@mail postfix]# postconf myhostname
myhostname = mail.taashee.com
[root@mail postfix]# postconf -d myhostname
myhostname = mail.taashee.com
[root@mail postfix]# postconf -d myorigin
myorigin = $myhostname
[root@mail postfix]# postconf -d mydomain
mydomain = example.com
[root@mail postfix]# postconf myorigin
myorigin = $myhostname
[root@mail postfix]#
CHECKING WITH MAIL COMMAND
[root@mail postfix]# su - raj
[raj@mail ~]$ echo testmail | mail -s thefirstmail rajat
THE OUTPUT OF tail -f /var/log/maillog.
July 711:07:27 mail postfix/pickup[6523]: 9FF6B135FCA: uid=511 from=
July 711:07:27 mail postfix/cleanup[8412]: 9FF6B135FCA: message-
id=<20090125053727.9FF6B135FCA@mail.taashee.com>
July 711:07:27 mail postfix/qmgr[6524]: 9FF6B135FCA: from=, size=336,
nrcpt=1 (queue active)
July 711:07:27 mail postfix/local[8414]: 9FF6B135FCA: to=, orig_to=,
relay=local, delay=0.07, delays=0.03/0.01/0/0.03, dsn=2.0.0, status=sent (delivered to mailbox)
July 711:07:27 mail postfix/qmgr[6524]: 9FF6B135FCA: removed
CHECKING MAIL ON RAJAT USER
[root@mail postfix]# mail -u rajat
Mail version 8.1 6/6/93. Type ? for help.
"/var/mail/rajat": 1 message 1 new
>N 1 rajat@mail. Sun July 711:07 14/498 "thefirstmail"
&
NOW CHANGE myorigin parameter
[root@mail postfix]# grep mydomain /etc/postfix/main.cf
# The mydomain parameter specifies the local internet domain name.
# $mydomain is used as a default value for many other configuration
#mydomain = domain.tld
# machines, you should (1) change this to $mydomain and (2) set up
myorigin = $mydomain
AND CHECK
[root@mail postfix]# postconf myorigin
myorigin = $mydomain
SET ALSO mydestination parameters.
[root@mail postfix]# postconf mydestination
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
SO WHENEVER YOU SEND A MAIL IT WILL SEND AS USER@mydomain instead of user@hostname and
$mydomain is also considered as local domain now.
LIKE FROM LOG
FIRST CASE WHEN myorigin = $myhostname
July 711:23:33 mail postfix/pickup[10798]: 91217135FD7: uid=511 from=
July 711:23:33 mail postfix/cleanup[10937]: 91217135FD7: message-
id=<20090125055333.91217135FD7@mail.taashee.com>
July 711:23:33 mail postfix/qmgr[10799]: 91217135FD7: from=, size=326,
nrcpt=1 (queue active)
July 711:23:33 mail postfix/local[10939]: 91217135FD7: to=, relay=local,
delay=0.04, delays=0.03/0.01/0/0, dsn=2.0.0, status=sent (delivered to mailbox)
July 711:23:33 mail postfix/qmgr[10799]: 91217135FD7: removed
SECOND CASE WHEN myorigin = $mydomain
July 711:25:16 mail postfix/pickup[11177]: AE0F8135FD7: uid=511 from=
July 711:25:16 mail postfix/cleanup[11247]: AE0F8135FD7: message-
id=<20090125055516.AE0F8135FD7@mail.taashee.com>
July 711:25:16 mail postfix/qmgr[11178]: AE0F8135FD7: from=, size=315,
nrcpt=1 (queue active)
July 711:25:16 mail postfix/local[11249]: AE0F8135FD7: to=, relay=local,
delay=0.05, delays=0.04/0.01/0/0, dsn=2.0.0, status=sent (delivered to mailbox)
July 711:25:16 mail postfix/qmgr[11178]: AE0F8135FD7: removed
REDUCE INFORMATION LEAKAGE BY DISABLING THE vrfy command
[root@mail postfix]# postconf disable_vrfy_command
disable_vrfy_command = no
[root@mail postfix]# postconf -e 'disable_vrfy_command = yes'
[root@mail postfix]# postconf disable_vrfy_command
disable_vrfy_command = yes
[root@mail postfix]#
LET US CHECK
[root@vhost ~]# telnet 192.168.0.253 25
Trying 192.168.0.253...
Connected to mail.taashee.com (192.168.0.253).
Escape character is '^]'.
220 mail.taashee.com ESMTP Postfix
vrfy rajat
502 5.5.1 VRFY command is disabled
[root@mail postfix]# postconf smtpd_banner
smtpd_banner = $myhostname ESMTP $mail_name
[root@vhost ~]# telnet 192.168.0.253 25
Trying 192.168.0.253...
Connected to mail.taashee.com (192.168.0.253).
Escape character is '^]'.
220 mail.taashee.com ESMTP Postfix
vrfy rajat
502 5.5.1 VRFY command is disabled
^]
telnet> quit
Connection closed.
[root@mail postfix]# postconf -e 'smtpd_banner = $myhostname ESMTP'
[root@mail postfix]# postconf smtpd_banner
smtpd_banner = $myhostname ESMTP
[root@mail postfix]# service postfix restart
Shutting down postfix: [ OK ]
Starting postfix:
[root@vhost ~]# telnet 192.168.0.253 25
Trying 192.168.0.253...
Connected to mail.taashee.com (192.168.0.253).
Escape character is '^]'.
220 mail.taashee.com ESMTP
FORCE CONNECTING HOST TO ISSUE A CORRECT HELO OR EHLO BEFORE SENDING ANY COMMAND
[root@mail postfix]# postconf smtpd_helo_required
smtpd_helo_required = no
[root@mail postfix]# postconf -e 'smtpd_helo_required = yes'
[root@mail postfix]# postconf smtpd_helo_required
smtpd_helo_required = yes
[root@mail postfix]# service postfix restart
Shutting down postfix: [ OK ]
Starting postfix: [ OK ]
[root@mail postfix]#
SIMILARLY ALSO SEND HELO OR EHLO WHEN WE ESTABLIESHED THE CONNECTION
[root@mail postfix]# postconf smtp_always_send_ehlo
smtp_always_send_ehlo = yes
LET US SETUP MAIL BOX DELEVERY AS MAIL DIR.
[root@mail postfix]# postconf home_mailbox
home_mailbox = Maildir/
[root@mail postfix]# postconf -e 'home_mailbox = Maildir/'
[root@mail postfix]# yum install dovecot
Loading "security" plugin
Loading "rhnplugin" plugin
Loading "installonlyn" plugin
This system is not registered with RHN.
RHN support will be disabled.
Setting up Install Process
Setting up repositories
Reading repository metadata in from local files
Parsing package install arguments
Resolving Dependencies
--> Populating transaction set with selected packages. Please wait.
---> Downloading header for dovecot to pack into transaction set.
dovecot-1.0-1.2.rc15.el5. 100% |=========================| 27 kB 00:00
---> Package dovecot.i386 0:1.0-1.2.rc15.el5 set to be updated
--> Running transaction check
--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15) for package: dovecot
--> Processing Dependency: libmysqlclient.so.15 for package: dovecot
--> Restarting Dependency Resolution with new changes.
--> Populating transaction set with selected packages. Please wait.
---> Downloading header for mysql to pack into transaction set.
mysql-5.0.22-2.1.0.1.i386 100% |=========================| 36 kB 00:00
---> Package mysql.i386 0:5.0.22-2.1.0.1 set to be updated
--> Running transaction check
--> Processing Dependency: perl(DBI) for package: mysql
--> Restarting Dependency Resolution with new changes.
--> Populating transaction set with selected packages. Please wait.
---> Downloading header for perl-DBI to pack into transaction set.
perl-DBI-1.52-1.fc6.i386. 100% |=========================| 16 kB 00:00
---> Package perl-DBI.i386 0:1.52-1.fc6 set to be updated
--> Running transaction check
Dependencies Resolved
================================================================
Package Arch Version Repository Size
================================================================
Installing:
dovecot i386 1.0-1.2.rc15.el5 rhel 1.5 M
Installing for dependencies:
mysql i386 5.0.22-2.1.0.1 rhel 3.0 M
perl-DBI i386 1.52-1.fc6 rhel 605 k
Transaction Summary
================================================================
Install 3 Package(s)
Update 0 Package(s)
Remove 0 Package(s)
Total download size: 5.1 M
Is this ok [y/N]: y
Downloading Packages:
(1/3): dovecot-1.0-1.2.rc 100% |=========================| 1.5 MB 00:00
(2/3): perl-DBI-1.52-1.fc 100% |=========================| 605 kB 00:00
(3/3): mysql-5.0.22-2.1.0 100% |=========================| 3.0 MB 00:00
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing: perl-DBI ######################### [1/3]
Installing: mysql ######################### [2/3]
Installing: dovecot ######################### [3/3]
Installed: dovecot.i386 0:1.0-1.2.rc15.el5
Dependency Installed: mysql.i386 0:5.0.22-2.1.0.1 perl-DBI.i386 0:1.52-1.fc6
Complete!
[root@mail postfix]#
UNCOMMENT THE FOLLOWING LINE FROM /etc/dovecot.conf
protocols = imap imaps pop3 pop3s
AS WE NEED TO SETUP DOVECOT TO ACCEPT MAIL AS MAILDIR FORMAT WE NEED TO CHANGE
FOLLOWING LINE ALSO.
mail_location = maildir:~/Maildir
[root@mail postfix]# service dovecot restart
Stopping Dovecot Imap: [FAILED]
Starting Dovecot Imap: [ OK ]
[root@mail postfix]# chkconfig dovecot on
[root@mail postfix]#
LET US NOW CONFIGURE SASL ON CLIENT SIDE AUTHENTICATION
[root@mail postfix]# chkconfig --list | grep saslauthd
saslauthd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
[root@mail postfix]#
[root@mail postfix]# chkconfig saslauthd on
ONE CAN REFFER [root@mail postfix]# vim /usr/share/doc/postfix-2.3.3/README_FILES/SASL_README
[root@mail postfix]# postconf smtpd_sasl_auth_enable
smtpd_sasl_auth_enable = no
[root@mail postfix]# postconf -e 'smtpd_sasl_auth_enable = yes'
[root@mail postfix]# postconf smtpd_sasl_auth_enable
smtpd_sasl_auth_enable = yes
FROM main.cf
#sasl authentication
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
permit_mynetworks permit_sasl_authenticated
smtpd_sasl_authenticated_header = yes
broken_sasl_auth_clients = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
---------------
Added dovecot configuration on date
-----------
Add following entry in "auth default " section at the end. ( /etc/dovecot.conf )
---------entry start-----------
socket listen {
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
} <-----------do not add this, it is already there to complete the auth default section.
-----------end----------
Thanks.
Rajat

Linux Memory use

#!/usr/bin/python
import os, sys, time
a="\x00"*(32*1024*1024) #alloc 32MiB
pid=os.fork()
if(not pid):
time.sleep(1)
sys.exit()
sizel=map(float,open("/proc/"+str(pid)+"/statm").readlines()[0].split()[1:3])
print "only %.1f%% reported as shared" % ((sizel[1]/sizel[0])*100)
os.wait()


--

import sys, os, string

if os.geteuid() != 0:
sys.stderr.write("Sorry, root permission required.\n");
sys.exit(1)

PAGESIZE=os.sysconf("SC_PAGE_SIZE")/1024 #KiB
our_pid=os.getpid()

#(major,minor,release)
def kernel_ver():
kv=open("/proc/sys/kernel/osrelease").readline().split(".")[:3]
for char in "-_":
kv[2]=kv[2].split(char)[0]
return (int(kv[0]), int(kv[1]), int(kv[2]))

kv=kernel_ver()

have_pss=0

#return Private,Shared
#Note shared is always a subset of rss (trs is not always)
def getMemStats(pid):
global have_pss
Private_lines=[]
Shared_lines=[]
Pss_lines=[]
Rss=int(open("/proc/"+str(pid)+"/statm").readline().split()[1])*PAGESIZE
if os.path.exists("/proc/"+str(pid)+"/smaps"): #stat
for line in open("/proc/"+str(pid)+"/smaps").readlines(): #open
if line.startswith("Shared"):
Shared_lines.append(line)
elif line.startswith("Private"):
Private_lines.append(line)
elif line.startswith("Pss"):
have_pss=1
Pss_lines.append(line)
Shared=sum([int(line.split()[1]) for line in Shared_lines])
Private=sum([int(line.split()[1]) for line in Private_lines])
#Note Shared + Private = Rss above
#The Rss in smaps includes video card mem etc.
if have_pss:
pss_adjust=0.5 #add 0.5KiB as this average error due to trunctation
Pss=sum([float(line.split()[1])+pss_adjust for line in Pss_lines])
Shared = Pss - Private
elif (2,6,1) <= kv <= (2,6,9):
Shared=0 #lots of overestimation, but what can we do?
Private = Rss
else:
Shared=int(open("/proc/"+str(pid)+"/statm").readline().split()[2])
Shared*=PAGESIZE
Private = Rss - Shared
return (Private, Shared)

def getCmdName(pid):
cmd = file("/proc/%d/status" % pid).readline()[6:-1]
exe = os.path.basename(os.path.realpath("/proc/%d/exe" % pid))
if exe.startswith(cmd):
cmd=exe #show non truncated version
#Note because we show the non truncated name
#one can have separated programs as follows:
#584.0 KiB + 1.0 MiB = 1.6 MiB mozilla-thunder (exe -> bash)
# 56.0 MiB + 22.2 MiB = 78.2 MiB mozilla-thunderbird-bin
return cmd

cmds={}
shareds={}
count={}
for pid in os.listdir("/proc/"):
try:
pid = int(pid) #note Thread IDs not listed in /proc/ which is good
if pid == our_pid: continue
except:
continue
try:
cmd = getCmdName(pid)
except:
#permission denied or
#kernel threads don't have exe links or
#process gone
continue
try:
private, shared = getMemStats(pid)
except:
continue #process gone
if shareds.get(cmd):
if have_pss: #add shared portion of PSS together
shareds[cmd]+=shared
elif shareds[cmd] < shared: #just take largest shared val
shareds[cmd]=shared
else:
shareds[cmd]=shared
cmds[cmd]=cmds.setdefault(cmd,0)+private
if count.has_key(cmd):
count[cmd] += 1
else:
count[cmd] = 1

#Add shared mem for each program
total=0
for cmd in cmds.keys():
cmds[cmd]=cmds[cmd]+shareds[cmd]
total+=cmds[cmd] #valid if PSS available

sort_list = cmds.items()
sort_list.sort(lambda x,y:cmp(x[1],y[1]))
sort_list=filter(lambda x:x[1],sort_list) #get rid of zero sized processes

#The following matches "du -h" output
#see also human.py
def human(num, power="Ki"):
powers=["Ki","Mi","Gi","Ti"]
while num >= 1000: #4 digits
num /= 1024.0
power=powers[powers.index(power)+1]
return "%.1f %s" % (num,power)

def cmd_with_count(cmd, count):
if count>1:
return "%s (%u)" % (cmd, count)
else:
return cmd

print " Private + Shared = RAM used\tProgram \n"
for cmd in sort_list:
print "%8sB + %8sB = %8sB\t%s" % (human(cmd[1]-shareds[cmd[0]]),
human(shareds[cmd[0]]), human(cmd[1]),
cmd_with_count(cmd[0], count[cmd[0]]))
if have_pss:
print "-" * 33
print " " * 24 + "%8sB" % human(total)
print "=" * 33
print "\n Private + Shared = RAM used\tProgram \n"

#Warn of possible inaccuracies
#2 = accurate & can total
#1 = accurate only considering each process in isolation
#0 = some shared mem not reported
#-1= all shared mem not reported
def shared_val_accuracy():
"""http://wiki.apache.org/spamassassin/TopSharedMemoryBug"""
if kv[:2] == (2,4):
if open("/proc/meminfo").read().find("Inact_") == -1:
return 1
return 0
elif kv[:2] == (2,6):
if os.path.exists("/proc/"+str(os.getpid())+"/smaps"):
if open("/proc/"+str(os.getpid())+"/smaps").read().find("Pss:")!=-1:
return 2
else:
return 1
if (2,6,1) <= kv <= (2,6,9):
return -1
return 0
else:
return 1

vm_accuracy = shared_val_accuracy()
if vm_accuracy == -1:
sys.stderr.write(
"Warning: Shared memory is not reported by this system.\n"
)
sys.stderr.write(
"Values reported will be too large, and totals are not reported\n"
)
elif vm_accuracy == 0:
sys.stderr.write(
"Warning: Shared memory is not reported accurately by this system.\n"
)
sys.stderr.write(
"Values reported could be too large, and totals are not reported\n"
)
elif vm_accuracy == 1:
sys.stderr.write(
"Warning: Shared memory is slightly over-estimated by this system\n"
"for each program, so totals are not reported.\n"
)

Performance and Tuning

Kernel

To successfully run enterprise applications, such as a database server, on your Linux distribution, you may be required to update some of the default kernel parameter settings. For example, the 2.4.x series kernel message queue parameter msgmni has a default value (for example, shared memory, or shmmax is only 33,554,432 bytes on Red Hat Linux by default) that allows only a limited number of simultaneous connections to a database. Here are some recommended values (by the IBM DB2 Support Web site) for database servers to run optimally:

- kernel.shmmax=268435456 for 32-bit
- kernel.shmmax=1073741824 for 64-bit
- kernel.msgmni=1024
- fs.file-max=8192
- kernel.sem="250 32000 32 1024"

Shared Memory

To view current settings, run command:
# more /proc/sys/kernel/shmmax

To set it to a new value for this running session, which takes effect immediately, run command:
# echo 268435456 > /proc/sys/kernel/shmmax

To set it to a new value permanently (so it survives reboots), modify the sysctl.conf file:
...
kernel.shmmax = 268435456
...

Semaphores

To view current settings, run command:
# more /proc/sys/kernel/sem
250 32000 32 1024

To set it to a new value for this running session, which takes effect immediately, run command:
# echo 500 512000 64 2048 > /proc/sys/kernel/sem
Parameters meaning:
SEMMSL - semaphores per ID
SEMMNS - (SEMMNI*SEMMSL) max semaphores in system
SEMOPM - max operations per semop call
SEMMNI - max semaphore identifiers

ulimits

To view current settings, run command:
# ulimit -a

To set it to a new value for this running session, which takes effect immediately, run command:
# ulimit -n 8800
# ulimit -n -1 // for unlimited; recommended if server isn't shared

Alternatively, if you want the changes to survive reboot, do the following:

- Exit all shell sessions for the user you want to change limits on.
- As root, edit the file /etc/security/limits.conf and add these two lines toward the end:
user1 soft nofile 16000
user1 hard nofile 20000
** the two lines above changes the max number of file handles - nofile - to new settings.
- Save the file.
- Login as the user1 again. The new changes will be in effect.


Message queues

To view current settings, run command:
# more /proc/sys/kernel/msgmni
# more /proc/sys/kernel/msgmax

To set it to a new value for this running session, which takes effect immediately, run command:
# echo 2048 > /proc/sys/kernel/msgmni
# echo 64000 > /proc/sys/kernel/msgmax

Network

Gigabit-based network interfaces have many performance-related parameters inside of their device driver such as CPU affinity. Also, the TCP protocol can be tuned to increase network throughput for connection-hungry applications.

Tune TCP

To view current TCP settings, run command:
# sysctl net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_time = 7200 // 2 hours
where net.ipv4.tcp_keepalive_time is a TCP tuning parameter.

To set a TCP parameter to a value, run command:
# sysctl -w net.ipv4.tcp_keepalive_time=1800

A list of recommended TCP parameters, values, and their meanings:

Tuning Parameter Tuning Value Description of impact
------------------------------------------------------------------------------
net.ipv4.tcp_tw_reuse
net.ipv4.tcp_tw_recycle 1 Reuse sockets in the time-wait state
---
net.core.wmem_max 8388608 Increase the maximum write buffer queue size
---
net.core.rmem_max 8388608 Increase the maximum read buffer queue size
---
net.ipv4.tcp_rmem 4096 87380 8388608 Set the minimum, initial, and maximum sizes for the
read buffer. Note that this maximum should be less
than or equal to the value set in net.core.rmem_max.
---
net.ipv4.tcp_wmem 4096 87380 8388608 Set the minimum, initial, and maximum sizes for the
write buffer. Note that this maximum should be less
than or equal to the value set in net.core.wmem_max.
---
timeout_timewait echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout Determines the time that must elapse before
TCP/IP can release a closed connection and reuse its resources.
This interval between closure and release is known as the TIME_WAIT
state or twice the maximum segment lifetime (2MSL) state.
During this time, reopening the connection to the client and
server cost less than establishing a new connection. By reducing the
value of this entry, TCP/IP can release closed connections faster, providing
more resources for new connections. Adjust this parameter if the running application
requires rapid release, the creation of new connections, and a low throughput
due to many connections sitting in the TIME_WAIT state.

Disk I/O

Choose the Right File System

Use 'ext3' file system in Linux.
- It is enhanced version of ext2
- With journaling capability - high level of data integrity (in event of unclean shutdown)
- It does not need to check disks on unclean shutdown and reboot (time consuming)
- Faster write - ext3 journaling optimizes hard drive head motion

# mke2fs -j -b 2048 -i 4096 /dev/sda
mke2fs 1.32 (09-Nov-2002)
/dev/sda is entire device, not just one partition!
Proceed anyway? (y,n) y
Filesystem label=
OS type: Linux
Block size=2048 (log=1)
Fragment size=2048 (log=1)
13107200 inodes, 26214400 blocks
1310720 blocks (5.00%) reserved for the super user
First data block=0
1600 block groups
16384 blocks per group, 16384 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
16384, 49152, 81920, 114688, 147456, 409600, 442368, 802816, 1327104,
2048000, 3981312, 5619712, 10240000, 11943936

Writing inode tables: done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

Use 'noatime' File System Mount Option

Use 'noatime' option in the file system boot-up configuration file 'fstab'. Edit the fstab file under /etc. This option works the best if external storage is used, for example, SAN:

# more /etc/fstab
LABEL=/ / ext3 defaults 1 1
none /dev/pts devpts gid=5,mode=620 0 0
none /proc proc defaults 0 0
none /dev/shm tmpfs defaults 0 0
/dev/sdc2 swap swap defaults 0 0
/dev/cdrom /mnt/cdrom udf,iso9660 noauto,owner,kudzu,ro 0 0
/dev/fd0 /mnt/floppy auto noauto,owner,kudzu 0 0
/dev/sda /database ext3 defaults,noatime 1 2
/dev/sdb /logs ext3 defaults,noatime 1 2
/dev/sdc /multimediafiles ext3 defaults,noatime 1 2

Tune the Elevator Algorithm in Linux Kernel for Disk I/O

After choosing the file system, there are several kernel and mounting options that can affect it. One such kernel setting is the elevator algorithm. Tuning the elevator algorithm helps the system balance the need for low latency with the need to collect enough data to efficiently organize batches of read and write requests to the disk. The elevator algorithm can be adjusted with the following command:

# elvtune -r 1024 -w 2048 /dev/sda
/dev/sda elevator ID 2
read_latency: 1024
write_latency: 2048
max_bomb_segments: 6

The parameters are: read latency (-r), write latency (-w) and the device affected.
Red Hat recommends using a read latency half the size of the write latency (as shown).
As usual, to make this setting permanent, add the 'elvtune' command to the
/etc/rc.d/rc.local script.

Others

Disable Unnecessary Daemons (They Take up Memory and CPU)

There are daemons (background services) running on every server that are probably not needed. Disabling these daemons frees memory, decreases startup time, and decreases the number of processes that the CPU has to handle. A side benefit to this is increased security of the server because fewer daemons mean fewer exploitable processes.


Some example Linux daemons running by default (and should be disabled). Use command:

#/sbin/chkconfig --levels 2345 sendmail off
#/sbin/chkconfig sendmail off

Daemon


Description

apmd


Advanced power management daemon

autofs


Automatically mounts file systems on demand (i.e.: mounts a CD-ROM automatically)

cups


Common UNIX� Printing System

hpoj


HP OfficeJet support

isdn


ISDN modem support

netfs


Used in support of exporting NFS shares

nfslock


Used for file locking with NFS

pcmcia


PCMCIA support on a server

rhnsd


Red Hat Network update service for checking for updates and security errata

sendmail


Mail Transport Agent

xfs


Font server for X Windows

Shutdown GUI

Normally, there is no need for a GUI on a Linux server. All administration tasks can be achieved by the command line, redirecting the X display or through a Web browser interface. Modify the 'inittab' file to set boot level as 3:

To set the initial runlevel (3 instead of 5) of a machine at boot,
modify the /etc/inittab file as shown:

http://i35.tinypic.com/2d2jdbr.jpg

How do I Find Out Linux CPU Utilization


Whenever a Linux system CPU is occupied by a process, it is unavailable for processing other requests. Rest of pending requests must wait till CPU is free. This becomes a bottleneck in the system. Following command will help you to identify CPU utilization, so that you can troubleshoot CPU related performance problems.

Finding CPU utilization is one of the important tasks. Linux comes with various utilities to report CPU utilization. With these commands, you will be able to find out:

* CPU utilization
* Display the utilization of each CPU individually (SMP cpu)
* Find out your system's average CPU utilization since the last reboot etc
* Determine which process is eating the CPU(s)
Old good top command to find out Linux cpu load

The top program provides a dynamic real-time view of a running system. It can display system summary information as well as a list of tasks currently being managed by the Linux kernel.
The top command monitors CPU utilization, process statistics, and memory utilization. The top section contains information related to overall system status - uptime, load average, process counts, CPU status, and utilization statistics for both memory and swap space.
Top command to find out Linux cpu usage

Type the top command:
$ top

Output:

You can see Linux CPU utilization under CPU stats. The task’s share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time. In a true SMP environment (multiple CPUS), top will operate in number of CPUs. Please note that you need to type q key to exit the top command display.

The top command produces a frequently-updated list of processes. By default, the processes are ordered by percentage of CPU usage, with only the "top" CPU consumers shown. The top command shows how much processing power and memory are being used, as well as other information about the running processes.
Find Linux CPU utilization using mpstat and other tools

Please note that you need to install special package called sysstat to take advantage of following commands. This package includes system performance tools for Linux (Red Hat Linux / RHEL includes these tools by default).

# apt-get install sysstat
Use up2date command if you are using RHEL:
# up2date sysstat
Display the utilization of each CPU individually using mpstat

If you are using SMP (Multiple CPU) system, use mpstat command to display the utilization of each CPU individually. It report processors related statistics. For example, type command:
# mpstat Output:

Linux 2.6.15.4 (debian) Thursday 06 April 2006

05:13:05 IST CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
05:13:05 IST all 16.52 0.00 2.87 1.09 0.07 0.02 0.00 79.42 830.06

The mpstat command display activities for each available processor, processor 0 being the first one. Global average activities among all processors are also reported. The mpstat command can be used both on SMP and UP machines, but in the latter, only global average activities will be printed.:
# mpstat -P ALL
Output:

Linux 2.6.15.4 (wwwportal1.xxxx.co.in) Thursday 06 April 2006

05:14:58 IST CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
05:14:58 IST all 16.46 0.00 2.88 1.08 0.07 0.02 0.00 79.48 835.96
05:14:58 IST 0 16.46 0.00 2.88 1.08 0.07 0.02 0.00 79.48 835.96
05:14:58 IST 1 15.77 2.70 3.17 2.01 0.05 0.03 0.00 81.44 822.54

Another output from my HP Dual Opteron 64 bit server:# mpstat -P ALLOutput:

Linux 2.6.5-7.252-smp (ora9.xxx.in) 04/07/06

07:44:18 CPU %user %nice %system %iowait %irq %soft %idle intr/s
07:44:18 all 3.01 57.31 0.36 0.13 0.01 0.00 39.19 1063.46
07:44:18 0 5.87 69.47 0.44 0.05 0.01 0.01 24.16 262.11
07:44:18 1 1.79 48.59 0.36 0.23 0.00 0.00 49.02 268.92
07:44:18 2 2.19 42.63 0.28 0.16 0.01 0.00 54.73 260.96
07:44:18 3 2.17 68.56 0.34 0.06 0.03 0.00 28.83 271.47

Report CPU utilization using sar command

You can display today’s CPU activity, with sar command:
# sar
Output:

Linux 2.6.9-42.0.3.ELsmp (dellbox.xyz.co.in) 01/13/2007

12:00:02 AM CPU %user %nice %system %iowait %idle
12:10:01 AM all 1.05 0.00 0.28 0.04 98.64
12:20:01 AM all 0.74 0.00 0.34 0.38 98.54
12:30:02 AM all 1.09 0.00 0.28 0.10 98.53
12:40:01 AM all 0.76 0.00 0.21 0.03 99.00
12:50:01 AM all 1.25 0.00 0.32 0.03 98.40
01:00:01 AM all 0.80 0.00 0.24 0.03 98.92
...
.....
..
04:40:01 AM all 8.39 0.00 33.17 0.06 58.38
04:50:01 AM all 8.68 0.00 37.51 0.04 53.78
05:00:01 AM all 7.10 0.00 30.48 0.04 62.39
05:10:01 AM all 8.78 0.00 37.74 0.03 53.44
05:20:02 AM all 8.30 0.00 35.45 0.06 56.18
Average: all 3.09 0.00 9.14 0.09 87.68

Comparison of CPU utilization

The sar command writes to standard output the contents of selected cumulative activity counters in the operating system. The accounting system, based on the values in the count and interval parameters. For example display comparison of CPU utilization; 2 seconds apart; 5 times, use:
# sar -u 2 5
Output (for each 2 seconds. 5 lines are displayed):

Linux 2.6.9-42.0.3.ELsmp (www1lab2.xyz.ac.in) 01/13/2007

05:33:24 AM CPU %user %nice %system %iowait %idle
05:33:26 AM all 9.50 0.00 49.00 0.00 41.50
05:33:28 AM all 16.79 0.00 74.69 0.00 8.52
05:33:30 AM all 17.21 0.00 80.30 0.00 2.49
05:33:32 AM all 16.75 0.00 81.00 0.00 2.25
05:33:34 AM all 14.29 0.00 72.43 0.00 13.28
Average: all 14.91 0.00 71.49 0.00 13.61

Where,

* -u 12 5 : Report CPU utilization. The following values are displayed:
o %user: Percentage of CPU utilization that occurred while executing at the user level (application).
o %nice: Percentage of CPU utilization that occurred while executing at the user level with nice priority.
o %system: Percentage of CPU utilization that occurred while executing at the system level (kernel).
o %iowait: Percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request.
o %idle: Percentage of time that the CPU or CPUs were idle and the system did not have an outstanding disk I/O request.

To get multiple samples and multiple reports set an output file for the sar command. Run the sar command as a background process using.
# sar -o output.file 12 8 >/dev/null 2>&1 &
Better use nohup command so that you can logout and check back report later on:
# nohup sar -o output.file 12 8 >/dev/null 2>&1 &

All data is captured in binary form and saved to a file (data.file). The data can then be selectively displayed ith the sar command using the -f option.
# sar -f data.file
Task: Find out who is monopolizing or eating the CPUs

Finally, you need to determine which process is monopolizing or eating the CPUs. Following command will displays the top 10 CPU users on the Linux system.
# ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10
OR
# ps -eo pcpu,pid,user,args | sort -r -k1 | less
Output:

%CPU PID USER COMMAND
96 2148 vivek /usr/lib/vmware/bin/vmware-vmx -C /var/lib/vmware/Virtual Machines/Ubuntu 64-bit/Ubuntu 64-bit.vmx -@ ""
0.7 3358 mysql /usr/libexec/mysqld --defaults-file=/etc/my.cnf --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --skip-locking --socket=/var/lib/mysql/mysql.sock
0.4 29129 lighttpd /usr/bin/php
0.4 29128 lighttpd /usr/bin/php
0.4 29127 lighttpd /usr/bin/php
0.4 29126 lighttpd /usr/bin/php
0.2 2177 vivek [vmware-rtc]
0.0 9 root [kacpid]
0.0 8 root [khelper]

Now you know vmware-vmx process is eating up lots of CPU power. ps command displays every process (-e) with a user-defined format (-o pcpu). First field is pcpu (cpu utilization). It is sorted in reverse order to display top 10 CPU eating process.
iostat command

You can also use iostat command which report Central Processing Unit (CPU) statistics and input/output statistics for devices and partitions. It can be use to find out your system's average CPU utilization since the last reboot.
# iostatOutput:

Linux 2.6.15.4 (debian) Thursday 06 April 2006

avg-cpu: %user %nice %system %iowait %steal %idle
16.36 0.00 2.99 1.06 0.00 79.59

Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
hda 0.00 0.00 0.00 16 0
hdb 6.43 85.57 166.74 875340 1705664
hdc 0.03 0.16 0.00 1644 0
sda 0.00 0.00 0.00 24 0

You may want to use following command, which gives you three outputs every 5 seconds (as previous command gives information since the last reboot):$ iostat -xtc 5 3
GUI tools for your laptops/desktops

Above tools/commands are quite useful on remote server. For local system with X GUI installed you can try out gnome-system-monitor. It allows you to view and control the processes running on your system. You can access detailed memory maps, send signals, and terminate the processes.
$ gnome-system-monitor

In addition, the gnome-system-monitor provides an overall view of the resource usage on your system, including memory and CPU allocation.

gnome-system-monitor - view and control the processes

Further readings

* For more information and command option please read man pages of top, iostat, mpstat, sar, ps commands.

Linux Limit CPU Usage Per Process

I don't want background process to eat all my CPU. I know how to find out CPU utilization but how do I limit the cpu usage of a process under Linux operating system? How do I force a process to limit itself to 25% only?

You can use cpulimit program that attempts to limit the cpu usage of a process. Limits are expressed in percentage and not in cpu time. cpulimit does not act on the nice value or other scheduling priority stuff, but on the real cpu usage. Also, it is able to adapt itself to the overall system load, dynamically and quickly.
Install cpulimit

Type the following commands to install latest stable release:
# cd /tmp
# wget 'http://downloads.sourceforge.net/cpulimit/cpulimit-1.1.tar.gz'
# tar cpulimit-1.1.tar.gz
# cd cpulimit-1.1
# make
# cp cpulimit /usr/local/sbin/
# rm -rf cpulimit*
A note about Debian / Ubuntu Linux users

Type the following command to install cpulimit:
$ sudo apt-get update
$ sudo apt-get install cpulimit
How do I use cpulimit?

To limit CPU usage of the process called firefox to 30%, enter:
# cpulimit -e firefox -l 30
To limit CPU usage of the process to 30% by using its PID, enter:
# cpulimit -p 1313 -l 30
To find out PID of the process use any of the following:
# ps aux | less
# ps aux | grep firefox
# pgrep -u vivek php-cgi
# pgrep lighttpd
You can also use absolute path name of the executable, enter:
# cpulimit -P /opt/firefox/firebox -l 30
Where,

* -p : Process PID.
* -e : Process name.
* -l : percentage of CPU allowed from 0 to 100.
* -P: absolute path name of the executable program file.

Root vs Normal User Account

From the project webpage:

cpulimit should run at least with the same user running the controlled process. But it is much better if you run cpulimit as root, in order to have a higher priority and a more precise control.

A Note About SMP (Multicore / MultiCpu) Systems

Again quoting from the project webpage:

If your machine has one processor you can limit the percentage from 0% to 100%, which means that if you set for example 50%, your process cannot use more than 500 ms of cpu time for each second. But if your machine has four processors, percentage may vary from 0% to 400%, so setting the limit to 200% means to use no more than half of the available power. In any case, the percentage is the same of what you see when you run top.

Related Throttling Utilities

1. ionice utility - Avoid sudden outburst of backup shell script / program disk I/O.
2. Limit disk I/O for rsync tool.
3. Linux nice command: Run Process With Modified Scheduling Priority ( nicenesses )
4. renice command: Change the Priority of a Already Running Process

LAMP Server Step by Step

LAMP is short for Linux, Apache, MySQL, PHP. This tutorial shows how you can install an Apache2 webserver on an OpenSUSE 11.1 server with PHP5 support (mod_php) and MySQL support.

I do not issue any guarantee that this will work for you!


1 Preliminary Note

In this tutorial I use the hostname server1.example.com with the IP address 192.168.0.100. These settings might differ for you, so you have to replace them where appropriate.

2 Installing MySQL 5.0

First we install MySQL 5.0 like this:

yast2 -i mysql mysql-client

Then we create the system startup links for MySQL (so that MySQL starts automatically whenever the system boots) and start the MySQL server:

chkconfig --add mysql
/etc/init.d/mysql start

To secure the MySQL installation, run:

mysql_secure_installation

Now you will be asked several questions:

server1:~ # mysql_secure_installation




NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!


In order to log into MySQL to secure it, we'll need the current
password for the root user. If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): <-- ENTER OK, successfully used password, moving on... Setting the root password ensures that nobody can log into the MySQL root user without the proper authorisation. Set root password? [Y/n] <-- Y New password: <-- fill in your desired MySQL root password Re-enter new password: <-- confirm that password Password updated successfully! Reloading privilege tables.. ... Success! By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] <-- Y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] <-- Y ... Success! By default, MySQL comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] <-- Y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] <-- Y ... Success! Cleaning up... All done! If you've completed all of the above steps, your MySQL installation should now be secure. Thanks for using MySQL! server1:~ # Now your MySQL setup should be secured. 3 Installing Apache2 Apache2 is available as an OpenSUSE package, therefore we can install it like this: yast2 -i apache2 Now configure your system to start Apache at boot time... chkconfig --add apache2 ... and start Apache: /etc/init.d/apache2 start http://i33.tinypic.com/2u6ikwo.jpg Now direct your browser to http://192.168.0.100, and you should see the Apache2 placeholder page (don't worry about the 403 error, this happens because there's no index file (e.g. index.html) in the document root directory): Apache's default document root is /srv/www/htdocs/ on OpenSUSE, and the configuration file is /etc/apache2/httpd.conf. Additional configurations are stored in the /etc/apache2/conf.d/ directory. 4 Installing PHP5 We can install PHP5 and the Apache PHP5 module as follows: yast2 -i apache2-mod_php5 We must restart Apache afterwards: /etc/init.d/apache2 restart 5 Testing PHP5 / Getting Details About Your PHP5 Installation The document root of the default web site is /srv/www/htdocs/. We will now create a small PHP file (info.php) in that directory and call it in a browser. The file will display lots of useful details about our PHP installation, such as the installed PHP version. vi /srv/www/htdocs/info.php

Now we call that file in a browser (e.g. http://192.168.0.100/info.php):

http://i34.tinypic.com/p402g.jpg

As you see, PHP5 is working, and it's working through the Apache 2.0 Handler, as shown in the Server API line. If you scroll further down, you will see all modules that are already enabled in PHP5. MySQL is not listed there which means we don't have MySQL support in PHP5 yet.


6 Getting MySQL Support In PHP5

To get MySQL support in PHP, we can install the php5-mysql package. It's a good idea to install some other PHP5 modules as well as you might need them for your applications:

yast2 -i php5-mysql php5-bcmath php5-bz2 php5-calendar php5-ctype php5-curl php5-dbase php5-dom php5-ftp php5-gd php5-gettext php5-gmp php5-iconv php5-imap php5-ldap php5-mbstring php5-mcrypt php5-ncurses php5-odbc php5-openssl php5-pcntl php5-pgsql php5-posix php5-shmop php5-snmp php5-soap php5-sockets php5-sqlite php5-sysvsem php5-tokenizer php5-wddx php5-xmlrpc php5-xsl php5-zlib php5-exif php5-fastcgi php5-pear php5-sysvmsg php5-sysvshm

Now restart Apache2:

/etc/init.d/apache2 restart

Now reload http://192.168.0.100/info.php in your browser and scroll down to the modules section again. You should now find lots of new modules there, including the MySQL module:

http://i37.tinypic.com/np2qg0.jpg

7 phpMyAdmin

phpMyAdmin is a web interface through which you can manage your MySQL databases.

phpMyAdmin can be installed as follows:

cd /srv/www/htdocs
wget http://downloads.sourceforge.net/project/phpmyadmin/phpMyAdmin/3.2.2/phpMyAdmin-3.2.2-all-languages.tar.gz?use_mirror=dfn
tar xvfz phpMyAdmin-3.2.2-all-languages.tar.gz
mv phpMyAdmin-3.2.2-all-languages phpmyadmin

Afterwards, you can access phpMyAdmin under http://192.168.0.100/phpmyadmin/:

http://i38.tinypic.com/15hykyc.jpg

8 Links

* Apache: http://httpd.apache.org/
* PHP: http://www.php.net/
* MySQL: http://www.mysql.com/
* OpenSUSE: http://www.opensuse.org/
* phpMyAdmin: http://www.phpmyadmin.net/

Wednesday, October 14, 2009

Linux System Info


#!/bin/sh
# This script was written by Rajat Patel.
# This is the script is the result of joint effort of Rajat Patel
# You can contact the author at 
# THIS IS A INTERACTIVE PROGRAM TO DISPLAY YOUR SYSTEM INFORMATION.
# TYPE ./sysinfo --help FOR OPTIONS


# THE WHOLE SCRIPT CAN BE BROADLY DIVIDED INTO 3 MODULES -
###################################################################################################################
# MODULE 1:- #
# THIS IS RESPONSIBLE FOR CLEAN UP JOBS AND ALSO PERFORMS EXCEPTION HANDLING. #
###################################################################################################################

# CLEANUP CLEANS THE TEMPORARY FILE(S) CREATED
cleanup(){

rm -f "$TEMP" 2>> "$TMPLOG"
rm -f "$CHOICE" 2>> "$TMPLOG"
if [ `cat "$TMPLOG" | wc -l` -gt 0 ]
then
printerr 4 1
else
rm -f "$TMPLOG"
fi
if [ -d "$SYSINFODIR" ] && [ `ls -al "$SYSINFODIR" | wc -l` -le 4 ]
then
rm -fr "$SYSINFODIR"
fi


}

# QUIT FUNCTION IS CALLED IF THE SCRIPT IS KILLED PREMATURELY DURING EXECUTION IT SIMPLY PERFORMS CLEANUP
quit(){
cleanup
if [ -z $@ ]
then
clear
fi
exit 2
}

# INIT INITITALIZES THE VARIABLE AND THE ENVIRONMENT
init(){

script_name="$0"
VERSION=2.3
OLD_PATH=`echo $PATH`
PATH=$PATH:/sbin:/usr/sbin
SYSINFODIR="$HOME/S&M-Sysinfo"
TEMP="${SYSINFODIR}/sysinfo.tmp"
ERRLOG="${SYSINFODIR}/sysinfo_err.log"
TMPLOG="${SYSINFODIR}/sysinfo.log"
CHOICE="${SYSINFODIR}/sysinfo_choice.tmp"
DATE=`date '+%Y.%m.%d'`
SAVEINFO="${SYSINFODIR}/sysinfo.out.${DATE}"
ERRORSTRING="NULL"
TRIVIALCODE="1"
TITLE=""

if [ -z "$*" ]
then

if [ -f "$SYSINFODIR" ]
then
cat "$SYSINFODIR" >> "${SYSINFODIR}.old"
rm -f "$SYSINFODIR" 2> /dev/null
fi
if [ -d "$SYSINFODIR" ]
then
echo > /dev/null
else
mkdir "$SYSINFODIR"
echo -e "This folder $SYSINFODIR was created by the program $0\n\n" >> "${SYSINFODIR}/README"
echo -e 'S&M Sysinfo, Sysinfo by Rajat!!' >> "${SYSINFODIR}/README"
echo -e "sysinfo Version $VERSION" >> "${SYSINFODIR}/README"
echo -e "Author -- Rajat Patel, Yeswedeal" >> "${SYSINFODIR}/README"
echo -e "Copyright (C) 2009 Rajat Patel" >> "${SYSINFODIR}/README"
echo -e "This is free software distributed under the terms of GPL\n\n\n\n\n" >> "${SYSINFODIR}/README"

fi

if [ -f "$TMPLOG" ]
then
cat "$TMPLOG" >> "${TMPLOG}.old"
rm -f "$TMPLOG"
fi


if [ -f "$TEMP" ] || [ -f "$CHOICE" ]
then
rm -f "$TEMP"
fi
if [ -f "$CHOICE" ]
then
rm -f "$CHOICE"
fi

echo -e "\nInitializing Graphical Mode... Successful\n\nPress OK to continue.\n(Press 'Esc' and click 'OK' to enter text mode)" > $TEMP
dialog --title "GUI TEST" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72 2> /dev/null



if [ "$?" -eq 0 ]
then
gui_support=y
else
gui_support=n
clear
echo -e "\nInitializing Graphical Mode... Failed!!\nThis can even happen if you press Esc during initialization of graphical mode.\nThe program will run in text mode\n\n"
echo "Press Enter to continue...."
read
fi



fi


}

# PRINTERR IS FOR TAKING THE NECESSARY ACTION IF AN ERROR OCCURS. IT PRINTS AN ERROR MESSAGE DEPENDING ON
# THE FIRST ARGUMENT AND THEN EITHER EXITS AFTER GENERATING A BUG REPORT AFTER GETTING PERMISSION FROM THE
# USER RUNNING THE SCRIPT WITHIN THE USER'S HOME DIRECTORY UNDER THE NAME "bug_report_sysinfo" OR SIMPLY
# RETURNS TO THE POINT WHERE THE EXCEPTION OCCURED DEPENDING UPON THE SECOND ARGUMENT.
printerr(){

case "$1" in
"1")
if [ "$gui_support" = 'y' ]
then
dialog --colors --title "\Z1$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\n\Z1Sorry, I was unable to retrieve the required information from your system.\nPOSSIBLE CAUSE OF ERROR AND SOLUTION :-\nIt seems that the proc filesystem is not enabled in the kernel - Run script after enabling it.If it is enabled then it may not be mounted - Run script after mounting it. If it is mounted then you do not have enough permissions to retrieve information from it - Run the script as root." 19 72
else
echo -e "\nSorry, I was unable to retrieve the required information from your system.\nPOSSIBLE CAUSE OF ERROR AND SOLUTION :-\nIt seems that the proc filesystem is not enabled in the kernel - Run script after enabling it.If it is enabled then it may not be mounted - Run script after mounting it. If it is mounted then you do not have enough permissions to retrieve information from it - Run the script as root."
echo -e "\nPress Enter to continue..."
read
fi
;;
"2")
if [ "$gui_support" = 'y' ]
then
dialog --colors --title "\Z1$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --colors --msgbox "\n\Z1Sorry, I was unable to retrieve the required information from your system.\nPOSSIBLE CAUSE OF ERROR AND SOLUTION :-\nEither your system does not support showing the details you are looking for or you do not have enough permissions to do that. If you are not root try runnig the script with root priviledge." 19 72
else
echo -e "\nSorry, I was unable to retrieve the required information from your system.\nPOSSIBLE CAUSE OF ERROR AND SOLUTION :-\nEither your system does not support showing the details you are looking for or you do not have enough permissions to do that. If you are not root try runnig the script with root priviledge."
echo -e "\nPress Enter to continue..."
read
fi
;;
"3")
if [ "$gui_support" = 'y' ]
then
dialog --colors --title "\Z1$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --colors --msgbox "\Z1Sorry, I was unable to retrieve the required information from your system.\nPOSSIBLE CAUSE OF ERROR AND SOLUTION :-\nIt seems you do not have enough permissions. Try runnig the script with root priviledge." 19 72
else
echo -e "Sorry, I was unable to retrieve the required information from your system.\nPOSSIBLE CAUSE OF ERROR AND SOLUTION :-\nIt seems you do not have enough permissions. Try runnig the script with root priviledge."
echo -e "\nPress Enter to continue..."
read
fi
;;

"4")
echo -e "\n\n------------------------------------------------------------" >> "$TMPLOG"
echo -e "Above Error Report Genenrated on:- " >> "$TMPLOG"
date >> "$TMPLOG"
echo -e "********************\n\n\n\n" >> "$TMPLOG"

if [ "$gui_support" = 'y' ]
then
dialog --colors --title "\Z1ERROR" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\Z1A log file -- $TMPLOG was created. This happened because I faced some problem during my execution. If you suspect a bug, report it to the author at sending him the log file alongwith." 19 72
else
echo -e "A log file -- $TMPLOG was created. This happened because I faced some problem during my execution. If you suspect a bug, report it to the author at sending him the log file alongwith."
echo -e "\nPress Enter to continue..."
read
fi
;;
"5")
if [ "$gui_support" = 'y' ]
then
dialog --colors --title "\Z1$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --colors --msgbox "\n\Z1Sorry, I was unable to retrieve the required information from your system.\nPOSSIBLE CAUSE OF ERROR AND SOLUTION :-\nYour system does not support showing the details you are looking for." 19 72
else
echo -e "\nSorry, I was unable to retrieve the required information from your system.\nPOSSIBLE CAUSE OF ERROR AND SOLUTION :-\nYour system does not support showing the details you are looking for."
echo -e "\nPress Enter to continue..."
read
fi
;;
*)
if [ "$gui_support" = 'y' ]
then
dialog --colors --title "\Z1ERROR" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\n\n\Z1It seems someone has modified this script. Please do not report bug to author. Instead try and contact the person/media/website/agency from where you got this script." 19 72
else
echo -e "\n\nIt seems someone has modified this script. Please do not report bug to author. Instead try and contact the person/media/website/agency from where you got this script."
echo -e "\nPress Enter to continue..."
read
fi
;;
esac

if [ "$2" = "0" ] && [ "$ERRORSTRING" != "NULL" ]
then
if [ "$gui_support" = "y" ]
then
dialog --colors --title "\Z1BUG REPORT GENERATOR" --backtitle "Author - Rajat Patel, Yeswedeal" --yesno "\Z1If the mentioned steps did not solve your problem then report a bug to the author. Send the bug report that is automatically generated by this script along with your system information. However do not care to report a bug if:- \nyou do not want this script to generate the bug report. Or you are running this script in a non Linux operating system. This script is written for Linux only.\nReport bugs to the author at rajat@Yeswedeal.com\n\nA bug report will be generated -- $ERRLOG. If it already exists, it will won't get overwritten, it will be appended \nMake sure you have write permission in your home directory before pressing yes\nShould this script generate a bug report? " 19 72

if [ "$?" = "0" ]
then
create_bug_report=y
fi
else
echo -e "If the mentioned steps did not solve your problem then report a bug to the author. Send the bug report that is automatically generated by this script along with your system information. However do not care to report a bug if:- \nyou do not want this script to generate the bug report. Or you are running this script in a non Linux operating system. This script is written for Linux only.\nReport bugs to the author at rajat@Yeswedeal.com\n\nA bug report will be generated -- $ERRLOG. If it already exists, it will won't get overwritten, it will be appended \nMake sure you have write permission in your home directory before typing \'y\'\nShould this script generate a bug report? (y/n) ..."
read create_bug_report
fi


if [ "$create_bug_report" = 'y' ]
then

if [ "$gui_support" = "y" ]
then
dialog --colors --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "\Z1Generating Bug Report.\nPlease wait...\n(This may take a long time)" 9 45
else
echo -e "\n\nGenerating Bug Report.(This may take a long time)\nPlease Wait..."
fi

echo -e "\n\n------------------------------------------------------------\n" >> $ERRLOG
echo -ne "\nError Report Generated on:- " >> $ERRLOG
date >> $ERRLOG

echo -e "\n\nScript Output:-\n\n" >> $ERRLOG

$script_name -a >> $ERRLOG 2>> $ERRLOG

echo -e "\n\n------------------------------------------------------------\n\n" >> $ERRLOG
echo "Error_code: $1" >> $ERRLOG
bug_report_gen=$?
if [ "$bug_report_gen" != "0" ] && [ "$gui_support" = "y" ]
then
dialog --title "ERROR" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nI faced some problem. Bug report was not generated.\n" 15 65
return
fi
if [ "$bug_report_gen" != "0" ] && [ "$gui_support" = "y" ]
then
echo -e "\nI faced some problem. Bug report was not generated.\n"
echo -e "Press Enter to continue..."
read
return
fi

case "$3" in
"proc")
echo -e "\nRoot Directory:\n " >> $ERRLOG
ls -l / >> $ERRLOG 2>> $ERRLOG
echo -e "\nProc Directory:\n " >> $ERRLOG
ls /proc -lR >> $ERRLOG 2>> $ERRLOG
echo -e "\n" >> $ERRLOG
;;
"passwd")
echo -e "\netc Directory:\n" >> $ERRLOG
ls -lR /etc/ >> $ERRLOG 2>> $ERRLOG
echo -e "\n\npasswd:\n" >> $ERRLOG
cat /etc/passwd >> $ERRLOG 2>> $ERRLOG
echo -e "\n" >> $ERRLOG
;;
"group")
echo -e "\netc Directory:\n" >> $ERRLOG
ls -lR /etc/ >> $ERRLOG 2>> $ERRLOG
echo -e "\n\ngroup:\n" >> $ERRLOG
cat /etc/group >> $ERRLOG 2>> $ERRLOG
echo -e "\n" >> $ERRLOG
;;

*)
echo -e "\n Trying to execute -- $3 \n" >> $ERRLOG
$3 >> $ERRLOG 2>> $ERRLOG
echo -e "\n" >> $ERRLOG
;;
esac

if [ "$bug_report_gen" = "0" ] && [ "$gui_support" = "y" ]
then
dialog --title "BUG REPORT GENERATOR" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nBug report generated: $ERRLOG\n" 15 65
return
else
echo -e "\nBug report generated: $ERRLOG\n"
echo -e "\nPress Enter to continue..."
read
fi

return
fi

if [ "$create_bug_report" != "y" ] && [ "$gui_support" = "y" ]
then
dialog --title "BUG REPORT GENERATOR" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nBug report was not generated\nAborted by user.\n" 15 65
return
else
echo -e "\nBug report was not generated\nAborted by user.\n"
echo -e "\nPress Enter to continue..."
read
fi

fi
}

#FOR SAVING TO DISK
save(){

echo -e "---------------------------------------------------------------------------" >> "$SAVEINFO"
echo -ne " Following information saved on : " >> "$SAVEINFO"
date >> "$SAVEINFO"
echo -e "---------------------------------------------------------------------------\n" >> "$SAVEINFO"
cat "$TEMP" >> "$SAVEINFO"
echo -e "############################################################################\n\n" >> "$SAVEINFO"
}

#THIS SHOWS THE EXIT MESSAGE.
exit_msg(){

if [ "$gui_support" = 'y' ]
then
dialog --clear --title "THANK YOU FOR USING THIS PROGRAM" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nsysinfo Version $VERSION\nCopyright (C) 2009 Rajat Patel\nThis is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE\nAuthors:-\nRajat Patel" 15 62
else
clear
echo -e "\n\n\t\t THANK YOU FOR USING THIS PROGRAM\n\n"
echo -e "\nsysinfo Version $VERSION\nCopyright (C) 2009 Rajat Patel\nThis is free software; see the source for copying conditions.\nThere is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE\n\nAuthors:-\nRajat Patel"
echo -e "\nPress Enter to exit...."
read
fi

}


# END OF MODULE 1
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#




####################################################################################################################
# MODULE 2:- #
#IT IS THIS PART WHICH IS ACTUALLY RESPONSIBLE FOR DISPLAYING ALL THE INFORMATION. #
####################################################################################################################

#***********************************************#
# SUBMODULE A:- #
# THIS SUBMODULE DISPLAYS THE USER INFORMATION. #
#***********************************************#

# THIS IS FOR PRINTING THE LIST OF ALL THE USERS IN THE HOST MACHINE
usertot(){


if [ ! -r /etc/passwd ]
then
echo -e "ERROR : username of all the users is not available"
TITLE='ERROR - USERNAME NOT RETRIEVABLE'
TRIVIALCODE=0
ERRORSTRING="passwd"
return 3
fi
TITLE="USER INFORMATION"
if [ `awk -F: '{ if( $3 >= 500 && $3 <= 9999 ) printf "%s\n", $1 ; }' /etc/passwd | wc -l` -eq 0 ] then echo -e "\n\nNO ORDINARY USERS FOUND!!" return fi echo " ****************************************" echo -e " ==::List of Users in The Local Host::==" echo " ****************************************" echo -e "*********************************************************************" echo -e "\n Username Full Name Home Login Shell" echo -e "*********************************************************************" awk -F: '{ if( $3 >= 500 && $3 <= 9999 ) printf " %-10s %-18s %-16s %-9s \n", $1, $5, $6, $7 }' /etc/passwd echo "*********************************************************************" echo -e "\n" return 0 } # THIS PRINTS OUT INFORMATION OF ALL THE USERS LOGGED IN THE HOST MACHINE userlog(){ type who > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : User information is not available.\nSomething is terribly wrong with your system."
TITLE='ERROR - USER INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING="who"
return 5
else
who > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : User information is not available.\nSomething is terribly wrong with your system."
TITLE='ERROR - CONFIGURATION INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING="who"
return 2
fi
fi

TITLE="USERS LOGGED IN"

echo -e " *****************************************"
echo -e " ==::List of Users Currently Logged in::=="
echo -e " *****************************************"
echo " ***************************************************"
echo ' USERNAME TERMINAL TIME LOGGED IN'
echo " ***************************************************"
who | awk '{ printf " %-18s %-9s %s\n", $1, $2, $5 ; }'
echo -e " ***************************************************\n"
whoami | awk '{ printf " Your Username is : %s\n", $1 ; }'
who am i | awk '{printf " You are Working in Terminal : %s \n\n\n", $2 ; }'
return 0
}

# THIS PRINTS OUT THE DETAIL OF THE USER INTERACTIVELY
userdetail(){

TITLE="DETAIL OF USER $1"
username="$@"
finger -p "$username" > "$TEMP" 2> /dev/null
grep Login "$TEMP" > /dev/null 2>&1
if [ $? -eq 0 ]
then
strln=`echo -e "\nDetails of User $username:-" |wc -m`
echo -e "\nDetails of User $username:-" > "$TEMP"

while [ "$strln" != "2" ]
do
echo -n "*"
strln=`expr $strln - 1`
done >> "$TEMP"

echo -e "\n" >> "$TEMP"
finger -p "$username" >> "$TEMP"
echo >> "$TEMP"
return 0
else
echo -e "\n\n\n\t\tUser $username could not be found!!" >> "$TEMP"
echo -e "\n\n\t\tPlease Enter a valid username." >> "$TEMP"
return 1
fi
return 0
}


groupinfo(){

if [ ! -r /etc/group ]
then
echo -e "ERROR : groupname not available"
TITLE='ERROR - GROUP INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING="group"
return 3
fi
TITLE="GROUP INFORMATION"

echo -e " **************************"
echo -e " ==::GROUPS INFORMATION::=="
echo -e " **************************\n"
echo -e " *******************************"
echo -e " GROUPS GROUP ID"
echo -e " *******************************"

cat /etc/group | awk -F: '{ printf " %-15s %7s\n", $1, $3 }'
echo -e " *******************************"
echo -e "\n"
return 0
}


#*************************************************#
# SUBMODULE B:- #
# THIS SUBMODULE DISPLAYS THE SYSTEM INFORMATION. #
#*************************************************#

# THIS FUNCTION DISPLAYS HARDWARE INFORMATION LIKE CPU INFO AND MEMORY INFO.
hwdinfo(){

if [ ! -r /proc/cpuinfo ] && [ ! -r /proc/meminfo ]
then
echo -e "ERROR : Hardware information is not available. Maybe some problem with proc."
TRIVIALCODE=0
ERRORSTRING="proc"
TITLE='ERROR - HARDWARE INFORMATION NOT AVAILABLE'
return 1
fi
TITLE="BASIC HARDWARE INFORMATION"

echo -e "**********************************"
echo -e "==::BASIC HARDWARE INFORMATION::=="
echo -e "**********************************"
echo -e "\nCPU INFORMATION:-"
echo -e "*****************"
cpu_count=`cat /proc/cpuinfo | grep processor | wc -l`
count=1
while [ $count -le $cpu_count ]
do
cat /proc/cpuinfo | sed -n -e '/processor/p' | head -n $count | tail -n 1
cat /proc/cpuinfo | sed -n -e '/vendor/p' | head -n $count | tail -n 1
cat /proc/cpuinfo | sed -n -e '/model/p' | head -n $count | tail -n 1
echo -n "cpu MHz :" | head -n $count | tail -n 1
cat /proc/cpuinfo | sed -n -e '/cpu/p' | sed -n '/Hz/p' | awk -F : '{ printf "%s\n", $2 ; }' | head -n $count | tail -n 1
cat /proc/cpuinfo | sed -n -e '/cpu family/p' | head -n $count | tail -n 1
cat /proc/cpuinfo | sed -n -e '/cache/p' | head -n $count | tail -n 1
cat /proc/cpuinfo | sed -n -e '/step/p' | head -n $count | tail -n 1
cat /proc/cpuinfo | sed -n -e '/flags/p' | head -n $count | tail -n 1
echo -en "cpu architecture: "
uname -m
echo
count=`expr $count + 1`
done

echo -e "MEMORY:-"
echo -e "********"
echo -en "Total System Memory :"
cat /proc/meminfo | sed -n -e '/MemTotal/p' | awk '{ printf "%s %s\n", $2, $3 ; }'
echo -en "Total Swap Memory :"
cat /proc/meminfo | sed -n -e '/SwapTotal/p' | awk '{ printf "%s %s\n", $2, $3 ; }'

if [ "`cat /etc/X11/* 2> /dev/null | grep -A 3 [mM]onitor | wc -l`" != "0" ]
then
echo -e "\nMONITOR INFORMATION:-"
echo -e "*********************"
for fileX11 in /etc/X11/*
do
if [ ! -L $fileX11 ] && [ -f $fileX11 ]
then
cat $fileX11
fi
done 2> /dev/null | grep -A 5 [mM]onitor | sed '/[sS]ection/d' | grep [I]dentif | tail -n 1
for fileX11 in /etc/X11/*
do
if [ ! -L $fileX11 ] && [ -f $fileX11 ]
then
cat $fileX11
fi
done 2> /dev/null | grep -A 5 [mM]onitor | sed '/[sS]ection/d' | grep [mM]odel | tail -n 1
for fileX11 in /etc/X11/*
do
if [ ! -L $fileX11 ] && [ -f $fileX11 ]
then
cat $fileX11
fi
done 2> /dev/null | grep -A 5 [mM]onitor | sed '/[sS]ection/d' | grep [Vv]endor | sed '/Monitor Vendor/d' | tail -n 1
fi

echo -e "\nIDE Drives:-"
echo -e "************"
if [ "`dmesg 2> /dev/null | sed -n -e '/[hs]d[a-z]:/p' | sed -n -e '/drive/p' | sed -e '/[cC]ache/d' -e '/driver/d' -e '/[Ee]rror/d' | wc -l`" != "0" ]
then
dmesg | sed -n -e '/[hs]d[a-z]:/p' | sed -n -e '/drive/p' | sed -e '/[cC]ache/d' -e '/driver/d' -e '/[Ee]rror/d'
else
if [ "`cat /var/log/dmesg 2> /dev/null | sed -n -e '/[hs]d[a-z]:/p' | sed -n -e '/drive/p' | sed -e '/[cC]ache/d' -e '/driver/d' -e '/[Ee]rror/d' -e '/disk/d' | wc -l`" != "0" ]
then
cat /var/log/dmesg | sed -n -e '/[hs]d[a-z]:/p' | sed -n -e '/drive/p' | sed -e '/[cC]ache/d' -e '/driver/d' -e '/[Ee]rror/d' -e '/disk/d'
else
cat /proc/ide/hd[a-z]/model
fi
fi

if [ "`cat /proc/scsi/scsi 2>> /dev/null | grep -A 1 '[vV]endor'| wc -l`" != "0" ]
then
echo -e "\nSCSI Devices:-"
echo -e "**************"
cat /proc/scsi/scsi | grep -A 1 '[vV]endor'
fi
echo -e "\n"
return 0
}

# THIS ONE PRINTS THE BASIC CONFIGURATION INFO. LIKE OS, KERNEL VERSION ETC.
configinfo(){

type uname > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : Configuration information is not available."
TITLE='ERROR - CONFIGURATION INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING="uname"
return 5
else
uname > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : Configuration information is not available."
TITLE='ERROR - CONFIGURATION INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING="uname"
return 3
fi
fi
TITLE="CONFIGURATION INFORMATION"

echo -e " ***********************************************"
echo -e " ==::BASIC SYSTEM CONFIGURATION INFORMATION::== "
echo -e " ***********************************************"
echo -en " System OS : "
uname -s
echo -en " Release : "
for i in /etc/*[rv]e[lr][es][ai][so][en]
do
if [ -L "$i" ]
then
echo > /dev/null
else
cat "$i"
fi
done 2> /dev/null | sed '/LSB/d' | head -n 1
echo -en " Kernel Version : "
uname -r
echo -en " Hostname : "
uname -n
grep ':initdefault' /etc/inittab 1> /dev/null

if [ "$?" -eq 0 ]
then
echo -en " Default Runlevel : "
grep ':initdefault' /etc/inittab | sed 's/:/ /g' | awk '{ printf "%s\n", $2 ; }'
fi

runlevel > /dev/null 2>> /dev/null

if [ "$?" -eq 0 ]
then
echo -en " Current Runlevel : "
runlevel | awk '{ printf "%s\n", $2 ; }'
echo -en " Previous Runlevel : "
runlevel | awk '{ printf "%s\n", $1 ; }'
fi

gcc -v 1> /dev/null 2>&1

if [ "$?" = "0" ] && [ `gcc --version | grep 'gcc' | awk '{ printf "%s\n", $3 ; }' | wc -l` -eq 1 ]
then
echo -ne " GCC Version : "
gcc --version | grep 'gcc' | awk '{ printf "%s\n", $3 ; }'
else
echo -e " GCC : Not Installed"
fi

echo -n " Boot Loader(s) Installed : "
if [ -f /boot/grub/menu.lst ] || [ -f /etc/lilo.conf ]
then
if [ -f /boot/grub/menu.lst ]
then
echo -n "GRUB"
fi
if [ -f /boot/grub/menu.lst ] && [ -f /etc/lilo.conf ]
then
echo -n ", "
fi
if [ -f /etc/lilo.conf ]
then
echo -n "LILO"
fi
else
echo -n "Could not determine"
fi
echo -e "\n\n"
return 0
}

# THIS ONE PRINTS THE DISKDRIVE INFORMATION LIKE LISTING OUT PARTITIONS AND FILESYSTEM.
hddinfo(){

if [ ! -r /proc/partitions ]
then
echo -e "ERROR : Disk drive information is not available. Maybe some problem with proc."
TITLE='ERROR - DISK DRIVE INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING="proc"
return 1
fi
TITLE="DISK DRIVE INFORMATION"

echo -e "******************************"
echo -e "==::DISK DRIVE INFORMATION::=="
echo -e "******************************"

if [ "`cat /proc/partitions 2> /dev/null | wc -l`" != "0" ]
then
echo -e "\nList of Partitions (includes even unmounted partitions, if any) :-"
echo -e "******************************************************************"
cat /proc/partitions | grep [a-z]d[a-z][1-9][0-9]* | awk '{ printf "%s\n", $4 }'
echo -e "******************************************************************\n"
fi

echo -e "Mounted Filesystems :-"
echo -e "**********************"
mount > /dev/null 2>&1
if [ "$?" != 0 ]
then
echo -e "\nINFORMATION NOT AVAILABLE!!\n"
else
echo -e "********************************************************************************"
printf "%-15s %-20s %-15s %-5s\n" "PARTITION" "MOUNTED ON" "FILESYSTEM" "REMARK"
echo -e "********************************************************************************"
mount | sed -n '/dev/p' | sed -e '/proc/d' -e '/none/d' -e '/shm/d' -e '/pts/d' | awk '{ printf "%-15s %-20s %-15s %-5s\n", $1,$3,$5,$6 ; } '
echo -e "********************************************************************************\n"
fi

echo -e "Disk Drive Usage :-"
echo -e "******************"
df > /dev/null 2>&1
if [ "$?" != 0 ]
then
echo -e "\nINFORMATION NOT AVAILABLE!!\n"
else
echo -e "**********************************************************************"
printf "%-12s %-20s %5s %5s %5s %5s\n" "PARTITION" "MOUNTED ON" "SIZE" "USED" "AVAIL" "%USED"
echo -e "**********************************************************************"
df -h | sed -n '/dev/p' | sed -e '/none/d' -e '/shm/d' -e '/pts/d' | awk '{ printf "%-12s %-20s %5s %5s %5s %5s\n",$1,$6,$2,$3,$4,$5 ; }'
echo -e "**********************************************************************\n\n"
fi
return 0
}

# THIS LISTS OUT THE PCI DEVICES, CONTROLLERS AND BRIDGES ETC.
pciinfo(){

type lspci > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : PCI information is not available."
TITLE='ERROR - PCI INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING='find / | grep lspci'
return 5
else
lspci > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : PCI information is not available."
TITLE='ERROR - PCI INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING='lspci'
return 3
fi
fi
TITLE="PCI INFORMATION"

echo -e "*******************************"
echo -e "==::PCI Buses and Devices ::=="
echo -e "*******************************"

echo -e "\nGraphics Card :-"
echo "****************"
lspci | grep VGA | awk -F: '{ print $3 $4 }'

echo -e "\nSound Card :-"
echo "*************"
lspci | grep '[sS]ound' | awk -F: '{ print $3 $4 }'
lspci | grep '[aA][uU][dD][iI][oO]' | awk -F: '{ print $3 $4 }'

if [ "`lspci | grep 'USB' | awk -F: '{ print $3 $4 }'| wc -l`" != "0" ]
then
echo -e "\nUSB Controller :-"
echo "*****************"
lspci | grep 'USB' | awk -F: '{ print $3 $4 }'
fi


if [ "`lspci | grep 'IDE' | awk -F: '{ print $3 $4 }'| wc -l`" != "0" ]
then
echo -e "\nIDE Controller :-"
echo "*****************"
lspci | grep 'IDE' | awk -F: '{ print $3 $4 }'
fi

if [ "`lspci | grep 'FireWire' | awk -F: '{ print $3 $4 }'| wc -l`" != "0" ]
then
echo -e "\nFireWire Controller :-"
echo "**********************"
lspci | grep 'FireWire' | awk -F: '{ print $3 $4 }'
fi


if [ "`lspci | grep 'I/O' | awk -F: '{ print $3 $4 }'| wc -l`" != "0" ]
then
echo -e "\nI/O Controller :-"
echo "*****************"
lspci | grep 'I/O' | awk -F: '{ print $3 $4 }'
fi

echo -e "\nOther PCI Controller/Bridge/Device :-"
echo "*************************************"
lspci | sed -e '/[sS]ound/d' -e '/I\/O/d' -e '/VGA/d' -e '/[aA][uU][dD][iI][oO]/d' -e '/USB/d' -e '/IDE/d' -e '/FireWire/d' | awk -F: '{ print $3 $4 }'
echo -e "\n"
return 0
}

# AND THIS ONE PRINTS OUT THE MEMORY INFORMATION
meminfo(){

if [ ! -r /proc/meminfo ]
then
echo -e "ERROR : Memory information is not available. Maybe some problem with proc."
TITLE='ERROR - MEMORY INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING="proc"
return 1
fi
TITLE="MEMORY INFORMATION"

echo -e " ***************************"
echo -e " ==::System Memory Usage::=="
echo -e " ***************************"
echo -en "\n Total System Memory : "
cat /proc/meminfo | sed -n -e '/MemTotal:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Total Swap Memory : "
cat /proc/meminfo | sed -n -e '/SwapTotal:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Free System Memory : "
cat /proc/meminfo | sed -n -e '/MemFree:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Free Swap Memory : "
cat /proc/meminfo | sed -n -e '/SwapFree:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Cached Memory : "
cat /proc/meminfo | sed -n -e '/Cached:/p' | sed -e '/[sS]wap[cC]ached:/d'| awk '{ printf "%7s %s", $2, $3   }'
echo -en "\n Cached Swap Memory : "
cat /proc/meminfo | sed -n -e '/SwapCached:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Active : "
cat /proc/meminfo | sed -n -e '/Active:/p' | sed -e '/Inactive:/d' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Inactive : "
cat /proc/meminfo | sed -n -e '/Inactive:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n High Total : "
cat /proc/meminfo | sed -n -e '/HighTotal:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n High Free : "
cat /proc/meminfo | sed -n -e '/HighFree:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Low Total : "
cat /proc/meminfo | sed -n -e '/LowTotal:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Low Free : "
cat /proc/meminfo | sed -n -e '/LowFree:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Dirty : "
cat /proc/meminfo | sed -n -e '/Dirty:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Write Back : "
cat /proc/meminfo | sed -n -e '/Writeback:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Mapped : "
cat /proc/meminfo | sed -n -e '/Mapped:/p' | awk '{ printf "%7s %s", $2, $3 ; }'
echo -en "\n Page Tables : "
cat /proc/meminfo | sed -n -e '/PageTables:/p' | awk '{ printf "%7s %s", $2, $3 ; }'

echo -en "\n Swap Partition : "
cat /proc/swaps | sed -n -e '/dev/p' | awk '{ printf " %s ", $1 }'
echo -e "\n\n"
return 0
}

# TO VIEW ALL THE RUNNING PROCESSES IN THE HOST MACHINE, THIS FUNCTION IS USED
procinfo(){

type ps > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : Processes information is not available."
TITLE='ERROR - PROCESSES INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING="ps"
return 5
else
ps > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : Processes information is not available."
TITLE='ERROR - PROCESSES INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING="ps"
return 3
fi
fi
TITLE="PROCESSES INFORMATION"

echo -e " ***********************************"
echo -e " ==::CURRENTLY RUNNING PROCESSES::=="
echo -e " ***********************************"
ps aux
echo -e "\n"
return 0
}

# TO VIEW MOTHERBOARD INFORMATION. YOU NEED ROOT PRIVILEDG FOR THIS.
mboardinfo(){

type dmidecode > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : Advanced hardware information is not available.\nYour System does not support showing this information."
TITLE='ERROR - ADVANCED HARDWARE INFORMATION NOT AVAILABLE'
TRIVIALCODE=1
return 5
else
dmidecode > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : Advanced hardware information is not available.\nRun the script with root priviledge."
TITLE='ERROR - ADVANCED HARDWARE INFORMATION NOT AVAILABLE'
TRIVIALCODE=1
return 3
fi
fi
TITLE="ADVANCED HARDWARE INFORMATION"

echo -e "\t ***********************************"
echo -e "\t ==::ADVANCED SYSTEM INFORMATION::=="
echo -e "\t ***********************************\n"


echo -e "\t\tBIOS Information :-"
echo -e "\t\t*******************"
if [ "`dmidecode | grep -A5 -e 'BIOS Information' | sed '/BIOS Information/d' | wc -l`" != "0" ]
then
dmidecode | grep -A5 -e 'BIOS Information' | sed '/BIOS Information/d'

else
echo "Not Available"
fi
echo

echo -e "\n\n\t\tBase Board Information :-"
echo -e "\t\t*************************"
if [ "`dmidecode | grep -A4 -e 'Base Board Information' | sed '/Base Board Information/d' | wc -l`" != "0" ]
then
dmidecode | grep -A4 -e 'Base Board Information' | sed '/Base Board Information/d'
else
echo "Not Available"
fi
echo

if [ "`dmidecode | grep -A6 -e 'Chassis Information' | sed '/Chassis Information/d' | wc -l`" != "0" ]
then
echo -e "\n\n\t\tChassis Information :-"
echo -e "\t\t*************************"
dmidecode | grep -A8 -e 'Chassis Information' | sed '/Chassis Information/d'
fi
echo

if [ "`dmidecode | grep -A7 -e 'Memory Controller Information' | sed '/Memory Controller Information/d' | wc -l`" != "0" ]
then
echo -e "\n\n\t\tMemory Controller Information :-"
echo -e "\t\t********************************"
dmidecode | grep -A7 -e 'Memory Controller Information' | sed '/Memory Controller Information/d'
fi
echo

if [ "`dmidecode | grep -A7 -e 'Memory Module Information' | sed '/Memory Module Information/d' | wc -l`" != "0" ]
then
echo -e "\n\n\t\tMemory Module Information :-"
echo -e "\t\t****************************"
dmidecode | grep -A7 -e 'Memory Module Information' | sed '/Memory Module Information/d'
fi
echo

echo -e "\n\n\t\tProcessor Information :-"
echo -e "\t\t************************"

cpu_count=`dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Family:' | wc -l`
count=1
if [ $cpu_count -eq 0 ]
then
echo "Not Available"
fi

while [ "$count" -le "$cpu_count" ]
do
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Socket Designation:' | head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Type:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Family:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Manufacturer:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'ID:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Signature:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Version:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Voltage:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Externel Clock:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Max Speed:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'Current Speed:'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'L1 Cache'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'L2 Cache'| head -n $count | tail -n 1
dmidecode | grep -A50 -e 'Processor Information' | sed '/Processor Information/d' | grep 'L3 Cache'| head -n $count | tail -n 1
count=`expr $count + 1`
if [ "$count" -le "$cpu_count" ]
then
echo "---"
fi
done

echo

echo -e "\n\n\t\tSystem Slot Information :-"
echo -e "\t\t**************************"
if [ "`dmidecode | grep -A5 -e 'System Slot Information' | sed '/System Slot Information/d' | wc -l`" != "0" ]
then
dmidecode | grep -A5 -e 'System Slot Information' | sed '/System Slot Information/d'
else
echo "Not Available"
fi
echo

echo -e "\n\n\t\tCache Information :-"
echo -e "\t\t********************"
if [ "`dmidecode | grep -A6 -e 'Cache Information' | sed '/Cache Information/d' | wc -l`" != "0" ]
then
dmidecode | grep -A6 -e 'Cache Information' | sed '/Cache Information/d'
else
echo "Not Available"
fi
echo

if [ "`dmidecode | grep -A3 -e 'On Board Device Information' | sed '/On Board Device Information/d' | wc -l`" != "0" ]
then
echo -e "\n\n\t\tOn Board Device Information :-"
echo -e "\t\t****************************"
dmidecode | grep -A3 -e 'On Board Device Information' | sed '/On Board Device Information/d'
fi
echo

if [ "`dmidecode | grep -A5 -e 'Port Connector Information' | sed '/Port Connector Information/d' | wc -l`" != "0" ]
then
echo -e "\n\n\t\tPort Connector Information :-"
echo -e "\t\t*****************************"
dmidecode | grep -A5 -e 'Port Connector Information' | sed '/Port Connector Information/d'
echo
fi
echo
return 0
}

# THIS DISPLAYS SERVICES INFORMATION

serviceinfo(){

type service > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : Service information is not available.\nYour System does not support showing this information."
TITLE='ERROR - SERVICE INFORMATION NOT AVAILABLE'
TRIVIALCODE=1
return 5
fi
TITLE="SERVICE INFORMATION"

echo -e "*****************************"
echo -e "==::SERVICES INFORMATION ::=="
echo -e "*****************************\n"

echo -e "RUNNING SERVICES :-"
echo -e "*******************"
echo -ne "NONE\b\b\b\b"
service --status-all 2> /dev/null | grep running | sed '/not/d'
echo

echo -e "\nSTOPPED SERVICES :-"
echo -e "*******************"
echo -ne "NONE\b\b\b\b"
service --status-all 2> /dev/null | grep stopped
echo

echo -e "\nDISABLED SERVICES :-"
echo -e "*******************"
echo -ne "NONE\b\b\b\b"
service --status-all 2> /dev/null | grep disabled
echo -e "\n\n"
return 0
}


# THIS DISPLAYS NETWORK INFORMATION
networkinfo(){

type ifconfig > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : Network information is not available.\nYour System does not support showing this information."
TITLE='ERROR - NETWORK INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING='ifconfig'
return 5
else
ifconfig > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo -e "ERROR : Network information is not available.\nRun the script with root priviledge."
TITLE='ERROR - NETWORK INFORMATION NOT AVAILABLE'
TRIVIALCODE=0
ERRORSTRING='ifconfig'
return 3
fi
fi
TITLE="NETWORK INFORMATION"

echo -e " ****************************"
echo -e " ==::NETWORK INFORMATION ::=="
echo -e " ****************************\n"
if [ `ifconfig -a | grep eth | wc -l` != "0" ]
then
neth=`ifconfig -a | grep eth | wc -l`
counteth=1
while [ $counteth -le $neth ]
do
count=`expr $counteth \* 4 - 1`
echo -ne "Ethernet Card : "
ifconfig -a | grep eth[0-9] | awk '{ print $1 }' | head -n $counteth | tail -n 1 | awk '{ printf "%s\n", $1 }'
echo -ne "Hardware Address : "
ifconfig -a | sed -n -e 's/.*HWaddr.//p' | head -n $counteth | tail -n 1 | awk '{ printf "%s\n", $1 }'
echo -ne "Inet Address : "
if [ `ifconfig -a | grep -A 2 eth | head -n $count | grep 'inet addr:' | tail -n 1 | sed -n -e 's/.*inet addr.//p' | sed -n -e 's/Bcast.*//p' | awk '{ printf "%s\n", $1 }' | wc -l` -eq 0 ]
then
echo -n -e "Not Applicable\n"
else
ifconfig -a | grep -A 2 eth | head -n $count | grep 'inet addr:' | tail -n 1 | sed -n -e 's/.*inet addr.//p' | sed -n -e 's/Bcast.*//p' | awk '{ printf "%s\n", $1 }'
fi
echo -ne "Broadcast Address : "
if [ `ifconfig -a | grep -A 2 eth | head -n $count| grep 'Bcast:' | tail -n 1 | sed -n -e 's/.*Bcast.//p' | sed -n -e 's/Mask.*//p' | awk '{ printf "%s\n", $1 }' | wc -l` -eq 0 ]
then
echo -n -e "Not Applicable\n"
else
ifconfig -a | grep -A 2 eth | head -n $count| grep 'Bcast:' | tail -n 1 | sed -n -e 's/.*Bcast.//p' | sed -n -e 's/Mask.*//p' | awk '{ printf "%s\n", $1 }'
fi
echo -ne "Mask : "
if [ `ifconfig -a | grep -A 2 eth | head -n $count | grep 'Mask:' | tail -n 1 | sed -n -e 's/.*Mask.//p' | awk '{ printf "%s\n", $1 }' | wc -l` -eq 0 ]
then
echo -n -e "Not Applicable\n"
else
ifconfig -a | grep -A 2 eth | head -n $count | grep 'Mask:' | tail -n 1 | sed -n -e 's/.*Mask.//p' | awk '{ printf "%s\n", $1 }'
fi

echo -e "\nRX/TX Packets Information :- "

echo
ifconfig -a | grep eth[0-9] -A 7 | head -n `expr $counteth + 7` | grep [RT]X
echo -e "\n\n"
counteth=`expr $counteth + 1`
done

else
echo -e "\nIT APPEARS THAT NO NETWORK CARD IS INSTALLED\n\n"
fi
return 0
}

# END OF MODULE 2
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#



####################################################################################################################
# MODULE 3:- #
# THIS MODULE DISPLAYS THE VARIOUS MENUS AND TAKES INPUTS FROM THE USER #
####################################################################################################################

# THIS DISPLAYS THE MENU FOR PRINTING USER INFORMATION
userinfo_menu(){

if [ "$gui_support" = 'y' ]
then

cancel_userinfo_menu=0
while [ "$cancel_userinfo_menu" != "1" ]
do
dialog --title "USER INFORMATION MENU" --backtitle "Author - Rajat Patel, Yeswedeal" --extra-button --extra-label "Save" --cancel-label "Back" --menu "\nSelect Any Item Below and then Press 'OK' to view information or 'Save' to Save it to disk:\n" 19 40 7 1 "List all users in host machine" 2 "Users currently logged in" 3 "Detail of a user" 4 "Group Information" 5 "Quit" 2> "$CHOICE"

cancel_userinfo_menu=$?
choice2=`cat $CHOICE`

if [ "$cancel_userinfo_menu" = "3" ]
then

case "$choice2" in
1)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
usertot > $TEMP 2>> $TMPLOG
if [ "$?" != "0" ]
then
printerr "$?" "$TRIVIALCODE" "$ERRORSTRING"
else
save
fi
;;
2)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
userlog > $TEMP 2>> $TMPLOG
save
;;
3)
type finger > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
printerr 2 1
else
cancel_userdetail=0
while [ "$cancel_userdetail" != "1" ]
do

dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --cancel-label "Back" --inputbox " `echo "Users :\n"; awk -F: '{ if( $3 >= 500 && $3 <= 9999 ) printf "%s, ", $1 ; }' /etc/passwd` \n\nEnter a username to Save the Details to disk (or press Cancel to go back to previous menu):" 19 70 2> "$CHOICE"

cancel_userdetail=$?
username=`cat $CHOICE`

if [ -n "$username" ] && [ "$cancel_userdetail" = "0" ]
then

dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
userdetail "$username"

if [ "$?" = "1" ]
then
dialog --title "USER NOT FOUND!!" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72
else
save
fi

fi
done

fi
;;
4)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
groupinfo > $TEMP 2>> $TMPLOG
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
save
fi
;;
5)
exit_msg
quit
;;
esac

dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
continue
fi


case "$choice2" in
1)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
usertot > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72

fi
;;
2)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
userlog > "$TEMP" 2>> "$TMPLOG"
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 62
;;
3)
type finger > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
printerr 2 1
else
cancel_userdetail=0
while [ "$cancel_userdetail" != "1" ]
do

dialog --title "USER DETAIL" --backtitle "Author - Rajat Patel, Yeswedeal" --cancel-label "Back" --inputbox " `echo "Users :\n"; awk -F: '{ if( $3 >= 500 && $3 <= 9999 ) printf "%s, ", $1 ; }' /etc/passwd` \n\nEnter a username to View Details (or press Cancel to go back to previous menu):" 19 70 2> "$CHOICE"

cancel_userdetail=$?
username=`cat $CHOICE`

if [ -n "$username" ] && [ "$cancel_userdetail" = "0" ]
then

dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
userdetail "$username"
dialog --title "USER DETAIL" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72

fi
done

fi

;;
4)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
groupinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 20 52
fi
;;
5)
exit_msg
quit
;;
esac

done
else
choice2=1
while [ -z "$choice2" ] || [ "$choice2" != "6" ]
do
clear
echo -e "\nAuthor - Rajat Patel, Yeswedeal\n\n"
echo -e "\n*******************************"
echo -e "==:: USER INFORMATION MENU ::=="
echo "*******************************"
echo "1) List all users in host machine"
echo "2) Users currently logged in"
echo "3) Information about a particular user"
echo "4) Group Information"
echo "5) Save All User Information to Disk"
echo "6) Back to previous menu"
echo -en "\nPlease Enter Your Choice (1-6): "
read choice2

case "$choice2" in
1)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
usertot > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
clear
if [ "$EXIT_STATUS" != "0" ]
then

printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
;;
2)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
userlog > "$TEMP" 2>> "$TMPLOG"
clear
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
;;
3)
type finger > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
clear
printerr 2 1
else
username=n
while [ "$username" != q ]
do

clear
echo "Users :"
awk -F: '{ if( $3 >= 500 && $3 <= 9999 ) printf "%s, ", $1 ; }' /etc/passwd echo -e "\nEnter a Username to View Details" echo -n " (q to Return to Previous Menu) : " read username if [ -n "$username" ] && [ "$username" != "q" ] then echo -e "\n\nRetrieving Information." echo -n "Please wait..." userdetail "$username" clear more $TEMP echo -en "\nPress Enter to Continue..." read fi done fi ;; 4) echo -e "\n\nRetrieving Information." echo -n "Please wait..." groupinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
clear
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read

fi
;;
5)
echo -ne "\n\n\nSaving Information.\nPlease wait..."
main -uUg > $TEMP 2> /dev/null
save
echo -e "\n\nInformation Saved in File: $SAVEINFO"
echo -n "Press Enter to continue...."
read
;;
6)
return
;;
esac

done

fi
return 0
}

# THIS DISPLAYS THE MENU FOR PRINTING SYSTEM INFORMATION
systeminfo_menu(){


if [ "$gui_support" = 'y' ]
then

cancel_systeminfo_menu=0
while [ "$cancel_systeminfo_menu" != 1 ]
do

dialog --title "SYSTEM INFORMATION MENU" --backtitle "Author - Rajat Patel, Yeswedeal" --extra-button --extra-label "Save" --cancel-label "Back" --menu "\nSelect Any Item Below and then Press 'OK' to view information or 'Save' to Save it to disk:\n" 19 40 9 1 "Basic Hardware Information" 2 "Basic System Configuration" 3 "Diskdrive Information" 4 "PCI Information" 5 "Memory Usage" 6 "Running Processes" 7 "Advanced System Information" 8 "Services Information" 9 "Quit" 2> "$CHOICE"

cancel_systeminfo_menu=$?
choice1=`cat $CHOICE`

if [ "$cancel_systeminfo_menu" = "3" ]
then
case "$choice1" in
1)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
hwdinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
save
dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
fi
;;
2)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
configinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
save
dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
fi
;;
3)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
hddinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
save
dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
fi
;;
4)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
pciinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
save
dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
fi
;;
5)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
meminfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
save
dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
fi
;;
6)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
procinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
save
dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
fi
;;
7)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
mboardinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
save
dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
fi
;;
8)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40
serviceinfo > "$TEMP" 2> /dev/null
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
if [ `cat $TEMP | wc -l` -le 17 ]
then
printerr 2 1
else
save
dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
fi
fi
;;
9)
exit_msg
quit
;;
esac
continue
fi

case "$choice1" in
1)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
hwdinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72

fi
;;
2)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
configinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72
fi
;;
3)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
hddinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72
fi
;;
4)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
pciinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else

dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72
fi
;;
5)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
meminfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72
fi
;;
6)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
procinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72
fi
;;

7)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
mboardinfo > "$TEMP" 2>> $TMPLOG
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72

fi
;;

8)
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
serviceinfo > "$TEMP" 2>> $TMPLOG
EXIT_STATUS="$?"
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
if [ `cat $TEMP | wc -l` -le 17 ]
then
printerr 2 1
else
dialog --title "$TITLE" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 72
fi

fi
;;
9)
exit_msg
quit
;;
esac

done
else

choice1=1
while [ -z "$choice1" ] || [ "$choice1" != "10" ]
do
clear
echo -e "\nAuthor - Rajat Patel, Yeswedeal\n\n"
echo -e "\n*********************************"
echo -e "==:: SYSTEM INFORMATION MENU ::=="
echo "*********************************"
echo "1) Basic Hardware Information"
echo "2) Basic System Configuration"
echo "3) Diskdrive Information"
echo "4) PCI Information"
echo "5) Memory Usage"
echo "6) Running Processes"
echo "7) Advanced System Information"
echo "8) Services Information"
echo "9) Save All System Information to Disk"
echo "10) Back to previous menu"
echo -en "\nEnter Your Choice (1-10): "
read choice1

case "$choice1" in
1)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
hwdinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
clear
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
;;
2)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
configinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
clear
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
;;
3)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
hddinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
clear
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
;;
4)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
pciinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
clear
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
;;
5)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
meminfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
clear
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
;;
6)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
procinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
clear
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
;;

7)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
mboardinfo > "$TEMP" 2>> "$TMPLOG"
EXIT_STATUS="$?"
clear
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
;;
8)
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
serviceinfo > "$TEMP" 2>> $TMPLOG
clear
if [ "$EXIT_STATUS" != "0" ]
then
printerr "$EXIT_STATUS" "$TRIVIALCODE" "$ERRORSTRING"
else
if [ `cat $TEMP | wc -l` -le 17 ]
then
printerr 2 1
else
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
fi
;;
9)
echo -ne "\n\n\nSaving Information.\nPlease wait..."
main -dsHcmpDS > $TEMP 2>> $TMPLOG
save
echo -e "\n\nInformation Saved in File: $SAVEINFO"
echo -n "Press Enter to continue...."
read
;;
10)
return
;;

esac
done

fi
return 0
}

# THERE IS NO MENU FOR DISPLAYING NETWORK INFORMATION TILL NOW, BUT AS A STANDARD FOLLOWED IN THIS SCRIPT,
# I HAVE ADDED THIS FUNCTION HERE.
nwinfo_menu(){

if [ "$gui_support" = 'y' ]
then
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Retrieving Information.\nPlease wait..." 7 40
networkinfo > "$TEMP" 2>> "$TMPLOG"
dialog --title "NETWORK INFORMATION" --backtitle "Author - Rajat Patel, Yeswedeal" --exit-label "OK" --textbox "$TEMP" 19 70
else
echo -e "\n\nRetrieving Information."
echo -n "Please wait..."
networkinfo > "$TEMP" 2>> "$TMPLOG"
clear
more "$TEMP"
echo -en "\nPress Enter to Continue..."
read
fi
return 0
}

# THIS DISPLAYS THE MAIN MENU. THIS IS WHAT THE USER SEES WHEN HE RUNS THE SCRIPT WITHOUT ANY OPTION
# WHEN USED WITH AN OPTION, IT DISPLAYS THE NECESSARY INFO. AND EXITS.
main(){

if [ -z "$*" ]
then

if [ "$gui_support" = "y" ]
then
cancel_main=0

while [ "$cancel_main" != "1" ]
do

dialog --title "MAIN MENU" --backtitle "Author - Rajat Patel, Yeswedeal" --extra-button --extra-label "Save" --cancel-label "Exit" --menu "\nSelect Any Item Below and then Press 'OK' to view information or 'Save' to Save it to disk:\n" 19 38 5 1 "User Information" 2 "System Information" 3 "Network Information" 2> $CHOICE

cancel_main=$?

choice=`cat $CHOICE`

if [ "$cancel_main" = "3" ]
then
dialog --backtitle "Author - Rajat Patel, Yeswedeal" --infobox "Saving Information.\nPlease wait..." 7 40

case "$choice" in
1)
main -uUg > $TEMP 2>> $TMPLOG
;;
2)
main -dsHcmpDS > $TEMP 2>> $TMPLOG
;;
3)
main -N > $TEMP 2>> $TMPLOG
;;
esac

save
dialog --title "FILE SAVED" --backtitle "Author - Rajat Patel, Yeswedeal" --msgbox "\nInformation Saved in File: $SAVEINFO\n" 12 45
continue
fi

case "$choice" in
1)
userinfo_menu
;;
2)
systeminfo_menu
;;
3)
nwinfo_menu
;;
esac

done
else
choice=1
while [ -z "$choice" ] || [ "$choice" != 5 ]
do
clear
echo -e "\nAuthor - Rajat Patel, Yeswedeal\n"
echo -e "\n***************"
echo -e "==:: MENU ::=="
echo "***************"
echo "1) User Information"
echo "2) System Information"
echo "3) Network Information"
echo "4) Save All Information to Disk"
echo "5) Exit"
echo -en "\nPlease Enter Your Choice (1-4): "
read choice

case "$choice" in
1)
userinfo_menu
;;
2)
systeminfo_menu
;;
3)
nwinfo_menu
;;
4)
echo -ne "\n\n\nSaving Information.\nPlease wait..."
main -a > $TEMP 2> /dev/null
save
echo -e "\n\nInformation Saved in File: $SAVEINFO"
echo -n "Press Enter to continue...."
read
;;
esac
done


fi

exit_msg
cleanup
clear


else #THIS IS FOR TAKING CARE OF OPTIONS
for param in "$@"
do
if [ "$param" = "--help" ] || [ "$param" = "-h" ]
then
echo -e 'S&M Sysinfo, Sysinfo by Manna & Sid!!'
echo -e "sysinfo Version $VERSION"
echo -e "Author -- Rajat Patel, Yeswedeal"
echo -e "Copyright (C) 2009 Rajat Patel"
echo -e "This is free software; see the source for copying conditions."
echo -e "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE"
echo -e "\nUsage: sysinfo [OPTION]..."
echo -e "A textmode graphical utility for displaying system information"
echo -e "Run without options to enter graphical menu"
echo -e "\nOptions:"
echo -e "\t-h, --help display this help and exit"
echo -e "\t-v, --version display version and exit"
echo -e "\t-a, --all display all information in the following order"
echo -e "\t-u, --usertot display total users in host"
echo -e "\t-U, --userlog display users currently logged in"
echo -e "\t-g, --grpinfo display groups along with the GID"
echo -e "\t-d, --hardware display hardware information"
echo -e "\t-s, --sysconf display system configuration information"
echo -e "\t-H, --hdd display disk-drive information"
echo -e "\t-c, --pci display PCI information"
echo -e "\t-m, --mem display memory usage information"
echo -e "\t-p, --proc display currently running processs"
echo -e "\t-N, --nwinfo display network information"
echo -e "\t-D, --advhdw display advanced hardware information (needs root priviledge)"
echo -e "\t-S, --service display services information (may need root priviledge)\n"
echo -e "Report Bugs to "
exit 0

fi
if [ "$param" = "--version" ] || [ "$param" = "-v" ]
then
echo -e 'S&M Sysinfo, Sysinfo by Manna & Sid!!'
echo -e "sysinfo Version $VERSION"
echo -e "Author -- Rajat Patel, Yeswedeal"
echo -e "Copyright (C) 2009 Rajat Patel"
echo -e "This is free software; see the source for copying conditions."
echo -e "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE"
exit 0
fi

case "$param" in
--*)
;;
-*h*)
main -h
;;
-*v*)
main -v
;;
[^-]*)
echo -e "\nERROR: Does not take any arguments" 1>&2
echo -e "Try \"sysinfo --help\" for more information\n" 1>&2
exit 1
;;
-*[^ahdsuUgHcmpNDS]*)
echo -e "\nERROR: Unkown option -- \"$param\" " 1>&2
echo -e "Type \"sysinfo --help\" for more information\n" 1>&2
exit 1
;;
esac

done
echo
for param in "$@"
do
short=0
case "$param" in
"--all")
main -a
return
;;
"--usertot")
usertot
;;
"--userlog")
userlog
;;
"--grpinfo")
groupinfo
;;
"--hardware")
hwdinfo
;;
"--sysconf")
configinfo
;;
"--hdd")
hddinfo
;;

"--pci")
pciinfo
;;

"--mem")
meminfo
;;

"--proc")
procinfo
;;
"--nwinfo")
networkinfo
;;
"--advhdw")
mboardinfo
;;
"--service")
serviceinfo
;;
"--"*)
echo -e "ERROR: Unkown option -- \"$param\" " 1>&2
echo -e "Type \"sysinfo --help\" for more information\n" 1>&2
exit 1
;;
"-"*)
short=1
;;
esac
# THIS PART CHECKS FOR SHORT OPTIONS WHICH CAN EVEN BE COMBINED
# BELIEVE ME, THIS PART IS REAL TRICKY!!
# I AM STILL NOT SURE WHETHER THIS PART IS TOTALY BUG FREE
if [ "$short" -eq 1 ]
then
while [ "$param" != "-" ]
do
case "$param" in
-*a*)
main -uUgdsHcmpNDS
return
;;
esac
case "$param" in
-u*)
usertot
param=`echo "$param" | sed -n -e 's/u//p'`
;;
esac
case "$param" in
-U*)
userlog
param=`echo "$param" | sed -n -e 's/U//p'`
;;
esac
case "$param" in
-g*)
groupinfo
param=`echo "$param" | sed -n -e 's/g//p'`
;;
esac
case "$param" in
-d*)
hwdinfo
param=`echo "$param" | sed -n -e 's/d//p'`
;;
esac

case "$param" in
-s*)
configinfo
param=`echo "$param" | sed -n -e 's/s//p'`
;;
esac

case "$param" in
-H*)
hddinfo
param=`echo "$param" | sed -n -e 's/H//p'`
;;
esac
case "$param" in
-c*)
pciinfo
param=`echo "$param" | sed -n -e 's/c//p'`
;;
esac
case "$param" in
-m*)
meminfo
param=`echo "$param" | sed -n -e 's/m//p'`
;;
esac
case "$param" in
-p*)
procinfo
param=`echo "$param" | sed -n -e 's/p//p'`
;;
esac
case "$param" in
-N*)
networkinfo
param=`echo "$param" | sed -n -e 's/N//p'`
;;
esac
case "$param" in
-D*)
mboardinfo
param=`echo "$param" | sed -n -e 's/D//p'`
;;
esac
case "$param" in
-S*)
serviceinfo
param=`echo "$param" | sed -n -e 's/S//p'`
;;
esac

done
fi

done

fi
return "$?"
}




######################################################################################################################
##############******************** EXECUTION OF THE SCRIPT STARTS HERE ********************#######################
######################################################################################################################
# SIMPLY 3 STEPS:-

#STEP 1 :-
# INITITIALIZING THE ENVIRONMENT
trap "quit $1 ; " 1 2 3 7 9 11 15
init "$@"
# STEP 2 :-
# CALLING MAIN FUNCTIONS PASSING ALL THE ARGUMENTS ALONG WITH


trap "quit $1 ; " 1 2 3 7 9 11 15
main "$@"
# SETP 3 :-
# EXIT
exit 0

######################################################################################################################
###############******************** EXECUTION OF THE SCRIPT ENDS HERE *********************#######################
######################################################################################################################
Rajat Patel