static ssize_t handle_read( const int64 clientsocket ) { struct http_data* h = io_getcookie( clientsocket ); ssize_t l; if( ( l = io_tryread( clientsocket, static_inbuf, sizeof static_inbuf ) ) <= 0 ) { handle_dead( clientsocket ); return 0; } /* If we get the whole request in one packet, handle it without copying */ if( !array_start( &h->request ) ) { if( memchr( static_inbuf, '\n', l ) ) return http_handle_request( clientsocket, static_inbuf, l ); h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; array_catb( &h->request, static_inbuf, l ); return 0; } h->flag |= STRUCT_HTTP_FLAG_ARRAY_USED; array_catb( &h->request, static_inbuf, l ); if( array_failed( &h->request ) ) return http_issue_error( clientsocket, CODE_HTTPERROR_500 ); if( ( array_bytes( &h->request ) > 8192 ) && !accesslist_isblessed( (char*)&h->ip, OT_PERMISSION_MAY_SYNC ) ) return http_issue_error( clientsocket, CODE_HTTPERROR_500 ); if( memchr( array_start( &h->request ), '\n', array_bytes( &h->request ) ) ) return http_handle_request( clientsocket, array_start( &h->request ), array_bytes( &h->request ) ); return 0; }
int sv_stat(sv_stat_t *svst, char *path) { array_t full_path = ARRAY_INIT(1); int ok_fd; struct stat st; int status_fd; int32_t tmp; /* Check if 'down' exist indicating that the service isn't started when * supervise starts up. */ if (array_path(&full_path, path, "down")) { array_reset(&full_path); errno = ENOMEM; return -1; } if (stat(array_start(&full_path), &st) == -1) { if (errno != ENOENT) { array_reset(&full_path); return ESVSTATDOWN; } svst->autostart = 1; } else svst->autostart = 0; /* Attempt to open the supervise/ok fifo to see if supervise is actually * running. */ if (array_path(&full_path, path, SUPERVISE_OK_PATH)) { array_reset(&full_path); errno = ENOMEM; return -1; } ok_fd = open_write(array_start(&full_path)); if (ok_fd == -1) { array_reset(&full_path); if (errno == ENODEV) return ESVNOTRUN; return ESVOPENOK; } close(ok_fd); /* Load the contents of the supervise/status file. */ if (array_path(&full_path, path, SUPERVISE_STATUS_PATH)) { array_reset(&full_path); errno = ENOMEM; return -1; } if (sv_stat_load(svst, array_start(&full_path)) == -1) { array_reset(&full_path); return -1; } array_reset(&full_path); return 0; }
void fmt_tofrom_array(unsigned long (*func)(char*,const char*,unsigned long), array* dest,array* src) { unsigned long needed; char* x; if (array_failed(dest) || array_failed(src)) { array_fail(dest); return; } needed=func(0,array_start(src),array_bytes(src)); if (array_allocate(dest,1,array_bytes(dest)+needed-1)) { x=((char*)array_start(dest))+array_bytes(dest)-needed; func(x,array_start(src),array_bytes(src)); } else array_fail(dest); }
void fmt_tofrom_array(size_t (*func)(char*,const char*,size_t), array* dest,array* src) { size_t needed; char* x; if (array_failed(dest) || array_failed(src)) { array_fail(dest); return; } needed=func(0,array_start(src),array_bytes(src)); if (array_bytes(dest)+needed>needed && array_allocate(dest,1,array_bytes(dest)+needed-1)) { x=((char*)array_start(dest))+array_bytes(dest)-needed; func(x,array_start(src),array_bytes(src)); } else array_fail(dest); }
size_t scan_tofrom_array(size_t (*func)(const char*,char*,size_t*), array* src,array* dest) { size_t scanned; size_t needed; char* x; array_cat0(src); if (array_failed(src) || array_failed(dest)) return 0; needed=array_bytes(src); x=((char*)array_start(dest))+array_bytes(dest); if (!array_allocate(dest,1,array_bytes(dest)+needed-1)) return 0; needed=func(array_start(src),x,&scanned); array_truncate(src,1,array_bytes(src)-1); return needed; }
int sv_stat_save(char *path, sv_stat_t *svst) { int fd; array_t new_path = ARRAY_INIT(1); int r; char status[SUPERVISE_STATUS_SIZE]; uint32_t tmp; /* Pack the svstat data into the status byte array. */ taia_pack(status, &svst->timestamp); tmp = svst->pid; ((uint32_t *)status)[3] = htobe32(tmp); status[16] = svst->paused; status[17] = svst->mode; /* Construct the path for the .new file into the array which *MUST* be freed * before returning. */ array_append(&new_path, path, strlen(path)); array_append(&new_path, SUPERVISE_STATUS_NEW_EXT, strlen(SUPERVISE_STATUS_NEW_EXT)); array_append_null(&new_path); if (array_failed(&new_path)) { array_reset(&new_path); errno = ENOMEM; return -1; } /* Open the tmp file, write the status byte array to it, verify the entire * array was written, and finally rename it to status. */ fd = open_trunc(array_start(&new_path)); if (fd == -1) { array_reset(&new_path); return ESVOPENSTATNEW; } r = write(fd, status, SUPERVISE_STATUS_SIZE); if ((r == -1) || (r != SUPERVISE_STATUS_SIZE)) { close(fd); array_reset(&new_path); return ESVWRITESTATNEW; } close(fd); if (rename(array_start(&new_path), path) == -1) { array_reset(&new_path); return ESVWRITESTAT; } array_reset(&new_path); return 0; }
/** * Compress data in ZIP buffer and move result to the write buffer of * the connection. * This function closes the connection on error. * @param Idx Connection handle. * @return true on success, false otherwise. */ GLOBAL bool Zip_Flush( CONN_ID Idx ) { int result; unsigned char zipbuf[WRITEBUFFER_SLINK_LEN]; int zipbuf_used = 0; z_stream *out; out = &My_Connections[Idx].zip.out; out->avail_in = (uInt)array_bytes(&My_Connections[Idx].zip.wbuf); if (!out->avail_in) return true; /* nothing to do. */ out->next_in = array_start(&My_Connections[Idx].zip.wbuf); assert(out->next_in != NULL); out->next_out = zipbuf; out->avail_out = (uInt)sizeof zipbuf; #ifdef DEBUG_ZIP Log(LOG_DEBUG, "out->avail_in %d, out->avail_out %d", out->avail_in, out->avail_out); #endif result = deflate( out, Z_SYNC_FLUSH ); if(( result != Z_OK ) || ( out->avail_in > 0 )) { Log( LOG_ALERT, "Compression error: code %d!?", result ); Conn_Close( Idx, "Compression error!", NULL, false ); return false; } if (out->avail_out <= 0) { /* Not all data was compressed, because data became * bigger while compressing it. */ Log(LOG_ALERT, "Compression error: buffer overflow!?"); Conn_Close(Idx, "Compression error!", NULL, false); return false; } assert(out->avail_out <= WRITEBUFFER_SLINK_LEN); zipbuf_used = WRITEBUFFER_SLINK_LEN - out->avail_out; #ifdef DEBUG_ZIP Log(LOG_DEBUG, "zipbuf_used: %d", zipbuf_used); #endif if (!array_catb(&My_Connections[Idx].wbuf, (char *)zipbuf, (size_t) zipbuf_used)) { Log (LOG_ALERT, "Compression error: can't copy data!?"); Conn_Close(Idx, "Compression error!", NULL, false); return false; } My_Connections[Idx].bytes_out += zipbuf_used; My_Connections[Idx].zip.bytes_out += array_bytes(&My_Connections[Idx].zip.wbuf); array_trunc(&My_Connections[Idx].zip.wbuf); return true; } /* Zip_Flush */
GLOBAL char * Channel_Topic( CHANNEL *Chan ) { char *ret; assert( Chan != NULL ); ret = array_start(&Chan->topic); return ret ? ret : ""; } /* Channel_Topic */
unsigned long scan_to_array(unsigned long (*func)(const char*,char*,unsigned long*), const char* src,array* dest) { unsigned long scanned; unsigned long needed=str_len(src); char* x=((char*)array_start(dest))+array_bytes(dest); if (!array_allocate(dest,1,array_bytes(dest)+needed-1)) return 0; return func(src,x,&scanned); }
/** * Send help for a given topic to the client. * * @param Client The client requesting help. * @param Topic The help topic requested. * @return CONNECTED or DISCONNECTED. */ static bool Help(CLIENT *Client, const char *Topic) { char *line; size_t helptext_len, len_str, idx_start, lines = 0; bool in_article = false; assert(Client != NULL); assert(Topic != NULL); helptext_len = array_bytes(&Conf_Helptext); line = array_start(&Conf_Helptext); while (helptext_len > 0) { len_str = strlen(line) + 1; assert(helptext_len >= len_str); helptext_len -= len_str; if (in_article) { /* The first character in each article text line must * be a TAB (ASCII 9) character which will be stripped * in the output. If it is not a TAB, the end of the * article has been reached. */ if (line[0] != '\t') { if (lines > 0) return CONNECTED; else break; } /* A single '.' character indicates an empty line */ if (line[1] == '.' && line[2] == '\0') idx_start = 2; else idx_start = 1; if (!IRC_WriteStrClient(Client, "NOTICE %s :%s", Client_ID(Client), &line[idx_start])) return DISCONNECTED; lines++; } else { if (line[0] == '-' && line[1] == ' ' && strcasecmp(&line[2], Topic) == 0) in_article = true; } line += len_str; } /* Help topic not found (or empty)! */ if (!IRC_WriteStrClient(Client, "NOTICE %s :No help for \"%s\" found!", Client_ID(Client), Topic)) return DISCONNECTED; return CONNECTED; }
static void http_senddata( const int64 sock, struct ot_workstruct *ws ) { struct http_data *cookie = io_getcookie( sock ); ssize_t written_size; if( !cookie ) { io_close(sock); return; } /* whoever sends data is not interested in its input-array */ if( ws->keep_alive && ws->header_size != ws->request_size ) { size_t rest = ws->request_size - ws->header_size; if( array_start(&cookie->request) ) { memmove( array_start(&cookie->request), ws->request + ws->header_size, rest ); array_truncate( &cookie->request, 1, rest ); } else array_catb(&cookie->request, ws->request + ws->header_size, rest ); } else array_reset( &cookie->request ); written_size = write( sock, ws->reply, ws->reply_size ); if( ( written_size < 0 ) || ( ( written_size == ws->reply_size ) && !ws->keep_alive ) ) { array_reset( &cookie->request ); free( cookie ); io_close( sock ); return; } if( written_size < ws->reply_size ) { char * outbuf; tai6464 t; if( !( outbuf = malloc( ws->reply_size - written_size ) ) ) { array_reset( &cookie->request ); free(cookie); io_close( sock ); return; } memcpy( outbuf, ws->reply + written_size, ws->reply_size - written_size ); iob_addbuf_free( &cookie->batch, outbuf, ws->reply_size - written_size ); /* writeable short data sockets just have a tcp timeout */ if( !ws->keep_alive ) { taia_uint( &t, 0 ); io_timeout( sock, t ); io_dontwantread( sock ); } io_wantwrite( sock ); } }
void fmt_to_array(size_t (*func)(char*,const char*,size_t), array* a,const char* src,size_t len) { size_t needed=func(0,src,len); if (array_bytes(a)+needed>=needed && array_allocate(a,1,array_bytes(a)+needed-1)) { char* x=((char*)array_start(a))+array_bytes(a)-needed; func(x,src,len); } else array_fail(a); }
static void print_strarray(buffer* b, array* a) { size_t i, n = array_length(a, sizeof(char *)); char** x = array_start(a); for(i = 0; i < n; ++i) { char* s = x[i]; if(s == 0) break; buffer_puts(b, x[i]); buffer_putc(b, '\n'); } buffer_flush(b); }
static int fnmatch_strarray(buffer* b, array* a, const char* string, int flags) { size_t i, n = array_length(a, sizeof(char *)); char** x = array_start(a); int ret = FNM_NOMATCH; for(i = 0; i < n; ++i) { char* s = x[i]; if(s == 0) break; if((ret = fnmatch(s, string, flags)) != FNM_NOMATCH) break; } return ret; }
GLOBAL bool Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key) { char *file_name, line[COMMAND_LEN], *nick, *pass; FILE *fd; assert(Chan != NULL); assert(Client != NULL); assert(Key != NULL); if (!Channel_HasMode(Chan, 'k')) return true; if (*Key == '\0') return false; if (strcmp(Chan->key, Key) == 0) return true; file_name = array_start(&Chan->keyfile); if (!file_name) return false; fd = fopen(file_name, "r"); if (!fd) { Log(LOG_ERR, "Can't open channel key file \"%s\" for %s: %s", file_name, Chan->name, strerror(errno)); return false; } while (fgets(line, (int)sizeof(line), fd) != NULL) { ngt_TrimStr(line); if (! (nick = strchr(line, ':'))) continue; *nick++ = '\0'; if (!Match(line, Client_User(Client))) continue; if (! (pass = strchr(nick, ':'))) continue; *pass++ = '\0'; if (!Match(nick, Client_ID(Client))) continue; if (strcmp(Key, pass) != 0) continue; fclose(fd); return true; } fclose(fd); return false; } /* Channel_CheckKey */
int sv_start_log(char *path) { array_t sa = ARRAY_INIT(1); char *path_log; int r; array_append(&sa, path, strlen(path)); if (path[strlen(path) - 1] != '/') array_append(&sa, "/", 1); array_append(&sa, "log", 3); array_append_null(&sa); path_log = array_start(&sa); r = sv_start(path_log); array_reset(&sa); return r; }
int sv_restart_log(char *path, int timeout) { array_t sa = ARRAY_INIT(1); char *path_log; int r; /* Create a dynamic storage array to contain the full path to the log * directory which MUST be freed before returning. */ array_append(&sa, path, strlen(path)); if (path[strlen(path) - 1] == '/') array_append(&sa, "/", 1); array_append(&sa, "log", 3); array_append_null(&sa); path_log = array_start(&sa); r = sv_restart(path_log, timeout); array_reset(&sa); return r; }
/** * Create a compact form of the specified call stack. * One int per frame containing * the method number and current offset. If the ignore parameter is non null * then frames that have a matching this field will not be included in the * trace. This allow the frames for the creation of an exception object to * be ignored. */ Object * create_stack_trace(Thread *thread, Object *ignore) { int frameCnt = thread->stackFrameIndex; Object *stackArray; JINT *data; int i; StackFrame *topFrame = ((StackFrame *)array_start(thread->stackFrameArray)) + frameCnt; StackFrame *stackFrame = topFrame; MethodRecord *methodBase = get_method_table(get_class_record(0)); byte *pcBase = get_binary_base() + 2; // Ignore frames if required. if (ignore) { while ((STACKWORD)ignore == *(stackFrame->localsBase)) { stackFrame--; frameCnt--; } } // Try and allocate the space for the trace. stackArray = new_single_array(AI, frameCnt); if (stackArray == JNULL) return JNULL; if (thread == currentThread) topFrame->pc = getPc(); // adjust top most pc to allow for return address hack topFrame->pc += 2; // Fill in the trace. data = jint_array(stackArray); for(i = 0; i < frameCnt; i++) { data[i] = ((stackFrame->methodRecord - methodBase) << 16) | (stackFrame->pc - pcBase - stackFrame->methodRecord->codeOffset); stackFrame--; } // restore correct pc topFrame->pc -= 2; return stackArray; }
static int pem_passwd_cb(char *buf, int size, int rwflag, void *password) { array *pass = password; int passlen; (void)rwflag; /* rwflag is unused if DEBUG is not set. */ assert(rwflag == 0); /* 0 -> callback used for decryption. * See SSL_CTX_set_default_passwd_cb(3) */ passlen = (int) array_bytes(pass); LogDebug("pem_passwd_cb buf size %d, array size %d", size, passlen); assert(passlen >= 0); if (passlen <= 0) { Log(LOG_ERR, "PEM password required but not set [in pem_passwd_cb()]!"); return 0; } size = passlen > size ? size : passlen; memcpy(buf, (char *)(array_start(pass)), size); return size; }
int main() { array_t array = ARRAY_INIT(1); char buf[FMT_ULONG_MAX + 1]; int r; for (;;) { array_reset(&array); r = bio_get_line(&array, bio_0); if (r <= 0) break; buf[fmt_ulong(buf, r)] = 0; array_append_null(&array); bio_put_str(bio_1, buf); bio_put_str(bio_1, " - "); bio_put_str(bio_1, array_start(&array)); bio_put_str(bio_1, "\n"); bio_flush(bio_1); } return 0; }
int64 io_waituntil2(int64 milliseconds) { #ifndef __MINGW32__ struct pollfd* p; #endif long i,j,r; if (!io_wanted_fds) return 0; #ifdef HAVE_EPOLL if (io_waitmode==EPOLL) { int n; struct epoll_event y[50]; if ((n=epoll_wait(io_master,y,50,milliseconds))==-1) return -1; int first_new = -1; int last_new = -1; for (i=n-1; i>=0; --i) { io_entry* e=array_get(&io_fds,sizeof(io_entry),y[i].data.fd); if (e) { if (y[i].events&(EPOLLERR|EPOLLHUP)) { /* error; signal whatever app is looking for */ if (e->wantread) y[i].events|=EPOLLIN; if (e->wantwrite) y[i].events|=EPOLLOUT; } #ifdef EPOLLRDNORM if (y[i].data.fd == io_master && !e->canread && (y[i].events&(EPOLLIN|EPOLLPRI|EPOLLRDNORM|EPOLLRDBAND))) { #else if (y[i].data.fd == io_master && !e->canread && (y[i].events&(EPOLLIN|EPOLLPRI))) { #endif e->canread=1; e->next_read=first_new; if(first_new == -1) last_new = y[i].data.fd; first_new=y[i].data.fd; } } } //if(n > 1) printf("n: %d\n", n); for (i=n-1; i>=0; --i) { //for (i=0; i < n; i++) { io_entry* e=array_get(&io_fds,sizeof(io_entry),y[i].data.fd); if (e) { #ifdef EPOLLRDNORM if (!e->canread && (y[i].events&(EPOLLIN|EPOLLPRI|EPOLLRDNORM|EPOLLRDBAND))) { #else if (!e->canread && (y[i].events&(EPOLLIN|EPOLLPRI))) { #endif e->canread=1; e->next_read=first_readable; first_readable=y[i].data.fd; } if (!e->canwrite && (y[i].events&EPOLLOUT)) { e->canwrite=-1; e->next_write=first_writeable; first_writeable=y[i].data.fd; } } else { epoll_ctl(io_master,EPOLL_CTL_DEL,y[i].data.fd,y+i); } } // if there are new connections, put them first... if(last_new != -1) { if(first_readable != -1) { io_entry* e=array_get(&io_fds,sizeof(io_entry),last_new); e->next_read=first_readable; } first_readable = first_new; } return n; } #endif #ifdef HAVE_KQUEUE if (io_waitmode==KQUEUE) { struct kevent y[100]; int n; struct timespec ts; ts.tv_sec=milliseconds/1000; ts.tv_nsec=(milliseconds%1000)*1000000; if ((n=kevent(io_master,0,0,y,100,milliseconds!=-1?&ts:0))==-1) return -1; for (i=n-1; i>=0; --i) { io_entry* e=array_get(&io_fds,sizeof(io_entry),y[--n].ident); #ifdef DEBUG if (!e) { e=e; } #endif if (e) { if (y[n].flags&EV_ERROR) { /* error; signal whatever app is looking for */ if (e->wantread) y[n].filter=EVFILT_READ; else if (e->wantwrite) y[n].filter=EVFILT_WRITE; } if (!e->canread && (y[n].filter==EVFILT_READ)) { e->canread=1; e->next_read=first_readable; first_readable=y[n].ident; } if (!e->canwrite && (y[n].filter==EVFILT_WRITE)) { e->canwrite=1; e->next_write=first_writeable; first_writeable=y[i].ident; } #ifdef DEBUG } else { fprintf(stderr,"got kevent on fd#%d, which is not in array!\n",y[n].ident); #endif } } return n; } #endif #ifdef HAVE_DEVPOLL if (io_waitmode==DEVPOLL) { dvpoll_t timeout; struct pollfd y[100]; int n; timeout.dp_timeout=milliseconds; timeout.dp_nfds=100; timeout.dp_fds=y; if ((n=ioctl(io_master,DP_POLL,&timeout))==-1) return -1; for (i=n-1; i>=0; --i) { io_entry* e=array_get(&io_fds,sizeof(io_entry),y[--n].fd); if (e) { if (y[n].revents&(POLLERR|POLLHUP|POLLNVAL)) { /* error; signal whatever app is looking for */ if (e->wantread) y[n].revents=POLLIN; if (e->wantwrite) y[n].revents=POLLOUT; } if (!e->canread && (y[n].revents&POLLIN)) { e->canread=1; if (e->next_read==-1) { e->next_read=first_readable; first_readable=y[n].fd; } } if (!e->canwrite && (y[n].revents&POLLOUT)) { e->canwrite=1; if (e->next_write==-1) { e->next_write=first_writeable; first_writeable=y[i].fd; } } #ifdef DEBUG } else { fprintf(stderr,"got kevent on fd#%d, which is not in array!\n",y[n].fd); #endif } } return n; } #endif #ifdef HAVE_SIGIO if (io_waitmode==_SIGIO) { siginfo_t info; struct timespec ts; int r; io_entry* e; if (alt_firstread>=0 && (e=array_get(&io_fds,sizeof(io_entry),alt_firstread)) && e->canread) return 1; if (alt_firstwrite>=0 && (e=array_get(&io_fds,sizeof(io_entry),alt_firstwrite)) && e->canwrite) return 1; if (milliseconds==-1) r=sigwaitinfo(&io_ss,&info); else { ts.tv_sec=milliseconds/1000; ts.tv_nsec=(milliseconds%1000)*1000000; r=sigtimedwait(&io_ss,&info,&ts); } switch (r) { case SIGIO: /* signal queue overflow */ signal(io_signum,SIG_DFL); goto dopoll; default: if (r==io_signum) { io_entry* e=array_get(&io_fds,sizeof(io_entry),info.si_fd); if (e) { if (info.si_band&(POLLERR|POLLHUP)) { /* error; signal whatever app is looking for */ if (e->wantread) info.si_band|=POLLIN; if (e->wantwrite) info.si_band|=POLLOUT; } if (info.si_band&POLLIN && !e->canread) { debug_printf(("io_waituntil2: enqueueing %ld in normal read queue before %ld\n",info.si_fd,first_readable)); e->canread=1; e->next_read=first_readable; first_readable=info.si_fd; } if (info.si_band&POLLOUT && !e->canwrite) { debug_printf(("io_waituntil2: enqueueing %ld in normal write queue before %ld\n",info.si_fd,first_writeable)); e->canwrite=1; e->next_write=first_writeable; first_writeable=info.si_fd; } #ifdef DEBUG } else { fprintf(stderr,"got kevent on fd#%d, which is not in array!\n",info.si_fd); #endif } } } return 1; } dopoll: #endif #ifdef __MINGW32__ DWORD numberofbytes; ULONG_PTR x; LPOVERLAPPED o; if (first_readable!=-1 || first_writeable!=-1) { fprintf(stderr,"io_waituntil2() returning immediately because first_readable(%p) or first_writeable(%p) are set\n",first_readable,first_writeable); return; } fprintf(stderr,"Calling GetQueuedCompletionStatus %p...",io_comport); if (GetQueuedCompletionStatus(io_comport,&numberofbytes,&x,&o,milliseconds==-1?milliseconds:INFINITE)) { io_entry* e=array_get(&io_fds,sizeof(io_entry),x); fprintf(stderr," OK. Got %x, e=%p\n",x,e); if (!e) return 0; e->errorcode=0; fprintf(stderr,"o=%p, e->or=%p, e->ow=%p, e->os=%p\n",o,&e->or,&e->ow,&e->os); fprintf(stderr,"e->readqueued=%d, e->writequeued=%d, e->acceptqueued=%d, e->connectqueued=%d, e->sendfilequeued=%d\n", e->readqueued,e->writequeued,e->acceptqueued,e->connectqueued,e->sendfilequeued); if (o==&e->or && e->readqueued==1) { e->readqueued=2; e->canread=1; e->bytes_read=numberofbytes; e->next_read=first_readable; first_readable=x; // printf("read %lu bytes on fd %lu: %p\n",numberofbytes,x,e); } else if (o==&e->ow && e->writequeued==1) { e->writequeued=2; e->canwrite=1; e->bytes_written=numberofbytes; e->next_write=first_writeable; first_writeable=x; } else if (o==&e->or && e->acceptqueued==1) { e->acceptqueued=2; e->canread=1; e->next_read=first_readable; first_readable=x; } else if (o==&e->ow && e->connectqueued==1) { e->connectqueued=2; e->canwrite=1; e->next_write=first_writeable; first_writeable=x; } else if (o==&e->os && e->sendfilequeued==1) { e->sendfilequeued=2; e->canwrite=1; e->bytes_written=numberofbytes; e->next_write=first_writeable; first_writeable=x; } return 1; } else { /* either the overlapped I/O request failed or we timed out */ DWORD err; io_entry* e; fprintf(stderr," failure, o=%p.\n",o); if (!o) return 0; /* timeout */ /* we got a completion packet for a failed I/O operation */ err=GetLastError(); if (err==WAIT_TIMEOUT) return 0; /* or maybe not */ e=array_get(&io_fds,sizeof(io_entry),x); if (!e) return 0; /* WTF?! */ e->errorcode=err; if (o==&e->or && (e->readqueued || e->acceptqueued)) { if (e->readqueued) e->readqueued=2; else if (e->acceptqueued) e->acceptqueued=2; e->canread=1; e->bytes_read=-1; e->next_read=first_readable; first_readable=x; } else if ((o==&e->ow || o==&e->os) && (e->writequeued || e->connectqueued || e->sendfilequeued)) { if (o==&e->ow) { if (e->writequeued) e->writequeued=2; else if (e->connectqueued) e->connectqueued=2; } else if (o==&e->os) e->sendfilequeued=2; e->canwrite=1; e->bytes_written=-1; e->next_write=first_writeable; first_writeable=x; } return 1; } #else for (i=r=0; i<array_length(&io_fds,sizeof(io_entry)); ++i) { io_entry* e=array_get(&io_fds,sizeof(io_entry),i); if (!e) return -1; e->canread=e->canwrite=0; if (e->wantread || e->wantwrite) { struct pollfd* p; if ((p=array_allocate(&io_pollfds,sizeof(struct pollfd),r))) { p->fd=i; p->events=(e->wantread?POLLIN:0) + (e->wantwrite?POLLOUT:0); ++r; } else return -1; } } p=array_start(&io_pollfds); if ((i=poll(array_start(&io_pollfds),r,milliseconds))<1) return -1; for (j=r-1; j>=0; --j) { io_entry* e=array_get(&io_fds,sizeof(io_entry),p->fd); if (p->revents&(POLLERR|POLLHUP|POLLNVAL)) { /* error; signal whatever app is looking for */ if (e->wantread) p->revents|=POLLIN; if (e->wantwrite) p->revents|=POLLOUT; } if (!e->canread && (p->revents&POLLIN)) { e->canread=1; e->next_read=first_readable; first_readable=p->fd; } if (!e->canwrite && (p->revents&POLLOUT)) { e->canwrite=1; e->next_write=first_writeable; first_writeable=p->fd; } p++; } return i; #endif }
/** * @param classRecord Record for method class. * @param methodRecord Calle's method record. * @param retAddr What the PC should be upon return. * @return true iff the stack frame was pushed. */ boolean dispatch_special (MethodRecord *methodRecord, byte *retAddr) { /** * Note: This code is a little tricky, particularly when used with * a garbage collector. It manipulates the stack frame and in some cases * may need to perform memory allocation. In all cases we must take care * to ensure that if an allocation can be made then any live objects * on the stack must be below the current stack pointer. * In addition to the above we take great care so that this function can * be restarted (to allow us to wait for available memory). To enable this * we avoid making any commitments to changes to global state until both * stacks have been commited. */ #if DEBUG_METHODS int debug_ctr; #endif Object *stackFrameArray; StackFrame *stackFrame; StackFrame *stackBase; int newStackFrameIndex; STACKWORD *newStackTop; #if DEBUG_BYTECODE printf("call method %d ret %x\n", methodRecord - get_method_table(get_class_record(0)), retAddr); printf ("\n------ dispatch special - %d ------------------\n\n", methodRecord->signatureId); #endif #if DEBUG_METHODS printf ("dispatch_special: %d, %d\n", (int) methodRecord, (int) retAddr); printf ("-- signature id = %d\n", methodRecord->signatureId); printf ("-- code offset = %d\n", methodRecord->codeOffset); printf ("-- flags = %d\n", methodRecord->mflags); printf ("-- num params = %d\n", methodRecord->numParameters); //printf ("-- stack ptr = %d\n", (int) get_stack_ptr()); //printf ("-- max stack ptr= %d\n", (int) (currentThread->stackArray + (get_array_size(currentThread->stackArray))*2)); #endif // First deal with the easy case of a native call... if (is_native (methodRecord)) { #if DEBUG_METHODS printf ("-- native\n"); #endif // WARNING: Once the instruction below has been executed we may have // references on the stack that are above the stack pointer. If a GC // gets run when in this state the reference may get collected as // grabage. This means that any native functions that take a reference // parameter and that may end up allocating memory *MUST* protect that // reference before calling the allocator... pop_words_cur (methodRecord->numParameters); switch(dispatch_native (methodRecord->signatureId, get_stack_ptr_cur() + 1)) { case EXEC_RETRY: // Need to re-start the instruction, so reset the state of the stack curStackTop += methodRecord->numParameters; break; case EXEC_CONTINUE: // Normal completion return to the requested point. curPc = retAddr; break; case EXEC_RUN: // We are running new code, curPc will be set. Nothing to do. break; case EXEC_EXCEPTION: // An exception has been thrown. The PC will be set correctly and // the stack may have been adjusted... break; } // Stack frame not pushed return false; } // Now start to build the new stack frames. We start by placing the // the new stack pointer below any params. The params will become locals // in the new frame. newStackTop = get_stack_ptr_cur() - methodRecord->numParameters; newStackFrameIndex = (int)(byte)currentThread->stackFrameIndex; if (newStackFrameIndex >= 255) { throw_new_exception (JAVA_LANG_STACKOVERFLOWERROR); return false; } #if DEBUG_METHODS //for (debug_ctr = 0; debug_ctr < methodRecord->numParameters; debug_ctr++) // printf ("-- param[%d] = %ld\n", debug_ctr, (long) get_stack_ptr()[debug_ctr+1]); #endif stackFrameArray = ref2obj(currentThread->stackFrameArray); stackBase = (StackFrame *)array_start(stackFrameArray); // Setup OLD stackframe ready for return stackFrame = stackBase + (newStackFrameIndex); stackFrame->stackTop = newStackTop; stackFrame->pc = retAddr; // Push NEW stack frame // Increment size of stack frame array but do not commit to it until we have // completely built both new stacks. newStackFrameIndex++; stackFrame++; if (((byte *)stackFrame - (byte *)stackBase) >= get_array_length(stackFrameArray)) { #if FIXED_STACK_SIZE throw_new_exception (JAVA_LANG_STACKOVERFLOWERROR); return false; #else if (expand_call_stack(currentThread) < 0) return false; stackFrame = (StackFrame *)array_start(currentThread->stackFrameArray) + newStackFrameIndex; #endif } // Initialize rest of new stack frame stackFrame->methodRecord = methodRecord; stackFrame->monitor = null; stackFrame->localsBase = newStackTop + 1; // Allocate space for locals etc. newStackTop = init_sp(stackFrame, methodRecord); stackFrame->stackTop = newStackTop; currentThread->stackFrameIndex = newStackFrameIndex; // Check for stack overflow if (is_stack_overflow (newStackTop, methodRecord)) { #if FIXED_STACK_SIZE throw_new_exception (JAVA_LANG_STACKOVERFLOWERROR); return false; #else if (expand_value_stack(currentThread, methodRecord->maxOperands+methodRecord->numLocals) < 0) { currentThread->stackFrameIndex--; return false; } // NOTE at this point newStackTop is no longer valid! newStackTop = stackFrame->stackTop; #endif } // All set. So now we can finally commit to the new stack frames update_constant_registers (stackFrame); curStackTop = newStackTop; // and jump to the start of the new code curPc = get_code_ptr(methodRecord); return true; }
int64 iob_send(int64 s,io_batch* b) { /* Windows has a sendfile called TransmitFile, which can send one * header and one trailer buffer. */ iob_entry* x,* last; io_entry* e; int64 sent; int i; if (b->bytesleft==0) return 0; sent=-1; e=iarray_get(&io_fds,s); if (!e) { errno=EBADF; return -3; } if (!(x=array_get(&b->b,sizeof(iob_entry),b->next))) return -3; /* can't happen error */ last=(iob_entry*)(((char*)array_start(&b->b))+array_bytes(&b->b)); fprintf(stderr,"iob_send() called!\n"); if (e->canwrite || e->sendfilequeued==1) { fprintf(stderr,"...reaping finished WriteFile/TransmitFile.\n"); /* An overlapping write finished. Reap the result. */ if (e->bytes_written==-1) return -3; if (e->bytes_written<x->n) { sent=e->bytes_written; if (x->n < e->bytes_written) { e->bytes_written-=x->n; x->n=0; ++x; } x->n -= e->bytes_written; x->offset += e->bytes_written; b->bytesleft -= e->bytes_written; } e->canwrite=0; e->sendfilequeued=0; } for (i=0; x+i<last; ++i) if (x[i].n) break; if (x[i].type==FROMBUF) { fprintf(stderr,"found non-sent buffer batch entry at %d\n",i); if (x+i+1 < last && (x[i+1].type==FROMFILE)) { fprintf(stderr,"Next is a file, can use TransmitFile\n",i); TRANSMIT_FILE_BUFFERS tfb; e->sendfilequeued=1; memset(&tfb,0,sizeof(tfb)); memset(&e[i].os,0,sizeof(e[i].os)); e[i].os.Offset=x[i].offset; e[i].os.OffsetHigh=(x[i].offset>>32); fprintf(stderr,"Calling TransmitFile on %p...",s); if (!TransmitFile(s,(HANDLE)x[i].fd, x[i].n+tfb.HeadLength>0xffff?0xffff:x[i].n, 0,&e[i].os,&tfb,TF_USE_KERNEL_APC)) { if (GetLastError()==ERROR_IO_PENDING) { fprintf(stderr," pending.!\n"); e->writequeued=1; errno=EAGAIN; e->errorcode=0; return -1; } else { fprintf(stderr," failed!\n"); e->errorcode=errno; return -3; } } fprintf(stderr," OK!\n"); return sent; } else {
int main(int argc, char **argv, char **envp) { array_t array; bio_t bin; char bin_data[8192]; bio_t *bio; int fd; char *name; int opt; ssize_t r; struct stat st; char *type = 0; while ((opt = sgetopt(argc, argv, "t:")) != -1) { switch (opt) { case '?': usage(); case 't': type = soptarg; break; } } argv += soptind; if (!type) usage(); array_init(&array, 1); /* Set the initial buffered io pointer to use stdin and set the default name * to '-'. */ bio = bio_0; name = "-"; for (;;) { if (*argv) { /* If a path was given then check to see if it's a directory and skip * over it if it is. */ if (stat(*argv, &st)) err(1, "fatal"); if (S_ISDIR(st.st_mode)) { errno = EISDIR; warn(*argv); argv++; continue; } /* Open the file for reading and construct our own buffered io struct to * use for reading in the file and hashing it. Also set the default * buffered io pointer to our own and update the name to reflect the * current file. */ fd = open_read(*argv); if (fd == -1) err(1, "fatal"); bio_init(&bin, read, fd, bin_data, sizeof(bin_data)); bio = &bin; name = *argv; } /* If there's no more arguments passed on the command line and the default * buffered io pointer doesn't point to stdin then that means all of the * files have been hashed and it's time to exit. */ else if ((bio != bio_0)) break; if (!strcmp(type, "md4")) handle_md4(&array, bio); else if (!strcmp(type, "md5")) handle_md5(&array, bio); else if (!strcmp(type, "sha1")) handle_sha1(&array, bio); else if (!strcmp(type, "sha256")) handle_sha256(&array, bio); else if (!strcmp(type, "sha512")) handle_sha512(&array, bio); else errx(1, "fatal: %s", "unknown type"); bio_put_str(bio_1, array_start(&array)); bio_put_str(bio_1, " "); bio_put_str(bio_1, name); bio_put_str(bio_1, "\n"); bio_flush(bio_1); array_trunc(&array); if (*argv) close(fd); if ((!*argv) || (!*++argv)) break; } return 0; }
/** * NOTE: The technique is not the same as that used in TinyVM. * The return value indicates the impact of the call on the VM * system. EXEC_CONTINUE normal return the system should return to the return * address provided by the VM. EXEC_RUN The call has modified the value of * VM PC and this should be used to restart execution. EXEC_RETRY The call * needs to be re-tried (typically for a GC failure), all global state * should be left intact, the PC has been set appropriately. * */ int dispatch_native(TWOBYTES signature, STACKWORD * paramBase) { STACKWORD p0 = paramBase[0]; switch (signature) { case wait_4_5V: return monitor_wait((Object *) word2ptr(p0), 0); case wait_4J_5V: return monitor_wait((Object *) word2ptr(p0), ((int)paramBase[1] > 0 ? 0x7fffffff : paramBase[2])); case notify_4_5V: return monitor_notify((Object *) word2ptr(p0), false); case notifyAll_4_5V: return monitor_notify((Object *) word2ptr(p0), true); case start_4_5V: // Create thread, allow for instruction restart return init_thread((Thread *) word2ptr(p0)); case yield_4_5V: schedule_request(REQUEST_SWITCH_THREAD); break; case sleep_4J_5V: sleep_thread(((int)p0 > 0 ? 0x7fffffff : paramBase[1])); schedule_request(REQUEST_SWITCH_THREAD); break; case getPriority_4_5I: push_word(get_thread_priority((Thread *) word2ptr(p0))); break; case setPriority_4I_5V: { STACKWORD p = (STACKWORD) paramBase[1]; if (p > MAX_PRIORITY || p < MIN_PRIORITY) return throw_new_exception(JAVA_LANG_ILLEGALARGUMENTEXCEPTION); else set_thread_priority((Thread *) word2ptr(p0), p); } break; case currentThread_4_5Ljava_3lang_3Thread_2: push_ref(ptr2ref(currentThread)); break; case interrupt_4_5V: interrupt_thread((Thread *) word2ptr(p0)); break; case interrupted_4_5Z: { JBYTE i = currentThread->interruptState != INTERRUPT_CLEARED; currentThread->interruptState = INTERRUPT_CLEARED; push_word(i); } break; case isInterrupted_4_5Z: push_word(((Thread *) word2ptr(p0))->interruptState != INTERRUPT_CLEARED); break; case join_4_5V: join_thread((Thread *) word2ptr(p0), 0); break; case join_4J_5V: join_thread((Thread *) word2obj(p0), paramBase[2]); break; case halt_4I_5V: schedule_request(REQUEST_EXIT); break; case shutdown_4_5V: shutdown_program(false); break; case currentTimeMillis_4_5J: push_word(0); push_word(systick_get_ms()); break; case readSensorValue_4I_5I: push_word(sp_read(p0, SP_ANA)); break; case setPowerTypeById_4II_5V: sp_set_power(p0, paramBase[1]); break; case freeMemory_4_5J: push_word(0); push_word(getHeapFree()); break; case totalMemory_4_5J: push_word(0); push_word(getHeapSize()); break; case floatToRawIntBits_4F_5I: // Fall through case intBitsToFloat_4I_5F: push_word(p0); break; case doubleToRawLongBits_4D_5J: // Fall through case longBitsToDouble_4J_5D: push_word(p0); push_word(paramBase[1]); break; case drawString_4Ljava_3lang_3String_2II_5V: { String *p = (String *)word2obj(p0); Object *charArray; if (!p) return throw_new_exception(JAVA_LANG_NULLPOINTEREXCEPTION); charArray = (Object *) word2ptr(get_word_4_ns(fields_start(p))); if (!charArray) return throw_new_exception(JAVA_LANG_NULLPOINTEREXCEPTION); display_goto_xy(paramBase[1], paramBase[2]); display_jstring(p); } break; case drawInt_4III_5V: display_goto_xy(paramBase[1], paramBase[2]); display_int(p0, 0); break; case drawInt_4IIII_5V: display_goto_xy(paramBase[2], paramBase[3]); display_int(p0, paramBase[1]); break; case asyncRefresh_4_5V: display_update(); break; case clear_4_5V: display_clear(0); break; case getDisplay_4_5_1B: push_word(display_get_array()); break; case setAutoRefreshPeriod_4I_5I: push_word(display_set_auto_update_period(p0)); break; case getRefreshCompleteTime_4_5I: push_word(display_get_update_complete_time()); break; case bitBlt_4_1BIIII_1BIIIIIII_5V: { Object *src = word2ptr(p0); Object *dst = word2ptr(paramBase[5]); display_bitblt((byte *)(src != NULL ?jbyte_array(src):NULL), paramBase[1], paramBase[2], paramBase[3], paramBase[4], (byte *)(dst!=NULL?jbyte_array(dst):NULL), paramBase[6], paramBase[7], paramBase[8], paramBase[9], paramBase[10], paramBase[11], paramBase[12]); break; } case getSystemFont_4_5_1B: push_word(display_get_font()); break; case setContrast_4I_5V: nxt_lcd_set_pot(p0); break; case getBatteryStatus_4_5I: push_word(battery_voltage()); break; case getButtons_4_5I: push_word(buttons_get()); break; case getTachoCountById_4I_5I: push_word(nxt_motor_get_count(p0)); break; case controlMotorById_4III_5V: nxt_motor_set_speed(p0, paramBase[1], paramBase[2]); break; case resetTachoCountById_4I_5V: nxt_motor_set_count(p0, 0); break; case i2cEnableById_4II_5V: if (i2c_enable(p0, paramBase[1]) == 0) return EXEC_RETRY; else break; case i2cDisableById_4I_5V: i2c_disable(p0); break; case i2cStatusById_4I_5I: push_word(i2c_status(p0)); break; case i2cStartById_4II_1BIII_5I: { Object *p = word2obj(paramBase[2]); JBYTE *byteArray = p ? jbyte_array(p) + paramBase[3] : NULL; push_word(i2c_start(p0, paramBase[1], (U8 *)byteArray, paramBase[4], paramBase[5])); } break; case i2cCompleteById_4I_1BII_5I: { Object *p = word2ptr(paramBase[1]); JBYTE *byteArray = p ? jbyte_array(p) + paramBase[2] : NULL; push_word(i2c_complete(p0, (U8 *)byteArray, paramBase[3])); } break; case playFreq_4III_5V: sound_freq(p0,paramBase[1], paramBase[2]); break; case btGetBC4CmdMode_4_5I: push_word(bt_get_mode()); break; case btSetArmCmdMode_4I_5V: if (p0 == 0) bt_set_arm7_cmd(); else bt_clear_arm7_cmd(); break; case btSetResetLow_4_5V: bt_set_reset_low(); break; case btSetResetHigh_4_5V: bt_set_reset_high(); break; case btWrite_4_1BII_5I: { Object *p = word2ptr(p0); byte *byteArray = (byte *) jbyte_array(p); push_word(bt_write(byteArray, paramBase[1], paramBase[2])); } break; case btRead_4_1BII_5I: { Object *p = word2ptr(p0); byte *byteArray = (byte *) jbyte_array(p); push_word(bt_read(byteArray, paramBase[1], paramBase[2])); } break; case btPending_4_5I: { push_word(bt_event_check(0xffffffff)); } break; case btEnable_4_5V: if (bt_enable() == 0) return EXEC_RETRY; else break; case btDisable_4_5V: bt_disable(); break; case usbRead_4_1BII_5I: { Object *p = word2ptr(p0); byte *byteArray = (byte *) jbyte_array(p); push_word(udp_read(byteArray,paramBase[1], paramBase[2])); } break; case usbWrite_4_1BII_5I: { Object *p = word2ptr(p0); byte *byteArray = (byte *) jbyte_array(p); push_word(udp_write(byteArray,paramBase[1], paramBase[2])); } break; case usbStatus_4_5I: { push_word(udp_event_check(0xffffffff)); } break; case usbEnable_4I_5V: { udp_enable(p0); } break; case usbDisable_4_5V: { udp_disable(); } break; case usbReset_4_5V: udp_reset(); break; case usbSetSerialNo_4Ljava_3lang_3String_2_5V: { byte *p = word2ptr(p0); int len; Object *charArray = (Object *) word2ptr(get_word_4_ns(fields_start(p))); len = get_array_length(charArray); udp_set_serialno((U8 *)jchar_array(charArray), len); } break; case usbSetName_4Ljava_3lang_3String_2_5V: { byte *p = word2ptr(p0); int len; Object *charArray = (Object *) word2ptr(get_word_4_ns(fields_start(p))); len = get_array_length(charArray); udp_set_name((U8 *)jchar_array(charArray), len); } break; case flashWritePage_4_1BI_5I: { Object *p = word2ptr(p0); unsigned long *intArray = (unsigned long *) jint_array(p); push_word(flash_write_page(intArray,paramBase[1])); } break; case flashReadPage_4_1BI_5I: { Object *p = word2ptr(p0); unsigned long *intArray = (unsigned long *) jint_array(p); push_word(flash_read_page(intArray,paramBase[1])); } break; case flashExec_4II_5I: push_word(run_program((byte *)(&FLASH_BASE[(p0*FLASH_PAGE_SIZE)]), paramBase[1])); break; case playSample_4IIIII_5V: sound_play_sample(((unsigned char *) &FLASH_BASE[(p0*FLASH_PAGE_SIZE)]) + paramBase[1],paramBase[2],paramBase[3],paramBase[4]); break; case playQueuedSample_4_1BIIII_5I: push_word(sound_add_sample((U8 *)jbyte_array(word2obj(p0)) + paramBase[1],paramBase[2],paramBase[3],paramBase[4])); break; case getTime_4_5I: push_word(sound_get_time()); break; case getDataAddress_4Ljava_3lang_3Object_2_5I: if (is_array(word2obj(p0))) push_word (ptr2word ((byte *) array_start(word2ptr(p0)))); else push_word (ptr2word ((byte *) fields_start(word2ptr(p0)))); break; case getObjectAddress_4Ljava_3lang_3Object_2_5I: push_word(p0); break; case gc_4_5V: // Restartable garbage collection return garbage_collect(); case shutDown_4_5V: shutdown(); // does not return case boot_4_5V: display_clear(1); while (1) nxt_avr_firmware_update_mode(); // does not return case arraycopy_4Ljava_3lang_3Object_2ILjava_3lang_3Object_2II_5V: return arraycopy(word2ptr(p0), paramBase[1], word2ptr(paramBase[2]), paramBase[3], paramBase[4]); case executeProgram_4I_5V: // Exceute program, allow for instruction re-start return execute_program(p0); case setDebug_4_5V: set_debug(word2ptr(p0)); break; case eventOptions_4II_5I: { byte old = debugEventOptions[p0]; debugEventOptions[p0] = (byte)paramBase[1]; push_word(old); } break; case suspendThread_4Ljava_3lang_3Object_2_5V: suspend_thread(ref2ptr(p0)); break; case resumeThread_4Ljava_3lang_3Object_2_5V: resume_thread(ref2ptr(p0)); break; case getProgramExecutionsCount_4_5I: push_word(gProgramExecutions); break; case getFirmwareRevision_4_5I: push_word((STACKWORD) getRevision()); break; case getFirmwareRawVersion_4_5I: push_word((STACKWORD) VERSION_NUMBER); break; case hsEnable_4II_5V: { if (hs_enable((int)p0, (int)paramBase[1]) == 0) return EXEC_RETRY; } break; case hsDisable_4_5V: { hs_disable(); } break; case hsWrite_4_1BII_5I: { Object *p = word2ptr(p0); byte *byteArray = (byte *) jbyte_array(p); push_word(hs_write(byteArray, paramBase[1], paramBase[2])); } break; case hsRead_4_1BII_5I: { Object *p = word2ptr(p0); byte *byteArray = (byte *) jbyte_array(p); push_word(hs_read(byteArray, paramBase[1], paramBase[2])); } break; case hsPending_4_5I: { push_word(hs_pending()); } break; case hsSend_4BB_1BII_1C_5I: { Object *p = word2ptr(paramBase[2]); U8 *data = (U8 *)jbyte_array(p); p = word2ptr(paramBase[5]); U16 *crc = (U16 *)jchar_array(p); push_word(hs_send((U8) p0, (U8)paramBase[1], data, paramBase[3], paramBase[4], crc)); } break; case hsRecv_4_1BI_1CI_5I: { Object *p = word2ptr(p0); U8 *data = (U8 *)jbyte_array(p); p = word2ptr(paramBase[2]); U16 *crc = (U16 *)jchar_array(p); push_word(hs_recv(data, paramBase[1], crc, paramBase[3])); } break; case getUserPages_4_5I: push_word(FLASH_MAX_PAGES - flash_start_page); break; case setVMOptions_4I_5V: gVMOptions = p0; break; case getVMOptions_4_5I: push_word(gVMOptions); break; case isAssignable_4II_5Z: push_word(is_assignable(p0, paramBase[1])); break; case cloneObject_4Ljava_3lang_3Object_2_5Ljava_3lang_3Object_2: { Object *newObj = clone((Object *)ref2obj(p0)); if (newObj == NULL) return EXEC_RETRY; push_word(obj2ref(newObj)); } break; case memPeek_4III_5I: push_word(mem_peek(p0, paramBase[1], paramBase[2])); break; case memCopy_4Ljava_3lang_3Object_2IIII_5V: mem_copy(word2ptr(p0), paramBase[1], paramBase[2], paramBase[3], paramBase[4]); break; case memGetReference_4II_5Ljava_3lang_3Object_2: push_word(mem_get_reference(p0, paramBase[1])); break; case setSensorPin_4III_5V: sp_set(p0, paramBase[1], paramBase[2]); break; case getSensorPin_4II_5I: push_word(sp_get(p0, paramBase[1])); break; case setSensorPinMode_4III_5V: sp_set_mode(p0, paramBase[1], paramBase[2]); break; case readSensorPin_4II_5I: push_word(sp_read(p0, paramBase[1])); break; case nanoTime_4_5J: { U64 ns = systick_get_ns(); push_word(ns >> 32); push_word(ns); } break; case createStackTrace_4Ljava_3lang_3Thread_2Ljava_3lang_3Object_2_5_1I: { Object *trace = create_stack_trace((Thread *)ref2obj(p0), ref2obj(paramBase[1])); if (trace == NULL) return EXEC_RETRY; push_word(obj2ref(trace)); } break; case registerEvent_4_5I: push_word(register_event((NXTEvent *) ref2obj(p0))); break; case unregisterEvent_4_5I: push_word(unregister_event((NXTEvent *) ref2obj(p0))); break; case changeEvent_4II_5I: push_word(change_event((NXTEvent *) ref2obj(p0), paramBase[1], paramBase[2])); break; case isInitialized_4I_5Z: push_word(is_initialized_idx(p0)); break; case allocate_4II_5Ljava_3lang_3Object_2: { Object *allocated; if(paramBase[1]>0){ allocated=new_single_array(p0,paramBase[1]); }else{ allocated=new_object_for_class(p0); } if(allocated == NULL) return EXEC_RETRY; push_word(obj2ref(allocated)); } break; case memPut_4IIII_5V: store_word_ns((byte *)(memory_base[p0] + paramBase[1]), paramBase[2],paramBase[3]); break; case notifyEvent_4ILjava_3lang_3Thread_2_5Z: push_word(debug_event(paramBase[1], NULL, (Thread*) ref2obj(paramBase[2]), 0, 0, 0, 0)); break; case setThreadRequest_4Ljava_3lang_3Thread_2Llejos_3nxt_3debug_3SteppingRequest_2_5V: { Thread *th = (Thread*) ref2obj(p0); th->debugData = (REFERENCE) paramBase[1]; // currently we only get stepping requests if(paramBase[1]) th->flags |= THREAD_STEPPING; else th->flags &= ~THREAD_STEPPING; } break; case isStepping_4Ljava_3lang_3Thread_2_5Z: { Thread *th = (Thread*) ref2obj(p0); push_word(is_stepping(th)); } break; case setBreakpointList_4_1Llejos_3nxt_3debug_3Breakpoint_2I_5V: breakpoint_set_list((Breakpoint**) array_start(p0), paramBase[1]); break; case enableBreakpoint_4Llejos_3nxt_3debug_3Breakpoint_2Z_5V: breakpoint_enable((Breakpoint*) word2ptr(p0), (boolean) paramBase[1]); break; case firmwareExceptionHandler_4Ljava_3lang_3Throwable_2II_5V: firmware_exception_handler((Throwable *)p0, paramBase[1], paramBase[2]); break; case exitThread_4_5V: currentThread->state = DEAD; schedule_request(REQUEST_SWITCH_THREAD); break; case updateThreadFlags_4Ljava_3lang_3Thread_2II_5I: ((Thread *)p0)->flags |= paramBase[1]; ((Thread *)p0)->flags &= ~paramBase[2]; //printf("m %x %d\n", p0, ((Thread *)p0)->flags); push_word(((Thread *)p0)->flags); break; default: return throw_new_exception(JAVA_LANG_NOSUCHMETHODERROR); } return EXEC_CONTINUE; }
/** * uncompress data and copy it to read buffer. * Returns true if data has been unpacked or no * compressed data is currently pending in the zread buffer. * This function closes the connection on error. * @param Idx Connection handle. * @return true on success, false otherwise. */ GLOBAL bool Unzip_Buffer( CONN_ID Idx ) { int result; unsigned char unzipbuf[READBUFFER_LEN]; int unzipbuf_used = 0; unsigned int z_rdatalen; unsigned int in_len; z_stream *in; assert( Idx > NONE ); z_rdatalen = (unsigned int)array_bytes(&My_Connections[Idx].zip.rbuf); if (z_rdatalen == 0) return true; in = &My_Connections[Idx].zip.in; in->next_in = array_start(&My_Connections[Idx].zip.rbuf); assert(in->next_in != NULL); in->avail_in = z_rdatalen; in->next_out = unzipbuf; in->avail_out = (uInt)sizeof unzipbuf; #ifdef DEBUG_ZIP Log(LOG_DEBUG, "in->avail_in %d, in->avail_out %d", in->avail_in, in->avail_out); #endif result = inflate( in, Z_SYNC_FLUSH ); if( result != Z_OK ) { Log(LOG_ALERT, "Decompression error: %s (code=%d, ni=%d, ai=%d, no=%d, ao=%d)!?", in->msg, result, in->next_in, in->avail_in, in->next_out, in->avail_out); Conn_Close(Idx, "Decompression error!", NULL, false); return false; } assert(z_rdatalen >= in->avail_in); in_len = z_rdatalen - in->avail_in; unzipbuf_used = READBUFFER_LEN - in->avail_out; #ifdef DEBUG_ZIP Log(LOG_DEBUG, "unzipbuf_used: %d - %d = %d", READBUFFER_LEN, in->avail_out, unzipbuf_used); #endif assert(unzipbuf_used <= READBUFFER_LEN); if (!array_catb(&My_Connections[Idx].rbuf, (char*) unzipbuf, (size_t)unzipbuf_used)) { Log (LOG_ALERT, "Decompression error: can't copy data!?"); Conn_Close(Idx, "Decompression error!", NULL, false); return false; } if( in->avail_in > 0 ) { array_moveleft(&My_Connections[Idx].zip.rbuf, 1, in_len ); } else { array_trunc( &My_Connections[Idx].zip.rbuf ); My_Connections[Idx].zip.bytes_in += unzipbuf_used; } return true; } /* Unzip_Buffer */
/** * Generate predefined persistent channels and &SERVER */ GLOBAL void Channel_InitPredefined( void ) { CHANNEL *new_chan; const struct Conf_Channel *conf_chan; const char *c; size_t i, channel_count = array_length(&Conf_Channels, sizeof(*conf_chan)); conf_chan = array_start(&Conf_Channels); assert(channel_count == 0 || conf_chan != NULL); for (i = 0; i < channel_count; i++, conf_chan++) { if (!conf_chan->name[0]) continue; if (!Channel_IsValidName(conf_chan->name)) { Log(LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"", conf_chan->name); continue; } new_chan = Channel_Search(conf_chan->name); if (new_chan) { Log(LOG_INFO, "Can't create pre-defined channel \"%s\": name already in use.", conf_chan->name); Set_KeyFile(new_chan, conf_chan->keyfile); continue; } new_chan = Channel_Create(conf_chan->name); if (!new_chan) { Log(LOG_ERR, "Can't create pre-defined channel \"%s\"!", conf_chan->name); continue; } Log(LOG_INFO, "Created pre-defined channel \"%s\".", conf_chan->name); Channel_ModeAdd(new_chan, 'P'); if (conf_chan->topic[0]) Channel_SetTopic(new_chan, NULL, conf_chan->topic); c = conf_chan->modes; while (*c) Channel_ModeAdd(new_chan, *c++); Channel_SetKey(new_chan, conf_chan->key); Channel_SetMaxUsers(new_chan, conf_chan->maxusers); Set_KeyFile(new_chan, conf_chan->keyfile); } if (channel_count) array_free(&Conf_Channels); /* Make sure the local &SERVER channel exists */ if (!Channel_Search("&SERVER")) { new_chan = Channel_Create("&SERVER"); if (new_chan) { Channel_SetModes(new_chan, "mnPt"); Channel_SetTopic(new_chan, Client_ThisServer(), "Server Messages"); } else Log(LOG_ERR, "Failed to create \"&SERVER\" channel!"); } else LogDebug("Required channel \"&SERVER\" already exists, ok."); } /* Channel_InitPredefined */
int main(int argc, char **argv, char **envp) { char ch; struct cdbmake cm; array_t data = ARRAY_INIT(1); int32_t dlen; int fd; uint32_t i; array_t key = ARRAY_INIT(1); int32_t klen; char *path; char *tmp; if (!*argv || !*++argv) usage(); path = *argv; if (!*++argv) usage(); tmp = *argv; /* Create the temporary file and start the cdb creation process with it. */ fd = open("test.cdb", O_CREAT | O_TRUNC | O_WRONLY, 0644); if (fd == -1) strerr_die4sys(111, FATAL, "unable to create ", tmp, ": "); if (cdbmake_start(&cm, fd) == -1) strerr_die2sys(111, FATAL, "cdbmake initialization failed: "); for (;;) { /* Skip over new lines and require the first character to be '+'. */ ch = get_ch(); if (ch == '\n') break; if (ch != '+') die_format(); /* Read the key length. */ klen = get_len(','); if (klen == -1) die_format(); /* Read the data length. */ dlen = get_len(':'); if (dlen == -1) die_format(); /* Truncate the key array and load it with the key from the cdb record. */ array_trunc(&key); for (i = 0; i < klen; i++) { ch = get_ch(); array_append(&key, &ch, 1); } /* Verify the separator is ->. */ if ((get_ch() != '-') || (get_ch() != '>')) die_format(); /* Truncate the data array and load it with the data from the cdb record. */ array_trunc(&data); for (i = 0; i < dlen; i++) { ch = get_ch(); array_append(&data, &ch, 1); } /* The line is valid, so add it to the cdb file and check that it ends with * a new line. */ if (cdbmake_add(&cm, array_start(&key), klen, array_start(&data), dlen) == -1) die_write(); if (get_ch() != '\n') die_format(); } /* Finish the cdb file, sync it to disk, close it, and finally rename it to * the target path. */ if (cdbmake_finish(&cm) == -1) die_write(); if (fsync(fd) == -1) die_write(); if (close(fd) == -1) die_write(); if (rename(tmp, path) == -1) strerr_die6sys(111, FATAL, "unable to rename ", tmp, " to ", path, ": "); _exit(0); }