00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <stdio.h>
00038 #ifndef _WIN32
00039 #include <unistd.h>
00040 #include "config.h"
00041 #else
00042 #include <windows.h>
00043 #include "winconfig.h"
00044 #endif
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include "include/cmd_prompt.h"
00048 #include "include/commands.h"
00049 #include "include/agent.h"
00050 #include "config.h"
00051
00052 #ifdef HAVE_LIBREADLINE
00053 #include <readline/readline.h>
00054 #include <readline/history.h>
00055 #endif
00056
00057
00058
00059
00060 #ifdef HAVE_LIBREADLINE
00061 int initialize_readline (void);
00062 char ** command_completion (char* text, int start, int end);
00063 char * command_generator (char* text, int state);
00064
00065 int initialize_readline (void)
00066 {
00067 rl_readline_name = "$";
00068 rl_attempted_completion_function = (CPPFunction *)command_completion;
00069 return 0;
00070 }
00071
00072 char ** command_completion (char* text, int start, int end)
00073 {
00074 char **matches;
00075 matches = (char **)NULL;
00076
00077 if (start == 0)
00078 matches = (char**)completion_matches (text, command_generator);
00079
00080 return (matches);
00081 }
00082
00083 char * command_generator (char* text, int state)
00084 {
00085 static int list_index, len;
00086 char *name;
00087
00088 if (!state)
00089 {
00090 list_index = 0;
00091 len = strlen (text);
00092 }
00093
00094 while ((name = command_cmds[list_index]))
00095 {
00096 list_index++;
00097
00098 if (strncmp (name, text, len) == 0)
00099 return (strdup(name));
00100 }
00101
00102 return ((char *)NULL);
00103 }
00104
00105
00106
00107
00108 char* stripwhite (char* string)
00109 {
00110 register char *s, *t;
00111 for (s = string; whitespace (*s); s++);
00112 if (*s == 0) return (s);
00113 t = s + strlen (s) - 1;
00114 while (t > s && whitespace (*t)) t--;
00115 *++t = '\0';
00116 return s;
00117 }
00118
00119 #endif
00120
00121 cmd_prompt_p
00122 cmd_prompt_Initialize(mc_platform_p mc_platform)
00123 {
00124 cmd_prompt_p cmd_prompt;
00125 cmd_prompt = (cmd_prompt_p)malloc(sizeof(cmd_prompt_t));
00126 return cmd_prompt;
00127 }
00128
00129 int
00130 cmd_prompt_Destroy(cmd_prompt_p cmd_prompt)
00131 {
00132 free(cmd_prompt);
00133 return MC_SUCCESS;
00134 }
00135
00136 void
00137 cmd_prompt_Start( mc_platform_p mc_platform )
00138 {
00139 cmd_prompt_p cmd_prompt = mc_platform->cmd_prompt;
00140 #ifndef _WIN32
00141 pthread_attr_t attr;
00142 pthread_attr_init(&attr);
00143 if(mc_platform->stack_size[MC_THREAD_CP] != -1) {
00144 pthread_attr_setstacksize
00145 (
00146 &attr,
00147 mc_platform->stack_size[MC_THREAD_CP]
00148 );
00149 }
00150 #else
00151 int stack_size;
00152 if (mc_platform->stack_size[MC_THREAD_CP] < 1) {
00153
00154 stack_size = mc_platform->stack_size[MC_THREAD_CP]+1;
00155 } else {
00156 stack_size = mc_platform->stack_size[MC_THREAD_CP];
00157 }
00158 #endif
00159 THREAD_CREATE
00160 (
00161 &cmd_prompt->thread,
00162 cmd_prompt_Thread,
00163 (void*)mc_platform
00164 );
00165 }
00166
00167 #ifndef _WIN32
00168 void*
00169 cmd_prompt_Thread(void* arg)
00170 #else
00171 DWORD WINAPI
00172 cmd_prompt_Thread( LPVOID arg )
00173 #endif
00174 {
00175 char *buf;
00176 command_t cmd;
00177 mc_platform_p mc_platform = (mc_platform_p)arg;
00178 cmd.index = COMMAND_COUNT;
00179 printf("\n");
00180 #if !defined(HAVE_LIBREADLINE) || defined(_WIN32)
00181 buf = (char*)malloc(sizeof(char) * 100);
00182 if (!buf) {fprintf(stderr, "Malloc failed at %s:%d.\n", __FILE__, __LINE__); }
00183 #endif
00184
00185 #ifdef HAVE_LIBREADLINE
00186 initialize_readline();
00187 #endif
00188 while(1)
00189 {
00190
00191 #ifdef HAVE_LIBREADLINE
00192 buf = readline("MobileC > ");
00193 if (buf == NULL) {
00194 sleep(5);
00195 continue;
00196 }
00197 if (*buf) {
00198 add_history(buf);
00199 }
00200 #else
00201 printf("MobileC > ");
00202 #ifndef _WIN32
00203 if (!fgets(buf, 100, stdin))
00204 #else
00205 if (!gets(buf))
00206 #endif
00207 {
00208 fprintf(stderr, "fgets failed at %s:%d\n", __FILE__, __LINE__);
00209 #ifdef _WIN32
00210 Sleep(5000);
00211 #else
00212 sleep(5);
00213 #endif
00214 return NULL;
00215 }
00216 #endif
00217
00218 if(strlen(buf) > 0) {
00219 if (buf[strlen(buf)-1] == '\n')
00220 {
00221 buf[strlen(buf)-1] = '\0';
00222 }
00223 }
00224 cmd.num_args = split_string(&cmd.args, buf);
00225 process_command(&cmd);
00226 exec_command(cmd, mc_platform);
00227 dealloc_command(&cmd);
00228 #ifdef HAVE_LIBREADLINE
00229 free(buf);
00230 #endif
00231 }
00232 return 0;
00233 }
00234
00235
00236
00237
00238
00239
00240 int split_string(char ***args, const char *buf)
00241 {
00242
00243 int toggle = 0;
00244 int num_args = 0;
00245 int i;
00246 int j;
00247 char *word;
00248 char *_buf;
00249 _buf = (char*)malloc(strlen(buf) * sizeof(char) + 1);
00250 strcpy(_buf, buf);
00251 for(i=0; i<(int)strlen(_buf); i++)
00252 {
00253 if(_buf[i] != ' ')
00254 {
00255 if(toggle == 0)
00256 {
00257 toggle = 1;
00258 num_args++;
00259 }
00260 }
00261 else
00262 {
00263 toggle = 0;
00264 }
00265 }
00266
00267
00268 *args = (char **)malloc(sizeof(char *)*num_args);
00269
00270
00271 j = 0;
00272 word = strtok(_buf, " ");
00273 while(word != NULL)
00274 {
00275 (*args)[j] = (char*)malloc(sizeof(char)*strlen(word)+1);
00276 strcpy((*args)[j], word);
00277 j++;
00278 word = strtok(NULL, " ");
00279 }
00280 free(_buf);
00281
00282 return num_args;
00283 }
00284
00285
00286
00287
00288 int process_command(command_t *cmd)
00289 {
00290 int i;
00291 if(cmd->num_args == 0)
00292 {
00293 return 0;
00294 }
00295 for(i=0; i<COMMAND_COUNT; i++)
00296 {
00297 if(!strcmp(cmd->args[0], command_cmds[i]))
00298 {
00299 break;
00300 }
00301 }
00302 cmd->index = i;
00303 return 0;
00304 }
00305
00306 int exec_command(command_t cmd, mc_platform_p global)
00307 {
00308 if(cmd.num_args == 0)
00309 {
00310 return 0;
00311 }
00312 if(cmd.index == COMMAND_COUNT)
00313 {
00314 printf("Unknown command: %s\n", cmd.args[0]);
00315 printf("Type \"help\" for a listing of commands.\n");
00316 return 1;
00317 }
00318
00319 return cmd_handlers[cmd.index](&cmd, global);
00320 }
00321
00322 int dealloc_command(command_t *cmd)
00323 {
00324 int i;
00325 for(i=0; i<cmd->num_args; i++)
00326 {
00327 free(cmd->args[i]);
00328 }
00329 free(cmd->args);
00330
00331 return 0;
00332 }
00333
00334
00335
00336
00337 int handler_QUIT(void *arg, mc_platform_p global)
00338 {
00339 MUTEX_LOCK(global->quit_lock);
00340 global->quit = 1;
00341 COND_BROADCAST (global->quit_cond);
00342 MUTEX_UNLOCK(global->quit_lock);
00343 return 0;
00344 }
00345
00346 int handler_HELP(void *arg, mc_platform_p global)
00347 {
00348 command_t *cmd = (command_t*)arg;
00349 int i;
00350
00351 if(cmd->num_args > 1)
00352 {
00353 for(i=0; i<COMMAND_COUNT; i++)
00354 {
00355 if(!strcmp(command_cmds[i], cmd->args[1]))
00356 {
00357 break;
00358 }
00359 }
00360
00361 if(i == COMMAND_COUNT)
00362 {
00363
00364 printf("Sorry, the command '%s' does not exist.\n", cmd->args[1]);
00365 }
00366 else
00367 {
00368 printf("%s\n", command_descriptions[i]);
00369 }
00370 }
00371 else
00372 {
00373 printf("For info about help, type \"help help\"\n");
00374 printf("Current commands are:\n");
00375 for(i=0; i<COMMAND_COUNT; i++)
00376 {
00377 printf("%s\n", command_cmds[i]);
00378 }
00379 }
00380
00381 return 0;
00382 }
00383
00384 int handler_SEND(void *arg, mc_platform_p global)
00385 {
00386 command_t* cmd = (command_t*)arg;
00387 if(cmd->num_args != 2)
00388 {
00389 printf("%s\n", command_descriptions[COMMAND_SEND]);
00390 return 0;
00391 }
00392 return MC_SendAgentFile(NULL, cmd->args[1]);
00393 }
00394
00395 int handler_PRINT_CONNECTLIST(void *arg, mc_platform_p global)
00396 {
00397 ListRDLock(global->connection_queue);
00398 ListForEachCB(global->connection_queue, (ListElemGenericFunc_t)connection_Print);
00399 ListRDUnlock(global->connection_queue);
00400 return 0;
00401 }
00402
00403 int handler_PRINTLIST_MESSAGE(void *arg, mc_platform_p global)
00404 {
00405 ListRDLock(global->message_queue);
00406 ListForEachCB(global->message_queue, (ListElemGenericFunc_t)message_Print);
00407 ListRDUnlock(global->message_queue);
00408 return 0;
00409 }
00410
00411 int handler_PRINTLIST_AGENTS(void *arg, mc_platform_p global)
00412 {
00413 ListRDLock(global->agent_queue);
00414 ListForEachCB(global->agent_queue, (ListElemGenericFunc_t)agent_Print);
00415 ListRDUnlock(global->agent_queue);
00416 return 0;
00417 }
00418
00419 int handler_FLUSH_AGENTS(void *arg, mc_platform_p global)
00420 {
00421 ListWRLock(global->agent_queue);
00422 ListClearCB(global->agent_queue, (ListElemDestroyFunc_t) agent_Destroy);
00423 ListWRUnlock(global->agent_queue);
00424 return 0;
00425 }
00426
00427 int handler_COMPOSE_SEND(void *arg, mc_platform_p global)
00428 {
00429
00430 command_t* cmd = (command_t*)arg;
00431 MCAgent_t agent;
00432 char name[80];
00433 char server[200];
00434 if(cmd->num_args != 4)
00435 {
00436 printf("%s\n", command_descriptions[COMMAND_COMPOSE_SEND]);
00437 return 0;
00438 }
00439 sprintf(name, "agent%d", rand()%1000);
00440 sprintf(server, "%s:%s", cmd->args[2], cmd->args[3]);
00441 agent = MC_ComposeAgentFromFile(
00442 name,
00443 global->hostname,
00444 name,
00445 cmd->args[1],
00446 NULL,
00447 server,
00448 0
00449 );
00450 if (agent != NULL) {
00451 MC_AddAgent(global->agency, agent);
00452 return 0;
00453 } else {
00454 return -1;
00455 }
00456 }