Showing posts with label Perl. Show all posts
Showing posts with label Perl. Show all posts

Friday, November 8, 2013

Mounting Debian ISO files as Offline Software Repository

If you are not connected to internet, then still you can install packages from Debian Installer ISOs. For example, if Debian 7.0 (Wheezy) ISOs are in directory /media/FreeAgent GoFlex Drive/Softwares/Debian_7.0_Wheezy directory and we want to mount these iso in /mnt/Debian/ directory. The following command can be used:
$ sudo $(which mount_debian.pl) -d /mnt/Debian -g -r "/media/FreeAgent GoFlex Drive/Softwares/Debian_7.0_Wheezy"
Using iso(s) dir '/media/FreeAgent GoFlex Drive/Softwares/Debian_7.0_Wheezy'
Using mount point dir '/mnt/Debian'
...
Total 11 iso(s) mounted successfully.
Unmounting of the iso(s) can be achieved by the following command:
$ sudo $(which mount_debian.pl) -d /mnt/Debian -u -g -r
Running: umount "/mnt/Debian"/*.iso
Running: rmdir "/mnt/Debian"/*.iso
Running: cp "/etc/apt/sources.list.net" "/etc/apt/sources.list"
Running: apt-get update
...
Usage of the command:
$ sudo $(which mount_debian.pl)
/home/mitesh/Perl/mount_debian.pl: Please provide Dir where Debian installer iso(s) are present.
USAGE: /home/mitesh/Perl/mount_debian.pl [options] iso_dir
          -a apt_sources_dir        default  /etc/apt
          -d mount_base_dir         default  /mnt/Debian
          -g                        debug on 
          -r                        apt-get update 
          -u                        unmount 
          iso_dir                   Dir where Debian installer iso(s) are present.

PS: iso_dir is not required with -u command

The mount_debian.sh perl script is given as follows:
#!/usr/bin/perl -w
#===============================================================================
#
#         FILE:  mount_debian.pl
#
#        USAGE:  ./mount_debian.pl 
#
#  DESCRIPTION:  
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh)
#      COMPANY:  
#      VERSION:  1.0
#      CREATED:  11/07/2013 10:30:04 PM IST
#     REVISION:  ---
#===============================================================================

use strict;
use warnings;

use Getopt::Std;
my $apt_sources_dir = "/etc/apt";
my $mount_point_base = "/mnt/Debian";
my $umount = 0;
my $reload = 0;
my $debug = 0;

sub usage()
{
    print STDERR "USAGE: $0 [options] <iso_dir>\n";
    print STDERR "          -a <apt_sources_dir>    apt sources dir: default  $apt_sources_dir\n";
    print STDERR "          -d <mount_base_dir>     mount point dir: default  $mount_point_base\n";
    print STDERR "          -g                      debug on \n";
    print STDERR "          -r                      apt-get update \n";
    print STDERR "          -u                      unmount \n";
    print STDERR "          <iso_dir>               Dir where Debian installer iso(s) are present.\n";
}

sub run_cmd()
{
    my $cmd = $_[0];
    print "Running: $cmd\n" if $debug;
    system("$cmd");
    my $retval = $?; 
    if ($retval != 0)
    {   
        print STDERR "Error in running: $cmd\nExit code = $retval\n";
    }   
    return ($retval);
}

sub run_cmd_get()
{
    my $cmd = $_[0];
    print "Running: $cmd\n" if $debug;
    my @outs = `$cmd`;
    my $retval = $?;
    if ($retval < 0)
    {
        print STDERR "Error in running: $cmd\nExit code = $retval\n";
        exit($retval);
    }
    chomp(@outs);
    return (@outs);
}
sub take_backup() 
{
    my $file1 = $_[0];
    my $file2 = $_[1];
    my $cmd = "cp \"$file1\" \"$file2\"";
    my $retval = &run_cmd("$cmd");
    if ($retval != 0)
    {
        print STDERR "$0: Cannot copy \"$file1\" to \"$file2\"\n";
        exit(-1);
    }
    return 1;
}
sub reload_repo()
{
    my $file1 = $_[0];
    my $file2 = $_[1];

    my $cmd = "cp \"$file1\" \"$file2\"";
    my $retval = &run_cmd($cmd);
    exit(-1) if ($retval != 0);

    $cmd = "apt-get update";
    $retval = &run_cmd($cmd);
    exit(-1) if ($retval != 0);
}

my %opts;
getopt('a:d:', \%opts);

foreach my $opt (sort keys %opts)
{
    if (!defined($opts{$opt}))
    {
        print STDERR "$0: Requires value for option '$opt'\n";
        &usage();
        exit(-1);
    }
    else 
    {
        if ($opts{$opt} =~ m/^-/) 
        {
            print STDERR "$0: Requires value for option '$opt'\n";
            &usage();
            exit(-1);
        }
    }
}
$apt_sources_dir = $opts{"a"} if (defined($opts{"a"}));
$mount_point_base = $opts{"d"} if (defined($opts{"d"}));
$debug = 1 if (defined($opts{"g"}));
$reload = 1 if (defined($opts{"r"}));
$umount = 1 if (defined($opts{"u"}));

my $apt_dvd = "$apt_sources_dir/sources.list.dvd";
my $apt_net = "$apt_sources_dir/sources.list.net";
my $apt_orig = "$apt_sources_dir/sources.list";

my $retval = 0;
my $cmd;
$retval = `whoami`;
chomp($retval);
unless ($retval eq "root")
{
    print STDERR "$0: Please run this script as 'root' user.\n";
    &usage();
    exit(-1);
}

unless ($umount)
{

if (@ARGV != 1) 
{
    print STDERR "$0: Please provide Dir where Debian installer iso(s) are present.\n";
    &usage();
    exit(-1);
}
my $iso_dir = "$ARGV[0]";
## Check for iso dir presence
unless (-d "$iso_dir") 
{
    print STDERR "$0: Please make sure the iso(s) dir '$iso_dir' is present\n";
    exit(-1);
}
print "Using iso(s) dir '$iso_dir'\n" if ($debug);

## Check for destination dir
unless (-d "$mount_point_base") 
{
    $cmd = "mkdir -p \"$mount_point_base\"";
    $retval = &run_cmd("$cmd");
    if ($retval != 0) 
    {
        print STDERR "$0: Cannot create dir '$mount_point_base'\n";
        exit(-1);
    }
}
print "Using mount point dir '$mount_point_base'\n" if ($debug);

## Taking backup of ftp/http line sources.list
my $is_backed_up = 0;
if (-f "$apt_net") 
{
    ## Take backup only when ftp / http (internet)
    $cmd = "grep -v -e \"^#\" -e \"^\$\" \"$apt_orig\" | egrep -c \"(ftp|http)://\"";
    my @nets = &run_cmd_get($cmd);
    if ($nets[0] > 0) 
    {
        $is_backed_up = &take_backup("$apt_orig", "$apt_net");
    }
}
else
{
    $is_backed_up = &take_backup("$apt_orig", "$apt_net");
}

## Get loop devices
$cmd = "ls /dev/loop[0-9]*";
my @temps = &run_cmd_get($cmd);
my %loop_devices;
my $nloop_devices = @temps;
foreach my $temp (@temps) 
{
    $loop_devices{$temp} = 1;
}
$cmd = "ls \"$iso_dir\" | grep -i \"\.iso\$\"";
@temps = &run_cmd_get($cmd);
my %iso_images;
my $niso_images = @temps;
foreach my $temp (@temps) 
{
    $iso_images{$temp} = 1;
}
$cmd = "df | awk '{print \$1}' | grep \"/dev/loop\"";
@temps = &run_cmd_get($cmd);
my %mounted_loop_devices;
my $nmounted_loop_devices = @temps;
foreach my $temp (@temps) 
{
    $mounted_loop_devices{$temp} = 1;
}

## Check for free loop devices
my $nfree_loops = $nloop_devices - $nmounted_loop_devices;
if ($niso_images > $nfree_loops)
{
    print "Less available loop devices $nfree_loops than isos $niso_images\n" if ($debug);
    my $req_loops = $niso_images - $nfree_loops; 
    if ($nmounted_loop_devices == 0) 
    {
        print "Reloading loop kernel module with extra $req_loops loop devices\n" if $debug;
        $cmd = "rmmod loop";
        $retval = &run_cmd($cmd);
        print "$retval\n";
        exit(-1) if ($retval != 0);
        $cmd = "modprobe loop max_loop=$niso_images";
        $retval = &run_cmd($cmd);
        exit(-1) if ($retval != 0);
    }
    else 
    {
        print STDERR "Please reload 'loop' kernel module. After unloading following loop devices...\n";
        foreach my $temp (sort keys %mounted_loop_devices)
        {
            print STDERR "$temp\n";
        }
        print STDERR "\nrmmod loop\n";
        my $temp = $nmounted_loop_devices + $req_loops;
        print STDERR "\nmodprobe loop max_loop=$temp\n\n";
        exit(-2);
    }
}

## Create entries in sources.list file
open(SFH, ">$apt_orig") or die("$0: Cannot write in file '$apt_orig'\n");
foreach my $iso (sort keys %iso_images)
{
    print "Mounting iso $iso ...\n" if $debug;
    my $dest_dir = "$mount_point_base/$iso";
    unless (-d "$dest_dir") 
    {
        $cmd = "mkdir -p \"$dest_dir\"";
        $retval = &run_cmd($cmd);
        exit(-1) if ($retval != 0);
    }
    $cmd = "df \"$dest_dir\" | grep -c \"^/dev/loop.*\.iso\$\"";
    my @mounts = &run_cmd_get($cmd); 
    if ($mounts[0] == 0) ## Mount only if not mounted
    {
        $cmd = "mount -o loop,ro \"$iso_dir/$iso\" \"$dest_dir\"";
        $retval = &run_cmd($cmd);
        exit(-1) if ($retval != 0);

        ## read distro version dir in dists/
        $cmd = "ls -l \"$dest_dir/dists\" | grep \"^d\" | awk '{print \$(NF)}' | head -1";
        my $version = `$cmd`;
        if (defined($version) and ($version ne ""))
        {
            $cmd = "ls -l \"$dest_dir/dists\"/*/ | grep \"^d\" | sort -u | awk '{print \$(NF)}' | awk '{sec=sec\" \"\$1} END{print sec}'";
            my $sections = `$cmd`;
            if (defined($sections))
            {
                chomp($sections);
                chomp($version);
                print SFH "deb file://$dest_dir $version $sections\n";
            }
        }
    }
}
print SFH "\n## Automatically generated by $0 ##\n";
close(SFH);
print "Total $niso_images iso(s) mounted successfully.\n" if $debug;

## Reload repository if sources.list is updated
if ($is_backed_up and $reload)
{
    &reload_repo("$apt_orig", "$apt_dvd");
}
exit(0);
}
#######################################
## umount code                       ##
#######################################

$cmd = "umount \"$mount_point_base\"/*.iso";
$retval = &run_cmd($cmd);
exit(-1) if ($retval != 0);
$cmd = "rmdir \"$mount_point_base\"/*.iso";
$retval = &run_cmd($cmd);
exit(-1) if ($retval != 0);
if ($reload)
{
    &reload_repo("$apt_net", "$apt_orig");
}
exit(0);

PS: The above script can be used with any Debian Package Management related distros like Ubuntu, Linux Mint, etc.

Saturday, March 31, 2012

Command Line Dictionary : meaning of

If we have only console, and we want to quickly see meaning of some word. Then we can use following perl script to get dictionary meaning of a word. It uses perl, curl and html2text.
The source code of meaning_of.pl is :
#!/usr/bin/perl -w

## Search the dict.org

use strict;
use warnings;

sub print_usage() 
{
    print STDERR "USAGE: $0 <query>\n";
}

if (@ARGV < 1)
{
    &print_usage();
    exit(-1);
}

my $query = "$ARGV[0]";
$query =~ s/ /\%20/g;

my $cmd = "curl -# -A \"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\" -d \"Form=Dict1&Query=${query}&Strategy=*&Database=english\" \"http://www.dict.org/bin/Dict\" | html2text 2>/dev/null";
#system($cmd);
#exit($?);

open(MOFH, "$cmd | ") or die("$0: cannot execute: $cmd\n");

my $skip_lines = 10; # skip first 10 lines
my $line;
while ($line = <MOFH>)
{
    --$skip_lines;
    next if ($skip_lines > 0);
    chomp($line);
    print "$line\n";
}
close(MOFH);

exit(0);
Sample run of above perl script :

$ meaning_of.pl happiness

######################################################################## 100.0%
===============================================================================
4 definitions found for happiness
From The_Collaborative_International_Dictionary_of_English_v.0.48:

  Happiness \Hap"pi*ness\, n. [From Happy.]
     1. Good luck; good fortune; prosperity.
        [1913 Webster]

              All happiness bechance to thee in Milan! --Shak.
        [1913 Webster]

     2. An agreeable feeling or condition of the soul arising from
        good fortune or propitious happening of any kind; the
        possession of those circumstances or that state of being
        which is attended with enjoyment; the state of being
        happy; contentment; joyful satisfaction; felicity;
        blessedness.
        [1913 Webster]

     3. Fortuitous elegance; unstudied grace; -- used especially
        of language.
        [1913 Webster]

              Some beauties yet no precepts can declare,
              For there's a happiness, as well as care. --Pope.

     Syn: Happiness, Felicity, Blessedness, Bliss.

     Usage: Happiness is generic, and is applied to almost every
            kind of enjoyment except that of the animal appetites;
            felicity is a more formal word, and is used more
            sparingly in the same general sense, but with elevated
            associations; blessedness is applied to the most
            refined enjoyment arising from the purest social,
            benevolent, and religious affections; bliss denotes
            still more exalted delight, and is applied more
            appropriately to the joy anticipated in heaven.
            [1913 Webster]

                  O happiness! our being's end and aim! --Pope.
            [1913 Webster]

                  Others in virtue place felicity,
                  But virtue joined with riches and long life;
                  In corporal pleasures he, and careless ease.
                                                    --Milton.
            [1913 Webster]

                  His overthrow heaped happiness upon him;
                  For then, and not till then, he felt himself,
                  And found the blessedness of being little.
                                                    --Shak.
            [1913 Webster]
From WordNet_(r)_3.0_(2006):

  happiness
      n 1: state of well-being characterized by emotions ranging from
           contentment to intense joy [syn: happiness, felicity]
           [ant: unhappiness]
      2: emotions experienced when in a state of well-being [ant:
         sadness, unhappiness]
From Moby_Thesaurus_II_by_Grady_Ward,_1.0:

  117 Moby Thesaurus words for "happiness":
     Easy Street, acceptance, affluence, appropriateness, beatification,
     beatitude, becomingness, bed of roses, bewitchment, blessedness,
     bliss, blissfulness, blitheness, blithesomeness, brightness, cheer,
     cheerfulness, cheeriness, cheery vein, civility, cloud nine,
     clover, comfort, composure, content, contentedness, contentment,
     decency, decorousness, decorum, delectation, delight, ease,
     easy circumstances, ecstasy, ecstatics, elation, enchantment,
     enjoyment, entire satisfaction, eupeptic mien, euphoria,
     exaltation, exhilaration, exuberance, felicity, fitness,
     fittingness, fleshpots, fulfillment, gaiety, geniality,
     genteelness, gentility, gladness, gladsomeness, glee, good cheer,
     gracious life, gracious living, heaven, high spirits, hopefulness,
     intoxication, jollity, joy, joyance, joyfulness, joyousness,
     jubilation, lap of luxury, life of ease, loaves and fishes, luxury,
     meetness, optimism, overhappiness, overjoyfulness, paradise,
     peace of mind, pleasantness, pleasure, properness, propriety,
     prosperity, prosperousness, radiance, rapture, ravishment,
     reconcilement, reconciliation, resignation, rightness,
     rosy expectation, sanguine humor, sanguineness, satisfaction,
     security, seemliness, seventh heaven, success, suitability,
     sunniness, sunshine, the affluent life, the good life,
     thriving condition, transport, unalloyed happiness,
     upward mobility, urbanity, velvet, weal, wealth, welfare,
     well-being, winsomeness


From The_Devil's_Dictionary_(1881-1906):

  HAPPINESS, n.  An agreeable sensation arising from contemplating the
  misery of another.

===============================================================================
      Questions or comments about this site? Contact webmaster@dict.org

Thursday, February 23, 2012

Mount/Unmount USB pendrive/USB Harddisk

We have seen sometimes automounting of external drives(USB Pendrive/USB harddisk) work and sometimes it simply does not work. The pain increase when there are multiple partitions in the external drive. To resolve this issue, I have written a perl script to mount/unmount multiple partitions.

The following perl script is useful in following cases:
1. Mounting/Unmounting(-u flag for unmounting) partitions in external drives.
2. Mounting/Unmounting partitions of internal drives too (-d , to (mount to)/(unmount from) any specific location).
3. This script also recognizes single vfat(FAT32) partition(When filesystem was created across the entire device: please refer mkfs.vfat -I) pen-drive too.
4. Others (if you find anything else, please comment :) )

#!/usr/bin/perl -w
#===============================================================================
#
#         FILE:  mount_usb_disks.pl
#
#        USAGE:  ./mount_usb_disks.pl 
#
#  DESCRIPTION:  Mount USB disks or pendrive
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
#      COMPANY:  Yahoo Inc, India
#      VERSION:  1.0
#      CREATED:  02/22/2012 05:37:54 PM IST
#     REVISION:  ---
#===============================================================================

use strict;
use warnings;

use Getopt::Std;
my $mount_point_base = "/mnt/usb_disks";
my $umount = 0;

sub usage()
{
    print STDERR "USAGE: $0 [options] \n";
    print STDERR "          -d <mount_base_dir>     mount point dir: default  $mount_point_base\n";
    print STDERR "          -u                      unmount \n";
}

sub run_cmd()
{
    my $cmd = $_[0];
    print "Running: $cmd\n";
    system("$cmd");
    my $retval = $?;
    if ($retval < 0)
    {
        print STDERR "Error in running: $cmd\n$retval\n";
    }
    return ($retval);
}

sub run_cmd_get()
{
    my $cmd = $_[0];
    print "Running: $cmd\n";
    my @outs = `$cmd`;
    my $retval = $?;
    if ($retval < 0)
    {
        print STDERR "Error in running: $cmd\n$retval\n";
        exit($retval);
    }
    chomp(@outs);
    return (@outs);
}

my %opts;
getopt('d:', \%opts);

foreach my $opt (sort keys %opts)
{
    if (!defined($opts{$opt}))
    {   
        print STDERR "$0: Requires value for option '$opt'\n";
        &usage();
        exit(-1);
    }   
}
if (defined($opts{"d"}))
{
    $mount_point_base = $opts{"d"};
}
if (defined($opts{"u"}))
{
    $umount = 1;
}

my $retval = 0;
my $cmd;
$retval = `whoami`;
chomp($retval);
unless ($retval eq "root")
{
    print STDERR "$0: Please run this script as 'root' user.\n";
    &usage();
    exit(-1);
}
unless ($umount)
{
    print "Mounting on $mount_point_base\n";
    unless (-d "$mount_point_base") 
    {
        $retval = &run_cmd("mkdir -p $mount_point_base");
        exit($retval) if ($retval < 0);
    }

    my @temps = &run_cmd_get("mount | awk '{print \$1}' | grep \"^/dev/\"");
    my %mounted_devs;
    foreach my $temp (@temps)
    {
        $mounted_devs{$temp} = 1;
        $temp =~ s/\/sd([a-z]).*/\/sd$1/;
        $mounted_devs{$temp}++;
    }
    ## Take care of swap
    @temps = &run_cmd_get("cat /proc/swaps | awk '{print \$1}' | grep \"^/dev/\"");
    foreach my $temp (@temps)
    {
        $mounted_devs{$temp} = 1;
        $temp =~ s/\/sd([a-z]).*/\/sd$1/;
        $mounted_devs{$temp}++;
    }
    my %unmounted_devs;
    my $total = 0;
    @temps = &run_cmd_get("ls /dev/sd*");
    foreach my $temp (@temps)
    {
        next if (defined($mounted_devs{$temp}));
        ## Take care of logical partition, which cannot be mounted
        my @outs = &run_cmd_get("fdisk -s $temp");
        $retval = $outs[0];
        next if ($retval <= 1);      
        $unmounted_devs{$temp} = 1;
        $temp =~ s/\/sd([a-z]).*/\/sd$1/;
        if (defined($unmounted_devs{$temp}))
        {
            delete($unmounted_devs{$temp});
            $total--;
        }
        $total++;
    }
    if ($total == 0)
    {
        print "$0: No partition to mount.\nexiting...\n";
        exit(0);
    }

    print "\n--------------------------------------------\n";
    print "Following partitions are not mounted...\n";
    print "--------------------------------------------\n";
    foreach my $temp (sort keys %unmounted_devs) 
    {
        print "$temp\n";
    }
    print "--------------------------------------------\n";

    ## Now we can mount these
    foreach my $temp (sort keys %unmounted_devs)
    {
        my $mount_dir = $temp;
        $mount_dir =~ s/^\/dev\//$mount_point_base\//;
        print "Mounting $temp -> $mount_dir\n";
        unless (-d "$mount_dir")
        {
            $retval = &run_cmd("mkdir -p $mount_dir");
            exit($retval) if ($retval < 0);
        }

        $cmd = "mount $temp $mount_dir";
        $retval = &run_cmd("$cmd");
        if ($retval < 0)
        {
            print STDERR "!!!Cannot mount $temp on $mount_dir\n";
        }
    }
}
else
{
    unless ($mount_point_base =~ m/^\//) 
    {
        $retval = `pwd`;
        chomp($retval);
        $mount_point_base = "$retval/$mount_point_base";
    }
    print "Unmounting from $mount_point_base\n";
    $cmd = "mount | awk -F \" on \" '{print \$2}' | awk -F \" type \" '{print \$1}' | grep \"$mount_point_base\"";
    my @temps = &run_cmd_get("$cmd");
    if (@temps == 0)
    {
        print "$0: No partition to unmount.\nexiting...\n";
        exit(0);
    }
    print "\n--------------------------------------------\n";
    print "Following directories are mounted...\n";
    print "--------------------------------------------\n";
    foreach my $temp (@temps)
    {
        print "$temp\n";
    }
    print "--------------------------------------------\n";

    foreach my $temp (@temps)
    {
        $cmd = "umount $temp";
        $retval = &run_cmd("$cmd");
        if ($retval < 0)
        {
            print STDERR "!!!Cannot umount $temp\n";
        }
        else
        {
            &run_cmd("rmdir $temp");       # delete dir if empty
        }
    }
}
exit(0);

Monday, February 13, 2012

Video Cutter V2: Video Cutting Using Mencoder

I have upgraded the Video Cutter program. Now it has 2 more features:
1. Strict Mode (-s flag): In this mode, strict monotonously increasing order of times must be given in the configuration (default: video_cutter.conf) file.
2. Joining Split Videos (-j flag): When this flag is given with the command, it does join the split video files into a single video file.

Here is the updated version of the earlier perl script:
#!/usr/bin/perl -w
#===============================================================================
#
#         FILE:  video_cutter.pl
#
#        USAGE:  ./video_cutter.pl [options] <input_video_file>
#
#  DESCRIPTION:  
#
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Mitesh Singh Jat (mitesh), <mitesh[at]yahoo-inc[dot]com>
#      VERSION:  2.0
#      CREATED:  02/12/2011 03:57:55 PM IST
#===============================================================================

use strict;
use warnings;

use Getopt::Std;

sub usage()
{
    print STDERR "USAGE: $0 [options] <input_video_file>\n";
    print STDERR "          -c <conf_file>    default  /base_dir/input_video_file/video_cutter.conf\n";
    print STDERR "                            Start_time(hh:mm:ss),End_time(hh:mm:ss)\n\n";
    print STDERR "          -o <out_dir>      default  /base_dir/input_video_file/\n";
    print STDERR "          -s                strict format check for conf files     [default: no checking]\n";
    print STDERR "          -j                Join output splits into one video file [default: no joining]\n";
}

sub hms_to_seconds()
{
    my $end_sec = 0;
    my ($h, $m, $s) = split(/:/, $_[0]);
    $s = defined($s) ? $s : 0;
    $end_sec += $s;
    $m = defined($m) ? $m : 0;
    $end_sec += (60 * $m);
    $h = defined($h) ? $h : 0;
    $end_sec += (60 * 60 * $h);
    return($end_sec);
}

sub check_times_in_file()
{
    my $conf_file = $_[0];
    open(FH, "$conf_file") or die("$0: Cannot open '$conf_file'\n");
    my $line;
    my $nline = 0;
    my $prev_end_sec = -1;
    while ($line = <FH>)
    {
        chomp($line);
        ++$nline;
        next if ($line =~ m/^#/);
        my ($start_time, $end_time) = split(/,/, $line);
        if (!defined($end_time))
        {
            print STDERR "$0: End time(HH:MM:SS) is not present in line no $nline: $line\n";
            close(CFH);
            return;
        }
        my ($h, $m, $s) = split(/:/, $start_time);
        if (!defined($s))
        {
            print STDERR "$0: Start time is not in format (HH:MM:SS) line no $nline: $line\n";
            close(CFH);
            return;
        }
        ($h, $m, $s) = split(/:/, $end_time);
        if (!defined($s))
        {
            print STDERR "$0: End time is not in format (HH:MM:SS) line no $nline: $line\n";
            close(CFH);
            return;
        }

        my $start_sec = &hms_to_seconds($start_time);
        my $end_sec = &hms_to_seconds($end_time);
        if ($start_sec >= $end_sec)
        {
            print STDERR "$0: $start_sec >= $end_sec in line no $nline: $line\n";
            close(CFH);
            return;
        }
        if ($prev_end_sec >= $start_sec)
        {
            print STDERR "$0: $prev_end_sec >= $start_sec in line no $nline: $line and prev line\n";
            close(CFH);
            return;
        }
        $prev_end_sec = $end_sec;
    }
    close(FH);
    return ($nline);
}

my %opts;
getopt('o:c:', \%opts);

foreach my $opt (sort keys %opts)
{
    if (!defined($opts{$opt}))
    {
        print STDERR "$0: Requires value for option '$opt'\n";
        &usage();
        exit(-1);
    }
}

if (@ARGV != 1)
{
    &usage();
    exit(-1);
}

my $input_video_file = "$ARGV[0]";
my $out_dir = `dirname $input_video_file`;
chomp($out_dir);
my $conf_file = "$out_dir/video_cutter.conf";
my $strict_checking = 0;
my $join_outputs = 0;
my $out_video_files = "";

if (defined($opts{"c"}))
{
    $conf_file = $opts{"c"};
}
if (defined($opts{"o"}))
{
    $out_dir = $opts{"o"};
}
if (defined($opts{"s"}))
{
    $strict_checking = 1;
}
if (defined($opts{"j"}))
{
    $join_outputs = 1;
}

unless (-f "$input_video_file")
{
    print STDERR "$0: Input video file '$input_video_file' is not present\n";
    exit(-1);
}
unless (-f "$conf_file")
{
    print STDERR "$0: split conf file '$conf_file' is not present\n";
    exit(-1);
}
unless (-d "$out_dir")
{
    print STDERR "$0: out dir '$out_dir' is not present\n";
    exit(-1);
}
unless (-w "$out_dir")
{
    print STDERR "$0: out dir '$out_dir' is not writable\n";
    exit(-1);
}

my $mencoder = "/usr/local/bin/mencoder";
unless (-x $mencoder)
{
    $mencoder = "/usr/bin/mencoder";
}
unless (-x $mencoder)
{
    print STDERR "$0: please install mencoder\n";
    print STDERR "sudo apt-get install mencoder\n";
    exit(-1);
}

open(CFH, "$conf_file") or die("$0: Cannot open '$conf_file'\n");
my $line;
my $nline = 0;
my $nsplit = 0;
my $split_name = `basename $input_video_file`;
chomp($split_name);
$split_name =~ s/\.[^.]*$//;
my $split_ext = $input_video_file;
$split_ext =~ s/.*\.([^.]*)$/$1/;
my $success = 0;

if ($strict_checking == 1)
{
    print "Strict Mode\n";
    my $retval = &check_times_in_file($conf_file);
    if (!defined($retval))
    {
        print STDERR "$0: Problem in conf file \"$conf_file\"\n";
        exit(-1);
    }
}
while ($line = <CFH>)
{
    chomp($line);
    $nline++;
    next if ($line =~ m/^#/);
    my ($start_time, $end_time) = split(/,/, $line);
    next if (!defined($end_time));
    my $start_sec = &hms_to_seconds($start_time);
    my $end_sec = &hms_to_seconds($end_time);
    if ($start_sec >= $end_sec)
    {
        print STDERR "$0: $start_sec >= $end_sec\n";
        print STDERR "    $start_time >= $end_time ... skipping for line no $nline ...\n";
        next;
    }
    $end_sec -= $start_sec;
    my $cmd = sprintf("%s -ss %d -endpos %d -ovc copy -oac copy -o %s/%s_%03d.%s %s", 
            $mencoder, $start_sec, $end_sec, $out_dir, $split_name, $nsplit,
            $split_ext, $input_video_file);
    print "\n\n";
    print "-" x 80 . "\n";;
    print "$cmd\n";
    system("$cmd");
    if ($? != 0)
    {
        print STDERR "$0: failed to create $nsplit split for line no $nline\n";
        print STDERR "\t$cmd\n";
    }
    else
    {
        print STDOUT "Created $nsplit split for line $nline\n";
        $out_video_files .= sprintf(" %s/%s_%03d.%s", $out_dir, $split_name, $nsplit, $split_ext);
        $success++;
    }
    print "-" x 80 . "\n";;
    $nsplit++;
}

close(CFH);

print "\n";
print "=" x 80 . "\n";;
printf("Total lines = %d,   Success = %d/%d,  Failure = %d/%d\n",
        $nline, $success, $nsplit,
        $nsplit - $success, $nsplit);
print "=" x 80 . "\n";;

if ($join_outputs == 1)
{
    if ($success < 1)
    {
        print STDERR "$0: failed to join video files.\n";
        exit(-1);
    }
    my $joined_video_file = sprintf("%s/%s_joined.%s", $out_dir, $split_name, $split_ext);
    my $cmd = sprintf("%s -ovc copy -oac copy -o %s %s", 
            $mencoder, $joined_video_file, $out_video_files);
    print "\n\n";
    print "-" x 80 . "\n";;
    print "Joining Video Files into $joined_video_file\n";
    print "-" x 80 . "\n";;
    print "$cmd\n";
    system("$cmd");
    if ($? != 0)
    {
        print STDERR "$0: failed to create joined video file $joined_video_file\n";
        print STDERR "\t$cmd\n";
    }
    else
    {
        print STDOUT "Created joined video file $joined_video_file\n";
    }
    print "-" x 80 . "\n";;
}

exit(0);