Started on the zebra shell - api-level debugging tool
[idzebra-moved-to-github.git] / index / zebrash.c
1 /* zebrash.c - command-line interface to zebra API 
2  *  $ID$
3  *
4  * Copyrigth 2003 Index Data Aps
5  *
6  */
7  
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12
13 #if HAVE_READLINE_READLINE_H
14 #include <readline/readline.h> 
15 #endif
16 #if HAVE_READLINE_HISTORY_H
17 #include <readline/history.h>
18 #endif
19
20 #include "zebraapi.h"
21
22 #define MAX_NO_ARGS 32
23 #define MAX_OUT_BUFF 4096
24 #define MAX_ARG_LEN 1024
25 #define PROMPT "ZebraSh>"
26 #define DEFAULTCONFIG "./zebra.cfg"
27
28 /**************************************
29  * Global variables (yuck!)
30  */
31
32 ZebraService zs=0;  /* our global handle to zebra */
33 ZebraHandle  zh=0;  /* the current session */
34                   /* time being, only one session works */
35
36 /**************************************
37  * Help functions
38  */
39
40  
41 static int split_args( char *line, char** argv )
42 { /* splits line into individual null-terminated strings, 
43    * returns pointers to them in argv */
44   char *p=line;
45   int i=0;
46   argv[0]=0; /* by default */
47   while (*p==' ' || *p=='\t' || *p=='\n')
48     p++;
49   while (*p)
50   {
51     while (*p==' ' || *p=='\t' || *p=='\n')
52       p++;
53     argv[i++]=p;
54     argv[i]=0;
55     while (*p && *p!=' ' && *p!='\t' && *p!='\n')
56       p++;
57     *p++='\0';
58   }
59   return i;
60 }
61
62  
63  /**************************************
64  * Individual commands
65  */
66
67  int cmd_echo( char *args[], char *outbuff)
68  {
69    strcpy(outbuff, args[0]);
70    return 0;
71  }
72  
73  int cmd_quit( char *args[], char *outbuff)
74  {
75    strcpy(outbuff, "bye");
76    return -99; /* special stop signal */
77  }
78  
79  int cmd_help( char *args[], char *outbuff); 
80  
81  int cmd_zebra_start( char *args[], char *outbuff)
82  {
83    char *conf=args[1];
84    if (!conf || !*conf) {
85      strcat(outbuff,"no config file specified, using "
86                      DEFAULTCONFIG "\n" );
87      conf=DEFAULTCONFIG;
88    }
89    zs=zebra_start(conf);
90    if (!zs) {
91      strcpy(outbuff, "zebra_open failed" );
92      return 2;
93    }
94    return 0; /* ok */
95  }
96  
97  int cmd_zebra_stop( char *args[], char *outbuff)
98  {
99    if (!zs)
100      strcat(outbuff,"zebra seems not to have been started, "
101                     "stopping anyway");
102    zebra_stop(zs);
103    zs=0;
104    return 0; /* ok */
105  }
106
107 int cmd_zebra_open( char *args[], char *outbuff)
108 {
109   if (!zs)
110     strcat(outbuff,"zebra seems not to have been started, "
111                    "trying anyway");
112   zh=zebra_open(zs);
113   return 0; /* ok */
114 }
115
116 int cmd_zebra_close( char *args[], char *outbuff)
117 {
118   if (!zh)
119     strcat(outbuff,"Seems like you have not called zebra_open,"
120                    "trying anyway");
121   zebra_close(zh);
122   return 0; /* ok */
123 }
124  
125  
126 /**************************************
127  * Command table, parser, and help 
128  */
129
130  struct cmdstruct
131  {
132    char * cmd;
133    char * args;
134    char * explanation;
135    int (*testfunc)(char *args[], char *outbuff);
136  } ;
137
138  struct cmdstruct cmds[] = {
139    { "zebra_start", "[configfile]", 
140         "starts the zebra service", cmd_zebra_start },
141    { "zebra_stop", "", 
142         "stops the zebra service", cmd_zebra_stop },
143    { "zebra_open", "", 
144         "starts a zebra session", cmd_zebra_open },
145    { "zebra_close", "", 
146         "closes a zebra session", cmd_zebra_close },
147    { "echo", "string", "ouputs the string", cmd_echo },
148    { "quit", "", "exits the program", cmd_quit },
149    { "help", "", 0, cmd_help },
150    
151    {0,0,0,0} /* end marker */
152  };
153  
154  int onecommand( char *line, char *outbuff)
155  {
156    int i;
157    char *argv[MAX_NO_ARGS];
158    int n;
159    char argbuf[MAX_ARG_LEN];
160    strncpy(argbuf,line, MAX_ARG_LEN-1);
161    argbuf[MAX_ARG_LEN-1]='\0'; /* just to be sure */
162    n=split_args(argbuf, argv);
163    if (0==n)
164      return 0; /* no command on line, too bad */
165    for (i=0;cmds[i].cmd;i++)
166      if (0==strcmp(cmds[i].cmd, argv[0])) 
167      {
168        if (n>1)
169          argv[0]= line + (argv[1]-argbuf); /* rest of the line */
170        else
171          argv[0]=""; 
172        return ((cmds[i].testfunc)(argv,outbuff));
173      }
174    sprintf (outbuff, "Unknown command '%s'. Try help",argv[0] );
175    return -1; 
176  }
177  
178  int cmd_help( char *args[], char *outbuff)
179  { 
180    int i;
181    char tmp[MAX_ARG_LEN];
182    for (i=0;cmds[i].cmd;i++)
183      if (cmds[i].explanation)
184      {
185        sprintf(tmp, "%s %s %s\n",
186          cmds[i].cmd, cmds[i].args, cmds[i].explanation);
187        strcat(outbuff,tmp);
188      }
189     return 0;
190  }
191  
192  
193 /************************************** 
194  * The shell
195  */
196  
197 void shell()
198 {
199   int rc=0;
200   while (rc!=-99)
201   {
202     char buf[MAX_ARG_LEN];
203     char outbuff[MAX_OUT_BUFF];
204 #if HAVE_READLINE_READLINE_H
205     char* line_in;
206           line_in=readline(PROMPT);
207           if (!line_in)
208             break;
209 #if HAVE_READLINE_HISTORY_H
210           if (*line_in)
211             add_history(line_in);
212 #endif
213           if(strlen(line_in) > MAX_ARG_LEN-1) {
214             fprintf(stderr,"Input line too long\n");
215             break;
216           };
217           strcpy(buf,line_in);
218           free (line_in);
219 #else    
220           printf (PROMPT); 
221           fflush (stdout);
222           if (!fgets (buf, MAX_ARG_LEN-1, stdin))
223             break;
224 #endif 
225     outbuff[0]='\0';
226     rc=onecommand(buf, outbuff);
227         printf("%s\n", outbuff);
228   }
229
230  }
231  
232  
233 /**************************************
234  * Main 
235  */
236  
237 int main (int argc, char ** argv)
238 {
239   shell();
240   return 0;
241 } /* main */