Tools/DiskTool - Added script file support
[tpg/acess2.git] / Tools / DiskTool / main.c
1 /*
2  */
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <errno.h>
6 #include <stdint.h>
7 #include <string.h>
8 #include <ctype.h>
9 #include <assert.h>
10 #include <disktool_common.h>
11
12 #define ACESS_VERSION   "0.15-pr"
13 #define VERSION_STR     "Acess2 DiskTool v"ACESS_VERSION
14
15  int    main(int argc, const char *argv[]);
16 void    PrintUsage(void);
17  int    RunCommand(int argc, const char *argv[]);
18 void    RunScript(const char *Filename);
19
20 // === CODE ===
21 int main(int argc, const char *argv[])
22 {
23         // Parse arguments
24         for( int i = 1; i < argc; i ++ )
25         {
26                 const char *arg = argv[i];
27                 if( arg[0] != '-' )
28                 {
29                         int rv = RunCommand(argc-i, argv+i);
30                         if( rv == 0 ) {
31                                 PrintUsage();
32                                 return 1;
33                         }
34                         else if( rv < 0 ) {
35                                 return 0;
36                         }
37                         else {
38                         }
39                         i += rv;
40                 }
41                 else if( arg[1] != '-' )
42                 {
43                         switch( *++arg )
44                         {
45                         case 's':
46                                 if( i+1 >= argc ) {
47                                         fprintf(stderr, "Option '-s' requires an argument\n");
48                                         return 1;
49                                 }
50                                 RunScript( argv[++i] );
51                                 break;
52                         default:
53                                 fprintf(stderr, "Unkown option '-%c', try --help\n", *arg);
54                                 return 1;
55                         }
56                 }
57                 else
58                 {
59                         if( strcmp(arg, "--help") == 0 ) {
60                                 PrintUsage();
61                                 return 0;
62                         }
63                         else if( strcmp(arg, "--version") == 0 ) {
64                                 fprintf(stderr, VERSION_STR);
65                                 return 0;
66                         }
67                         else {
68                                 fprintf(stderr, "Unknown option '%s', try --help\n", arg);
69                                 return 1;
70                         }
71                 }
72         }
73         
74         DiskTool_Cleanup();
75         
76         return 0;
77 }
78
79 void PrintUsage(void)
80 {
81         fprintf(stderr,
82                 "Usage:\n"
83                 " disktool <commands...>\n"
84                 "\n"
85                 "Commands:\n"
86                 " lvm <image> <ident>\n"
87                 " - Register an image with LVM\n"
88                 "  e.g.\n"
89                 "   `lvm ../AcessHDD.img HDD`\n"
90                 " mount <image> <mountname>\n"
91                 " - Bind an image to a name.\n"
92                 "  e.g.\n"
93                 "   `mount ../AcessFDD.img FDD`\n"
94                 "   `mount :HDD/0 hda1`\n"
95                 " ls <dir>\n"
96                 " - List a directory\n"
97                 "  e.g.\n"
98                 "   `ls ../`\n"
99                 "   `ls FDD:/`\n"
100                 "\n"
101                 );
102 }
103
104 int RunCommand(int argc, const char *argv[])
105 {
106         if( argc < 1 )  return 0;
107         
108         const char *name = argv[0];
109         if( strcmp("mount", name) == 0 )
110         {
111                 // Mount an image
112                 if( argc < 3 ) {
113                         fprintf(stderr, "mount takes 2 arguments (image and mountpoint)\n");
114                         return 0;
115                 }
116
117                 if( DiskTool_MountImage(argv[2], argv[1]) ) {
118                         fprintf(stderr, "Unable to mount '%s' as '%s'\n", argv[1], argv[2]);
119                         return -1;
120                 }
121
122                 return 2;
123         }
124         else if( strcmp("lvm", name) == 0 )
125         {
126                 // Bind a "file" to LVM
127                 if( argc < 3 ) {
128                         fprintf(stderr, "lvm takes 2 arguments (iamge and ident)\n");
129                         return 0;
130                 }
131
132                 if( DiskTool_RegisterLVM(argv[2], argv[1]) ) {
133                         fprintf(stderr, "Unable to register '%s' as LVM '%s'\n", argv[1], argv[2]);
134                         return -1;
135                 }
136                 
137                 return 2;
138         }
139         else if( strcmp("ls", name) == 0 )
140         {
141                 if( argc < 2 ) {
142                         fprintf(stderr, "ls takes 1 argument (path)\n");
143                         return 0;
144                 }
145
146                 DiskTool_ListDirectory(argv[1]);
147                 return 1;
148         }
149         else if( strcmp("cp", name) == 0 )
150         {
151                 
152                 if( argc < 3 ) {
153                         fprintf(stderr, "cp takes 2 arguments (source and destination)\n");
154                         return 0;
155                 }
156
157                 DiskTool_Copy(argv[1], argv[2]);
158
159                 return 2;
160         }
161         else if( strcmp("cat", name) == 0 ) {
162
163                 if( argc < 2 ) {
164                         fprintf(stderr, "cat takes 1 argument (path)\n");
165                         return 0;
166                 }
167
168                 DiskTool_Cat(argv[1]);
169
170                 return 1;
171         }
172         else {
173                 fprintf(stderr, "Unknown command '%s'\n", name);
174                 return 0;
175         }
176 }
177
178 int tokenise(const char **ptrs, int max_ptrs, char *buffer)
179 {
180          int    idx = 0;
181         while( *buffer )
182         {
183                 // Eat leading whitespace
184                 while( *buffer && isspace(*buffer) )
185                         buffer ++;
186                 if( *buffer == '"' ) {
187                         // Double-quoted string
188                         buffer ++;
189                         ptrs[idx++] = buffer;
190                         while( *buffer && *buffer != '"' )
191                         {
192                                 if( *buffer == '\\' && buffer[1] == '"' ) {
193                                         char *tmp = buffer;
194                                         while( tmp[1] ) {
195                                                 tmp[0] = tmp[1];
196                                                 tmp ++;
197                                         }
198                                 }
199                                 buffer ++;
200                         }
201                         if( *buffer )
202                                 *buffer++ = '\0';
203                 }
204                 else {
205                         // whitespace delimited string
206                         ptrs[idx++] = buffer;
207                         while( *buffer && !isspace(*buffer) )
208                                 buffer ++;
209                         if( *buffer )
210                                 *buffer++ = '\0';
211                 }
212         }
213         return idx;
214 }
215
216 void RunScript(const char *Filename)
217 {
218         FILE    *fp = fopen(Filename, "r");
219         if( !fp ) {
220                 fprintf(stderr, "Unable to open script '%s': %s\n", Filename, strerror(errno));
221                 exit(1);
222         }
223
224          int     line = 0;      
225         char    buf[128];
226         while( NULL != fgets(buf, sizeof(buf), fp) )
227         {
228                 line ++;
229                 const int max_tokens = 4;
230                 const char *tokens[max_tokens];
231                 int ntok = tokenise(tokens, max_tokens, buf);
232                 
233                 if( ntok > max_tokens ) {
234                         // ... 
235                         break ;
236                 }
237                 
238                 int rv = RunCommand(ntok, tokens);
239                 assert(rv + 1 <= ntok);
240                 if( rv == 0 ) {
241                         // Oops, bad command
242                         break;
243                 }
244                 else if( rv == -1 ) {
245                         // Internal error
246                         break;
247                 }
248                 else if( rv + 1 != ntok ) {
249                         // Too many arguments
250                         break;
251                 }
252         }
253         
254         fclose(fp);
255 }
256
257 // NOTE: This is in a native compiled file because it needs access to the real errno macro
258 int *Threads_GetErrno(void)
259 {
260         return &errno;
261 }
262
263 size_t _fwrite_stdout(size_t bytes, const void *data)
264 {
265         return fwrite(data, bytes, 1, stdout);
266 }

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