Return specific error codes where possible

We use Unix errno values where it makes sense.  Print the stack trace
and return 255 when we have an internal error.  We will need to return
more specific errors from jclouds and jclouds-karaf for this commit to
work well.  References #36.
diff --git a/assembly/src/main/filtered-resources/unix/bin/shell b/assembly/src/main/filtered-resources/unix/bin/shell
index 7790695..cc5b4a4 100644
--- a/assembly/src/main/filtered-resources/unix/bin/shell
+++ b/assembly/src/main/filtered-resources/unix/bin/shell
@@ -262,6 +262,8 @@
 
     # Setup classpath
     CLASSPATH="$KARAF_HOME/system/org/jclouds/cli/runner/${project.version}/runner-${project.version}.jar"
+    CLASSPATH="$CLASSPATH:$KARAF_HOME/system/org/jclouds/jclouds-core/${project.version}/jclouds-core-${project.version}.jar"
+    CLASSPATH="$CLASSPATH:$KARAF_HOME/system/org/jclouds/jclouds-blobstore/${project.version}/jclouds-blobstore-${project.version}.jar"
     CLASSPATH="$CLASSPATH:$KARAF_HOME/system/org/apache/karaf/shell/org.apache.karaf.shell.console/${karaf.version}/org.apache.karaf.shell.console-${karaf.version}.jar"
     #We set external libraries for logging.
     CLASSPATH="$CLASSPATH:$KARAF_HOME/lib/other/slf4j-api-${slf4j.version}.jar:$KARAF_HOME/lib/other/slf4j-log4j12-${slf4j.version}.jar:$KARAF_HOME/lib/other/log4j-${log4j.version}.jar"
diff --git a/runner/pom.xml b/runner/pom.xml
index abc2834..2b97511 100644
--- a/runner/pom.xml
+++ b/runner/pom.xml
@@ -34,6 +34,18 @@
             <artifactId>org.apache.karaf.shell.console</artifactId>
             <version>${karaf.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.jclouds</groupId>
+            <artifactId>jclouds-blobstore</artifactId>
+            <version>${jclouds.karaf.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jclouds</groupId>
+            <artifactId>jclouds-core</artifactId>
+            <version>${jclouds.karaf.version}</version>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/runner/src/main/java/org/jclouds/cli/runner/Main.java b/runner/src/main/java/org/jclouds/cli/runner/Main.java
index f8a1497..af56716 100644
--- a/runner/src/main/java/org/jclouds/cli/runner/Main.java
+++ b/runner/src/main/java/org/jclouds/cli/runner/Main.java
@@ -18,6 +18,7 @@
 
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -47,6 +48,8 @@
 import org.apache.karaf.shell.console.jline.TerminalFactory;
 import org.fusesource.jansi.Ansi;
 import org.fusesource.jansi.AnsiConsole;
+import org.jclouds.blobstore.ContainerNotFoundException;
+import org.jclouds.rest.AuthorizationException;
 
 /**
  * This is forked from Apache Karaf and aligned to the needs of jclouds cli.
@@ -58,9 +61,56 @@
     private String application = System.getProperty("karaf.name", "root");
     private String user = "karaf";
 
+    private static enum Errno {
+        ENOENT(2),
+        EIO(5),
+        EACCES(13),
+        UNKNOWN(255);
+
+        private final int errno;
+
+        Errno(int errno) {
+            this.errno = errno;
+        }
+
+        int getErrno() {
+            return errno;
+        }
+    }
+
     public static void main(String args[]) throws Exception {
         Main main = new Main();
-        main.run(args);
+        try {
+            main.run(args);
+        } catch (CommandNotFoundException cnfe) {
+            String str = Ansi.ansi()
+                    .fg(Ansi.Color.RED)
+                    .a("Command not found: ")
+                    .a(Ansi.Attribute.INTENSITY_BOLD)
+                    .a(cnfe.getCommand())
+                    .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
+                    .fg(Ansi.Color.DEFAULT).toString();
+            System.err.println(str);
+            System.exit(Errno.UNKNOWN.getErrno());
+        } catch (CommandException ce) {
+            System.err.println(ce.getNiceHelp());
+            System.exit(Errno.UNKNOWN.getErrno());
+        } catch (AuthorizationException ae) {
+            System.err.println("Authorization error: " + ae.getMessage());
+            System.exit(Errno.EACCES.getErrno());
+        } catch (ContainerNotFoundException cnfe) {
+            System.err.println("Container not found: " + cnfe.getMessage());
+            System.exit(Errno.ENOENT.getErrno());
+        } catch (FileNotFoundException fnfe) {
+            System.err.println("File not found: " + fnfe.getMessage());
+            System.exit(Errno.ENOENT.getErrno());
+        } catch (IOException ioe) {
+            System.err.println("IO error: " + ioe.getMessage());
+            System.exit(Errno.EIO.getErrno());
+        } catch (Throwable t) {
+            t.printStackTrace();
+            System.exit(Errno.UNKNOWN.getErrno());
+        }
     }
 
     /**
@@ -85,12 +135,7 @@
         InputStream in = unwrap(System.in);
         PrintStream out = wrap(unwrap(System.out));
         PrintStream err = wrap(unwrap(System.err));
-        try {
-            run(commandProcessor, args, in, out, err);
-        } catch (Throwable t) {
-            System.exit(1);
-        }
-        System.exit(0);
+        run(commandProcessor, args, in, out, err);
     }
 
 
@@ -128,7 +173,7 @@
 
     }
 
-    private void run(final CommandProcessorImpl commandProcessor, String[] args, final InputStream in, final PrintStream out, final PrintStream err) throws Throwable {
+    private void run(final CommandProcessorImpl commandProcessor, String[] args, final InputStream in, final PrintStream out, final PrintStream err) throws Exception {
 
         if (args.length > 0) {
             StringBuilder sb = new StringBuilder();
@@ -145,28 +190,7 @@
             session.put("USER", user);
             session.put("APPLICATION", application);
             session.put(NameScoping.MULTI_SCOPE_MODE_KEY, Boolean.toString(isMultiScopeMode()));
-
-            try {
-                session.execute(sb);
-            } catch (Throwable t) {
-                if (t instanceof CommandNotFoundException) {
-                    String str = Ansi.ansi()
-                            .fg(Ansi.Color.RED)
-                            .a("Command not found: ")
-                            .a(Ansi.Attribute.INTENSITY_BOLD)
-                            .a(((CommandNotFoundException) t).getCommand())
-                            .a(Ansi.Attribute.INTENSITY_BOLD_OFF)
-                            .fg(Ansi.Color.DEFAULT).toString();
-                    err.println(str);
-                } else if (t instanceof CommandException) {
-                    err.println(((CommandException) t).getNiceHelp());
-                } else {
-                    err.print(Ansi.ansi().fg(Ansi.Color.RED).toString());
-                    t.printStackTrace(err);
-                    err.print(Ansi.ansi().fg(Ansi.Color.DEFAULT).toString());
-                }
-                throw t;
-            }
+            session.execute(sb);
         } else {
             // We are going into full blown interactive shell mode.