Merge pull request #37 from maginatics/exit-codes

Return specific error codes where possible
diff --git a/assembly/src/main/filtered-resources/unix/bin/shell b/assembly/src/main/filtered-resources/unix/bin/shell
index db651d8..64f0ed7 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.