Whamcloud - gitweb
import older libsysio snapshot.
[fs/lustre-release.git] / libsysio / tests / test_driver.c
1 #define _BSD_SOURCE
2 #define _XOPEN_SOURCE 600
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <getopt.h>
8 #include <errno.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <sys/uio.h>
12 #include <sys/statvfs.h>
13 #include <fcntl.h>
14 #include <sys/queue.h>
15 #include <dirent.h>
16 #include <unistd.h>
17 #include <ctype.h>
18
19 #include "sysio.h"
20 #include "mount.h"
21 #include "test.h"
22 #include "test_driver.h"
23
24
25 struct queue_t;
26     
27 typedef struct cmd_tree_t {
28   char *res_name;
29   char *val;
30   int arg_count;
31   struct queue_t *children;
32 } cmd_tree;
33
34 struct queue_t {
35     char *val;
36     cmd_tree *cmd;
37     struct queue_t *next;
38 };
39
40 struct cmd_t cmd_list[] = {
41   {"alloc", get_buffer, usage_get_buffer},
42   {"chdir", test_do_chdir, usage_chdir},
43   {"checkbuf", do_checkbuf, usage_checkbuf},
44   {"chmod", test_do_chmod, usage_chmod},
45   {"chown", test_do_chown, usage_chown},
46   {"clear", test_do_clear, usage_clear},
47   {"close", test_do_close, usage_close},
48   {"cmpstr", cmp_bufs, usage_cmpbufs},
49   {"creat", test_do_creat, usage_creat},
50   {"debug", test_do_setdebug, usage_setdebug},
51   {"dup", test_do_dup, usage_dup},
52   {"dup2", test_do_dup2, usage_dup2},
53   {"endian", get_endian, usage_endian},
54   {"exit", test_do_exit, usage_exit},
55   {"fcntl", test_do_fcntl, usage_fcntl},
56   {"fdatasync", test_do_fdatasync, usage_fdatasync},
57   {"fill", test_do_fillbuff, usage_do_fillbuff},
58   {"free", free_buffer, usage_free_buffer},
59   {"fstat", test_do_fstat, usage_fstat},
60   {"fstatvfs", test_do_fstatvfs, usage_fstatvfs},
61   {"fsync", test_do_fsync, usage_fsync},
62   {"ftruncate", test_do_ftruncate, usage_ftruncate},
63   {"getcwd", test_do_getcwd, usage_getcwd},
64   {"getdirentries", test_do_getdirentries, usage_getdirentries},
65   {"init", test_do_init, usage_init},
66   {"init_iovec", test_do_init_iovec, usage_init_iovec},
67   {"init_xtvec", test_do_init_xtvec, usage_init_xtvec}, 
68   {"ioctl", test_do_ioctl, usage_ioctl},
69   {"iodone", test_do_iodone, usage_iodone},
70   {"iowait", test_do_iowait, usage_iowait},
71   {"ipread", test_do_ipread, usage_ipread},
72   {"ipreadv", test_do_ipreadv, usage_ipreadv},
73   {"ipwrite", test_do_ipwrite, usage_ipwrite},
74   {"ipwritev", test_do_ipwritev, usage_ipwritev},
75   {"iread", test_do_iread, usage_iread},
76   {"ireadv", test_do_ireadv, usage_ireadv},
77         {"ireadx", test_do_ireadx, usage_ireadx},
78   {"iwrite", test_do_iwrite, usage_iwrite},
79   {"iwritev", test_do_iwritev, usage_iwritev},
80   {"iwritex", test_do_iwritex, usage_iwritex},
81   {"list", test_do_list, usage_list},
82   {"lseek", test_do_lseek, usage_lseek},
83   {"lstat", test_do_lstat, usage_lstat},
84   {"mkdir", test_do_mkdir, usage_mkdir},
85   {"mknod", test_do_mknod, usage_mknod},
86   {"mount", test_do_mount, usage_mount},
87   {"open", test_do_open, usage_open},
88   {"printbuf", test_do_printbuf, usage_do_printbuf},
89   {"printline", test_do_printline, usage_printline},
90   {"pread", test_do_pread, usage_pread},
91   {"preadv", test_do_preadv, usage_preadv},
92   {"pwritev", test_do_pwritev, usage_pwritev},
93   {"pwrite", test_do_pwrite, usage_pwrite},
94   {"quit", test_do_exit, usage_exit},
95   {"read", test_do_read, usage_read},
96   {"readv", test_do_readv, usage_readv},
97         {"readx", test_do_readx, usage_readx},
98   {"rmdir", test_do_rmdir, usage_rmdir},
99   {"setbuf", do_setbuf, usage_setbuf},
100   {"sizeof", get_sizeof, usage_sizeof},
101   /*  {"setoutput", test_do_setoutput, usage_setoutput}, */
102   {"stat", test_do_stat, usage_stat},
103   {"statvfs", test_do_statvfs, usage_statvfs},
104   {"symlink", test_do_symlink, usage_symlink},
105   {"truncate", test_do_truncate, usage_truncate},
106   {"umask", test_do_umask, usage_umask},
107   {"umount", test_do_umount, usage_umount},
108   {"unlink", test_do_unlink, usage_unlink},
109   {"write", test_do_write, usage_write},
110   {"writev", test_do_writev, usage_writev},
111   {"writex", test_do_writex, usage_writex},
112   {NULL, NULL, NULL}
113 };
114
115 int run_cmd(cmd_tree *cmd_arg);
116 cmd_tree* build_tree(char **cmd, int *length, int total);
117 /*
118  * ##################################################
119  * # Memory functions                               #
120  * #  Intended to allow users to gain access to     #
121  * #  buffers of memory to be manipulated later     #
122  * ##################################################
123  */
124
125 void * alloc_buff32(unsigned int size, int align)
126 {
127   void* buf;
128   long buf_ptr;
129
130   /*
131   if ((err = memalign(&buf, align, size)) != 0) {
132     perror("memalign");
133     return 0;
134   }
135   */
136   size += align;
137   buf = malloc(size);
138   align--;
139   DBG(3, fprintf(outfp, "Buf is at %p\n", (void *)buf));
140   buf_ptr = (long)buf + ((long)buf & align);
141
142   DBG(3, fprintf(outfp, "Buf is at %p\n", (void *)buf_ptr));
143   return (void *)buf_ptr;
144 }
145
146 void free_buf32(void * ptr)
147 {
148   free(ptr);
149 }
150
151 long alloc_buff64(unsigned int size, int align)
152 {
153   char * buf;
154   long ret_value;
155
156   /*  
157       if (memalign((void **)&buf, align, size))
158       return 0;
159   */
160   size += align;
161   buf = malloc(size);
162   align--;
163   ret_value = (long)buf  + ((long)buf & align);
164   return ret_value;
165 }
166
167 void free_buf64(long ptr)
168 {
169   free((char *)ptr);
170 }
171
172   
173 /* 
174  * Hash function for variables. Shamelessly stolen
175  * from the ext3 code
176  */
177 unsigned int dx_hack_hash (const char *name, int len)
178 {
179   unsigned int hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
180   while (len--)
181     {
182       unsigned int hash = hash1 + (hash0 ^ (*name++ * 7152373));
183       if (hash & 0x80000000) hash -= 0x7fffffff;
184       hash1 = hash0;
185       hash0 = hash;
186     }
187   return hash0;
188 }
189
190 struct var_mapping *get_map(char *var_name)
191 {
192   int index;
193   struct var_mapping_list *curr;
194   
195
196  if (var_name[0] == '$') {
197     /* It is a name--chop off the initial and get the mapping $ */
198     var_name++;
199   }
200    
201   index = dx_hack_hash(var_name, strlen(var_name));
202   index %= MAX_VARS -1;
203
204   DBG(5, fprintf(outfp, "Got index of %d for %s\n", index, var_name));
205   curr = &map[index];
206   
207   while ((curr) && (curr->map.obj != -1) ) {
208     if ( (curr->map.name == NULL) || (strcmp(curr->map.name, var_name)) )
209       curr = curr->next;
210     else
211       return &curr->map;
212   }
213
214   return NULL;
215 }
216
217 char *get_str(char *var_name) 
218 {
219   /* See if it is a quoted string */
220   if (var_name[0] == '"') {
221     /* Chop off the beginning and end quotes and return the string */
222     int len = strlen(var_name);
223     var_name[len-1] = '\0';
224     var_name++;
225   }
226
227   return var_name;
228 }
229
230 static char* 
231 get_or_part(char **str, int* did_alloc)
232 {
233         char *tmp_str = *str;
234         int i, norm_str=0;
235
236         if (tmp_str == NULL)
237                 return NULL;
238
239         if (tmp_str[0] == '|') {
240                 tmp_str++;
241                 norm_str=1;
242         }
243
244         for (i=0; (unsigned int)i < strlen(tmp_str); i++) {
245                 if (tmp_str[i] == '|') {
246                         char *new_str = (char *)malloc(i+1);
247                         memcpy(new_str, tmp_str, i);
248                         new_str[i] = '\0';
249                         *did_alloc = 1;
250                         *str = &tmp_str[i];
251                         return new_str;
252                 }
253         }
254
255         if (norm_str) {
256                 *did_alloc = 0;
257                 *str = NULL;
258                 return tmp_str;
259         } 
260
261         return NULL;
262 }
263
264 int get_obj(char *var_name) 
265 {
266         char** str = &var_name;
267         char *str1;
268   struct var_mapping *var_map;
269   int did_alloc=0;
270         int obj=0, got_obj=0;
271
272   DBG(5, fprintf(outfp, "Getting object for %s\n", var_name));
273   
274   /* If var_name is a digit, we assume it is a literal */
275   if (isdigit(var_name[0])) 
276     return atoi(var_name); 
277  
278   /* 
279    * Check for '|', indicates that one or more values are or'd
280    * together
281    */
282         while ((str1 = get_or_part(str, &did_alloc)) != NULL) {
283
284                 if (isdigit(str1[0])) {
285                         if (str1[0] == '0') {
286                                 /* Assume octal format */
287                                 obj |= strtol(str1, NULL, 8);
288                         } else 
289                                 obj |= atoi(str1);
290                 } else {
291                         var_map = get_map(str1);
292                         if (!var_map) {
293                                 if (did_alloc)
294                                         free(str1);
295                                 return -1;
296                         }
297                         obj |= var_map->obj;
298                 }
299
300                 if (did_alloc) {
301                         did_alloc = 0;
302                         free(str1);
303                 }
304                 got_obj++;
305         }
306
307         if (got_obj)
308                 return obj;
309  
310   var_map = get_map(var_name);
311   if (!var_map)
312     return -1;
313   else
314     return var_map->obj;
315 }
316
317      
318 void store_result(char *var_name, int result)
319 {
320   int index = dx_hack_hash(var_name, strlen(var_name));
321   struct var_mapping_list *map_obj;
322   struct var_mapping_list *new_map;
323   index %= MAX_VARS -1 ;
324
325   if (map[index].map.obj >= 0) {
326
327     /* Got a collision --just chain it*/ 
328     new_map = malloc(sizeof(struct var_mapping_list));
329                      
330     map_obj = &map[index];
331     while (map_obj->next != NULL)
332       map_obj = map_obj->next;
333     
334     map_obj->next = new_map;
335   } else
336     new_map = &map[index];
337
338   new_map->map.name = malloc(strlen(var_name) + 1);
339   strcpy(new_map->map.name, var_name);
340   new_map->map.obj = result;
341   new_map->map.type = last_type;
342   new_map->next = NULL;
343   DBG(3, fprintf(outfp, "Stored %d in index %d hashed with %s\n",
344                 result, index, var_name));
345 }
346
347 void free_obj(char *obj_name)
348 {
349   int index;
350   struct var_mapping_list *prev, *curr;
351
352
353   /* See if it is a variable name */
354   if (obj_name[0] == '$') {
355     /* It is a name--chop off the initial $ */
356     obj_name++;
357   }
358   index = dx_hack_hash(obj_name, strlen(obj_name));
359   index %= MAX_VARS -1;
360
361   DBG(5, fprintf(outfp, "Got index of %d\n", index));
362   curr = &map[index];
363
364   prev = NULL;
365
366   while ((curr) && (curr->map.obj != -1) ) {
367     if (strcmp(curr->map.name, obj_name)) {
368       prev = curr;
369       curr = curr->next;
370     } else
371       break;
372   }
373
374   /* Remove the object from the chain */
375   if (prev) 
376     prev->next = curr->next;
377   
378   curr->map.obj = -1;
379   free(curr->map.name);
380   if (prev) 
381     free(curr);
382 }
383
384
385 /*
386  * Given a long string, returns the string divided into
387  * whitespace seperated words in list.  Returns the number
388  * of words
389  */
390 int parser(char *str, char** list)
391 {
392   int len, i=0, j=0, counter=-1;
393   int in_quotes = 0;
394   char *new_str;
395
396
397   len = strlen(str);
398   DBG(5, fprintf(outfp, "str is %s len is %d\n", str, len));
399   while (i < len) {
400    
401     if ((i==0) || ((str[i] == ' ') && (in_quotes == 0)) ) {
402       if (i != 0) {
403         new_str[j] = '\0';
404         DBG(5, fprintf(outfp, "Got word %s\n", list[counter]));
405         i++;
406       } 
407       while ((str[i] == ' ') && (in_quotes == 0))
408         i++;
409       counter++;
410       new_str = list[counter] = malloc(MAX_WORD);
411       j = 0;
412       
413     }
414     
415     new_str[j] = str[i];
416     if (str[i] == '"') {
417       if (in_quotes)
418         in_quotes = 0;
419       else
420         in_quotes = 1;
421     }
422     if ((str[i] == ' ') && (in_quotes==0)){
423       while (str[i+1] == ' ')
424                                 i++;
425       new_str[j] = '\0';
426     }
427     i++;
428     j++;
429
430   }
431   new_str[j] = '\0';
432   DBG(5, fprintf(outfp, "Got word %s\n", list[counter]));
433   return counter +1;
434 }
435
436
437 int execute_cmd(char *cmd, char **args, int arg_count)
438 {
439   int i = 0;
440
441   if (!strcmp(cmd, "help")) {
442     if (arg_count > 0) {
443                         while(cmd_list[i].cmd != NULL) {
444                                 if (!strcmp(cmd_list[i].cmd, args[0])) {
445                                         (cmd_list[i].usage)();
446                                         return 0;
447                                 }
448                                 i++;
449       }
450     } else {
451       do_help();
452       return 0;
453     }
454     return -1;
455   } 
456   while(cmd_list[i].cmd != NULL) {
457     if (!strcmp(cmd_list[i].cmd, cmd)) {
458       return (cmd_list[i].func)(arg_count, args);
459                 }
460     i++;
461   }
462   DBG(2, fprintf(outfp, "Command %s was invalid\n", cmd));
463   return INVALID_CMD;
464 }
465
466 int get_args(struct queue_t *child, char** list, int num_args, int argnum)
467 {
468   char *argval;
469
470   if (child->val != NULL) {
471     argval = child->val;
472   } else if (child->cmd != NULL) {
473     run_cmd(child->cmd);
474     if (child->cmd->res_name != NULL)
475       argval = child->cmd->res_name;
476     else {
477       char tmpstr[50];
478       int val = last_ret_val;
479       sprintf(tmpstr, "%x", val);
480       argval = tmpstr;
481     }
482   } else {
483     DBG(2, fprintf(outfp, "I am confused\n"));
484     return INVALID_ARGS;
485   }
486   
487   list[argnum] = malloc(strlen(argval) + 1);
488   strcpy(list[argnum], argval);
489   argnum++;
490
491   if (argnum == num_args)
492     return SUCCESS;
493   else if (child->next == NULL) {
494     DBG(2, fprintf(outfp, "Only on arg number %d out of %d, but ran out of children\n",
495                    argnum, num_args));
496     return INVALID_ARGS;
497   } else 
498     return get_args(child->next, list, num_args, argnum);
499
500   return SUCCESS;
501 }
502
503 int run_cmd(cmd_tree *cmd_arg)
504 {
505   char cmdstr[MAX_COMMAND];
506   char *cmdptr;
507   char **args;
508   int res, i;
509   struct buf_t *buf;
510   char *cmd;
511   struct queue_t *child;
512
513   if (cmd_arg == NULL)
514     return INVALID_CMD;
515
516   cmd = cmd_arg->val;
517   cmdptr = cmdstr;
518   child = cmd_arg->children;
519   if ( (!strcmp("exit", cmd)) || (!strcmp("quit", cmd)) ||
520        (!strcmp("EXIT", cmd)) || (!strcmp("QUIT", cmd)) )
521     strcpy(cmdstr, "exit");
522   else if (!strcmp("ALLOC", cmd)) 
523     strcpy(cmdstr, "alloc");
524   else if (!strcmp("FREE", cmd))
525     strcpy(cmdstr, "free");
526  else if (!strcmp("HELP", cmd))
527     strcpy(cmdstr, "help");
528   else if (!strcmp("CALL", cmd)) {
529     if (cmd_arg->arg_count < 1) {
530       DBG(2, fprintf(outfp, "Need at least one command\n"));
531       return INVALID_CMD;
532     }
533
534     cmd_arg->arg_count--;
535     if (child->val != NULL) 
536       cmdptr = child->val;
537     else {
538       DBG(2, fprintf(outfp, "Need to specify command\n"));
539       return INVALID_CMD;
540     }
541
542     DBG(3, fprintf(outfp, "Got cmd %s\n", child->val));
543     if (cmd_arg->arg_count != 0)
544       child = child->next;
545
546    
547   } else if (!strcmp("DEPOSIT", cmd))
548     strcpy(cmdstr, "fill");
549   else if (!strcmp("PRINT", cmd))
550     strcpy(cmdstr, "printbuf");
551   else {
552     if (cmd_arg->res_name != NULL) {
553       /* 
554        * If the cmd is not a valid command, just store it
555        */
556       res = get_obj(cmd_arg->children->val);
557       last_type = UINT;
558       if (res < 0) {
559                                 /* Just store it as a string */
560                                 buf = (struct buf_t *)malloc(sizeof(struct buf_t));
561                                 buf->len = strlen(cmd);
562                                 buf->buf = (char *)malloc(buf->len+1);
563                                 strcpy(buf->buf, cmd_arg->children->val);
564                                 buflist[next] = buf;
565                                 res = next;
566                                 DBG(3, fprintf(outfp, "Stored %s in index %d\n", (char *)buf->buf, next));
567                                 next++;
568                                 last_type = STR;
569       }
570       store_result(cmd_arg->res_name, res);
571       return SUCCESS;
572     } else
573       return INVALID_CMD;
574   }
575
576
577   if (cmd_arg->arg_count == 0)
578     args = NULL;
579   else {
580     args = (char **)malloc(sizeof(char *)*cmd_arg->arg_count);
581     get_args(child, args, cmd_arg->arg_count, 0);
582   } 
583
584   DBG(3, fprintf(outfp, "CMD: %s\n ARGS: ",cmdptr));
585   for (i=0; i < cmd_arg->arg_count; i++)
586     DBG(3, fprintf(outfp, "%s ", args[i]));
587   DBG(3, fprintf(outfp, "\n"));
588   res = execute_cmd(cmdptr, args, cmd_arg->arg_count);
589   if (cmd_arg->res_name != NULL)
590     store_result(cmd_arg->res_name, last_ret_val);
591
592   return res;
593
594
595
596 int is_command(char *name)
597 {
598     if ( (strcmp(name, "CALL"))  && (strcmp(name, "FILL"))  &&
599          (strcmp(name, "ALLOC")) && (strcmp(name, "PRINT")) &&
600          (strcmp(name, "FREE"))  && (strcmp(name, "exit"))  && 
601          (strcmp(name, "HELP"))  && (strcmp(name, "help"))  && 
602          (strcmp(name, "quit"))  && (strcmp(name, "EXIT"))  &&
603          (strcmp(name, "QUIT"))  && (strcmp(name, "DEPOSIT")) )
604         return 0;
605
606     return 1;
607 }
608
609 #define ARGS 1
610 int get_type(char *arg0)
611 {
612     if ((arg0[0] == '(') || (is_command(arg0)) ){
613         return 2;
614     }
615
616     return ARGS;
617 }
618                      
619         
620 int add_args(char **cmd, int length, int total, cmd_tree *tree)
621 {
622     int new_len, type;
623     struct queue_t *old, *new;
624
625     old = tree->children;
626     while ((old) && (old->next))
627         old = old->next;
628     new = (struct queue_t *)malloc(sizeof(struct queue_t));
629     if (old)
630         old->next = new;
631     else
632         tree->children = new;
633     new->next = NULL;
634
635     type = get_type(cmd[0]);
636     if (type < 0) {
637         DBG(2, fprintf(outfp, "Don't understand %s\n", cmd[0]));
638         return INVALID_CMD;
639     }
640     if (type == ARGS) {
641         new->val = (char *)malloc(strlen(cmd[0])+1);
642         strcpy(new->val, cmd[0]);
643         new->cmd = NULL;
644         total = 1;
645     } else {
646         new_len = length;
647         if (cmd[0][0] == '(') {
648             new_len--;
649         }
650
651         new->val = NULL;
652         new->cmd = build_tree(&cmd[1], &new_len, total);
653         if (new->cmd == NULL) { /* Invalid command */
654           return length; /* Pretend we used everything up */
655         }
656         total = (length - new_len);
657         DBG(4, fprintf(outfp, "Used %d bytes\n", total));
658     }
659  
660     return total;
661 }
662
663 void free_tree(cmd_tree* tree) 
664 {
665   if (!tree)
666     return;
667
668   if (tree->children) {
669    struct queue_t *child = tree->children;
670    struct queue_t *next;
671    do {
672      next = child->next;  
673      if (child->cmd) 
674        free_tree(child->cmd);
675      free(child->val);
676      free(child);
677      child = next;
678    } while (child);
679  }
680
681  if (tree->res_name)
682    free(tree->res_name);
683
684  if (tree->val)
685    free(tree->val);
686
687  free(tree);
688 }
689
690 cmd_tree* build_tree(char **cmd, int *length, int total)
691 {
692     int index = 0, used_args = 0;
693     cmd_tree *tree;
694     if ((*length < 0) || (!cmd) || (*cmd == NULL)) 
695                         return NULL;
696
697    
698     DBG(4, fprintf(outfp, "length is %d\n", *length));
699     tree = (cmd_tree *)malloc(sizeof(cmd_tree));
700     tree->res_name = NULL;
701     tree->children = NULL;
702     if (cmd[index][0] == '$') {
703                         tree->res_name = (char *)malloc(strlen(cmd[index])+1);
704                         strcpy(tree->res_name, (char*)(cmd[index]+1));
705                         index++;
706                         if (cmd[index][0] == '=')
707                                 index++;
708     } else
709       tree->res_name = NULL;
710
711     if (is_command(cmd[index]) == 0) {
712       if (tree->res_name == NULL) {
713                                 DBG(2, fprintf(outfp, "command %s is invalid \n", cmd[index]));
714         return NULL;
715       }
716     }
717
718     tree->val = (char *)malloc(strlen(cmd[index])+1);
719     strcpy(tree->val, cmd[index]);    
720     index++;
721     *length -= index;
722     tree->arg_count = 0;
723
724     if (*length == 0) {
725                         /* All done! */
726                         return tree;
727     }
728     
729     /* Got to get the arguments */
730     while (*length > 0) {
731
732                         if (cmd[index][0] == ')') {
733                                 *length = *length-1;
734                                 DBG(4, fprintf(outfp, "and now len is %d\n", *length));
735                                 return tree;
736                         }
737                         
738                         used_args = add_args(&cmd[index], *length, total, tree);
739                         tree->arg_count++;
740                         *length -= used_args;
741                         index += used_args;
742     }
743         
744     return tree;
745 }
746
747 char *line;
748 char *getline(char *prompt)
749 {
750   int i=-1;
751   int count=0;
752
753   line = malloc(MAX_LINE);
754   if ((do_prompt) && (infp == stdin)) 
755     printf(prompt);
756
757   do {
758     /* If we get an end of file, just wait */
759     if (feof(infp)) {
760       while (feof(infp) && (line[i] != '\n')) {
761                                 clearerr(infp);
762                                 count++;
763                                 fseek(infp, 0, SEEK_CUR);
764       }
765     } else {
766       i++;
767     }
768     fread(&line[i], 1, 1, infp);
769   } while(line[i] != '\n');
770
771   line[i] = '\0';
772
773   /*  fprintf(stderr, "Got word %s\n", line); */
774   DBG(5, fprintf(outfp, "Got word %s\n", line));
775   return line;
776 }
777
778 void my_perror(char *msg) 
779 {
780   char *errmsg = strerror(errno);
781   
782   DBG(2, fprintf(outfp, "%s: %s\n", msg, errmsg));
783 }
784   
785 /* Static list of flag names */
786 struct var_mapping flags_map[] = {
787   {"O_RDONLY", O_RDONLY, UINT },
788   {"O_WRONLY", O_WRONLY, UINT },
789   {"O_RDWR", O_RDWR, UINT },
790   {"O_CREAT", O_CREAT, UINT },
791   {"O_EXCL", O_EXCL, UINT },
792   {"O_NOCTTY", O_NOCTTY, UINT },
793   {"O_TRUNC", O_TRUNC, UINT },
794   {"O_APPEND", O_APPEND, UINT },
795   {"O_SYNC", O_NONBLOCK, UINT },
796   {"O_NDELAY", O_NDELAY, UINT },
797   {"O_SYNC", O_SYNC, UINT },
798   {"O_FSYNC", O_FSYNC, UINT },
799   {"O_ASYNC", O_ASYNC, UINT },
800   {"SEEK_SET", SEEK_SET, UINT },
801   {"SEEK_CUR", SEEK_CUR, UINT },
802   {"SEEK_END", SEEK_END, UINT },
803   {"S_ISUID", S_ISUID, UINT },
804   {"S_ISGID", S_ISGID, UINT },
805   {"S_ISVTX", S_ISVTX, UINT },
806   {"S_IRWXU", S_IRWXU, UINT },
807   {"S_IRUSR", S_IRUSR, UINT },
808   {"S_IREAD", S_IREAD, UINT },
809   {"S_IWUSR", S_IWUSR, UINT },
810   {"S_IWRITE", S_IWRITE, UINT },
811   {"S_IXUSR", S_IXUSR, UINT },
812   {"S_IEXEC", S_IEXEC, UINT },
813   {"S_IRWXG", S_IRWXG, UINT },
814   {"S_IRGRP", S_IRGRP, UINT },
815   {"S_IWGRP", S_IWGRP, UINT },
816   {"S_IXGRP", S_IXGRP, UINT },
817   {"S_IRWXO", S_IRWXO, UINT },
818   {"S_IROTH", S_IROTH, UINT },
819   {"S_IWOTH", S_IWOTH, UINT },
820   {"S_IXOTH", S_IXOTH, UINT },
821   {"S_IFCHR", S_IFCHR, UINT },
822   {"S_IFMT", S_IFMT, UINT },
823   {"S_IFBLK", S_IFBLK, UINT },
824   {"S_IFREG", S_IFREG, UINT },
825   {"S_IFIFO", S_IFIFO, UINT },
826   {"S_IFLNK", S_IFLNK, UINT },
827   { NULL, -1, SINT }
828 };
829  
830 void init_map()
831 {
832   int index = 0;
833
834   while (flags_map[index].obj != -1) {
835     store_result(flags_map[index].name, flags_map[index].obj);
836     index++;
837   }
838 }
839
840 int getquotedlen(char *str)
841 {
842         int i;
843         
844         if (str[0] != '"' && str[0] != '\'')
845                 return -1;
846         
847         for (i=1; str[i] != '\0' && str[i] != '"' && str[i] != '\''; i++);
848
849         return i;
850 }
851
852 int perform_op(int num1, int num2, char op) 
853 {
854         switch(op) {
855                 
856         case '+':
857                 return num1 + num2;
858                 break;
859
860         case '*':
861                 return num1 * num2;
862                 break;
863
864         case '/':
865                 return num1 / num2;
866                 break;
867
868         case '-':
869                 return num1 - num2;
870                 break;
871                 
872         case '%':
873                 return num1%num2;
874                 break;
875                 
876         default:
877                 return num1;
878         }
879         return 0;
880 }
881
882 int get_constant_val(char **str_ptr, int type)
883 {
884         struct buf_t *buf;
885         char *buf_ptr;
886         char *str = *str_ptr;
887         char ch;
888         int i, j, num1, num2, size;
889
890         printf("Getting constant val from %s\n", str);
891         switch(type) {
892         case 1:
893                 size = getquotedlen(str);
894                 buf = (struct buf_t *)malloc(sizeof(struct buf_t));
895                 buf->buf = alloc_buff32(size, 8);
896                 buf->len = size;
897                 buf_ptr = buf->buf;
898                 buflist[next] = buf;
899                 j=0;
900                 for (i=1; i < size; i++) {
901                         buf_ptr[j] = str[i];
902                         j++;
903                 }
904                 buf_ptr[j] = '\0';
905
906                 DBG(3, fprintf(outfp, "Your buffer (%p) (%p) is at index %d\n",
907                                                                          (void *)buf, buf->buf, next));
908                 next++;
909
910                 last_type = PTR;
911                 last_ret_val = next-1;
912                 return last_ret_val;
913                 break;
914
915         case 2:
916                 if (str[0] == '$') {
917                         num1 = get_obj(str);
918                 } else {        
919                         num1 = atoi(str);
920                 }
921                 str = str_ptr[1];
922                 ch = str_ptr[1][0];
923                 if ((ch == '+') || (ch == '/') || (ch == '*') || 
924                                 (ch == '-') || (ch == '%')) {
925                         if (str_ptr[2][0] == '$') 
926                                 num2 = get_obj(str_ptr[2]);
927                         else
928                                 num2 = atoi(str_ptr[2]);
929                         num1 = perform_op(num1, num2, ch);
930                 }
931
932                 last_type = UINT;
933                 last_ret_val = num1;
934
935                 break;
936
937         default:
938                 DBG(2, fprintf(outfp, "Can't understand type of %d\n", type));
939                 return INVALID_ARGS;
940         }
941
942         return last_ret_val;
943 }
944
945 int is_constant(char *str) 
946 {
947         if ((str[0] == '"') || (str[0] == '\''))
948                 return 1;
949
950         
951         if ( (str[0] == '$') || 
952                          ( ((int)str[0] > 47) && ((int)str[0] < 57) ) ) 
953                 return 2;
954
955         return 0;
956 }
957
958 int main(int argc, char *argv[])
959 {
960   int count, err, i, orig_count;
961   char *input, *name;
962   char **cmd;
963   cmd_tree *tree;
964         extern int _test_sysio_startup(void);
965
966   /*
967    * Init sysio lib.
968    */
969   err = _test_sysio_startup();
970   
971         /* Temp. hack until I do the right thing to fix this...*/
972         open("/dev/stdin",O_RDONLY); 
973         open("/dev/stdout",O_WRONLY); 
974         open("/dev/stderr",O_WRONLY);
975  
976   infp = stdin;
977   outfp = stdout;
978
979   do_prompt = 1;
980
981   errno = 0;
982   /* Get the input/output streams */
983   for (i = 1; i < argc; i++) {
984     if (!strcmp(argv[i], "--input")) {
985       i++;
986       infp = fopen(argv[i], "r");
987       if (!infp) {
988                                 fprintf(outfp, "Unable to open file %s for reading\n", argv[i]);
989                                 return -1;
990       }
991     } else if (!strcmp(argv[i], "--output")) {
992       i++;
993       outfp = fopen(argv[i], "w");
994       if (!outfp) {
995                                 fprintf(stderr, "Unable to open file %s for writing\n", argv[i]);
996                                 return -1;
997       }
998     } else if (!strcmp(argv[i], "--np")) {
999       do_prompt = 0;
1000     } else {
1001       fprintf(stderr, "%s: Invalid arg\n", argv[i]);
1002       return -1;
1003     }
1004   }
1005   /* Initilize the mapping */
1006   for (i=0; i < MAX_VARS; i++)
1007     map[i].map.obj = -1;
1008   
1009   /* Debug defaults */
1010   debug_level = 1;
1011   print_line = 0;
1012
1013
1014 #if 0
1015   /* sysio defaults */
1016   strcpy(root_driver, DEFAULT_DRIVER);
1017   strcpy(mntpath, "/");
1018   mntflgs = 0;
1019 #endif
1020
1021   my_errno = 0;
1022
1023   /* Set up line buffering */
1024   setlinebuf(outfp);
1025   setlinebuf(infp);
1026
1027   /* 
1028    * This sets up some common flags so that the string
1029    * names can be used (for instance 0_RDWR, SEEK_SET, etc
1030    */
1031   init_map();
1032   i=0;
1033   next = 0;
1034   while (1) {
1035     bzero(output, 4096);
1036
1037     input = getline("> ");
1038     cmd = malloc(MAX_COMMAND * sizeof(char *));
1039     count = orig_count = parser(input, cmd);
1040     name = NULL;
1041     if ((!count) || (count > MAX_COMMAND)){
1042       fprintf(outfp, "%s: invalid command\n", input);
1043     } else {
1044       i = 0;
1045       if (cmd[0][0] == '$') {
1046                                 /* Need to store output of command in var name */
1047                                 name = cmd[0]+1;
1048                                 DBG(4, fprintf(outfp, "name is %s\n", name));
1049                                 count--;
1050                                 /* The '=' is not necessary, but available */
1051                                 if (!strcmp(cmd[1], "=")){
1052                                         i++;
1053                                         count--;
1054                                 }
1055                                 i++;
1056                                 if ((err=is_constant(cmd[i])) != 0) {
1057                                         store_result((char *)(&cmd[0][1]), get_constant_val(&cmd[i], err));
1058                                         tree = NULL;
1059                                         err = 0;
1060                                 } else {
1061
1062                                         tree = build_tree(&cmd[i], &count, 0);
1063                                         if (tree != NULL) {
1064                                                 err = run_cmd(tree);
1065                                                 store_result((char *)(&cmd[0][1]), last_ret_val);
1066                                         }
1067                                 }
1068                         } else {
1069                                 
1070                                 tree = build_tree(cmd, &count, 0);
1071                                 if (tree != NULL)
1072                                         err = run_cmd(tree);
1073       }
1074       /* Print out return code and any string from command */
1075       fprintf(outfp, "%#04x %s\n", err, output);
1076       if (tree)
1077                                 free_tree(tree);
1078       /* fprintf(stderr, "%#04x %s\n", err, output); */
1079       for (i=0; i < count; i++)
1080                                 free(cmd[i]);
1081     }
1082     free(cmd);
1083     free(line);
1084   }
1085 }