Just somewhere to keep my notes while I'm playing.

Wednesday, January 22, 2014

Jar file 101

Here is a very simple example. I have a very simple single class application called Frame2.
The manifest file tells jar which class file has the "Main-Class" directive to run. Note that this file needs to end with a new line character.
PS C:\Users\tjinkers\java\swing> ls Frame2.*
Directory: C:\Users\tjinkers\java\swing

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 22/01/2014 15:37 693 Frame2.class
-a--- 22/01/2014 10:20 377 Frame2.java

PS C:\Users\tjinkers\java\swing> cat .\manifest.txt
Main-Class: Frame2
PS C:\Users\tjinkers\java\swing> jar cvfm Frame2.jar manifest.txt Frame2.class
added manifest
adding: Frame2.class(in = 693) (out= 471)(deflated 32%)
PS C:\Users\tjinkers\java\swing> ls Frame2.*

Directory: C:\Users\tjinkers\java\swing

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 22/01/2014 15:37 693 Frame2.class
-a--- 22/01/2014 17:04 948 Frame2.jar
-a--- 22/01/2014 10:20 377 Frame2.java

PS C:\Users\tjinkers\java\swing> ./Frame2.jar
PS C:\Users\tjinkers\java\swing>

Friday, June 28, 2013

iptables - the Linux firewall

I needed to test to see how a package would behave if a certain server was not available. I decided that the easiest way to do this was to use a firewall. As I haven't done much with firewalls previously, I though I should write it up.

To see what you have configures, use:
[root@ebl-oel57vm1 ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  144.20.15.203        0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
[root@ebl-oel57vm1 ~]#

[root@ebl-oel57vm1 ~]# iptables -A INPUT -s 138.1.187.71 -j DROP
[root@ebl-oel57vm1 ~]# ping 138.1.187.71 | head -3
^C
[root@ebl-oel57vm1 ~]#
This tells me that I have 3 different "chains" configured (a chain of rules), but only the INPUT chain has anything configured. It tells me that I will not accept requests from 144.20.15.203

This wasn't exactly what I wanted, I wanted to stop my server contacting this IP address, so I needed to do the following:

[root@ebl-oel57vm1 ~]# ## Revert back to the start
[root@ebl-oel57vm1 ~]# iptables -F INPUT
[root@ebl-oel57vm1 ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
[root@ebl-oel57vm1 ~]# ## Define an outbound firewall rule
[root@ebl-oel57vm1 ~]# iptables -A OUTPUT -d 138.1.187.71  -j REJECT
[root@ebl-oel57vm1 ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
REJECT     all  --  0.0.0.0/0            138.1.187.71        reject-with icmp-port-unreachable
[root@ebl-oel57vm1 ~]#

[root@ebl-oel57vm1 ~]# ping 138.1.187.71 | head -3
PING 138.1.187.71 (138.1.187.71) 56(84) bytes of data.
From 10.79.243.156 icmp_seq=1 Destination Port Unreachable
From 10.79.243.156 icmp_seq=1 Destination Port Unreachable
[root@ebl-oel57vm1 ~]#
Notice how when I blocked the IP Address on the inbound side my requests out didn't receive a reply, whilst when I blocked on the outbound side I got the message that the port was unreachable.

Pings
To stop your server responding to a Ping:
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
To stop your server from pinging another server
iptables -A OUTPUT -p icmp --icmp-type echo-request -j DROP

Editing IPTables
iptables-save > myfile
edit myfile
iptables-restore < myfile
rm myfile
 

Tuesday, April 23, 2013

Displaying files in date order

Here is an example of a program that reads all the files directory and displays them in date order.

#!/usr/bin/perl
use strict;

my ($MYDIR, $mtime, $filename,%filearray, $key);
my $LOGDIR="/mytest/logs";

sub numerically { $filearray{$a} <=> $filearray{$b}; }


# Read all the file names in to an array
opendir $MYDIR, $LOGDIR  or die "Unable to open file: $!\n";
my @allfiles = readdir $MYDIR;
closedir $MYDIR;
# For each file, get its modification time and store
print "Unsorted\n";

for (@allfiles) {
   next if $_ eq "." || $_ eq "..";
   $filename = $_;
   $mtime = (stat("/mytest/logs/" . $filename))[9];
   printf "\t$mtime\t\t$filename\n";
   # populate a hash called %filearray with a
   # key of the file name and a value of the mtime

   $filearray{$filename} = $mtime;
}

print "Sorted\n";
foreach $key (sort numerically ( keys(%filearray))) {
  print "\t$filearray{$key}\t\t$key\n";
}


Tuesday, April 9, 2013

Simple Perl

Perl is a highly complicated language, but it is possible to do some useful things using some pretty simple code. Here are a few examples.

Example 1
Here is a simple example of a program that reads a file and prints it out. I'm sure that it could be written with fewer lines of code, but this has the advantage of being a framework for any program you might need to write.
$ cat testfile
micky mouse
mini mouse
daffy duck

tjinkers@JINKERSON-PC ~/example
$ cat ./filelister.pl
#!/usr/bin/perl
use File::stat;
my $IFILE = $ARGV[0];
die "Unable to open input file\n" unless (open $inputfile, $IFILE);
while (<$inputfile>) {
        chomp;
        print $_ . "\n";
}
close  $inputfile;

tjinkers@JINKERSON-PC ~/example
$  ./filelister.pl testfile
micky mouse
mini mouse
daffy duck

tjinkers@JINKERSON-PC
~/example
Things to note:
  • $ARGV[0] is the first command line argument
  • 'die ... unless' - most programming languages put the condition before the action, but Perl is not fussy, and so here we tell the program to 'die' (end with an error condition) unless it is able to open its input file.
  • 'chomp' - if the final character of a string is a carriage return / line feed, remove it. Like so many Perl instructions, if you don't specify the variable, it uses the result of the previous operation, stored in $_
  • 'print $_ . "\n"' - print the result of the previous operation to stdout, concatenated with a new line character.
Example 2
Here is a  re-write of the above example, this time using a subroutine.
#!/usr/bin/perl
use strict;
use warnings;
sub processfile {
   die "Unable to open input file\n" unless (open my $inputfile, $_[0]);
   while (<$inputfile>) {
        chomp;
        print $_ . "\n";
   }
   close  $inputfile;
}
main {
   my $IFILE = $ARGV[0];
   processfile($IFILE);
   exit 0;
}
Things to note:

  • use strict; forces you to get the syntax write - always good practice!
  • We either need to declare the subroutine ahead of the main section, or include a dummy declaration above it.
Example 3
Here is another example, this time using a subroutine that returns a value, otherwise known as a function.
#!/usr/bin/perl
use strict;
use warnings;
use Scalar::Util qw(looks_like_number);
sub addthem {
   my $var=0;
   my $sum=0;
   foreach $var ( @_ ) {
     print $var . "\n";
     $sum=$sum+$var if (looks_like_number($var));
   }
   return $sum;
}
main {
   print addthem(@ARGV) . "\n";
   exit 0;
}


 Things to note:

  • The subroutine is called within the print statement.
  • The variable passed to the subroutine is an array of values which we rattle through, adding them up.
  • We are using the Scalar::Util utility to determine if the value passed is numeric. This utility contains a number of useful functions that are not quite popular enough to include in the main language definition.

Example 4
Here is a more complex example. The request was to write a piece of code that would read through a file. If it found 2 predetermined lines next to each other, the code had to insert the contents of a file beneath the second line. If the lines were not next to each other in sequence, they were to be ignored.

#!/usr/bin/perl
use File::stat;
use IO::File;
use warnings;
use strict;

die "Could not open stdin\n" unless ( open my $stdin, "< &STDIN");
my $trigger = "safety";
while (<$stdin>) {
        chomp;
        my $line = $_;
        print $line . "\n";
        if ( $line eq "line 2" ) {
                $trigger = "primed";
        } else {
                if ( $line eq "line 3" && $trigger eq "primed" ) {
                        ## print "Fire!\n";
                        die "Could not open include file\n" unless ( open my $ifile, "./insertfile.txt");
                        while (<$ifile>) {
                                chomp;
                                print $_ . "\n";
                        }
                        close $ifile;
                }
                $trigger = "safety";
        }
} 

Friday, March 15, 2013

File System Manipulation

Extending a 'normal' fdisk partition

The Task
We have a server with ext3 files systems. The file systems for root (/) and usr (/usr) are 4GB and need to be increased to 8GB.
  1. use fdisk to create a new partition of the correct size
  2. dd if=/dev/sda5 of=/dev/sda10
  3. e2fsck -f /dev/sda10
  4. resize2fs /dev/sda10
  5. e2label /dev/sda5 "oldroot"
  6. Reboot the system
Note: The above example assumes that you are using labels in /etc/fstab. If you are using UUID you will have to edit /etc/fstab. Actually - UUIDs are copied across, so we need to work a little harder on these.

Tuesday, December 6, 2011

Solaris 11 Package Updates

Using a Solaris 11 Repository
Solaris 11 has moved to a package management system that is similar to yum, in that is pulls from a network and manages dependencies.
The command used is pkg - enter pkg --help for a full list of options.
root@solaris:~# pkg publisher
PUBLISHER                             TYPE     STATUS   URI
solaris                               origin   online   http://pkg.oracle.com/solaris/release/
root@solaris:~# pkgrepo info -s http://pkg.oracle.com/solaris/release/
PUBLISHER PACKAGES STATUS           UPDATED
solaris   4292     online           2011-11-09T15:42:00.183118Z
root@solaris:~#

root@solaris:~# pkg update
No updates available for this image.
root@solaris:~#
Before you install a package you can dry-run it:
root@solaris:~# pkg install -nv gcc-3
           Packages to install:         2
     Estimated space available:   9.67 GB
Estimated space to be consumed: 219.43 MB
       Create boot environment:        No
Create backup boot environment:        No
            Services to change:         1
          Rebuild boot archive:        No

Changed packages:
solaris
  developer/gcc-3
    None -> 3.4.3,5.11-0.175.0.0.0.2.537:20111019T093736Z
  developer/gnu-binutils
    None -> 2.19,5.11-0.175.0.0.0.2.537:20111019T095434Z
Services:
  restart_fmri:
    svc:/application/texinfo-update:default
root@solaris:~#
The you go ahead and install the package:
 root@solaris:~# pkg install -nv gcc-3
           Packages to install:         2
     Estimated space available:   9.67 GB
Estimated space to be consumed: 219.43 MB
       Create boot environment:        No
Create backup boot environment:        No
            Services to change:         1
          Rebuild boot archive:        No

Changed packages:
solaris
  developer/gcc-3
    None -> 3.4.3,5.11-0.175.0.0.0.2.537:20111019T093736Z
  developer/gnu-binutils
    None -> 2.19,5.11-0.175.0.0.0.2.537:20111019T095434Z
Services:
  restart_fmri:
    svc:/application/texinfo-update:default
root@solaris:~#
 To list the packages that you have installed:
timj@solaris11vm2:~$ pkg list | head
NAME (PUBLISHER)                                  VERSION                    IFO
SUNWcs                                            0.5.11-0.170               i-r
archiver/gnu-tar                                  1.26-0.175.0.0.0.2.537     i--
audio/audio-utilities                             0.5.11-0.175.0.0.0.2.1     i--
codec/flac                                        1.2.1-0.175.0.0.0.0.0      i--
codec/libtheora                                   1.1.1-0.175.0.0.0.0.0      i--
codec/ogg-vorbis                                  2.30.0-0.175.0.0.0.0.0     i--
codec/speex                                       1.2-0.175.0.0.0.0.0        i--
communication/im/pidgin                           2.10.0-0.175.0.0.0.0.0     i--
compress/bzip2                                    1.0.6-0.175.0.0.0.2.537    i--
timj@solaris11vm2:~$
To list the details of a package:
timj@solaris11vm2:~$ pkg info xcalc
          Name: x11/xcalc
       Summary: xcalc - scientific calculator for X
   Description: xcalc is a scientific calculator desktop accessory that can
                emulate a TI-30 or an HP-10C.
      Category: Applications/Accessories
         State: Installed
     Publisher: solaris
       Version: 1.0.4.1
 Build Release: 5.11
        Branch: 0.175.0.0.0.0.1215
Packaging Date: September 27, 2011 12:58:35 PM
          Size: 104.32 kB
          FMRI: pkg://solaris/x11/xcalc@1.0.4.1,5.11-0.175.0.0.0.0.1215:20110927T125835Z
timj@solaris11vm2:~$
Want to know where a file comes from?:
timj@solaris11vm1:~$ pkg search libresolv.so
INDEX      ACTION VALUE                        PACKAGE
basename   link   lib/sparcv9/libresolv.so     pkg:/system/library@0.5.11-0.175.0.0.0.2.1
basename   link   usr/lib/sparcv9/libresolv.so pkg:/system/library@0.5.11-0.175.0.0.0.2.1
basename   link   lib/libresolv.so             pkg:/system/library@0.5.11-0.175.0.0.0.2.1
basename   link   usr/lib/amd64/libresolv.so   pkg:/system/library@0.5.11-0.175.0.0.0.2.1
basename   link   lib/amd64/libresolv.so       pkg:/system/library@0.5.11-0.175.0.0.0.2.1
basename   link   usr/lib/libresolv.so         pkg:/system/library@0.5.11-0.175.0.0.0.2.1
timj@solaris11vm1:~$
To update all packages:
root@solaris11vm1:~# pkg update
No updates available for this image.
root@solaris11vm1:~# 
What to do when things go wrong:

root@solaris11vm1:~# pkg verify -v   gcc-3
PACKAGE                                                                 STATUS
pkg://solaris/developer/gcc-3                                               OK
root@solaris11vm1:~# mkfile 1024 /usr/sfw/bin/gcc
root@solaris11vm1:~# pkg verify -v   gcc-3
PACKAGE                                                                 STATUS
pkg://solaris/developer/gcc-3                                            ERROR
        file: usr/sfw/bin/i386-pc-solaris2.11-gcc-3.4.3
                Mode: 01600 should be 0555
                Unexpected Exception: Request error: class file/memory mismatch
root@solaris11vm1:~# pkg fix   gcc-3
Verifying: pkg://solaris/developer/gcc-3                        ERROR        
        file: usr/sfw/bin/i386-pc-solaris2.11-gcc-3.4.3
                Mode: 01600 should be 0555
                Unexpected Exception: Request error: class file/memory mismatch
Created ZFS snapshot: 2011-12-07-15:27:53
Repairing: pkg://solaris/developer/gcc-3                   
                                                                             

DOWNLOAD                                  PKGS       FILES    XFER (MB)
Completed                                  1/1         1/1      0.1/0.1

PHASE                                        ACTIONS
Update Phase                                     3/3

PHASE                                          ITEMS
Image State Update Phase                         2/2
root@solaris11vm1:~# pkg verify -v   gcc-3
PACKAGE                                                                 STATUS
pkg://solaris/developer/gcc-3                                               OK
root@solaris11vm1:~#

Thursday, December 16, 2010

Mail merge in PHP

Just for a laugh

The question was, how do you do a mail merge in PHP. OK, it was a question that no-one was asking, but I never let the deter me before.


Input Data
$ cat inputdata
Tim,Jinkerson,
Ben,De Mora,
Jes,Ferrier,

tjinkers@TJINKERS-GB ~/merge
$ cat template
FAO: .f1 .f2
Dear .f1
Now is the winter of our discontent
made glorious summer by this sun of York
Many thanks
Tim

tjinkers@TJINKERS-GB ~/merge
$
The Program

$ cat mymerge.php
$filename = "template";
$mergef = "inputdata";
$fdm = fopen($mergef,"r");
$fnum=1;
$mdata = fgets($fdm, 512);
while (!feof($fdm))
{
  list($f1, $f2, $f3, $f4, $f5) = explode(",", $mdata);
  $fd = fopen($filename,"r");
  $contents = fread ($fd, filesize($filename));
  fclose ($fd);
  $ofilename = "file.".$f1.".".$f2.".".$fnum;
  $contents=str_replace(".f1", $f1, $contents);
  $contents=str_replace(".f2", $f2, $contents);
  $contents=str_replace(".f3", $f3, $contents);
  $contents=str_replace(".f4", $f4, $contents);
  $contents=str_replace(".f5", $f5, $contents);
  $fdo = fopen($ofilename,"w");
  fwrite ($fdo,$contents);
  fclose ($fdo);
  $fnum++;
  $mdata = fgets($fdm, 512);
}
fclose ($mergef);
?>

tjinkers@TJINKERS-GB ~/merge
$
For each line of the input data, the program reads the template file as a single string, and then does a replace on the markers for the input date. It writes the results out to a file who's name is based on the input data.


$ php mymerge.php


$ ls
file.Ben.De Mora.2  file.Jes.Ferrier.3  file.Tim.Jinkerson.1  inputdata  mymerge.php  template

tjinkers@TJINKERS-GB ~/merge
$ cat file.Tim.Jinkerson.1
FAO: Tim Jinkerson
Dear Tim
Now is the winter of our discontent
made glorious summer by this sun of York
Many thanks
Tim

tjinkers@TJINKERS-GB ~/merge
$