static int send_challenge_ack(int fd, unsigned char digest[16], unsigned ms) { char *s; char buf[DEFBUF_SIZ]; int siz = 2 + 1 + 16; int res; s = buf; put16be(s,siz - 2); put8(s, 'a'); memcpy(s, digest, 16); if ((res = ei_write_fill_t(fd, buf, siz, ms)) != siz) { EI_TRACE_ERR0("recv_challenge_reply", "-> SEND_CHALLENGE_ACK socket write failed"); erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } if (ei_tracelevel >= 3) { char buffer[33]; EI_TRACE_CONN1("recv_challenge_reply", "-> SEND_CHALLENGE_ACK (ok) digest = %s",hex((char *)digest,buffer)); } return 0; }
static int send_status(int fd, char *status, unsigned ms) { char *buf, *s; char dbuf[DEFBUF_SIZ]; int siz = strlen(status) + 1 + 2; int res; buf = (siz > DEFBUF_SIZ) ? malloc(siz) : dbuf; if (!buf) { erl_errno = ENOMEM; return -1; } s = buf; put16be(s,siz - 2); put8(s, 's'); memcpy(s, status, strlen(status)); if ((res = ei_write_fill_t(fd, buf, siz, ms)) != siz) { EI_TRACE_ERR0("send_status","-> SEND_STATUS socket write failed"); if (buf != dbuf) free(buf); erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } EI_TRACE_CONN1("send_status","-> SEND_STATUS (%s)",status); if (buf != dbuf) free(buf); return 0; }
static int send_name_or_challenge(int fd, char *nodename, int f_chall, unsigned challenge, unsigned version, unsigned ms) { char *buf; unsigned char *s; char dbuf[DEFBUF_SIZ]; int siz = 2 + 1 + 2 + 4 + strlen(nodename); const char* function[] = {"SEND_NAME", "SEND_CHALLENGE"}; int res; if (f_chall) siz += 4; buf = (siz > DEFBUF_SIZ) ? malloc(siz) : dbuf; if (!buf) { erl_errno = ENOMEM; return -1; } s = (unsigned char *)buf; put16be(s,siz - 2); put8(s, 'n'); put16be(s, version); put32be(s, (DFLAG_EXTENDED_REFERENCES | DFLAG_EXTENDED_PIDS_PORTS | DFLAG_FUN_TAGS | DFLAG_NEW_FUN_TAGS | DFLAG_NEW_FLOATS)); if (f_chall) put32be(s, challenge); memcpy(s, nodename, strlen(nodename)); if ((res = ei_write_fill_t(fd, buf, siz, ms)) != siz) { EI_TRACE_ERR1("send_name_or_challenge", "-> %s socket write failed", function[f_chall]); if (buf != dbuf) free(buf); erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } if (buf != dbuf) free(buf); return 0; }
void es_openAudio(sdl_data *sd, int len, char *buff) { int sendlen; char *bp, *start; int ff; SDL_AudioSpec desired, obtained, *obptr; bp = buff; ff = get8(bp); desired.freq = get32be(bp); desired.format = get16be(bp); desired.channels = get8(bp); desired.samples = get16be(bp); desired.padding = get16be(bp); desired.callback = myaudiomixer; /* Init the global data structures */ wave.sound = NULL; wave.soundpos = 0; wave.soundlen = 0; if(ff == 1) /* Force the requested format */ obptr = NULL; else obptr = &obtained; bp = start = sdl_getbuff(sd, 16); if( SDL_OpenAudio(&desired, obptr) < 0 ) { fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); } else { if(ff == 1) obptr = &desired; put32be(bp, obptr->freq); put16be(bp, obptr->format); put8(bp, obptr->channels); put8(bp, obptr->silence); put16be(bp, obptr->samples); put16be(bp, obptr->padding); put32be(bp, obptr->size); wave.silence = obptr->silence; } sendlen = (int) (bp - start); sdl_send(sd, sendlen); }
void es_getModState(sdl_data *sd, int len,char *buff) { Uint16 state; if ((state = SDL_GetModState()) != 0) { int sendlen; char *bp, *start; bp = start = sdl_get_temp_buff(sd, 2); put16be(bp, state); sendlen = bp - start; sdl_send(sd, sendlen); } }
/* stop the specified node */ int ei_unpublish_tmo(const char *alive, unsigned ms) { char buf[EPMDBUF]; char *s = (char*)buf; int len = 1 + strlen(alive); int fd, res; if (len > sizeof(buf)-3) { erl_errno = ERANGE; return -1; } put16be(s,len); put8(s,EI_EPMD_STOP_REQ); strcpy(s, alive); /* FIXME can't connect, return success?! At least commen whats up */ if ((fd = ei_epmd_connect_tmo(NULL,ms)) < 0) return fd; if ((res = ei_write_fill_t(fd, buf, len+2,ms)) != len+2) { closesocket(fd); erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } EI_TRACE_CONN1("ei_unpublish_tmo","-> STOP %s",alive); if ((res = ei_read_fill_t(fd, buf, 7, ms)) != 7) { closesocket(fd); erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } closesocket(fd); buf[7]=(char)0; /* terminate the string */ if (!strcmp("STOPPED",(char *)buf)) { EI_TRACE_CONN0("ei_unpublish_tmo","<- STOPPED (success)"); return 0; } else if (!strcmp("NOEXIST",(char *)buf)) { EI_TRACE_ERR0("ei_unpublish_tmo","<- NOEXIST (failure)"); erl_errno = EIO; return -1; } else { EI_TRACE_ERR0("ei_unpublish_tmo","<- unknown (failure)"); erl_errno = EIO; return -1; /* this shouldn't happen */ } return 0; }
void es_loadWAV(sdl_data *sd, int len, char *bp) { int sendlen; char *name, *start; SDL_AudioSpec obtained; Uint8 * ptr; Uint32 blen; name = bp; bp = start = sdl_get_temp_buff(sd, 28); if(NULL != SDL_LoadWAV(name, &obtained, &ptr, &blen)) { put32be(bp, obtained.freq); put16be(bp, obtained.format); put8(bp, obtained.channels); put8(bp, obtained.silence); put16be(bp, obtained.samples); put16be(bp, obtained.padding); put32be(bp, obtained.size); PUSHGLPTR(ptr, bp); put32be(bp, blen); } sendlen = (int) (bp - start); sdl_send(sd, sendlen); }
int ei_encode_atom_len(char *buf, int *index, const char *p, int len) { char *s = buf + *index; char *s0 = s; /* This function is documented to truncate at MAXATOMLEN (256) */ if (len > MAXATOMLEN) len = MAXATOMLEN; if (!buf) s += 3; else { put8(s,ERL_ATOM_EXT); put16be(s,len); memmove(s,p,len); /* unterminated string */ } s += len; *index += s-s0; return 0; }
int ei_encode_boolean(char *buf, int *index, int p) { char *s = buf + *index; char *s0 = s; char *val; int len; val = p ? "true" : "false"; len = strlen(val); if (!buf) s += 3; else { put8(s,ERL_ATOM_EXT); put16be(s,len); memmove(s,val,len); /* unterminated string */ } s += len; *index += s-s0; return 0; }
/* Internals */ static char* encode_event(const SDL_Event * ev, char * bp) { switch(ev->type) { case SDL_ACTIVEEVENT: /* Application loses/gains visibility */ put8(bp, SDL_ACTIVEEVENT); put8(bp, ev->active.gain); put8(bp, ev->active.state); break; case SDL_KEYDOWN: /* Keys pressed */ case SDL_KEYUP: /* Keys released */ put8(bp, SDL_KEYDOWN); /* Using same for both */ put8(bp, ev->key.which); put8(bp, ev->key.state); put8(bp, ev->key.keysym.scancode); put16be(bp, ev->key.keysym.sym); put16be(bp, ev->key.keysym.mod); put16be(bp, ev->key.keysym.unicode); break; case SDL_MOUSEMOTION: /* Mouse moved */ put8(bp, SDL_MOUSEMOTION); put8(bp, ev->motion.which); put8(bp, ev->motion.state); put16be(bp, SDL_GetModState()); put16be(bp, ev->motion.x); put16be(bp, ev->motion.y); put16be(bp, ev->motion.xrel); put16be(bp, ev->motion.yrel); break; case SDL_MOUSEBUTTONDOWN:/* Mouse button pressed */ case SDL_MOUSEBUTTONUP:/* Mouse button released */ put8(bp, SDL_MOUSEBUTTONDOWN); put8(bp, ev->button.which); put8(bp, ev->button.button); put8(bp, ev->button.state); put16be(bp, SDL_GetModState()); put16be(bp, ev->button.x); put16be(bp, ev->button.y); break; case SDL_JOYAXISMOTION:/* Joystick axis motion */ put8(bp, SDL_JOYAXISMOTION); put8(bp, ev->jaxis.which); put8(bp, ev->jaxis.axis); put16be(bp, ev->jaxis.value); break; case SDL_JOYBALLMOTION:/* Joystick trackball motion */ put8(bp, SDL_JOYBALLMOTION); put8(bp, ev->jball.which); put8(bp, ev->jball.ball); put16be(bp, ev->jball.xrel); put16be(bp, ev->jball.yrel); break; case SDL_JOYHATMOTION:/* Joystick hat position change */ put8(bp, SDL_JOYHATMOTION); put8(bp, ev->jhat.which); put8(bp, ev->jhat.hat); put16be(bp, ev->jhat.value); break; case SDL_JOYBUTTONDOWN:/* Joystick button pressed */ case SDL_JOYBUTTONUP: /* Joystick button released */ put8(bp, SDL_JOYBUTTONDOWN); put8(bp, ev->jbutton.which); put8(bp, ev->jbutton.button); put8(bp, ev->jbutton.state); break; case SDL_QUIT: /* User-requested quit */ put8(bp, SDL_QUIT); break; case SDL_VIDEORESIZE: put8(bp, SDL_VIDEORESIZE); put16be(bp, ev->resize.w); put16be(bp, ev->resize.h); break; case SDL_VIDEOEXPOSE: put8(bp, SDL_VIDEOEXPOSE); break; case SDL_SYSWMEVENT: /* System specific event */ break; default: /* Forward compatible */ fprintf(stderr, "ESDL received unsupported event type %x \n", ev->type); put8(bp, SDL_NOEVENT); break; } return bp; }
/* this protocol is a lot more complex than the old one */ static int ei_epmd_r4_publish (int port, const char *alive, unsigned ms) { char buf[EPMDBUF]; char *s = buf; int fd; int elen = 0; int nlen = strlen(alive); int len = elen + nlen + 13; /* hard coded: be careful! */ int n; int res, creation; if (len > sizeof(buf)-2) { erl_errno = ERANGE; return -1; } s = buf; put16be(s,len); put8(s,EI_EPMD_ALIVE2_REQ); put16be(s,port); /* port number */ put8(s,'h'); /* h = r4 hidden node */ put8(s, EI_MYPROTO); /* protocol 0 ?? */ put16be(s,EI_DIST_HIGH); /* highest understood version: 1 = R4 */ put16be(s,EI_DIST_LOW); /* lowest: 0 = R3 */ put16be(s,nlen); /* length of alivename */ strcpy(s, alive); s += nlen; put16be(s,elen); /* length of extra string = 0 */ /* no extra string */ if ((fd = ei_epmd_connect_tmo(NULL,ms)) < 0) return fd; if ((res = ei_write_fill_t(fd, buf, len+2, ms)) != len+2) { closesocket(fd); erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } EI_TRACE_CONN6("ei_epmd_r4_publish", "-> ALIVE2_REQ alive=%s port=%d ntype=%d " "proto=%d dist-high=%d dist-low=%d", alive,port,'H',EI_MYPROTO,EI_DIST_HIGH,EI_DIST_LOW); if ((n = ei_read_fill_t(fd, buf, 4, ms)) != 4) { EI_TRACE_ERR0("ei_epmd_r4_publish","<- CLOSE"); closesocket(fd); erl_errno = (n == -2) ? ETIMEDOUT : EIO; return -2; /* version mismatch */ } /* Don't close fd here! It keeps us registered with epmd */ s = buf; if (((res=get8(s)) != EI_EPMD_ALIVE2_RESP)) { /* response */ EI_TRACE_ERR1("ei_epmd_r4_publish","<- unknown (%d)",res); EI_TRACE_ERR0("ei_epmd_r4_publish","-> CLOSE"); closesocket(fd); erl_errno = EIO; return -1; } EI_TRACE_CONN0("ei_epmd_r4_publish","<- ALIVE2_RESP"); if (((res=get8(s)) != 0)) { /* 0 == success */ EI_TRACE_ERR1("ei_epmd_r4_publish"," result=%d (fail)",res); closesocket(fd); erl_errno = EIO; return -1; } creation = get16be(s); EI_TRACE_CONN2("ei_epmd_r4_publish", " result=%d (ok) creation=%d",res,creation); /* probably should save fd so we can close it later... */ /* epmd_saveconn(OPEN,fd,alive); */ /* return the creation number, for no good reason */ /* return creation;*/ /* no - return the descriptor */ return fd; }
static int ei_epmd_r4_port (struct in_addr *addr, const char *alive, int *dist, unsigned ms) { char buf[EPMDBUF]; char *s = buf; int len = strlen(alive) + 1; int fd; int ntype; int port; int dist_high, dist_low, proto; int res; #if defined(VXWORKS) char ntoabuf[32]; #endif if (len > sizeof(buf) - 3) { erl_errno = ERANGE; return -1; } put16be(s,len); put8(s,EI_EPMD_PORT2_REQ); strcpy(s,alive); /* connect to epmd */ if ((fd = ei_epmd_connect_tmo(addr,ms)) < 0) { return -1; } if ((res = ei_write_fill_t(fd, buf, len+2, ms)) != len+2) { closesocket(fd); erl_errno = (res == -2) ? ETIMEDOUT : EIO; return -1; } #ifdef VXWORKS /* FIXME use union/macro for level. Correct level? */ if (ei_tracelevel > 2) { inet_ntoa_b(*addr,ntoabuf); EI_TRACE_CONN2("ei_epmd_r4_port", "-> PORT2_REQ alive=%s ip=%s",alive,ntoabuf); } #else EI_TRACE_CONN2("ei_epmd_r4_port", "-> PORT2_REQ alive=%s ip=%s",alive,inet_ntoa(*addr)); #endif /* read first two bytes (response type, response) */ if ((res = ei_read_fill_t(fd, buf, 2, ms)) != 2) { EI_TRACE_ERR0("ei_epmd_r4_port","<- CLOSE"); erl_errno = (res == -2) ? ETIMEDOUT : EIO; closesocket(fd); return -2; /* version mismatch */ } s = buf; res = get8(s); if (res != EI_EPMD_PORT2_RESP) { /* response type */ EI_TRACE_ERR1("ei_epmd_r4_port","<- unknown (%d)",res); EI_TRACE_ERR0("ei_epmd_r4_port","-> CLOSE"); closesocket(fd); erl_errno = EIO; return -1; } /* got negative response */ if ((res = get8(s))) { /* got negative response */ EI_TRACE_ERR1("ei_epmd_r4_port","<- PORT2_RESP result=%d (failure)",res); closesocket(fd); erl_errno = EIO; return -1; } EI_TRACE_CONN1("ei_epmd_r4_port","<- PORT2_RESP result=%d (ok)",res); /* expecting remaining 8 bytes */ if ((res = ei_read_fill_t(fd,buf,8,ms)) != 8) { EI_TRACE_ERR0("ei_epmd_r4_port","<- CLOSE"); erl_errno = (res == -2) ? ETIMEDOUT : EIO; closesocket(fd); return -1; } closesocket(fd); s = buf; port = get16be(s); ntype = get8(s); proto = get8(s); dist_high = get16be(s); dist_low = get16be(s); EI_TRACE_CONN5("ei_epmd_r4_port", " port=%d ntype=%d proto=%d dist-high=%d dist-low=%d", port,ntype,proto,dist_high,dist_low); /* right network protocol? */ if (EI_MYPROTO != proto) { erl_errno = EIO; return -1; } /* is there overlap in our distribution versions? */ if ((EI_DIST_HIGH < dist_low) || (EI_DIST_LOW > dist_high)) { erl_errno = EIO; return -1; } /* choose the highest common version */ /* i.e. min(his-max, my-max) */ *dist = (dist_high > EI_DIST_HIGH ? EI_DIST_HIGH : dist_high); /* ignore the remaining fields */ return port; }
int ei_encode_atom_len_as(char *buf, int *index, const char *p, int len, erlang_char_encoding from_enc, erlang_char_encoding to_enc) { char *s = buf + *index; char *s0 = s; int offs; if (len >= MAXATOMLEN && (from_enc & (ERLANG_LATIN1|ERLANG_ASCII))) { return -1; } switch(to_enc) { case ERLANG_LATIN1: if (buf) { put8(s,ERL_ATOM_EXT); switch (from_enc) { case ERLANG_UTF8: len = utf8_to_latin1(s+2, p, len, MAXATOMLEN-1, NULL); if (len < 0) return -1; break; case ERLANG_ASCII: if (verify_ascii_atom(p, len) < 0) return -1; memcpy(s+2, p, len); break; case ERLANG_LATIN1: memcpy(s+2, p, len); break; default: return -1; } put16be(s,len); } else { s += 3; if (from_enc == ERLANG_UTF8) { len = utf8_to_latin1(NULL, p, len, MAXATOMLEN-1, NULL); if (len < 0) return -1; } else if (from_enc == ERLANG_ASCII) if (verify_ascii_atom(p, len) < 0) return -1; } break; case ERLANG_UTF8: offs = 1 + 1; switch (from_enc) { case ERLANG_LATIN1: if (len >= 256/2) offs++; len = latin1_to_utf8((buf ? s+offs : NULL), p, len, MAXATOMLEN_UTF8-1, NULL); break; case ERLANG_ASCII: if (verify_ascii_atom(p, len) < 0) return -1; if (buf) memcpy(s+offs,p,len); break; case ERLANG_UTF8: if (len >= 256) offs++; if (verify_utf8_atom(p, len) < 0) return -1; if (buf) memcpy(s+offs,p,len); break; default: return -1; } if (buf) { if (offs == 2) { put8(s, ERL_SMALL_ATOM_UTF8_EXT); put8(s, len); } else { put8(s, ERL_ATOM_UTF8_EXT); put16be(s, len); } } else s+= offs; break; default: return -1; } s += len; *index += s-s0; return 0; }