Tools/DiskTool - Added script file support
[tpg/acess2.git] / Tools / DiskTool / main.c
index f8781a4..3dd2aa0 100644 (file)
@@ -5,9 +5,77 @@
 #include <errno.h>
 #include <stdint.h>
 #include <string.h>
+#include <ctype.h>
+#include <assert.h>
 #include <disktool_common.h>
 
+#define ACESS_VERSION  "0.15-pr"
+#define VERSION_STR    "Acess2 DiskTool v"ACESS_VERSION
+
+ int   main(int argc, const char *argv[]);
+void   PrintUsage(void);
+ int   RunCommand(int argc, const char *argv[]);
+void   RunScript(const char *Filename);
+
 // === CODE ===
+int main(int argc, const char *argv[])
+{
+       // Parse arguments
+       for( int i = 1; i < argc; i ++ )
+       {
+               const char *arg = argv[i];
+               if( arg[0] != '-' )
+               {
+                       int rv = RunCommand(argc-i, argv+i);
+                       if( rv == 0 ) {
+                               PrintUsage();
+                               return 1;
+                       }
+                       else if( rv < 0 ) {
+                               return 0;
+                       }
+                       else {
+                       }
+                       i += rv;
+               }
+               else if( arg[1] != '-' )
+               {
+                       switch( *++arg )
+                       {
+                       case 's':
+                               if( i+1 >= argc ) {
+                                       fprintf(stderr, "Option '-s' requires an argument\n");
+                                       return 1;
+                               }
+                               RunScript( argv[++i] );
+                               break;
+                       default:
+                               fprintf(stderr, "Unkown option '-%c', try --help\n", *arg);
+                               return 1;
+                       }
+               }
+               else
+               {
+                       if( strcmp(arg, "--help") == 0 ) {
+                               PrintUsage();
+                               return 0;
+                       }
+                       else if( strcmp(arg, "--version") == 0 ) {
+                               fprintf(stderr, VERSION_STR);
+                               return 0;
+                       }
+                       else {
+                               fprintf(stderr, "Unknown option '%s', try --help\n", arg);
+                               return 1;
+                       }
+               }
+       }
+       
+       DiskTool_Cleanup();
+       
+       return 0;
+}
+
 void PrintUsage(void)
 {
        fprintf(stderr,
@@ -33,92 +101,157 @@ void PrintUsage(void)
                );
 }
 
-int main(int argc, char *argv[])
+int RunCommand(int argc, const char *argv[])
 {
-       // Parse arguments
-       for( int i = 1; i < argc; i ++ )
+       if( argc < 1 )  return 0;
+       
+       const char *name = argv[0];
+       if( strcmp("mount", name) == 0 )
        {
-               if( strcmp("mount", argv[i]) == 0 || strcmp("-i", argv[i]) == 0 ) {
-                       // Mount an image
-                       if( argc - i < 3 ) {
-                               fprintf(stderr, "mount takes 2 arguments (image and mountpoint)\n");
-                               PrintUsage();
-                               exit(-1);
-                       }
+               // Mount an image
+               if( argc < 3 ) {
+                       fprintf(stderr, "mount takes 2 arguments (image and mountpoint)\n");
+                       return 0;
+               }
 
-                       if( DiskTool_MountImage(argv[i+2], argv[i+1]) ) {
-                               fprintf(stderr, "Unable to mount '%s' as '%s'\n", argv[i+1], argv[i+2]);
-                               break;
-                       }
+               if( DiskTool_MountImage(argv[2], argv[1]) ) {
+                       fprintf(stderr, "Unable to mount '%s' as '%s'\n", argv[1], argv[2]);
+                       return -1;
+               }
 
-                       i += 2;
-                       continue ;
+               return 2;
+       }
+       else if( strcmp("lvm", name) == 0 )
+       {
+               // Bind a "file" to LVM
+               if( argc < 3 ) {
+                       fprintf(stderr, "lvm takes 2 arguments (iamge and ident)\n");
+                       return 0;
                }
-               
-               if( strcmp("mountlvm", argv[i]) == 0 || strcmp("lvm", argv[i]) == 0 ) {
-                       
-                       if( argc - i < 3 ) {
-                               fprintf(stderr, "lvm takes 2 arguments (iamge and ident)\n");
-                               PrintUsage();
-                               exit(-1);
-                       }
 
-                       if( DiskTool_RegisterLVM(argv[i+2], argv[i+1]) ) {
-                               fprintf(stderr, "Unable to register '%s' as LVM '%s'\n", argv[i+1], argv[i+2]);
-                               break;
-                       }
-                       
-                       i += 2;
-                       continue ;
+               if( DiskTool_RegisterLVM(argv[2], argv[1]) ) {
+                       fprintf(stderr, "Unable to register '%s' as LVM '%s'\n", argv[1], argv[2]);
+                       return -1;
                }
                
-               if( strcmp("ls", argv[i]) == 0 ) {
-                       if( argc - i < 2 ) {
-                               fprintf(stderr, "ls takes 1 argument (path)\n");
-                               PrintUsage();
-                               break;
-                       }
-
-                       DiskTool_ListDirectory(argv[i+1]);
-                       i += 1;
-                       continue ;
+               return 2;
+       }
+       else if( strcmp("ls", name) == 0 )
+       {
+               if( argc < 2 ) {
+                       fprintf(stderr, "ls takes 1 argument (path)\n");
+                       return 0;
                }
+
+               DiskTool_ListDirectory(argv[1]);
+               return 1;
+       }
+       else if( strcmp("cp", name) == 0 )
+       {
                
-               if( strcmp("cp", argv[i]) == 0 ) {
-                       
-                       if( argc - i < 3 ) {
-                               fprintf(stderr, "cp takes 2 arguments (source and destination)\n");
-                               PrintUsage();
-                               break;
-                       }
+               if( argc < 3 ) {
+                       fprintf(stderr, "cp takes 2 arguments (source and destination)\n");
+                       return 0;
+               }
+
+               DiskTool_Copy(argv[1], argv[2]);
 
-                       DiskTool_Copy(argv[i+1], argv[i+2]);                    
+               return 2;
+       }
+       else if( strcmp("cat", name) == 0 ) {
 
-                       i += 2;
-                       continue ;
+               if( argc < 2 ) {
+                       fprintf(stderr, "cat takes 1 argument (path)\n");
+                       return 0;
                }
 
-               if( strcmp("cat", argv[i]) == 0 ) {
+               DiskTool_Cat(argv[1]);
 
-                       if( argc - 1 < 2 ) {
-                               fprintf(stderr, "cat takes 1 argument (path)\n");
-                               PrintUsage();
-                               break;
+               return 1;
+       }
+       else {
+               fprintf(stderr, "Unknown command '%s'\n", name);
+               return 0;
+       }
+}
+
+int tokenise(const char **ptrs, int max_ptrs, char *buffer)
+{
+        int    idx = 0;
+       while( *buffer )
+       {
+               // Eat leading whitespace
+               while( *buffer && isspace(*buffer) )
+                       buffer ++;
+               if( *buffer == '"' ) {
+                       // Double-quoted string
+                       buffer ++;
+                       ptrs[idx++] = buffer;
+                       while( *buffer && *buffer != '"' )
+                       {
+                               if( *buffer == '\\' && buffer[1] == '"' ) {
+                                       char *tmp = buffer;
+                                       while( tmp[1] ) {
+                                               tmp[0] = tmp[1];
+                                               tmp ++;
+                                       }
+                               }
+                               buffer ++;
                        }
+                       if( *buffer )
+                               *buffer++ = '\0';
+               }
+               else {
+                       // whitespace delimited string
+                       ptrs[idx++] = buffer;
+                       while( *buffer && !isspace(*buffer) )
+                               buffer ++;
+                       if( *buffer )
+                               *buffer++ = '\0';
+               }
+       }
+       return idx;
+}
 
-                       DiskTool_Cat(argv[i+1]);
+void RunScript(const char *Filename)
+{
+       FILE    *fp = fopen(Filename, "r");
+       if( !fp ) {
+               fprintf(stderr, "Unable to open script '%s': %s\n", Filename, strerror(errno));
+               exit(1);
+       }
 
-                       i += 1;
-                       continue;
+        int     line = 0;      
+       char    buf[128];
+       while( NULL != fgets(buf, sizeof(buf), fp) )
+       {
+               line ++;
+               const int max_tokens = 4;
+               const char *tokens[max_tokens];
+               int ntok = tokenise(tokens, max_tokens, buf);
+               
+               if( ntok > max_tokens ) {
+                       // ... 
+                       break ;
+               }
+               
+               int rv = RunCommand(ntok, tokens);
+               assert(rv + 1 <= ntok);
+               if( rv == 0 ) {
+                       // Oops, bad command
+                       break;
+               }
+               else if( rv == -1 ) {
+                       // Internal error
+                       break;
+               }
+               else if( rv + 1 != ntok ) {
+                       // Too many arguments
+                       break;
                }
-       
-               fprintf(stderr, "Unknown command '%s'\n", argv[i]);
-               PrintUsage();
        }
        
-       DiskTool_Cleanup();
-       
-       return 0;
+       fclose(fp);
 }
 
 // NOTE: This is in a native compiled file because it needs access to the real errno macro

UCC git Repository :: git.ucc.asn.au