void commands(struct clients *client_t) { char rspsoneBuf[MAX_LINE * 2] = {0}; struct data_st *recv_pdt = client_t->recv_data; if ((recv_pdt->data_len > 0) && (recv_pdt->data != NULL)) { // SYSADMIN: 用于管理员调试 if ( strncasecmp(recv_pdt->data, "SYSADMIN ", 9) == 0 ) { } // LOGIN: 用于表示客户端登录 LOGIN account:abalam password:123qwe ios_token:111 get_friend_list:1 \r\n\r\n if ( strncasecmp(recv_pdt->data, "LOGIN ", 6) == 0 ) { char *pbuf = recv_pdt->data + 5; char myuid[128] = {0}; int ret = login_cmd(client_t, pbuf, strlen(pbuf)); if (ret != 0) { // 认证失败 snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s FAIL%s", TAG_LOGIN, DATA_END); safe_write(client_t, rspsoneBuf, strlen(rspsoneBuf)); } // init recv data reinit_data_without_free(recv_pdt); return ; } // HELO: 用于表示客户端信息 helo uid:0000001 ios_token:xxxxxxxxxxxxxx fid:0000220 if ( strncasecmp(recv_pdt->data, "HELO ", 5) == 0 ) { char *pbuf = recv_pdt->data + 5; char myuid[128] = {0}; int ret = helo_cmd(client_t, pbuf, strlen(pbuf), myuid, sizeof(myuid)); if (ret == 0) { // 检查是否有离线消息 int offline_msg_num = has_offline_msg(myuid); snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s OK %d%s", TAG_HELO, offline_msg_num, DATA_END); } else { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s FAIL 0%s", TAG_HELO, DATA_END); } // init recv data reinit_data_without_free(recv_pdt); safe_write(client_t, rspsoneBuf, strlen(rspsoneBuf)); return ; } // ALIVE: keep alive 保持在线 if ( strncasecmp(recv_pdt->data, "ALIVE ", 6) == 0 ) { char *pbuf = recv_pdt->data + 6; snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s OK %s", TAG_ALIVE, DATA_END); // init recv data reinit_data_without_free(recv_pdt); safe_write(client_t, rspsoneBuf, strlen(rspsoneBuf)); return; } // QUIT: 用户退出 if ( strncasecmp(recv_pdt->data, "QUIT ", 5) == 0 ) { char *pbuf = recv_pdt->data + 5; int ret = quit_cmd(client_t, pbuf, strlen(pbuf)); /* if (ret == 0) { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s OK %s", TAG_QUIT, DATA_END); } else { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s FAIL %s", TAG_QUIT, DATA_END); } */ // init recv data reinit_data_without_free(recv_pdt); //safe_write(client_t, rspsoneBuf, strlen(rspsoneBuf)); return ; } // SENDADDFRDREQ: 发送请求加为好友信息 if ( strncasecmp(recv_pdt->data, "SENDADDFRDREQ ", 14) == 0 ) { char *pbuf = recv_pdt->data + 14; char mid[MAX_LINE] = {0}; int ret = sendreq_addfriend(client_t, pbuf, strlen(pbuf), mid, sizeof(mid)); if (ret == 0) { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s OK %s", TAG_SENDADDFRIENDREQ, DATA_END); } else { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s FAIL %s", TAG_SENDADDFRIENDREQ, DATA_END); } // init recv data reinit_data_without_free(recv_pdt); safe_write(client_t, rspsoneBuf, strlen(rspsoneBuf)); return; } // SENDTXT: 发送送信息给对方 if ( strncasecmp(recv_pdt->data, "SENDTXT ", 8) == 0 ) { char *pbuf = recv_pdt->data + 8; char mid[MAX_LINE] = {0}; int ret = sendtxt_cmd(client_t, pbuf, strlen(pbuf), mid, sizeof(mid)); if (ret == 0) { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s OK %s%s", TAG_SENDTXT, mid, DATA_END); } else { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s FAIL %s%s", TAG_SENDTXT, mid, DATA_END); } // init recv data reinit_data_without_free(recv_pdt); safe_write(client_t, rspsoneBuf, strlen(rspsoneBuf)); return; } // SENDIMG: 发送送图片给对方 if ( strncasecmp(recv_pdt->data, "SENDIMG ", 8) == 0 ) { char *pbuf = recv_pdt->data + 8; char mid[MAX_LINE] = {0}; char thumb_img_url[MAX_LINE] = {0}; char qid[MAX_LINE] = {0}; int ret = sendimg_cmd(client_t, pbuf, strlen(pbuf), mid, sizeof(mid), thumb_img_url, sizeof(thumb_img_url), qid, sizeof(qid)); if (ret == 0) { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s OK %s %s %s%s", TAG_SENDIMG, mid, qid, thumb_img_url, DATA_END); } else { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s FAIL %s %s %s%s", TAG_SENDIMG, mid, qid, thumb_img_url, DATA_END); } // init recv data reinit_data_without_free(recv_pdt); safe_write(client_t, rspsoneBuf, strlen(rspsoneBuf)); return; } // SENDAUDIO: 发送送音频给对方 if ( strncasecmp(recv_pdt->data, "SENDAUDIO ", 10) == 0 ) { char *pbuf = recv_pdt->data + 10; char mid[MAX_LINE] = {0}; char qid[MAX_LINE] = {0}; char audio_url[MAX_LINE] = {0}; int ret = sendaudio_cmd(client_t, pbuf, strlen(pbuf), mid, sizeof(mid), audio_url, sizeof(audio_url), qid, sizeof(qid)); if (ret == 0) { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s OK %s %s %s %s", TAG_SENDAUDIO, mid, qid, audio_url, DATA_END); } else { snprintf(rspsoneBuf, sizeof(rspsoneBuf), "%s FAIL %s %s %s %s", TAG_SENDAUDIO, mid, qid, audio_url, DATA_END); } // init recv data reinit_data_without_free(recv_pdt); safe_write(client_t, rspsoneBuf, strlen(rspsoneBuf)); return; } } }
static bool dot_quit_cmd(UAContext *ua, const char *cmd) { quit_cmd(ua, cmd); return true; }
/* * .die (seg fault) * .dump (sm_dump) * .exit (no arg => .quit) */ bool dot_admin_cmds(UAContext *ua, const char *cmd) { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; STORERES *store = NULL; CLIENTRES *client = NULL; bool dir=false; bool do_deadlock=false; const char *remote_cmd; int i; JCR *jcr = NULL; int a; if (strncmp(ua->argk[0], ".die", 4) == 0) { if (find_arg(ua, "deadlock") > 0) { do_deadlock = true; remote_cmd = ".die deadlock"; } else { remote_cmd = ".die"; } } else if (strncmp(ua->argk[0], ".dump", 5) == 0) { remote_cmd = "sm_dump"; } else if (strncmp(ua->argk[0], ".exit", 5) == 0) { remote_cmd = "exit"; } else { ua->error_msg(_("Unknown command: %s\n"), ua->argk[0]); return true; } /* General debug? */ for (i = 1; i < ua->argc; i++) { if (bstrcasecmp(ua->argk[i], "dir") || bstrcasecmp(ua->argk[i], "director")) { dir = true; } if (bstrcasecmp(ua->argk[i], "client") || bstrcasecmp(ua->argk[i], "fd")) { client = NULL; if (ua->argv[i]) { client = (CLIENTRES *)GetResWithName(R_CLIENT, ua->argv[i]); } if (!client) { client = select_client_resource(ua); } } if (bstrcasecmp(ua->argk[i], NT_("store")) || bstrcasecmp(ua->argk[i], NT_("storage")) || bstrcasecmp(ua->argk[i], NT_("sd"))) { store = NULL; if (ua->argv[i]) { store = (STORERES *)GetResWithName(R_STORAGE, ua->argv[i]); } if (!store) { store = get_storage_resource(ua); } } } if (!dir && !store && !client) { /* * We didn't find an appropriate keyword above, so * prompt the user. */ start_prompt(ua, _("Available daemons are: \n")); add_prompt(ua, _("Director")); add_prompt(ua, _("Storage")); add_prompt(ua, _("Client")); switch(do_prompt(ua, "", _("Select daemon type to make die"), NULL, 0)) { case 0: /* Director */ dir=true; break; case 1: store = get_storage_resource(ua); break; case 2: client = select_client_resource(ua); break; default: break; } } if (store) { switch (store->Protocol) { case APT_NDMPV2: case APT_NDMPV3: case APT_NDMPV4: ua->warning_msg(_("Storage has non-native protocol.\n")); break; default: do_storage_cmd(ua, store, remote_cmd); break; } } if (client) { do_client_cmd(ua, client, remote_cmd); } if (dir) { if (strncmp(remote_cmd, ".die", 4) == 0) { if (do_deadlock) { ua->send_msg(_("The Director will generate a deadlock.\n")); P(mutex); P(mutex); } ua->send_msg(_("The Director will segment fault.\n")); a = jcr->JobId; /* ref NULL pointer */ jcr->JobId = 1000; /* another ref NULL pointer */ jcr->JobId = a; } else if (strncmp(remote_cmd, ".dump", 5) == 0) { sm_dump(false, true); } else if (strncmp(remote_cmd, ".exit", 5) == 0) { quit_cmd(ua, cmd); } } return true; }
/* Thread for tcp_node to accept standard input and transfer that standard input to queue for tcp_node or ip_node to handle */ void* _handle_tcp_node_stdin(void* node){ tcp_node_t tcp_node = (tcp_node_t)node; char line[LINE_MAX]; char cmd[LINE_MAX]; fd_set input; int ret, fgets_ret; unsigned i; /* let's just wait for 1/5 of a second for every stdin read */ struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; /* holder for the args that we're iterating over */ tcp_api_args_t args; plain_list_el_t el; while (tcp_node_running(tcp_node)&&tcp_node_ip_running(tcp_node)){ /* NOTE: this call fd_fgets (src/util/utils.c) is now non-blocking sort-of, it blocks for the amount of time defined in the struct timeval tv, and then returns control. It returns -1 if an error occurred, 0 if there's nothing to read, and 1 if there's something to read */ /* if less than 0, fgets() returned NULL */ if( (fgets_ret = fd_fgets(&input, line, sizeof(line), stdin, &tv)) < 0 ){ quit_cmd(line, tcp_node); break; } else{ /* >>>>>>>>>>>>>>>>> check all your spawned threads <<<<<<<<<< */ /* this is defined in include/utils/list.h and it just iterates over the passed in list, setting the given argument (thread) to the data of each list element */ plain_list_t list = tcp_node_thread_list(tcp_node); PLAIN_LIST_ITER(list, el) //in utils.h args = (tcp_api_args_t)el->data; if(args->done){ if(args->result < 0){ char* error_string = strerror(-(args->result)); printf("Error: %s returned %s\n", args->function_call, error_string); } else if(args->result==0) printf("%s on socket %d successful.\n", args->function_call, args->socket); else printf("%s on socket %d returned value: %d\n", args->function_call, args->socket, args->result); tcp_api_args_destroy(&args); plain_list_remove(list, el); } PLAIN_LIST_ITER_DONE(list); /* >>>>>>>>>>>>> now check what you read on stdin <<<<<<<<<<< */ /* didn't read anything */ if(fgets_ret == 0) continue; /* otherwise line has been set by fgets in fd_fgets() */ ret = sscanf(line, "%s", cmd); if (ret != 1){ fprintf(stderr, "syntax error (first argument must be a command)\n"); continue; } for (i=0; i < sizeof(cmd_table) / sizeof(cmd_table[0]); i++){ if (!strcmp(cmd, cmd_table[i].command)){ cmd_table[i].handler(line, tcp_node); break; } } if (i == sizeof(cmd_table) / sizeof(cmd_table[0])){ fprintf(stderr, "error: no valid command specified\n"); continue; } } } print(("exiting stdin thread"), CLOSING_PRINT); pthread_exit(NULL); }