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