Example #1
0
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;
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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);
}
Example #5
0
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;
}
Example #6
0
/**
 *  \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;
}
Example #7
0
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;
}
Example #8
0
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);
}
Example #9
0
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
}
Example #10
0
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);
}
Example #11
0
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);
}
Example #12
0
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);
}
Example #13
0
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);
}
Example #14
0
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);
}
Example #15
0
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);
}
Example #16
0
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);
}
Example #17
0
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;
    }
}
Example #18
0
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);
    }
}
Example #19
0
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 */
}
Example #20
0
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;
}