Java in a Windows EXE with launch4j

Originally published on: Sun, 16 Aug 2009 13:46:59 +0000

I noted today that a successful independently written / marketed ( MicroISV ) product had been built in Java. The redistributable files were available for both Windows and MacIntosh computers.

I emailed the author, asking what he used to build the installations for each. I’ll discuss the Mac software in a later post. For the Windows installation, he pointed me to a product called launch4j. ( See http://launch4j.sourceforge.net/ ).

Launch4j is an all-Java program that will bind a configurable Windows stub executable file to a Java jar file. The result is a jar embedded in a specially configured EXE.

When invoked, the EXE will execute the system’s appropriate JVM ( or will issue an error message if a compatible JVM hasn’t been found ) and will then execute the embedded jar file in this JVM.

Effectively, launch4j bottles up Java code into a Windows EXE.

Since launch4j is an all-Java program, one can actually build Windows EXE’s on various supported non-Windows platforms.

Let’s take a trivial sample Java program and turn it into an EXE with launch4j.

HeyGuys.java


// Display a simple message
// This code is in the public domain.

import javax.swing.*;

public class HeyGuys {
   public static void main(String[] args) {
      JOptionPane.showMessageDialog(null,"Hey, you guys!");
      System.exit(0);
   }
}

Enter the following to compile and execute the program:

javac HeyGuys.java 
java HeyGuys

The message:

heyguys

…should appear on the screen. Click OK.

Let’s take the file HeyGuys.class and put it in its own jar file. We first need to create a manifest file so that the jar will contain metadata to indicate which class should be executed via java.exe or javaw.exe.

Enter the following two lines in a file called manifest.mf:

Manifest-Version: 1.0
Main-Class: HeyGuys

Then, issue the following command:

jar -cfm heyguys.jar manifest.mf HeyGuys.class

Executing the above command should yield the file heyguys.jar.

Now, let’s try to execute the jar to see if we’ve packaged it up correctly.

java -jar heyguys.jar

You should see the same message window that was displayed earlier:

heyguys

Finally, let’s use launch4j to package up the jar into an EXE.

Although launch4j has a command-line interface, I first used the GUI. The first screen I filled in looked similar to this:

launch4j1

I tried to just save the EXE at that point, but I then needed to specify a minimum Java version on this tab:

launch4j2

After changing those values, launch4j wanted me to save those options in an XML file, so I just chose the name l4j.xml arbitrarily.

Launch4j then quickly packaged a small EXE.

If you run it on a version of Windows with Java 1.6.0 or above, you’ll see the message window. If you don’t have a 1.6.x JVM, you’ll be prompted to download one.

Note that launch4j is not an installer. Now that you have an EXE, you might want to build an installer around it with a product like Inno Setup or the NSIS installer system.

Also note that in addition to the bare options that I’ve chosen, a number of other options are available including the ability to set an icon and the ability to specify the JVM’s runtime parameters such has heap size.

The source code and EXE for the above sample program can be found here:

http://www.mailsend-online.com/wp/heyguys.zip

Posted in Programming | Tagged , | Leave a comment

Send GMail From the Windows Command-Line with MailWrench

Originally published on: Sun, 13 Feb 2011.

Google’s GMail service allows e-mail to be sent using an SMTPS ( SMTP over SSL ) interface. Sending GMail via the Windows command-line requires a command-line mailer with SMTPS support. My commercial MailWrench utility is one such program.

Update 25 July, 2012: MailWrench is now free, open source software. Please see the post at the following link:

https://lawlessguy.wordpress.com/2012/07/24/mailwrench-csharp-command-line-mailer-for-windows-is-now-free-software/

The GMail SMTPS service listens at port 587 on the server smtp.gmail.com. To configure MailWrench to send mail using GMail, create a text file that we’ll just name m.cfg and add the following configuration lines:

-ssl
-smtp smtp.gmail.com
-port 587
-id your_id@gmail.com
-password your_password

The MailWrench command-line you would then use to send a simple message would be something like the following:

MailWrench @m.cfg -to some_id@someserver.kom -msg "Hello!" -s "Testing!"

Note that any of the options specified in the file m.cfg could have been specified on the command-line itself. The “.cfg” files are intended to be used to contain options that rarely change when sending e-mails.

Since GMail does not allow arbitrary attachments, any file you attach must be one of the permissible attachment types ( word-processor documents, spreadsheets, images,audio, …etc. ) Your e-mail may not process properly if you send other file types.

To attach the image file test.png to the above e-mail, add the parameters -a test.png to the above command-line. The new command-line should look like the folllowing:

MailWrench @m.cfg -to some_id@someserver.kom -msg "Hello!" -s "Testing!" -a test.png
Posted in Programming | Tagged , , , | Leave a comment

WSH JavaScript Includes

Originally published on: Wed, 28 Apr 2010 00:09:54 +0000

I like to separate JavaScript functions into libraries that I can later reference in some other script.

It’s easy enough to reference these in HTML using the SRC attribute of the SCRIPT tag.

I the case of WSH, one can use a WSF document to dynamically construct a composite script via combinations of inline and/or external files. However, I prefer a more simple approach when I’m using WSH.

Please consider these two files:

one.js

   // MIT/X11 license. See includelib.js for full text of
   // license.
eval(new ActiveXObject("Scripting.FileSystemObject").
   OpenTextFile("inc.js",1).ReadAll());

display("Hello!");

inc.js

   // MIT/X11 license. See includelib.js for full text of
   // license.
display=function(x) {
   WScript.Echo(x);
}

The first couple of lines of one.js create a new FileSystemObject. Then, the dot operator is used to immediately refer to that object so that we can invoke OpenTextFile() to open a file called inc.js for mode 1 ( reading ).

Again, the dot operator is used to refer to the new object so that we can call the ReadAll() method to load the entire inc.js file into a string.

Finally, we call eval() to dynamically execute the contents of inc.js, effectively simulating an “include” operation available natively in other scripting languages.

In the inc.js file, I’ve chosen to use an alternate form of function definition that ensures that the named function will appear globally so that it can be referenced by other included modules.

We prove that we’ve invoked the included file which defines a function called display() by invoking this new function.

If you execute one.js via the following command-line:

cscript /nologo one.js

…you should see the output:

 Hello!

If you have a number of files to include, you might not want to keep creating FileSystemObject instances. We can create a library that encapsulates this behavior into a function and can then use the technique from one.js to dynamically evaluate that library.

includelib.js

// This single license text is applied to all examples one,js, 
// inc.js, includelib.js, and two.js.
// 
// License: MIT / X11
// Copyright (c) 2010 by James K. Lawless
// jimbo@radiks.net http://www.radiks.net/~jimbo
// http://www.mailsend-online.com
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

   var incfso=new ActiveXObject("Scripting.FileSystemObject"); 
   include=function(x) {
      eval(incfso.OpenTextFile(x,1).ReadAll());
   }

This library creates one global instance of FileSystemObject, incfso, for future reference.

By dynamically evaluating includelib.js, we now have a callable include() function. We can then include inc.js and can invoke the display method again.

two.js

   // MIT/X11 license. See includelib.js for full text of
   // license.

   // Use the short hack to load 
   // includelib.js
eval(new ActiveXObject("Scripting.FileSystemObject").
   OpenTextFile("includelib.js",1).ReadAll());

   // Now invoke include() function to bring in inc.js
include("inc.js");
display("Hello, again!");

When you execute two.js…

cscript /nologo two.js

…you should see the text:

Hello, again.
Posted in Programming | Tagged | Leave a comment

Embedding JavaScript in a Batch File

Originally published on: Fri, 07 Aug 2009 12:05:51 +0000

The program below is both a batch file and a JavaScript WSH console file. The dual nature of the file is achieved via JavaScript block comments and the strategy by which the command interpreter searches for target labels in a batch file.

Save the file below as hybrid.bat.

rem ( /*
@echo off
cscript /nologo /e:javascript hybrid.bat
goto end
*/ )

// by Jim Lawless
// This program sample is in the public domain

function rem() {
   WScript.StdOut.WriteLine("Hello, world!");
}

/*
:end */

The first line of code is benign for a batch file; the REM command is a single line remark, so it ignores all text after it.

The first line is constructed so that syntactically, it is also the beginning of a valid JavaScript function call for a function named rem().

Immediately after the first left-parenthesis in the call, a block-comment is used to mask the next few lines from the WSH JavaScript interpreter. Batch commands follow on the next three lines, ending with a goto.

The batch file itself invokes the WSH console interpreter cscript.exe passing in the name of the file ( hybrid.bat ) itself. After invocation of the script as a JavaScript file, the batch file portion attempts to transfer control to a label named end.

When the command processor attempts to transfer control to a label via the goto verb, each line of the batch file is examined sequentially until a matching label is found. Any syntax errors encountered ( the lines of JavaScript text ) are ignored.

Posted in Programming | Tagged | 2 Comments

Command Line Image Format Conversion in CSharp

Originally published on: Sat, 26 Sep 2009 14:44:24 +0000

I needed a quick-and-dirty command-line image format conversion utility. The .NET framework made the task pretty painless. I wrote the following utility that can convert between Windows Bitmap, JPEG, GIF, PNG, and TIFF images. ( TIFF may have a variety of subformats, so your mileage may vary when trying to convert to/from TIFF. )

imgconv.cs

// imgconv.cs - Simple command-line image file converter
//
// License: MIT / X11
// Copyright (c) 2009 by James K. Lawless
// jimbo@radiks.net http://www.radiks.net/~jimbo
// http://www.mailsend-online.com
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

using System ;
using System.Drawing;
using System.Drawing.Imaging;

namespace ImgConv
{
   public class ImgConv
   {
        [STAThread]
      public static void Main(string[] args)
      {
         ImageFormat fmt;
         string inputFile="",outputFile="";
         int i;
         fmt=ImageFormat.Jpeg;
         Console.WriteLine("\nimgconv by Jim Lawless - jimbo@radiks.net\n");

         for(i=0;i<args.Length;i++)
         {
            if(args[i].ToLower().Equals("-in"))
            {
               inputFile=args[i+1];
               i++;
            }
            else
            if(args[i].ToLower().Equals("-out"))
            {
               outputFile=args[i+1];
               i++;
            }
            else
            if(args[i].ToLower().Equals("-gif"))
            {
               fmt=ImageFormat.Gif;
            }
            else
            if(args[i].ToLower().Equals("-jpg"))
            {
               fmt=ImageFormat.Jpeg;
            }
            else
            if(args[i].ToLower().Equals("-png"))
            {
               fmt=ImageFormat.Png;
            }
            else
            if(args[i].ToLower().Equals("-bmp"))
            {
               fmt=ImageFormat.Bmp;
            }
            else
            if(args[i].ToLower().Equals("-tiff"))
            {
               fmt=ImageFormat.Tiff;
            }
            else
            {
               Console.WriteLine("Unknown option " + args[i]);
               Syntax();
               return;
            }
         }
         if( (inputFile=="")||(outputFile=="")) {
            Syntax();
            return;
         }
         Bitmap b=new Bitmap(inputFile);
         b.Save(outputFile,fmt);
      }
      public static void Syntax()
      {
         Console.WriteLine("Syntax:\timgconv.exe -in input_file_name -out    output_file_name [ -gif -png -tiff -jpg -bmp ]\n");
         Console.WriteLine("The default output format is -jpg.\n");
      }
   }
}
imgconv by Jim Lawless - jimbo@radiks.net

Syntax: imgconv.exe -in input_file_name -out output_file_name [ -gif -png -tiff -jpg -bmp ]

The default output format is -jpg.
To load a BMP file and save as a JPEG, issue the following command. ( The default output format is JPEG. You may optionally specify the -jpg parameter. )

imgconv -in file.bmp -out file.jpg

To load a JPEG file and save as a PNG, issue the following command.

imgconv -in file.jpg -out file.png -png

I haven’t tested this with Mono, yet.
The source and executable file for imgconv can be downloaded in a single archive at: http://www.mailsend-online.com/wp/imgconv.zip

Posted in Programming | Tagged | Leave a comment

A Simple Associative Array Library in C

Originally published on: Thu, 19 Nov 2009 02:35:02 +0000

I often need to use associative arrays when writing C code. You might be more familiar with these constructs under other names ( dictionaries, maps, hashmaps, hashes, …etc. ) I will use the term map in place of the words associative array.

A map is a collection of key / value pairs or name / value pairs. My implementation of a map structure allows strings as the only data that can be stored in the name and value.

Many implementations of maps use a hashed lookup to speed up execution. I have opted to use a simple forward-chained linked-list of map structures. When searching for an item in a map, the search will sequentially pass over every item in the list of map entries until a match is found. If no match is found, an empty string is returned.

This implementation is complete enough for my needs. See:

https://github.com/jimlawless/map_lib

http://www.mailsend-online.com/wp/map_lib.zip

The test program map_stuff.c loads and displays a map with name/value pairs. The names are all numbers. The values are words that sound like the numbers ( homonyms ).

The output from the map_stuff program is as follows:

Two Too
Four Fore
One Won

Two To
Four Fore
One Won

Eight 

Eight Ate

I did not provide any kind of iterator functions in the library. If I need to iterate through a given map, I will just use a for-loop and will use the ->nxt element to reach each successive entry.

Posted in Programming | Tagged | Leave a comment

Play MP3 Files with Python ( Windows )

Originally published on: Sun, 26 Jun 2011.

I’ve just read the book Grey Hat Python : Python Programming for Hackers and Reverse Engineers by Justin Seitz. The book introduced the Python ctypes library to me. The ctypes library, allows a Python program to access to lower-level features of the operating environment normally reserved for C programmers.

( The book itself was a great read that deserves its own post … after I’ve had time to tinker with all of the code. )

As an early experiment, I rewrote in Python the bulk of the command-line MP3 player I had originall written in C.  Please refer to the script below:

playmp3.py

# Copyright (c) 2011 by James K. Lawless
# jimbo@radiks.net http://www.mailsend-online.com
# License: MIT / X11
# See: http://www.mailsend-online.com/license.php
# for full license details.

from ctypes import *;

winmm = windll.winmm

def mciSend(s):
   i=winmm.mciSendStringA(s,0,0,0)
   if i<>0:
      print "Error %d in mciSendString %s" % ( i, s )

def playMP3(mp3Name):
   mciSend("Close All")
   mciSend("Open \"%s\" Type MPEGVideo Alias theMP3" % mp3Name)
   mciSend("Play theMP3 Wait")
   mciSend("Close theMP3")

playMP3("test.mp3")

The ZIP archive containing the above source can be downloaded from

http://www.mailsend-online.com/wp/playmp3.zip

Note that the above script does not play a script directly from the command-line; it exposes the function playMP3() which should allow one to write Python code to control the invocation of the given MP3 file through the Media Control Interface (MCI).

The script expects a file named test.mp3 to be present in the current directory. You can alter the last line of the script, substituting the name and location of a preferred MP3 file.

Please note that in the Python version of the code, I have omitted the call to the Win32 API function GetShortPathName(). Instead, I placed double-quotes around the name of the MP3 file in the MCI command-string to accommodate the occurrences of spaces in the filename and/or pathname.

Posted in Programming | Tagged | Leave a comment

Cheating the LZW

Originally published on: Fri, 24 Apr 2009 00:10:27 +0000

In the early days of the web, many web pages sported hit-counters that would generate a graphical meter indicating the number of visitors who had viewed the page.

I thought that it would be a nice thing to have on my own site, so I set out to build my own.

I had decided to try using Perl to build my counter as it had become my language of choice when developing other CGI’s.

Some of the popular hit-counters would accept libraries of JPEG’s or GIF’s representing various kinds of digits and would then use the GD graphics library to fuse the appropriate digit images together into a single image.

I opted to take a different route.

I had decided to use the GIF format for the output image. I wanted a lossless format that could represent a small, monochrome bitmap containing six eight-by-sixteen-pixel characters.

If one has a binary character-set available, building a raw bitmap of a stream of digits is relatively painless. A monochrome bitmap eight by sixteen by two (colors) by 6 (characters) can be represented in 768 bits ( 96 bytes ) uncompressed. That’s pretty tiny!

Unfortunately, the GIF format did not permit a flag to indicate that the bitmap image would be an uncompressed bitmap. So, I was going to have to employ the LZW compression algorithm on this tiny blob of data. …or WAS I ?

The LZW algorithm uses a protocol of sorts that must be observed by both the compressor and the decompressor. An initial code-size must be agreed upon by both prior to compression or decompression. This code-size value indicates the bit-width for each code in the I/O stream. ( Like many compression algorithms, the LZW leverages variable-length bit I/O. )

The code-size must allow for two codes; clear and end-of-input.

I decided on a code-size of three bits and allowed the LZW special characters to push the code-size up to four bits … which is easier to handle in bit-shift operations. The clear-code would become eight and the EOI code would be nine as three bits can represent the numbers zero through seven.

For each bit in the generated bitmap, I wrote both a nybble with a value representing a single pixel, …a one or a zero followed by a nybble representing the clear-code.

The bit-image was emitted without any true compression. In fact, using the LZW as a protocol, the stream of raw data grew in size ( four bits to represent a monochrome pixel instead of one plus an extra four bits for each clear code. ) This process uses a byte to represent a single pixel when both nybbles are coupled.

At the end of stream, I needed to emit the EOI character, so I simple wrote a byte with the value 9*16, shifting the nine four pixels to the left so that the decompressor would stop processing the bitmap.

The Perl code below illustrates this technique by creating a GIF file named number.gif with the digits “123456” represented as a bitmapped image.

Sample digits

number

You might change the value of $count to something other than “123456”, but it must be six characters in length and must be comprised of all digits.

The generated image is always 805 bytes in size. 768 bytes for the bitmap, one for the EOI code, and thirty-six bytes for the GIF header and footer.

# License: MIT / X11
# Copyright (c) 2009 by James K. Lawless
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the &quot;Software&quot;), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
@charset=(0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
56,24,124,124,12,254,56,254,124,124,
108,56,198,198,28,192,96,198,198,198,
198,120,6,6,60,192,192,6,198,198,
198,24,12,6,108,192,192,6,198,198,
214,24,24,60,204,252,252,12,124,126,
214,24,48,6,254,6,198,24,198,6,
198,24,96,6,12,6,198,48,198,6,
198,24,192,6,12,6,198,48,198,6,
108,24,198,198,12,198,198,48,198,12,
56,126,254,124,30,124,124,48,124,120,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0);

# &quot;clear&quot; code
$clr=8;

# end-of-input code in left-nybble of byte
$eoi=9*16;

# must be 6-digits
$count=&quot;123456&quot;;

open(FIL,&quot;&amp;gt;number.gif&quot;);
binmode(FIL);
# GIF 87 header
print FIL &quot;GIF87a&quot; ;
print FIL pack(&quot;CC&quot;,48,0); # Raster width 48
print FIL pack(&quot;CC&quot;,16,0); # Raster height 16

# Colormap, numbr bits color res -1, 0, bits per pixel - 1
# 1 000 0 000
print FIL pack(&quot;C&quot;,128);

# Background color index
print FIL pack(&quot;C&quot;,0);
# dummy byte
print FIL pack(&quot;C&quot;,0);

# Color Map
# Black
print FIL pack(&quot;CCC&quot;,0,0,0);

# White
print FIL pack(&quot;CCC&quot;,255,255,255);

# Image descriptor
# Separator
print FIL ',' ;

# Left
print FIL pack(&quot;CC&quot;,0,0);

# Top
print FIL pack(&quot;CC&quot;,0,0);

# Width
print FIL pack(&quot;CC&quot;,48,0);

# Height
print FIL pack(&quot;CC&quot;,16,0);

# Use global color map=0, sequential image = 0, 000, pixel -1 bpp
# 0 0 000 000
print FIL pack(&quot;C&quot;,0);

# Raster data
# Code size 3 ( LZW will use 4), this makes clear code 8!, EOI 9
print FIL pack(&quot;C&quot;,3);

# here's where we'll need to send the data out in blocks. It will be

$blkcount=0; # total blocks so far
$blkinprog=0; # block in progress

for($j=0;$j&amp;lt;16;$j++) {
  for($i=0;$i&amp;lt;6;$i++) {
    for($bits=128;$bits&amp;gt;=1;$bits=$bits/2) {
      # Determine bit settings
      $b=substr($count,$i,1)-'0';
      if( ($charset[$j*10+$b] &amp;amp; $bits) == $bits ) {
        $bitout = 16;
      }
      else {
        $bitout = 0;
      }
      if( $blkinprog == 0 ) {
        if($blkcount&amp;lt;3) {
          $blkinprog=240;
        }
        else {
          $blkinprog=49;
        }
        print FIL pack(&quot;C&quot;,$blkinprog);
        $blkcount++;
      }
      print FIL pack(&quot;C&quot;,$bitout+$clr);
      $blkinprog--;
    }
  }
}
print FIL pack(&quot;C&quot;,$eoi);

# Zero length for block
print FIL pack(&quot;C&quot;,0);
# Terminator
print FIL &quot;;&quot;;

close(FIL);
Posted in Programming | Tagged , | Leave a comment

Obfuscated C

Originally published on: Tue, 21 Apr 2009 23:51:27 +0000

I had written a little C program a while back for the 19th annual International Obfuscated C Coding contest.

Not only did my code not win … it didn’t even warrant an entry in the honorable mentions or anything like that. If you look at the winners and look back at my code, you’ll immediately see why; the winners and the runners-up were much more creative than my effort.

Rather than get lost in obscurity, I felt that my entry needed to be published, so it has been given the honor of appearing in my first public blog post.

Everyone, please meet lawless.c … a ROT-13 encoder/decoder that encodes/decodes one line at a time:

// Copyright (c) 2009 by Jim Lawless
#include <stdio.h>
#include <ctype.h>

char *z="DCFEBA";
int zzz;
void zzzzzzzzz(void) { zzz=zzz; }
typedef void (*ZZ)(void);
#define I
void zzzzzzz(void) { z-=6; }
#define r(x) isalpha(x) ? tolower(x)>'m' ? x-'\r' : x+'\r' : x
void zzzzzz(void) { if(!(zzz-10)) { z++; z++; } }
#define o(x) Z[*z-'A']();
#define t(x)
void zzzz(void) { zzz=fgetc(stdin); }
#define a(x) for(;*z;z++)
void zzzzz(void) { zzz=r(zzz); }
#define s(x)
void zzzzzzzz(void) { fputc(zzz,stdout); }

ZZ Z[12]={ zzzzzzz, zzzzzzzz, zzzz, zzzzzzzzz, zzzzzz, zzzzz };

int main() {

I s(lit) t(he) s(heet) t(he) s(heet) I s(lit) a(nd)
o(n) t(he) s(litted) s(heet) I s(it)
}

The rules for the 19th annual competition had noted that C preprocessor tricks might just as well not be used as each entry would be run through the preprocessor for expansion.

Here’s what the above code would look like after preprocessing;

char *z="DCFEBA";
int zzz;
void zzzzzzzzz(void) { zzz=zzz; }
typedef void (*ZZ)(void);

void zzzzzzz(void) { z-=6; }

void zzzzzz(void) { if(!(zzz-10)) { z++; z++; } }

void zzzz(void) { zzz=fgetc((&amp;_iob[0])); }

void zzzzz(void) { zzz=(__mb_cur_max &gt; 1 ? _isctype(zzz,(0x0100|0x1|0x2)) : _pctype[zzz] &amp;amp; (0x0100|0x1|0x2)) ? tolower(zzz)&gt;'m' ? zzz-'\r' : zzz+'\r' : zzz; }

void zzzzzzzz(void) { fputc(zzz,(&amp;_iob[1])); }

ZZ Z[12]={ zzzzzzz, zzzzzzzz, zzzz, zzzzzzzzz, zzzzzz, zzzzz };

int main() {

for(;*z;z++)
Z[*z-'A']();
}

I tried to use preprocessor abuse to get my cutesy “I slit the sheet…” lines into view … but the core of the processing was done via indirect invocation of entries in an array of function-pointers.

 

Posted in Computers, Programming | Tagged , | Leave a comment

Back to BASIC

I saw this nice post about learning to write programs on a TRS-80 computer.

http://baugues.com/trs-80/

I noted a number of comments on an aggregator site each suggesting using modern programming languages with interactive environments as an analogue to those days. While I agree that the interactive nature of BASIC made it approachable by the novice, I believe that the simplicity of the environment itself ( a self-contained, line-number-based editor ) and the spartan nature of the BASIC implementations of the 70’s and 80’s were also factors that allowed people to learn to code.

It’s fortunate that we have some BASIC implementations around that can still use the familiar 8-bit BASIC syntax. One of these is called Chipmunk BASIC. The author is programmer Ron Nicholson who worked for Apple and Amiga (among other prominent tech companies. ) Ron is currently an iOS developer.

One can download Chipmunk BASIC for Windows or for OS/X. For this post, I’ll be using the Windows version. I have been meaning to check out the newest OS/X version, but I just haven’t gotten around to it. Here’s the link to the Chipmunk BASIC area on Ron’s web site:

http://www.nicholson.com/rhn/basic/

You’ll need to download the Windows version ( the one that states that it is for Windows 2000/XP). Unzip the files to a folder. Find that folder and click on the chipmunkbasic executable file ( the one with the Chipmunk icon ).

cb_0

You should see a prompt like this:

cb_1

Let’s type in our first program. We’ll print the numbers 1 through 10 using a “for-next loop.” Let’s start by typing in the following line:

10 for x = 1 to 10

Press ENTER at the end of the line.

cb_2

Let’s now continue entering the rest of the program.

20 print x
30 next x

cb_3

Now, let’s execute the program by typing in the word “run” followed by the ENTER key:

cb_4

Let’s clear the screen by typing in the following:

cls

cb_5

cb_6

Now, let’s look at the program we’ve entered by typing in “list” and ENTER:

cb_7

The “new” command erases the program currently in memory. If we enter “new” and then enter “list”, you’ll see that no program listing is displayed. We erased it with the “new” command.

cb_8

Let’s clear the screen with “cls”. Let’s type in “new” again ( in case you’ve tinkered a bit since the last “new” ) and let’s enter another simple program. This one will ask you for your first name, store your response in the string variable n$, and will then use n$ to greet you by the name you entered.

new
10 print "What's your first name";
20 input n$
30 print "Hello there, " ; n$ ; "!"

Let’s run the above code:

cb_9

If we want to save this program for later use, we can use the “save” command.

save "greeting.bas"

This saves your BASIC program as a plain text file in the folder where you had installed Chipmunk BASIC. I’m afraid that Chipmunk BASIC doesn’t have a direct command for seeing the contents of the directory, but you can issue the Windows command-prompt’s “dir” command by using the “sys()” function:

sys("dir")

cb_10

Let’s erase the current program with a “new” followed by a “list” to make sure it’s gone:

cb_11

Now, let’s re-load “greeting.bas”:

cb_12

To exit Chipmunk BASIC, simply type “exit” and ENTER.

You’ll want to read through the accompanying manual BASIC_MANUAL.TXT which walks through Chipmunk BASIC’s commands, operators, and functions ( including features for opening the graphics screen and plotting points, lines, …etc. )

I think that the approach that classical BASIC takes is very friendly to the newcomer. I hope you have fun with this nice implementation of BASIC.

Posted in Programming | Tagged , | Leave a comment