int16_t non_std_m_message_recv(int Sockfd,int Echo_Size,void *Out){ void *buff = new char[STD_PACKAGE_SIZE]; void *data = new char[STD_PACKAGE_SIZE]; int i,totle,current; int length; length = recv(Sockfd,buff,STD_PACKAGE_SIZE,0); if(check_message(buff,length) < 0){ delete (char *)buff; delete (char *)data; return LINKC_FAILURE; } totle = ((LinkC_Message_Header*)buff)->Totle; current = ((LinkC_Message_Header*)buff)->Current; unpack_message(buff,data); memcpy((char *)Out+(current-1)*Echo_Size,data,Echo_Size); for(i=1;i<totle;i++){ length = recv(Sockfd,buff,STD_PACKAGE_SIZE,0); if(check_message(buff,length) < 0){ delete (char *)buff; delete (char *)data; return LINKC_FAILURE; } current = ((LinkC_Message_Header*)buff)->Current; unpack_message(buff,data); memcpy((char *)Out+(current-1)*Echo_Size,data,Echo_Size); } delete (char *)buff; delete (char *)data; return totle; }
static int ctrl_semihosting_setarmswi(p_Buffer * buffer, void *stateptr) { #ifdef ICEMAN2 /* Set the semi-hosting ARM SWI. */ int debugID, OSinfo1, OSinfo2, subreason; word semihosting_armswi, status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &semihosting_armswi); LogInfo(LOG_CTRL, ( "ctrl_semihosting_setarmswi(swi 0x%x)\n", semihosting_armswi)); status = angelOS_SemiHosting_SetARMSWI(OSinfo1, OSinfo2, semihosting_armswi); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SemiHosting_SetARMSWI, status); #else IGNORE(buffer); IGNORE(stateptr); LogInfo(LOG_CTRL, ( "ctrl_semihosting_setarmswi -> unsupported\n")); return -1; #endif }
static int ctrl_settopmem(p_Buffer * buffer, void *stateptr) { #ifdef ICEMAN2 /* Set the top of memory we report on a HEAPINFO SWI */ int debugID, OSinfo1, OSinfo2, subreason; word topmem; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &topmem); LogInfo(LOG_CTRL, ( "ctrl_settopmem(topmem = 0x%x)\n", topmem)); angel_SetTopMem((unsigned)topmem); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SetTopMem, RDIError_NoError); #else IGNORE(buffer); IGNORE(stateptr); return -1; #endif }
static int ctrl_download_agent(p_Buffer * buffer, void *stateptr) { /* Decode an loadagent message */ int debugID, OSinfo1, OSinfo2, subreason; word loadaddress, nbytes; word status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &loadaddress, &nbytes); LogInfo(LOG_CTRL, ( "ctrl_download_agent(loadadr = 0x%x, nbytes = %d)\n", loadaddress, nbytes)); status = angelOS_LoadAgent(OSinfo1, OSinfo2, loadaddress, nbytes); if (status == RDIError_NoError) { loadagent_address = loadaddress; loadagent_size = nbytes; loadagent_sofar = 0; } return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Download_Agent, status); }
static int ctrl_start_agent(p_Buffer * buffer, void *stateptr) { /* Decode an loadagent message */ int debugID, OSinfo1, OSinfo2, subreason, err; word startaddress; word status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &startaddress); LogInfo(LOG_CTRL, ( "ctrl_start_agent(startaddress = %x)\n", startaddress)); if (loadagent_sofar == loadagent_size && startaddress >= loadagent_address && startaddress < (loadagent_address + loadagent_size)) status = RDIError_NoError; else status = RDIError_BadConfigData; err = msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Start_Agent, status); if (err == RDIError_NoError && status == RDIError_NoError) angelOS_ExecuteNewAgent(startaddress); return err; }
/** * \param id MessageID of requested message * * Reads data from message queue until message with matching id is found. * * \return GString containing unpacked message. **/ GString *get_message_by_id(MessageID id) { GString *data = NULL; guint x, len; gboolean found = FALSE; g_mutex_lock(message_queue_mutex); do { len = g_queue_get_length(message_queue); for (x = 0; x<len; x++) { data = g_queue_peek_nth(message_queue, x); if (get_message_id(data) == id) { found = TRUE; g_queue_pop_nth(message_queue, x); break; } } if (found == FALSE) g_cond_wait(message_queue_cond, message_queue_mutex); } while (found == FALSE); g_mutex_unlock(message_queue_mutex); unpack_message(data); return data; }
static int ctrl_download_data(p_Buffer * buffer, void *stateptr) { /* Decode an addconfig message */ int debugID, OSinfo1, OSinfo2, reason, subreason, count, err; word nbytes; word status; IGNORE(stateptr); count = unpack_message(BUFFERDATA(*buffer), "%w%w%w%w%w%w", &reason, &debugID, &OSinfo1, &OSinfo2, &subreason, &nbytes); LogInfo(LOG_CTRL, ( "ctrl_download_data(nbytes = %d)\n", nbytes)); status = angelOS_LoadConfigData(OSinfo1, OSinfo2, nbytes, BUFFERDATA(*buffer) + count); if (status == RDIError_NoError && loadagent_address != -1) loadagent_sofar += nbytes; /* We make sure we release the buffer here as it may be the long one */ angel_ChannelReleaseBuffer(*buffer); *buffer = NULL; err = msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Download_Data, status); return err; }
static int ctrl_download_supported(p_Buffer * buffer, void *stateptr) { int debugID, OSinfo1, OSinfo2; /* For Angel return CantLoadConfig - we can't do that * for EmbeddedICE (ICEman) say we can * for EICEADP - the ADP over JTAG software say we can't */ #if defined(ICEMAN2) && !defined(JTAG_ADP_SUPPORTED) word status = RDIError_NoError; #else word status = RDIError_CantLoadConfig; #endif IGNORE(stateptr); LogInfo(LOG_CTRL, ( "ctrl_download_supported -> %d\n", status)); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Download_Supported, status); }
static int ctrl_semihosting_getthumbswi(p_Buffer * buffer, void *stateptr) { #ifdef ICEMAN2 /* Reads the value of the semi-hosting vector. */ int debugID, OSinfo1, OSinfo2, subreason; word semihosting_thumbswi, status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason); status = angelOS_SemiHosting_GetThumbSWI(OSinfo1, OSinfo2, &semihosting_thumbswi); LogInfo(LOG_CTRL, ("ctrl_semihosting_getthumbswi -> %08x\n", semihosting_thumbswi)); return msgsend(CI_HADP, "%w%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SemiHosting_GetThumbSWI, status, semihosting_thumbswi); #else IGNORE(buffer); IGNORE(stateptr); LogInfo(LOG_CTRL, ( "ctrl_semihosting_getthumbswi - unsupported\n")); return -1; #endif }
static int ctrl_nop(p_Buffer * buffer, void *stateptr) { /* Return an RDIError_NoError to indicate ctrl calls are available. */ int debugID, OSinfo1, OSinfo2; word status = RDIError_NoError; IGNORE(stateptr); LogInfo(LOG_CTRL, ( "ctrl_nop()\n")); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_NOP, status); }
static int ctrl_vectorcatch(p_Buffer * buffer, void *stateptr) { /* Specify which hardware exceptions should be reported to the debugger. */ int debugID, OSinfo1, OSinfo2, subreason; word status = RDIError_NoError; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &debug_VectorCatch); LogInfo(LOG_CTRL, ( "ctrl_vectorcatch(vectorcatch = 0x%x)\n", debug_VectorCatch)); status = angelOS_VectorCatch(OSinfo1, OSinfo2, debug_VectorCatch); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_VectorCatch, status); }
static int ctrl_log(p_Buffer * buffer, void *stateptr) { /* Read logging level. */ int debugID, OSinfo1, OSinfo2; word status = RDIError_NoError; word logsetting; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2); LogInfo(LOG_CTRL, ( "ctrl_log -> 0x%x\n", logsetting)); status = angelOS_Ctrl_Log(OSinfo1, OSinfo2, &logsetting); return msgsend(CI_HADP, "%w%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_Log, status, logsetting); }
static int ctrl_semihosting_setvector(p_Buffer * buffer, void *stateptr) { /* Set the semi-hosting vector. */ int debugID, OSinfo1, OSinfo2, subreason; word semihosting_vector, status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &semihosting_vector); LogInfo(LOG_CTRL, ( "ctrl_semihosting_setvector(vec = 0x%x)\n", semihosting_vector)); status = angelOS_SemiHosting_SetVector(OSinfo1, OSinfo2, semihosting_vector); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SemiHosting_SetVector, status); }
static int ctrl_semihosting_setstate(p_Buffer * buffer, void *stateptr) { /* Set whether or not semi-hosting is enabled. */ int debugID, OSinfo1, OSinfo2, subreason; word semihosting_state, status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &semihosting_state); LogInfo(LOG_CTRL, ("ctrl_semihosting_setstate(state = %d)\n", semihosting_state)); status = angelOS_SemiHosting_SetState(OSinfo1, OSinfo2, semihosting_state); return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SemiHosting_SetState, status); }
static int ctrl_pointstatus_break(p_Buffer * buffer, void *stateptr) { /* Return information about a breakpoint given a handle. */ int debugID, OSinfo1, OSinfo2, subreason; word status, hwresource, type; word handle; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &handle); LogInfo(LOG_CTRL, ( "ctrl_pointstatus_break(handle = 0x%x)\n", handle)); status = angelOS_BreakPointStatus(OSinfo1, OSinfo2, handle, &hwresource, &type); return msgsend(CI_HADP, "%w%w%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_PointStatus_Break, status, hwresource, type); }
static int ctrl_setlog(p_Buffer * buffer, void *stateptr) { /* Set logging level. */ int debugID, OSinfo1, OSinfo2, subreason; word logsetting; word status; IGNORE(stateptr); unpack_message(BUFFERDATA(*buffer) + 4, "%w%w%w", &debugID, &OSinfo1, &OSinfo2, &subreason, &logsetting); LogInfo(LOG_CTRL, ( "ctrl_setlog(logsetting = 0x%x)\n", logsetting)); /* Range check logsetting. */ if ((logsetting & 0x7) == logsetting) status = angelOS_Ctrl_SetLog(OSinfo1, OSinfo2, logsetting); else status = RDIError_Error; return msgsend(CI_HADP, "%w%w%w%w%w%w", (ADP_Control | TtoH), debugID, OSinfo1, OSinfo2, ADP_Ctrl_SetLog, status); }
void push_message(GString *msg) { MessageID msgid = get_message_id(msg); if (((unsigned char)msg->str[0] == 0xF0) && ((unsigned char)msg->str[msg->len-1] == 0xF7)) { debug_msg(DEBUG_VERBOSE, "Pushing correct message!"); } else { g_warning("Pushing incorrect message!"); } int x; if (debug_flag_is_set(DEBUG_HEX)) { for (x = 0; x<msg->len; x++) { if (x && (x % HEX_WIDTH) == 0) { printf("\n"); } printf("%02x ", (unsigned char)msg->str[x]); } if (x % HEX_WIDTH) { printf("\n"); } } debug_msg(DEBUG_VERBOSE, "Received %s", get_message_name(msgid)); SettingParam *param; switch (msgid) { case ACK: g_string_free(msg, TRUE); return; case NACK: g_warning("Received NACK!"); g_string_free(msg, TRUE); return; case RECEIVE_PARAMETER_VALUE: { unpack_message(msg); param = setting_param_new_from_data(&msg->str[8], NULL); if (debug_flag_is_set(DEBUG_MSG2HOST)) { GString *ipv = format_ipv(param->id, param->position, param->value); debug_msg(DEBUG_MSG2HOST, "RECEIVE_PARAMETER_VALUE\n%s", ipv->str); g_string_free(ipv, TRUE); } GDK_THREADS_ENTER(); apply_setting_param_to_gui(param); GDK_THREADS_LEAVE(); setting_param_free(param); g_string_free(msg, TRUE); return; } case RECEIVE_DEVICE_NOTIFICATION: unpack_message(msg); unsigned char *str = (unsigned char*)msg->str; switch (str[8]) { case NOTIFY_PRESET_MOVED: if (str[11] == PRESETS_EDIT_BUFFER && str[12] == 0) { GDK_THREADS_ENTER(); g_timeout_add(0, apply_current_preset_to_gui, NULL); GDK_THREADS_LEAVE(); debug_msg(DEBUG_MSG2HOST, "RECEIVE_DEVICE_NOTIFICATION: Loaded preset " "%d from bank %d", str[10], str[9]); } else { debug_msg(DEBUG_MSG2HOST, "RECEIVE_DEVICE_NOTIFICATION: %d %d moved to " "%d %d", str[9], str[10], str[11], str[12]); } break; case NOTIFY_MODIFIER_GROUP_CHANGED: { int i; if (debug_flag_is_set(DEBUG_HEX)) { printf("\n"); for (i = 0; i < msg->len; i++) { printf(" %02x", (unsigned char) str[i]); } printf("\n"); } debug_msg(DEBUG_MSG2HOST, "NOTIFY_MODIFIER_GROUP_CHANGED: Modifier group " "id %d changed", (str[9] << 8) | (str[10])); if (!modifier_linkable_list_request_pending) { send_message(REQUEST_MODIFIER_LINKABLE_LIST, "\x00\x01", 2); modifier_linkable_list_request_pending = TRUE; } break; } default: g_warning("Received unhandled device notification 0x%x", str[11]); } g_string_free(msg, TRUE); return; case RECEIVE_GLOBAL_PARAMETERS: unpack_message(msg); gint tot, n, x; tot = (unsigned char)msg->str[9]; if (debug_flag_is_set(DEBUG_HEX)) { for (n = 0; n < msg->len; n++) { printf("%02x ",(unsigned char) msg->str[n]); } printf("\n"); } n = 0; x = 10; do { param = setting_param_new_from_data(&msg->str[x], &x); debug_msg(DEBUG_MSG2HOST, "RECEIVE_GLOBAL_PARAMETERS ID: %5d " "Position: %2.1d Value: %6.1d: %s", param->id, param->position, param->value, "XXX"); GDK_THREADS_ENTER(); apply_setting_param_to_gui(param); GDK_THREADS_LEAVE(); setting_param_free(param); } while ( (x < msg->len) && n < tot); g_string_free(msg, TRUE); return; case RECEIVE_MODIFIER_LINKABLE_LIST: modifier_linkable_list_request_pending = FALSE; unpack_message(msg); tot = (unsigned char)msg->str[9]; if (debug_flag_is_set(DEBUG_HEX)) { for (n = 0; n < msg->len; n++) { printf("%02x ",(unsigned char) msg->str[n]); } printf("\n"); } update_modifier_linkable_list(msg); g_string_free(msg, TRUE); GDK_THREADS_ENTER(); create_modifier_group(EXP_POSITION, EXP_ASSIGN1); create_modifier_group(LFO1_POSITION, LFO_TYPE); create_modifier_group(LFO2_POSITION, LFO_TYPE); GDK_THREADS_LEAVE(); return; default: g_mutex_lock(message_queue_mutex); g_queue_push_tail(message_queue, msg); g_cond_signal(message_queue_cond); g_mutex_unlock(message_queue_mutex); break; } }
void push_message(GString *msg) { if (((unsigned char)msg->str[0] == 0xF0) && ((unsigned char)msg->str[msg->len-1] == 0xF7)) g_message("Pushing correct message!"); else g_warning("Pushing incorrect message!"); int x; for (x = 0; x<msg->len; x++) printf("%02x ", (unsigned char)msg->str[x]); printf("\n"); switch (get_message_id(msg)) { case ACK: g_message("Received ACK"); g_string_free(msg, TRUE); return; case NACK: g_message("Received NACK"); g_string_free(msg, TRUE); return; case RECEIVE_PARAMETER_VALUE: unpack_message(msg); SettingParam *param = setting_param_new_from_data(&msg->str[8], NULL); g_message("Received parameter change ID: %d Position: %d Value: %d", param->id, param->position, param->value); GDK_THREADS_ENTER(); apply_setting_param_to_gui(param); GDK_THREADS_LEAVE(); setting_param_free(param); g_string_free(msg, TRUE); return; case RECEIVE_DEVICE_NOTIFICATION: unpack_message(msg); unsigned char *str = (unsigned char*)msg->str; switch (str[8]) { case NOTIFY_PRESET_MOVED: if (str[11] == PRESETS_EDIT_BUFFER && str[12] == 0) { g_message("Loaded preset %d from bank %d", str[10], str[9]); GDK_THREADS_ENTER(); g_timeout_add(0, apply_current_preset_to_gui, NULL); GDK_THREADS_LEAVE(); } else g_message("%d %d moved to %d %d", str[9], str[10], str[11], str[12]); default: g_message("Received unhandled device notification"); } g_string_free(msg, TRUE); return; default: g_mutex_lock(message_queue_mutex); g_queue_push_tail(message_queue, msg); g_cond_signal(message_queue_cond); g_mutex_unlock(message_queue_mutex); } }
int HandleSysMessage(Packet *packet, hsys_state *stateptr) { unsigned int reason_code, mode, len, c, nbytes, nbtotal, nbtogo = 0; long posn, fl; char character; int err; /* Note: We must not free the buffer passed in as the callback handler */ /* expects to do this. Freeing any other buffers we have malloced */ /* ourselves is acceptable */ unsigned char *buffp = ((unsigned char *)BUFFERDATA(packet->pk_buffer))+16; /* buffp points to the parameters*/ /* the invidual messages, excluding*/ /* standard SYS fields (debugID, */ /* osinfo and reasoncode) */ unsigned char *buffhead = (unsigned char *)(packet->pk_buffer); int DebugID, OSInfo1, OSInfo2, count; const char* fmode[] = {"r","rb","r+","r+b", "w","wb","w+","w+b", "a","ab","a+","a+b", "r","r","r","r"} /* last 4 are illegal */ ; FILEHANDLE fh; /* fh is used as an index to the real file handle * in OSptr */ FILE *fhreal; unpack_message(BUFFERDATA(buffhead), "%w%w%w%w", &reason_code, &DebugID, &OSInfo1, &OSInfo2); /* Extract reason code from buffer. */ reason_code &= 0xFFFF; /* Strip away direction bit, OSInfo and */ /* DebugInfo fields. Will want to do some */ /* sort of validation on this later. */ switch(reason_code) { case CL_WriteC: /* Write a character to the terminal. */ /* byte data -> word status */ { #ifdef DEBUG int c = (int)(*buffp); printf("CL_WriteC: [%02x]>%c<", c, isprint(c) ? c : '.'); #endif stateptr->hostif->writec(stateptr->hostif->hostosarg, (int)(*buffp)); DevSW_FreePacket(packet); return msgsend(CI_CLIB,"%w%w%w%w%w", CL_WriteC|HtoT, DebugID, OSInfo1, OSInfo2, NoError); } case CL_Write0: /* Write a null terminated string to the terminal. */ { unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_Write0", TRUE, len, buffp+4); stateptr->hostif->write(stateptr->hostif->hostosarg, (char *) buffp+4, len); DevSW_FreePacket(packet); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Write0|HtoT, DebugID, OSInfo1, OSInfo2, NoError); } case CL_ReadC: /* Read a byte from the terminal */ { DebugPrintF(("CL_ReadC: ")); DevSW_FreePacket(packet); character = stateptr->hostif->readc(stateptr->hostif->hostosarg); DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character, isprint(character) ? character : '.')); return msgsend(CI_CLIB, "%w%w%w%w%w%b", CL_ReadC|HtoT, DebugID, OSInfo1, OSInfo2, NoError, character); } case CL_System: /* Pass NULL terminated string to the hosts command * interpreter. As it is nULL terminated we dont need * the length */ { unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_System", TRUE, len, buffp+4); err = system((char *)buffp+4); /* Use the string in the buffer */ stateptr->last_errno = errno; DebugCheckErr("system", TRUE, err, stateptr->last_errno); err = msgsend(CI_CLIB, "%w%w%w%w%w%w", CL_System|HtoT, DebugID, OSInfo1, OSInfo2, NoError, err); DevSW_FreePacket(packet); return err; } case CL_GetCmdLine: /* Returns the command line used to call the program */ { /* Note: we reuse the packet here, this may not always be desirable */ /* /* TODO: Use long buffers if possible */ DebugPrintF(("CL_GetCmdLine: \"%s\"\n", *(stateptr->CommandLine))); if (buffhead!=NULL) { len = strlen(*(stateptr->CommandLine)); if (len > Armsd_BufferSize-24) len = Armsd_BufferSize-24; packet->pk_length = len + msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_GetCmdLine|HtoT, DebugID, OSInfo1, OSInfo2, NoError, len); strncpy((char *) BUFFERDATA(buffhead)+24,*(stateptr->CommandLine), len); Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */ return 0; } else return -1; } case CL_Clock: /* Return the number of centiseconds since the support */ /* code started executing */ { time_t retTime = time(NULL); if (retTime == (time_t)-1) stateptr->last_errno = errno; else retTime *=100; DebugPrintF(("CL_Clock: %lu\n", retTime)); DebugCheckErr("time", TRUE, (retTime == (time_t)-1), stateptr->last_errno); DevSW_FreePacket(packet); return msgsend(CI_CLIB, "%w%w%w%w%w%w",CL_Clock|HtoT, DebugID, OSInfo1, OSInfo2, NoError, retTime); } case CL_Time: /* return time, in seconds since the start of 1970 */ { time_t retTime = time(NULL); if (retTime == (time_t)-1) stateptr->last_errno = errno; DebugPrintF(("CL_Time: %lu\n", retTime)); DebugCheckErr("time", TRUE, (retTime == (time_t)-1), stateptr->last_errno); DevSW_FreePacket(packet); return msgsend(CI_CLIB,"%w%w%w%w%w%w",CL_Time|HtoT, DebugID, OSInfo1, OSInfo2, NoError, retTime); } case CL_Remove: /* delete named in the null terminated string */ { /* Removing an open file will cause problems but once again * its not our problem, likely result is a tangled FileTable */ /* As the filename is passed with a null terminator we can use it * straight out of the buffer without copying it.*/ unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_Remove", TRUE, len, buffp+4); err=remove((char *)buffp+4); stateptr->last_errno = errno; DevSW_FreePacket(packet); DebugCheckErr("remove", TRUE, err, stateptr->last_errno); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Remove|HtoT, DebugID, OSInfo1, OSInfo2, err?-1:NoError); } case CL_Rename: /* rename file */ { /* Rename(word nbytes, bytes oname, word nbytes, bytes nname) * return(byte status) */ unsigned int len2; unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_Rename", FALSE, len, buffp+4); unpack_message(buffp+5+len, "%w", &len2); DebugCheckNullTermString("to", TRUE, len2, buffp+9+len); /* Both names are passed with null terminators so we can use them * directly from the buffer. */ err = rename((char *)buffp+4, (char *)buffp+9+len); stateptr->last_errno = errno; DebugCheckErr("rename", TRUE, err, stateptr->last_errno); DevSW_FreePacket(packet); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Rename|HtoT, DebugID, OSInfo1, OSInfo2, (err==0)? NoError : -1); } case CL_Open: /* open the file */ { /* Open(word nbytes, bytes name, byte mode) * return(word handle) */ unpack_message(buffp, "%w", &len); /* get the open mode */ unpack_message((buffp)+4+len+1, "%w", &mode); DebugCheckNullTermString("CL_Open", FALSE, len, buffp+4); DebugPrintF(("mode: %d\n", mode)); /* do some checking on the file first? */ /* check if its a tty */ if (strcmp((char *)buffp+4, ":tt")==0 && (mode==0||mode==1)) { /* opening tty "r" */ fhreal = stdin; stateptr->last_errno = errno; DebugPrintF(("\tstdin ")); } else if (strcmp((char *)buffp+4, ":tt")== 0 && (mode==4||mode==5)) { /* opening tty "w" */ fhreal = stdout; stateptr->last_errno = errno; DebugPrintF(("\tstdout ")); } else { fhreal = fopen((char *)buffp+4, fmode[mode&0xFF]); stateptr->last_errno = errno; DebugCheckNonNull("fopen", FALSE, fhreal, stateptr->last_errno); } DevSW_FreePacket(packet); c = NONHANDLE; if (fhreal != NULL) { /* update filetable */ for (c=3; c < HSYS_FOPEN_MAX; c++) { /* allow for stdin, stdout, stderr (!!! WHY? MJG) */ if (stateptr->OSptr->FileTable[c] == NULL) { stateptr->OSptr->FileTable[c]= fhreal; stateptr->OSptr->FileFlags[c]= mode & 1; DebugPrintF(("fh: %d\n", c)); break; } else if (c == HSYS_FOPEN_MAX) { /* no filehandles free */ DebugPrintF(("no free fh: %d\n", c)); stateptr->last_errno = EMFILE; } } } else { /* c = NULL;*/ DebugPrintF(("error fh: %d\n", c)); } (void) msgsend(CI_CLIB, "%w%w%w%w%w", CL_Open|HtoT, DebugID, OSInfo1, OSInfo2, c); return 0; } case CL_Close: /* close the file pointed to by the filehandle */ { unpack_message(buffp, "%w", &fh); DebugPrintF(("CL_Close: fh %d\n", fh)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) err = -1; else { if (fhreal == stdin || fhreal == stdout || fhreal == stderr) { stateptr->last_errno = errno; DebugPrintF(("\tskipping close of std*\n")); err = 0; } else { err = fclose(fhreal); if (err == 0) stateptr->OSptr->FileTable[fh]=NULL; stateptr->last_errno = errno; DebugCheckErr("fclose", TRUE, err, stateptr->last_errno); } } return msgsend(CI_CLIB,"%w%w%w%w%w", CL_Close|HtoT, DebugID, OSInfo1, OSInfo2, err); } case CL_Write: { /* Write(word handle, word nbtotal, word nbytes, bytes data) * return(word nbytes) * WriteX(word nbytes, bytes data) * return(word nbytes) */ unsigned char *rwdata = NULL, *rwhead = NULL; unsigned char *write_source = NULL; char flags; FILE *fhreal; unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */ err = -1; /* err == 0 is fwrite() error indication */ unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes); DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n", fh, nbtotal, nbytes)); fhreal = hsysGetRealFileHandle(stateptr, fh, &flags); nbtogo = nbtotal; /* deal with the file handle */ if (fhreal == NULL) err = 0; else { if (flags & READOP) fseek(fhreal,0,SEEK_CUR); stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP; nbtogo -= nbytes; if (nbtogo > 0) { write_source = rwdata = rwhead = (unsigned char *)malloc(nbtotal); if (rwhead == NULL) { fprintf(stderr, "OUT OF MEMORY at line %d in %s\n", __LINE__, __FILE__); return -1; } memcpy(rwdata, buffp+12, nbytes); rwdata += nbytes; } else write_source = buffp+12; } do { /* at least once!! */ if (nbtogo == 0 && err != 0) { /* Do the actual write! */ if (fhreal == stdout || fhreal == stderr) { stateptr->hostif->write(stateptr->hostif->hostosarg, (char *)write_source, nbtotal); } else err = fwrite(write_source, 1, nbtotal, fhreal); stateptr->last_errno = errno; DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno); } DevSW_FreePacket(packet); if (msgsend(CI_CLIB,"%w%w%w%w%w%w", ack_reason|HtoT, DebugID, OSInfo1, OSInfo2, (err == 0), nbtogo)) { fprintf(stderr, "COULD NOT REPLY at line %d in %s\n", __LINE__, __FILE__); if (rwhead != NULL) free(rwhead); return -1; } if (nbtogo == 0 || err == 0) { DebugPrintF(("\twrite complete - returning\n")); if (rwhead != NULL) free(rwhead); return 0; } else { /* await extension */ ack_reason = CL_WriteX; packet = DevSW_AllocatePacket(Armsd_BufferSize); if (packet == NULL) { fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n", __LINE__, __FILE__); if (rwhead != NULL) free(rwhead); return -1; } Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL); Adp_ChannelRead(CI_CLIB, &packet); Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleSysMessage, stateptr); buffhead = packet->pk_buffer; unpack_message(BUFFERDATA(buffhead), "%w%w%w%w%w", &reason_code, &DebugID, &OSInfo1, &OSInfo2, &nbytes); if (reason_code != (CL_WriteX|TtoH)) { DevSW_FreePacket(packet); free(rwhead); fprintf(stderr, "EXPECTING CL_WriteX GOT %u at line %d in %s\n", reason_code, __LINE__, __FILE__); return -1; } DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes)); memcpy(rwdata, BUFFERDATA(buffhead)+20, nbytes); rwdata += nbytes; nbtogo -= nbytes; } } while (TRUE); /* will return when done */ } case CL_WriteX: /* * NOTE: if we've got here something has gone wrong * CL_WriteX's should all be picked up within the * CL_Write loop, probably best to return an error here * do this for the moment just so we do actually return */ fprintf(stderr, "ERROR: unexpected CL_WriteX message received\n"); return -1; case CL_Read: { /* Read(word handle, word nbtotal) * return(word nbytes, word nbmore, bytes data) */ /* ReadX() * return(word nbytes, word nbmore, bytes data) */ unsigned char *rwdata, *rwhead; int gotlen; unsigned int max_data_in_buffer=Armsd_BufferSize-28; char flags; FILE *fhreal; unsigned int nbleft = 0, reason = CL_Read; err = NoError; unpack_message(buffp, "%w%w", &fh, &nbtotal); DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh, nbtotal)); rwdata = rwhead = (unsigned char *)malloc(nbtotal); if (rwdata == NULL) { fprintf(stderr, "OUT OF MEMORY at line %d in %s\n", __LINE__, __FILE__); DevSW_FreePacket(packet); return -1; } /* perform the actual read */ fhreal = hsysGetRealFileHandle(stateptr, fh, &flags); if (fhreal == NULL) { /* bad file handle */ err = -1; nbytes = 0; gotlen = 0; } else { if (flags & WRITEOP) fseek(fhreal,0,SEEK_CUR); stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP; if (isatty_(fhreal)) { /* reading from a tty, so do some nasty stuff, reading into rwdata */ if (angel_hostif->gets(stateptr->hostif->hostosarg, (char *)rwdata, nbtotal) != 0) gotlen = strlen((char *)rwdata); else gotlen = 0; stateptr->last_errno = errno; DebugPrintF(("ttyread %d\n", gotlen)); } else { /* not a tty, reading from a real file */ gotlen = fread(rwdata, 1, nbtotal, fhreal); stateptr->last_errno = errno; DebugCheckErr("fread", FALSE, (gotlen == 0), stateptr->last_errno); DebugPrintF(("(%d)\n", gotlen)); } } nbtogo = gotlen; do { /* at least once */ if ((unsigned int) nbtogo <= max_data_in_buffer) nbytes = nbtogo; else nbytes = max_data_in_buffer; nbtogo -= nbytes; /* last ReadX needs subtle adjustment to returned nbtogo */ if (nbtogo == 0 && err == NoError && reason == CL_ReadX) nbleft = nbtotal - gotlen; else nbleft = nbtogo; count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w%w", reason|HtoT, 0, ADP_HandleUnknown, ADP_HandleUnknown, err, nbytes, nbleft); if (err == NoError) { /* copy data into buffptr */ memcpy(BUFFERDATA(buffhead)+28, rwdata, nbytes); rwdata += nbytes; count += nbytes; } DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n", err, nbytes, nbtogo)); packet->pk_length = count; Adp_ChannelWrite(CI_CLIB, packet); if (nbtogo == 0 || err != NoError) { /* done */ free(rwhead); return 0; } else { /* await extension */ reason = CL_ReadX; packet = DevSW_AllocatePacket(Armsd_BufferSize); if (packet == NULL) { fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n", __LINE__, __FILE__); free(rwhead); return -1; } Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL); Adp_ChannelRead(CI_CLIB, &packet); Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleSysMessage, stateptr); buffhead = packet->pk_buffer; unpack_message(BUFFERDATA(buffhead),"%w", &reason_code); if (reason_code != (CL_ReadX|TtoH)) { fprintf(stderr, "EXPECTING CL_ReadX GOT %u at line %d in %s\n", reason_code, __LINE__, __FILE__); DevSW_FreePacket(packet); free(rwdata); return -1; } } } while (TRUE); /* will return above on error or when done */ } case CL_ReadX: /* If we're here something has probably gone wrong */ fprintf(stderr, "ERROR: Got unexpected CL_ReadX message\n"); return -1; case CL_Seek: { unpack_message(buffp, "%w%w", &fh, &posn); DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh, posn)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) err = -1; else { err = fseek(fhreal, posn, SEEK_SET); stateptr->last_errno = errno; DebugCheckErr("fseek", TRUE, err, stateptr->last_errno); } return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Seek|HtoT, DebugID, OSInfo1, OSInfo2, err); } case CL_Flen: { unpack_message(buffp, "%w", &fh); DebugPrintF(("CL_Flen: fh %d ", fh)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) fl = -1; else { posn = ftell(fhreal); if (fseek(fhreal, 0L, SEEK_END) < 0) { fl=-1; } else { fl = ftell(fhreal); fseek(fhreal, posn, SEEK_SET); } stateptr->last_errno = errno; } DebugPrintF(("returning len %ld\n", fl)); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Flen|HtoT, DebugID, OSInfo1, OSInfo2, fl); } case CL_IsTTY: { int ttyOrNot; unpack_message(buffp, "%w", &fh); DebugPrintF(("CL_IsTTY: fh %d ", fh)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) ttyOrNot = FALSE; else { ttyOrNot = isatty_(fhreal); stateptr->last_errno = errno; } DebugPrintF(("returning %s\n", ttyOrNot ? "tty (1)" : "not (0)")); return msgsend(CI_CLIB, "%w%w%w%w%w",CL_IsTTY|HtoT, DebugID, OSInfo1, OSInfo2, ttyOrNot); } case CL_TmpNam: { char *name; unsigned int tnamelen, TargetID; unpack_message(buffp, "%w%w", &tnamelen, &TargetID); DebugPrintF(("CL_TmpNam: tnamelen %d TargetID %d: ", tnamelen, TargetID)); DevSW_FreePacket(packet); TargetID = TargetID & 0xFF; if (stateptr->OSptr->TempNames[TargetID] == NULL) { if ((stateptr->OSptr->TempNames[TargetID] = (char *)malloc(L_tmpnam)) == NULL) { fprintf(stderr, "OUT OF MEMORY at line %d in %s\n", __LINE__, __FILE__); return -1; } tmpnam(stateptr->OSptr->TempNames[TargetID]); } name = stateptr->OSptr->TempNames[TargetID]; len = strlen(name) + 1; packet = DevSW_AllocatePacket(Armsd_BufferSize); if (packet == NULL) { fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n", __LINE__, __FILE__); return -1; } buffhead = packet->pk_buffer; if (len > tnamelen) { DebugPrintF(("TMPNAME TOO LONG!\n")); count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w", CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, -1); } else { DebugPrintF(("returning \"%s\"\n", name)); count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, 0, len); strcpy((char *)BUFFERDATA(buffhead)+count, name); count +=len+1; } packet->pk_length = count; Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */ return 0; } case CL_Unrecognised: DebugPrintF(("CL_Unrecognised!!\n")); return 0; default: fprintf(stderr, "UNRECOGNISED CL code %08x\n", reason_code); break; /* Need some sort of error handling here. */ /* A call to CL_Unrecognised should suffice */ } return -1; /* Stop a potential compiler warning */ }
int main(int argc, char* argv[]) { // blah blah blah option parsing // setup int unixSocket=createUnixSocket(DEFAULT_SERVER_SOCK); // select modifies the fd_sets, so we'll keep these as 'canonical' fd_set readfds; fd_set writefds; //Need? fd_set exceptfds; //pretty much everything FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); FD_SET(unixSocket, &readfds); FD_SET(unixSocket, &exceptfds); int maxfd=unixSocket+1; //to start, no other sockets //this will have to change to be able to handle signals and clean exits for (;;) { // Copy fd values for this loop fd_set readablefds; memcpy(&readablefds, &readfds, sizeof(fd_set)); fd_set writeablefds; memcpy(&writeablefds, &writefds, sizeof(fd_set)); fd_set exceptedfds; memcpy(&exceptedfds, &exceptfds, sizeof(fd_set)); //actually do the select //TODO: change this to pselect with signals, when we start to deal with // signals LOG(LOG_DEBUG,"About to select..."); select(maxfd, &readablefds, &writeablefds, &exceptedfds, NULL); LOG(LOG_DEBUG, "Done select"); // Now go through and look at the available fds to see what needs doing for (int i=0; i<maxfd; i++) { if (FD_ISSET(i, &readablefds)) { if (i==unixSocket) { int newfd = unixHandleAccept(i); if (newfd>0) { FD_SET(newfd,&readfds); FD_SET(newfd,&exceptfds); if (newfd>=maxfd) maxfd=newfd+1; LOG(LOG_DEBUG,"Handle %i added to select.",newfd); } else { LOG(LOG_WARNING, "Got bad handle back form unixHandleAccept()"); } } else { // is a general socket, read and display //first, find out how big the message is char *buf = NULL; int msgsize = recv(i, buf, 0, MSG_PEEK | MSG_TRUNC | MSG_DONTWAIT); // check that we didn't error if (msgsize==-1) { if (errno==EAGAIN || errno==EWOULDBLOCK) { //log information that this isn't working right LOG(LOG_NOTICE, "Socket %d misbehaving (would block); terminating: %s", i,strerror(errno)); } else { // its a real error; different message, level LOG(LOG_WARNING, "Socket %d has critical error; terminating (%s)", i, strerror(errno)); } FD_CLR(i,&readfds); FD_CLR(i,&exceptfds); destroyUnixSocket(i); // And pretend nothing happened continue; } //Allocate the correctly sized buffer buf = calloc(1,msgsize+1); // and repeat, but with trying to read the right size msgsize = recv(i, buf, msgsize, MSG_DONTWAIT); // check that we didn't error if (msgsize==-1) { if (errno==EAGAIN || errno==EWOULDBLOCK) { //log information that this isn't working right LOG(LOG_NOTICE, "Socket %d misbehaving (would block); terminating: %s", i,strerror(errno)); } else { // its a real error; different message, level LOG(LOG_WARNING, "Socket %d has critical error; terminating (%s)", i, strerror(errno)); } FD_CLR(i,&readfds); FD_CLR(i,&exceptfds); destroyUnixSocket(i); // And pretend nothing happened continue; } buf[msgsize]='\0'; //force trailing null byte // (This is paranoia, since turning the buffer into // a struct message promises it ends in a null byte in // the right places anyway) struct message *message_out = calloc( sizeof(struct message), 1); unpack_message(buf,msgsize, message_out); printf("Tag: %s\nMessage:%s\n", message_out->tag, message_out->message); free(buf); free(message_out->tag); free(message_out->message); } } if (FD_ISSET(i, &writeablefds)) { //do something? } if (FD_ISSET(i, &exceptedfds)) { if (i==unixSocket) { FD_CLR(unixSocket, &readfds); FD_CLR(unixSocket, &exceptfds); destroyUnixSocket(unixSocket); unixSocket=createUnixSocket(DEFAULT_SERVER_SOCK); FD_SET(unixSocket, &readfds); FD_SET(unixSocket, &exceptfds); if ( unixSocket >= maxfd) { maxfd = unixSocket+1; } } else { FD_CLR(i, &readfds); FD_CLR(i, &exceptfds); destroyUnixSocket(i); } } } } return 0; }