/home/dko/projects/mobilec/trunk/src/cmd_prompt.c

Go to the documentation of this file.
00001 /*[
00002  * Copyright (c) 2007 Integration Engineering Laboratory
00003                       University of California, Davis
00004  *
00005  * Permission to use, copy, and distribute this software and its
00006  * documentation for any purpose with or without fee is hereby granted,
00007  * provided that the above copyright notice appear in all copies and
00008  * that both that copyright notice and this permission notice appear
00009  * in supporting documentation.
00010  *
00011  * Permission to modify the software is granted, but not the right to
00012  * distribute the complete modified source code.  Modifications are to
00013  * be distributed as patches to the released version.  Permission to
00014  * distribute binaries produced by compiling modified sources is granted,
00015  * provided you
00016  *   1. distribute the corresponding source modifications from the
00017  *    released version in the form of a patch file along with the binaries,
00018  *   2. add special version identification to distinguish your version
00019  *    in addition to the base release version number,
00020  *   3. provide your name and address as the primary contact for the
00021  *    support of your modified version, and
00022  *   4. retain our contact information in regard to use of the base
00023  *    software.
00024  * Permission to distribute the released version of the source code along
00025  * with corresponding source modifications in the form of a patch file is
00026  * granted with same provisions 2 through 4 for binary distributions.
00027  *
00028  * This software is provided "as is" without express or implied warranty
00029  * to the extent permitted by applicable law.
00030 ]*/
00031 
00032 /* Filename: cmd_prompt.c */
00033 
00034 #include <stdio.h>
00035 #ifndef _WIN32
00036 #include <unistd.h>
00037 #else
00038 #include <windows.h>
00039 #endif
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include "include/cmd_prompt.h"
00043 #include "include/commands.h"
00044 #include "config.h"
00045 
00046 #ifdef HAVE_LIBREADLINE
00047 #include <readline/readline.h>
00048 #include <readline/history.h>
00049 #endif
00050 
00051 cmd_prompt_p
00052 cmd_prompt_Initialize(mc_platform_p mc_platform)
00053 {
00054   cmd_prompt_p cmd_prompt;
00055   cmd_prompt = (cmd_prompt_p)malloc(sizeof(cmd_prompt_t));
00056   return cmd_prompt;
00057 }
00058 
00059 int
00060 cmd_prompt_Destroy(cmd_prompt_p cmd_prompt)
00061 {
00062   free(cmd_prompt);
00063   return MC_SUCCESS;
00064 }
00065 
00066   void
00067 cmd_prompt_Start( mc_platform_p mc_platform )
00068 {
00069   cmd_prompt_p cmd_prompt = mc_platform->cmd_prompt;
00070 #ifndef _WIN32
00071   pthread_attr_t attr;
00072   pthread_attr_init(&attr);
00073   if(mc_platform->stack_size[MC_THREAD_CP] != -1) {
00074     pthread_attr_setstacksize
00075       (
00076        &attr,
00077        mc_platform->stack_size[MC_THREAD_CP]
00078       );
00079   }
00080 #else
00081   int stack_size;
00082   if (mc_platform->stack_size[MC_THREAD_CP] < 1) {
00083     /* In windows, 0 is default, not min */
00084     stack_size = mc_platform->stack_size[MC_THREAD_CP]+1; 
00085   } else {
00086     stack_size = mc_platform->stack_size[MC_THREAD_CP];
00087   }
00088 #endif
00089   THREAD_CREATE
00090     (
00091      &cmd_prompt->thread,
00092      cmd_prompt_Thread,
00093      (void*)mc_platform
00094     );
00095 }
00096 
00097 #ifndef _WIN32
00098   void*
00099 cmd_prompt_Thread(void* arg) 
00100 #else
00101   DWORD WINAPI
00102 cmd_prompt_Thread( LPVOID arg )
00103 #endif
00104 {
00105     char *buf;
00106     command_t cmd;
00107     mc_platform_p mc_platform = (mc_platform_p)arg;
00108     cmd.index = COMMAND_COUNT;
00109     printf("\n");
00110         buf = (char*)malloc(sizeof(char) * 100);
00111         if (!buf) {fprintf(stderr, "Malloc failed at %s:%d.\n", __FILE__, __LINE__); }
00112     while(1)
00113     {
00114         /* We want to repeatedly grab and execute the user's commands. */
00115 #ifdef HAVE_LIBREADLINE
00116         buf = readline("MobileC > ");
00117 #else
00118                 printf("MobileC > ");
00119 #ifndef _WIN32
00120                 if (!fgets(buf, 100, stdin)) 
00121 #else
00122                 if (!gets(buf))  /* FIXME, for the love of god FIXME */
00123 #endif
00124     {
00125                         fprintf(stderr, "fgets failed at %s:%d\n", __FILE__, __LINE__);
00126                 }
00127 #endif
00128         /* Get rid of newline character */
00129         if (buf[strlen(buf)-1] == '\n') 
00130         {
00131             buf[strlen(buf)-1] = '\0';
00132         }
00133         cmd.num_args = split_string(&cmd.args, buf);
00134         process_command(&cmd);
00135         exec_command(cmd, mc_platform);
00136         dealloc_command(&cmd);
00137     }
00138     return 0;
00139 } /*}}}*/
00140 
00141 /* Function: split_string
00142    This function takes the address of a **char data type and a character
00143    string. It splits up the character string by spaces, placing each
00144    word into each successive arg. It automatically allocates the first
00145    argument. */
00146 int split_string(char ***args, const char *buf) /*{{{*/
00147 {
00148     /* First lets figure out how many args. */
00149     int toggle = 0;
00150     int num_args = 0;
00151     int i;
00152     int j;
00153     char *word;
00154     char *_buf;
00155     _buf = malloc(strlen(buf) * sizeof(char) + 1);
00156     strcpy(_buf, buf);
00157     for(i=0; i<(int)strlen(_buf); i++) 
00158     {
00159         if(_buf[i] != ' ') 
00160         {
00161             if(toggle == 0) 
00162             {
00163                 toggle = 1;
00164                 num_args++;
00165             }
00166         } 
00167         else 
00168         {
00169             toggle = 0;
00170         }
00171     }
00172 
00173     /* Now we have num_args */
00174     *args = (char **)malloc(sizeof(char *)*num_args);
00175 
00176     /* Now we must allocate space and copy each arg */
00177     j = 0;
00178     word = strtok(_buf, " ");
00179     while(word != NULL) 
00180     {  
00181         (*args)[j] = (char*)malloc(sizeof(char)*strlen(word)+1);
00182         strcpy((*args)[j], word);
00183         j++;
00184         word = strtok(NULL, " ");
00185     }
00186     free(_buf);
00187 
00188     return num_args;
00189 } /*}}}*/
00190 
00191 /* Function: process_command
00192    This function looks at the information inside cmd.args and
00193    fills out the cmd.cmd enum */
00194 int process_command(command_t *cmd) /*{{{*/
00195 {
00196     int i;
00197     if(cmd->num_args == 0) 
00198     {
00199         return 0;
00200     }
00201     for(i=0; i<COMMAND_COUNT; i++) 
00202     {
00203         if(!strcmp(cmd->args[0], command_cmds[i])) 
00204         {
00205             break;
00206         }
00207     }
00208     cmd->index = i;
00209     return 0;
00210 } /*}}}*/
00211         
00212 int exec_command(command_t cmd, mc_platform_p global) /*{{{*/
00213 {
00214     if(cmd.num_args == 0) 
00215     { 
00216         return 0; 
00217     }
00218     if(cmd.index == COMMAND_COUNT) 
00219     {
00220         printf("Unknown command: %s\n", cmd.args[0]);
00221         printf("Type \"help\" for a listing of commands.\n");
00222         return 1;
00223     }
00224 
00225     return cmd_handlers[cmd.index](&cmd, global);
00226 } /*}}}*/
00227 
00228 int dealloc_command(command_t *cmd) /*{{{*/
00229 {
00230     int i;
00231     for(i=0; i<cmd->num_args; i++) 
00232     {
00233         free(cmd->args[i]);
00234     }
00235     free(cmd->args);
00236 
00237     return 0;
00238 } /*}}}*/
00239 
00240 /* * * * * * * * * * * * * * * *
00241    command handlers begin here *
00242    * * * * * * * * * * * * * * */
00243 int handler_QUIT(void *arg, mc_platform_p global) /*{{{*/
00244 {
00245     mc_platform_Destroy(global);
00246     exit(0);
00247     return 0;
00248 } /*}}}*/
00249 
00250 int handler_HELP(void *arg, mc_platform_p global) /*{{{*/
00251 {
00252     command_t *cmd = (command_t*)arg;
00253     int i;
00254     /* Find the command number */
00255     if(cmd->num_args > 1) 
00256     {
00257         for(i=0; i<COMMAND_COUNT; i++) 
00258         {
00259             if(!strcmp(command_cmds[i], cmd->args[1])) 
00260             {
00261                 break;
00262             }
00263         }
00264 
00265         if(i == COMMAND_COUNT) 
00266         { 
00267             /* No such command */
00268             printf("Sorry, the command '%s' does not exist.\n", cmd->args[2]);
00269         } 
00270         else 
00271         {
00272             printf("%s\n", command_descriptions[i]);
00273         }
00274     } 
00275     else 
00276     {
00277         printf("For info about help, type \"help help\"\n");
00278         printf("Current commands are:\n");
00279         for(i=0; i<COMMAND_COUNT; i++) 
00280         {
00281             printf("%s\n", command_cmds[i]);
00282         }
00283     }
00284 
00285     return 0;
00286 } /*}}}*/
00287 
00288 int handler_SEND(void *arg, mc_platform_p global) /*{{{*/
00289 {
00290     command_t* cmd = (command_t*)arg;
00291     if(cmd->num_args != 4) 
00292     {
00293         printf("%s\n", command_descriptions[COMMAND_SEND]);
00294         return 0;
00295     }
00296     return MC_SendAgentMigrationMessageFile(
00297             NULL,
00298             cmd->args[1],
00299             cmd->args[2],
00300             atoi(cmd->args[3])); 
00301 } /*}}}*/
00302     
00303 int handler_PRINT_CONNECTLIST(void *arg, mc_platform_p global) /*{{{*/
00304 {
00305     connection_queue_Print(global->connection_queue);
00306     return 0;
00307 } /*}}}*/
00308 
00309 int handler_PRINTLIST_MESSAGE(void *arg, mc_platform_p global) /*{{{*/
00310 {
00311     message_queue_Print(global->message_queue);
00312     return 0;
00313 } /*}}}*/
00314 
00315 int handler_PRINTLIST_AGENTS(void *arg, mc_platform_p global) /*{{{*/
00316 {
00317     agent_queue_Print(global->agent_queue);
00318     return 0;
00319 } /*}}}*/
00320 

Generated on Fri May 16 14:49:54 2008 for Mobile-C by  doxygen 1.5.4