Exemplo n.º 1
0
/**
	regexp_matched : 'regexp -> n:int -> string?
	<doc>Return the [n]th matched block by the regexp. If [n] is 0 then return 
	the whole matched substring. If the [n]th matched block was optional and not matched, returns null</doc>
**/
static value regexp_matched( value o, value n ) {
	pcredata *d;
	int m;
	val_check_kind(o,k_regexp);	
	d = PCRE(o);
	val_check(n,int);
	m = val_int(n);
	if( m < 0 || m >= d->nmatchs || val_is_null(d->str) )
		neko_error();
	{
		int start = d->matchs[m*2];
		int len = d->matchs[m*2+1] - start;
		value str;
		if( start == -1 )
			return val_null;
		str = alloc_empty_string(len);
		memcpy((char*)val_string(str),val_string(d->str)+start,len);
		return str;
	}
}
Exemplo n.º 2
0
value cgi_command( value v ) {
	val_check(v,string);
	if( strcmp(val_string(v),"stats") == 0 )
		return neko_stats_build(neko_vm_current());
	if( strcmp(val_string(v),"cache") == 0 ) {
		cache *c = (cache*)local_get(cache_root);
		value l = val_null;
		while( c != NULL ) {
			value a = alloc_array(4);
			val_array_ptr(a)[0] = c->file;
			val_array_ptr(a)[1] = c->main;
			val_array_ptr(a)[2] = alloc_int(c->hits);
			val_array_ptr(a)[3] = l;
			l = a;
			c = c->next;
		}
		return l;
	}
	neko_error();
}
Exemplo n.º 3
0
/**
	regexp_match : 'regexp -> string -> pos:int -> len:int -> bool
	<doc>Match [len] chars of a string starting at [pos] using the regexp.
	Return true if match found</doc>
**/
static value regexp_match( value o, value s, value p, value len ) {
	pcredata *d;
	int pp,ll;
	val_check_kind(o,k_regexp);
	val_check(s,string);
	val_check(p,int);
	val_check(len,int);
	pp = val_int(p);
	ll = val_int(len);
	if( pp < 0 || ll < 0 || pp > val_strlen(s) || pp + ll > val_strlen(s) )
		neko_error();
	d = PCRE(o);
	if( do_exec(d,val_string(s),ll+pp,pp) ) {
		d->str = s;
		return val_true;
	} else {
		d->str = val_null;
		return val_false;
	}
}
Exemplo n.º 4
0
Arquivo: ui.c Projeto: bendmorris/neko
/**
	ui_loop : void -> void
	<doc>
	Starts the native UI event loop. This method can only be called from the main thread.
	</doc>
**/
static value ui_loop() {
	if( !val_bool(ui_is_main()) )
		neko_error();
#	if defined(NEKO_WINDOWS)
	{
		MSG msg;
		while( GetMessage(&msg,NULL,0,0) ) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
			if( msg.message == WM_QUIT )
				break;
		}
	}
#	elif defined(NEKO_MAC)
	RunApplicationEventLoop();
#	else
	gtk_main();
#	endif
	return val_null;
}
Exemplo n.º 5
0
/**
	$sfind : src:string -> pos:int -> pat:string -> int?
	<doc>
	Return the first position starting at [pos] in [src] where [pat] was found.
	Return null if not found. Error if [pos] is outside [src] bounds.
	</doc>
**/
static value builtin_sfind( value src, value pos, value pat ) {
	int p, l, l2;
	const char *ptr;
	val_check(src,string);
	val_check(pos,int);
	val_check(pat,string);
	p = val_int(pos);
	l = val_strlen(src);
	l2 = val_strlen(pat);
	if( p < 0 || p >= l )
		neko_error();
	ptr = val_string(src) + p;
	while( l - p >= l2 ) {
		if( memcmp(ptr,val_string(pat),l2) == 0 )
			return alloc_int(p);
		p++;
		ptr++;
	}
	return val_null;
}
Exemplo n.º 6
0
/**
	sys_stat : string -> {
		gid => int,
		uid => int,
		atime => 'int32,
		mtime => 'int32,
		ctime => 'int32,
		dev => int,
		ino => int,
		nlink => int,
		rdev => int,
		mode => int,
		size => int
	}
	<doc>Run the [stat] command on the given file or directory.</doc>
**/
static value sys_stat( value path ) {
	struct stat s;
	value o;
	val_check(path,string);
	if( stat(val_string(path),&s) != 0 )
		neko_error();
	o = alloc_object(NULL);
	STATF(gid);
	STATF(uid);
	STATF32(atime);
	STATF32(mtime);
	STATF32(ctime);
	STATF(dev);
	STATF(ino);
	STATF(mode);
	STATF(nlink);
	STATF(rdev);
	STATF(size);
	STATF(mode);
	return o;
}
Exemplo n.º 7
0
/**
	$hadd : 'hash -> k:any -> v:any -> void
	<doc>
	Add the value [v] with key [k] to the hashtable. Previous binding is masked but not removed.
	</doc>
**/
static value builtin_hadd( value vh, value key, value val ) {
	vhash *h;
	hcell *c;
	int hkey;
	val_check_kind(vh,k_hash);
	h = val_hdata(vh);
	hkey = val_hash(key);
	if( hkey < 0 )
		neko_error();
	if( h->nitems >= (h->ncells << 1) )
		builtin_hresize(vh,alloc_int(h->ncells << 1));
	c = (hcell*)alloc(sizeof(hcell));
	c->hkey = hkey;
	c->key = key;
	c->val = val;
	hkey %= h->ncells;
	c->next = h->cells[hkey];
	h->cells[hkey] = c;
	h->nitems++;
	return val_null;
}
Exemplo n.º 8
0
/**
	socket_new : udp:bool -> 'socket
	<doc>Create a new socket, TCP or UDP</doc>
**/
static value socket_new( value udp ) {
	SOCKET s;
	val_check(udp,bool);
	if( val_bool(udp) )
		s = socket(AF_INET,SOCK_DGRAM,0);
	else
		s = socket(AF_INET,SOCK_STREAM,0);
	if( s == INVALID_SOCKET )
		neko_error();
#	ifdef NEKO_MAC
	setsockopt(s,SOL_SOCKET,SO_NOSIGPIPE,NULL,0);
#	endif
#	ifdef NEKO_POSIX
	// we don't want sockets to be inherited in case of exec
	{
		int old = fcntl(s,F_GETFD,0);
		if( old >= 0 ) fcntl(s,F_SETFD,old|FD_CLOEXEC);
	}
#	endif
	return alloc_abstract(k_socket,(value)(int_val)s);
}
Exemplo n.º 9
0
/**
	socket_recv_from : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
	<doc>
	Read data from an unconnected UDP socket, store the address from which we received data in addr.
	</doc>
**/
static value socket_recv_from( value o, value data, value pos, value len, value addr ) {
	int p,l,dlen,ret;
	int retry = 0;
	struct sockaddr_in saddr;
	int slen = sizeof(saddr);
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	val_check(addr,object);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(recv_from_again);
	if( retry++ > NRETRYS ) {
		sock_tmp t;
		t.sock = val_sock(o);
		t.buf = val_string(data) + p;
		t.size = l;
		neko_thread_blocking(tmp_recv,&t);
		ret = t.ret;
	} else
		ret = recvfrom(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL, (struct sockaddr*)&saddr, &slen);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_from_again);
#ifdef	NEKO_WINDOWS
		if( WSAGetLastError() == WSAECONNRESET )
			ret = 0;
		else
#endif
		return block_error();
	}
	alloc_field(addr,f_host,alloc_int32(*(int*)&saddr.sin_addr));
	alloc_field(addr,f_port,alloc_int(ntohs(saddr.sin_port)));
	return alloc_int(ret);
}
Exemplo n.º 10
0
/**
	socket_recv_char : 'socket -> int
	<doc>Read a single char from a connected socket.</doc>
**/
static value socket_recv_char( value o ) {
	int ret;
	int retry = 0;
	unsigned char cc;
	val_check_kind(o,k_socket);
	POSIX_LABEL(recv_char_again);
	if( retry++ > NRETRYS ) {
		sock_tmp t;
		t.sock = val_sock(o);
		t.buf = (char*)&cc;
		t.size = 1;
		neko_thread_blocking(tmp_recv,&t);
		ret = t.ret;
	} else
		ret = recv(val_sock(o),&cc,1,MSG_NOSIGNAL);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_char_again);
		return block_error();
	}
	if( ret == 0 )
		neko_error();
	return alloc_int(cc);
}
Exemplo n.º 11
0
/**
	socket_set_keepalive : 'socket -> bool -> time:int? -> interval:int? -> void
	<doc>
	Enable or disable TCP_KEEPALIVE flag for the socket
	</doc>
**/
static value socket_set_keepalive( value o, value b, value time, value interval ) {
	int val;
	SOCKET s;
	val_check_kind(o,k_socket);
	val_check(b,bool);
	if( !val_is_null(time) || !val_is_null(interval) ){
		val_check(time,int);
		val_check(interval,int);
	}
	s = val_sock(o);
	if( !val_bool(b) ) {
		val = 0;
		if( setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&val, sizeof(val)) != 0 )
			neko_error();
	} else {
		val = 1;
		if( setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&val, sizeof(val)) != 0 )
			neko_error();

		if( !val_is_null(time) && !val_is_null(interval) ) {
#			if defined(NEKO_WINDOWS)
			u_long params[3] = { 1, (unsigned long)val_int(time)*1000, (unsigned long)val_int(interval)*1000 };
			if( WSAIoctl(s, SIO_KEEPALIVE_VALS, &params, sizeof(params), NULL, 0, &val, NULL, NULL) != 0 )
				neko_error();
#			else
#			if defined(TCP_KEEPIDLE)
			val = val_int(time);
			if( setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&val, sizeof(val)) != 0 )
				neko_error();
#			elif defined(TCP_KEEPALIVE)
			val = val_int(time);
			if( setsockopt(s, IPPROTO_TCP, TCP_KEEPALIVE, (void *)&val, sizeof(val)) != 0 )
				neko_error();
#			endif
#			if defined(TCP_KEEPINTVL)
			val = val_int(interval);
			if( setsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&val, sizeof(val)) != 0 )
				neko_error();
#			endif
#			endif
		}
	}
	return val_null;
}
Exemplo n.º 12
0
static value cert_add_pem( value cert, value data ){
	mbedtls_x509_crt *crt;
	int r, len;
	unsigned char *buf;
	val_check(data,string);
	if( !val_is_null(cert) ){
		val_check_kind(cert,k_cert);
		crt = val_cert(cert);
		if( !crt )
			neko_error();
	}else{
		crt = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt));
		mbedtls_x509_crt_init( crt );
		cert = alloc_abstract(k_cert, crt);
		val_gc(cert,free_cert);
	}
	len = val_strlen(data)+1;
	buf = (unsigned char *)alloc(len);
	memcpy(buf, val_string(data), len-1);
	buf[len-1] = '\0';
	if( (r = mbedtls_x509_crt_parse(crt, buf, len)) < 0 )
		return ssl_error(r);
	return cert;
}
Exemplo n.º 13
0
/**
	Free an allocated ENetEvent struct from neko
**/
static value free_enetevent( value e ) {
	val_check_kind(e,k_udprevent);

	ENetEvent *event = (ENetEvent *)val_data(e);
	if(e == NULL)
		neko_error();

	// enet_packet_destroy frees the packet itself.
#ifdef ENET_DEBUG
printf("*** free_enetevent freeing packet\n");
#endif
	if(event->packet != NULL)
		enet_packet_destroy (event->packet);
#ifdef ENET_DEBUG
//printf("*** free_enetevent freeing event\n");
#endif
	enet_free(event);
	val_gc(e,NULL);
	val_kind(e) = NULL;
#ifdef ENET_DEBUG
//printf("*** free_enetevent done.\n");
#endif
	return val_true;
}
Exemplo n.º 14
0
//value ImageStringTTF(value img,value fontname,value ptsize, value angle, value x, value y,value string, value align, value antiAntiAlias, value color) {
value ImageStringTTF(value *args,int nargs) {
    enum {eImg,eFontname,ePtsize,eAngle,eX,eY,eString,eAlign,eAntiAlias,eColor,eSize};
    if (nargs!=eSize)
        neko_error();
    ImageData _img = getImage(args[eImg]);
    char *_fontname = val_string(args[eFontname]);
    double _ptsize = val_float(args[ePtsize]);
    double _angle = val_float(args[eAngle]);
    int _x = val_int(args[eX]);
    int _y = val_int(args[eY]);
    char *_string = val_string(args[eString]);
    int _align = val_int(args[eAlign]);
    int _antiAliasing = val_bool(args[eAntiAlias]);


    //calculation size of output
    int brect[8];
    char *err;
    err = gdImageStringFT(NULL,&brect[0],0,_fontname,_ptsize,_angle,0,0,_string);
    if (err)
        val_throw(alloc_string(err));

    int width = brect[2] - brect[6];
    int height = brect[3] - brect[7];

    switch (_align) {
    case 0: // LeftTop
        break;
    case 1: // CenterTop
        _x-=width/2;
        break;
    case 2: // RightTop
        _x-=width;
        break;
    case 3: // LeftMiddle
        _y-=height/2;
        break;
    case 4: // CenterMiddle
        _y-=height/2;
        _x-=width/2;
        break;
    case 5: // Right Middle
        _y-=height/2;
        _x-=width;
        break;
    case 6: // LeftBottom
        _y-=height;
        break;
    case 7: // CenterBottom
        _y-=height;
        _x-=width/2;
        break;
    case 8: // RightBottom
        _y-=height;
        _x-=width;
        break;
    default: //something went wrong
        val_throw(alloc_string("unknown position type"));
        break;
    }

    _y+=height;


    //drawing
    int _color = initColor(_img,args[eColor]);
    err = gdImageStringFT(imageImage(_img),&brect[0],getAntiAliasingColor(_color,_antiAliasing),_fontname,_ptsize,_angle,_x,_y,_string);
    if (err)
        val_throw(alloc_string(err));

    return val_null;
}
Exemplo n.º 15
0
/**
	$idiv : any -> any -> int
	<doc>Divide two integers. An error occurs if division by 0</doc>
**/
static value builtin_idiv( value a, value b ) {
	if( val_any_int(b) == 0 )
		neko_error();
	return alloc_best_int( val_any_int(a) / val_any_int(b) );
}
Exemplo n.º 16
0
/**
	$new : object? -> object
	<doc>Return a copy of the object or a new object if [null]</doc>
**/
static value builtin_new( value o ) {
	if( !val_is_null(o) && !val_is_object(o) )
		neko_error();
	return alloc_object(o);
}
Exemplo n.º 17
0
/**
	parse_multipart_data : onpart:function:2 -> ondata:function:3 -> void
	<doc>
	Incrementally parse the multipart data. call [onpart(name,filename)] for each part
	found and [ondata(buf,pos,len)] when some data is available
	</doc>
**/
static value parse_multipart_data( value onpart, value ondata ) {
	value buf;
	int len = 0;
	mcontext *c = CONTEXT();
	const char *ctype = ap_table_get(c->r->headers_in,"Content-Type");
	value boundstr;
	val_check_function(onpart,2);
	val_check_function(ondata,3);
	buf = alloc_empty_string(BUFSIZE);
	if( !ctype || strstr(ctype,"multipart/form-data") == NULL )
		return val_null;
	// extract boundary value
	{
		const char *boundary, *bend;
		if( (boundary = strstr(ctype,"boundary=")) == NULL )
			neko_error();
		boundary += 9;
		PARSE_HEADER(boundary,bend);
		len = (int)(bend - boundary);
		boundstr = alloc_empty_string(len+2);
		if( val_strlen(boundstr) > BUFSIZE / 2 )
			neko_error();
		val_string(boundstr)[0] = '-';
		val_string(boundstr)[1] = '-';
		memcpy(val_string(boundstr)+2,boundary,len);
	}
	len = 0;
    if( !ap_should_client_block(c->r) )
		neko_error();
	while( true ) {
		char *name, *end_name, *filename, *end_file_name, *data;
		int pos;
		// refill buffer
		// we assume here that the the whole multipart header can fit in the buffer
		fill_buffer(c,buf,&len);
		// is boundary at the beginning of buffer ?
		if( len < val_strlen(boundstr) || memcmp(val_string(buf),val_string(boundstr),val_strlen(boundstr)) != 0 )
			return discard_body(c);
		name = memfind(val_string(buf),len,"Content-Disposition:");
		if( name == NULL )
			break;
		name = memfind(name,len - (int)(name - val_string(buf)),"name=");
		if( name == NULL )
			return discard_body(c);
		name += 5;
		PARSE_HEADER(name,end_name);
		data = memfind(end_name,len - (int)(end_name - val_string(buf)),"\r\n\r\n");
		if( data == NULL )
			return discard_body(c);
		filename = memfind(name,(int)(data - name),"filename=");
		if( filename != NULL ) {
			filename += 9;
			PARSE_HEADER(filename,end_file_name);
		}
		data += 4;
		pos = (int)(data - val_string(buf));
		// send part name
		val_call2(onpart,copy_string(name,(int)(end_name - name)),filename?copy_string(filename,(int)(end_file_name - filename)):val_null);
		// read data
		while( true ) {
			const char *boundary;
			// recall buffer
			memmove(val_string(buf),val_string(buf)+pos,len - pos);
			len -= pos;
			pos = 0;
			fill_buffer(c,buf,&len);
			// lookup bounds
			boundary = memfind(val_string(buf),len,val_string(boundstr));
			if( boundary == NULL ) {
				if( len == 0 )
					return discard_body(c);
				// send as much buffer as possible to client
				if( len < BUFSIZE )
					pos = len;
				else
					pos = len - val_strlen(boundstr) + 1;
				val_call3(ondata,buf,alloc_int(0),alloc_int(pos));
			} else {
				// send remaining data
				pos = (int)(boundary - val_string(buf));
				val_call3(ondata,buf,alloc_int(0),alloc_int(pos-2));
				// recall
				memmove(val_string(buf),val_string(buf)+pos,len - pos);
				len -= pos;
				break;
			}
		}
	}
	return val_null;
}
Exemplo n.º 18
0
static value discard_body( mcontext *c ) {
	char buf[256];
	while( ap_get_client_block(c->r,buf,256) > 0 ) {
	}
	neko_error();
}
Exemplo n.º 19
0
/**
	process_run_raw : cmd:string -> 'process
	<doc>
	Start a process using a command. The input string contains
	the command as well as the arguments. Shell meta-characters
	will not be auto escaped/quoted. 
	</doc>
**/
CAMLprim value process_run_raw( value cmd ) {
	int i;
	vprocess *p;
	val_check(cmd,string);
	char* cmdStr = val_string(cmd);
#	ifdef _WIN32
	{
		SECURITY_ATTRIBUTES sattr;
		STARTUPINFO sinf;
		HANDLE proc = GetCurrentProcess();
		HANDLE oread,eread,iwrite;
		// creates commandline
		buffer b = alloc_buffer(NULL);
		char *sargs;
		buffer_append_char(b,'"');
		char* cmdexe = getenv("COMSPEC");
		if (!cmdexe) cmdexe = "cmd.exe";
		buffer_append_str(b,cmdexe);
		buffer_append_char(b,'"');
		buffer_append_str(b,"/C \"");
		buffer_append_str(b,cmdStr);
		buffer_append_char(b,'"');
		sargs = buffer_to_string(b);
		p = (vprocess*)alloc_private(sizeof(vprocess));
		// startup process
		sattr.nLength = sizeof(sattr);
		sattr.bInheritHandle = TRUE;
		sattr.lpSecurityDescriptor = NULL;
		memset(&sinf,0,sizeof(sinf));
		sinf.cb = sizeof(sinf);
		sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
		sinf.wShowWindow = SW_HIDE;
		CreatePipe(&oread,&sinf.hStdOutput,&sattr,0);
		CreatePipe(&eread,&sinf.hStdError,&sattr,0);
		CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0);
		DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS);
		CloseHandle(oread);
		CloseHandle(eread);
		CloseHandle(iwrite);
		
		if( !CreateProcess(NULL,val_string(sargs),NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) ) {
			CloseHandle(p->eread);
			CloseHandle(p->oread);
			CloseHandle(p->iwrite);
			free(sargs);
			neko_error();
		}
		free(sargs);
		// close unused pipes
		CloseHandle(sinf.hStdOutput);
		CloseHandle(sinf.hStdError);
		CloseHandle(sinf.hStdInput);
	}
#	else
	char **argv = (char**)alloc_private(sizeof(char*)*4);
	argv[0] = cmd = "/bin/sh";
	argv[1] = "-c";
	argv[2] = cmdStr;
	argv[3] = NULL;
	int input[2], output[2], error[2];
	if( pipe(input) || pipe(output) || pipe(error) )
		neko_error();
	p = (vprocess*)alloc_private(sizeof(vprocess));
	p->pid = fork();
	if( p->pid == -1 ) {
		do_close(input[0]);
		do_close(input[1]);
		do_close(output[0]);
		do_close(output[1]);
		do_close(error[0]);
		do_close(error[1]);
		neko_error();
	}
	// child
	if( p->pid == 0 ) {
		close(input[1]);
		close(output[0]);
		close(error[0]);
		dup2(input[0],0);
		dup2(output[1],1);
		dup2(error[1],2);
		execvp(val_string(cmd),argv);
		fprintf(stderr,"Command not found : %s\n",val_string(cmd));
		exit(1);
	}
	// parent
	do_close(input[0]);
	do_close(output[1]);
	do_close(error[1]);
	p->iwrite = input[1];
	p->oread = output[0];
	p->eread = error[0];
#	endif
	{
		value vp = alloc_abstract(k_process,p);
		val_gc(vp,free_process);
		return vp;
	}
}
Exemplo n.º 20
0
value hxfcgi_parse_multipart_neko(value hreq, value onpart, value ondata ) {
	val_check_kind(hreq,hxRequest);
	val_check_function(onpart,2);
	val_check_function(ondata,3);
	hxfcgi::Request *req = get_request(hreq);
	char *buf;
	int len = 0;
	char *boundstr;
	hxfcgi::BasicData b;
	string ctype = b.getHeader("CONTENT_TYPE");
	if(ctype.find("multipart/form-data") != 0)
		return val_null;
	// extract boundary value
	{
		const char *boundary, *bend;
		if( (boundary = strstr(ctype.c_str(),"boundary=")) == NULL )
			neko_error();
		boundary += 9;
		PARSE_HEADER(boundary,bend);
		len = (int)(bend - boundary);
		boundstr = (char *) malloc(sizeof(char) * (len+3));
		if( strlen(boundstr) > BUFSIZE / 2 )
			neko_error();
		
		boundstr[0] = '-';
		boundstr[1] = '-';
		memcpy(boundstr+2,boundary,len);
		boundstr[len+2] = 0;
	}
	
	len = 0;
	buf = (char *) malloc(sizeof(char) * (BUFSIZE));
	while( true ) {
		char *name, *end_name, *filename, *end_file_name, *data;
		int pos;
		// refill buffer
		// we assume here that the the whole multipart header can fit in the buffer
		req->bufferFill(buf,&len);
		// is boundary at the beginning of buffer ?
		if( len < (int) strlen(boundstr) || memcmp(buf,boundstr,strlen(boundstr)) != 0 ) {
			free(boundstr);
			free(buf);
			return val_null;
		}		
		name = memfind(buf,len,"Content-Disposition:");
		if( name == NULL )
			break;
		name = memfind(name,len - (int)(name - buf),"name=");
		if( name == NULL ) {
			free(boundstr);
			free(buf);
			return val_null;
		}
		name += 5;
		PARSE_HEADER(name,end_name);
		data = memfind(end_name,len - (int)(end_name - buf),"\r\n\r\n");
		if( data == NULL ) {
			free(boundstr);
			free(buf);
			return val_null;
		}
		filename = memfind(name,(int)(data - name),"filename=");
		if( filename != NULL ) {
			filename += 9;
			PARSE_HEADER(filename,end_file_name);
		}
		data += 4;
		pos = (int)(data - buf);
		// send part name
		val_call2(onpart,copy_string(name,(int)(end_name - name)),filename?copy_string(filename,(int)(end_file_name - filename)):val_null);
		
		
		// read data
		while( true ) {
			const char *boundary;
			// recall buffer
			memcpy(buf,buf+pos,len - pos);
			len -= pos;
			pos = 0;
			req->bufferFill(buf,&len);
			// lookup bounds
			boundary = memfind(buf,len,boundstr);
			if( boundary == NULL ) {
				if( len == 0 ) {
					free(boundstr);
					free(buf);
					return val_null;
				}
				// send as much buffer as possible to client
				if( len < BUFSIZE )
					pos = len;
				else
					pos = len - strlen(boundstr) + 1;
				val_call3(ondata,copy_string(buf,pos),alloc_int(0),alloc_int(pos));
			} else {
				// send remaining data
				pos = (int)(boundary - buf);
				val_call3(ondata,copy_string(buf,pos-2),alloc_int(0),alloc_int(pos-2));
				// recall
				memcpy(buf,buf+pos,len - pos);
				len -= pos;
				break;
			}
		}
	}	
	free(boundstr);
	free(buf);
	return val_null;
}
Exemplo n.º 21
0
static value enumerate_ips() {
	value rv, cur = NULL, tmp;
	int c,x;
	int addr;

#ifdef NEKO_WINDOWS
	LPSOCKET_ADDRESS_LIST list = NULL;
	SOCKET s;
	int len = 0;
	char *buf = (char *)malloc(4096);

	s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
	if(s == SOCKET_ERROR)
		neko_error();

	c = WSAIoctl(s,
			SIO_ADDRESS_LIST_QUERY,
			NULL,
			0,
			buf,
			4096,
			(unsigned long *) &len,
			NULL,
			NULL);
	closesocket(s);

printf("iface count: %d\n", len);
	if(c == SOCKET_ERROR || len <=0) {
		free(buf);
		neko_error();
	}

	list = (LPSOCKET_ADDRESS_LIST) buf;
	if(list->iAddressCount <= 0) {
		free(buf);
		neko_error();
	}

	char sbuf[20];
	for(x=0; x < list->iAddressCount; ++x) {
		sprintf(sbuf, "inet%d", x);
		tmp = alloc_array(3);
		val_array_ptr(tmp)[0] = alloc_string(sbuf);
		memcpy(&addr, &list->Address[x].lpSockaddr->sa_data[2], 4);
		//(SOCKADDR_IN *)list.Address[x].lpSockaddr)->sin_addr
		val_array_ptr(tmp)[1] = alloc_int(addr);
		val_array_ptr(tmp)[2] = val_null;
		if( cur )
			val_array_ptr(cur)[2] = tmp;
		else
			rv = tmp;
		cur = tmp;
	}
	// insert the localhost record.
	if(list->iAddressCount > 0) {
		sprintf(sbuf, "inet%d", list->iAddressCount);
		tmp = alloc_array(3);
		val_array_ptr(tmp)[0] = alloc_string(sbuf);
		val_array_ptr(tmp)[1] = alloc_int(16777343);
		val_array_ptr(tmp)[2] = val_null;
		if( cur )
			val_array_ptr(cur)[2] = tmp;
		else
			rv = tmp;
		cur = tmp;
	}
	free(buf);
	return rv;
#else
	struct ifconf ifc;
	int s;
	int icnt = 10; // number of potential network interfaces.

	s = socket(AF_INET, SOCK_DGRAM,0);
	if(s < 0)
		neko_error();

	ifc.ifc_buf = NULL;
	while(1) {
		ifc.ifc_len = sizeof(struct ifreq) * icnt;
		ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
		if(ioctl(s, SIOCGIFCONF, &ifc) < 0) {
			close(s);
			free(ifc.ifc_buf);
			neko_error();
		}
		if(ifc.ifc_len == icnt * sizeof(struct ifreq)) {
			// may have more interfaces than we allowed for.
			icnt += 5;
			continue;
		}
		break;
	}

	rv = alloc_array(ifc.ifc_len/sizeof(struct ifreq));
	struct ifreq *ifr = ifc.ifc_req;
	//struct ifreq ifr2;
	for(x = 0, c = 0; x < ifc.ifc_len; x += sizeof(struct ifreq), c++) {
		if(ifr->ifr_addr.sa_family == AF_INET) {
			printf("x: %d c: %d name: %s\n", x, c, ifr->ifr_name);
			tmp = alloc_array(3);
			val_array_ptr(tmp)[0] = alloc_string(ifr->ifr_name);
			memcpy(&addr, &ifr->ifr_addr.sa_data[2],4);
			val_array_ptr(tmp)[1] = alloc_int(addr);
			val_array_ptr(tmp)[2] = val_null;
			if( cur )
				val_array_ptr(cur)[2] = tmp;
			else
				rv = tmp;
			cur = tmp;
		}
		ifr++;
	}

	close(s);
	free(ifc.ifc_buf);
	return rv;
#endif
}
Exemplo n.º 22
0
/**
	sys_read_dir : string -> string list
	<doc>Return the content of a directory</doc>
**/
static value sys_read_dir( value path ) {
	value h = val_null;
	value cur = NULL, tmp;
#ifdef NEKO_WINDOWS
	WIN32_FIND_DATA d;
	HANDLE handle;
	buffer b;
	int len;
	val_check(path,string);
	len = val_strlen(path);
	b = alloc_buffer(NULL);
	val_buffer(b,path);
	if( len && val_string(path)[len-1] != '/' && val_string(path)[len-1] != '\\' )
		buffer_append(b,"/*.*");
	else
		buffer_append(b,"*.*");
	path = buffer_to_string(b);
	handle = FindFirstFile(val_string(path),&d);
	if( handle == INVALID_HANDLE_VALUE )
		neko_error();
	while( true ) {
		// skip magic dirs
		if( d.cFileName[0] != '.' || (d.cFileName[1] != 0 && (d.cFileName[1] != '.' || d.cFileName[2] != 0)) ) {
			tmp = alloc_array(2);
			val_array_ptr(tmp)[0] = alloc_string(d.cFileName);
			val_array_ptr(tmp)[1] = val_null;
			if( cur )
				val_array_ptr(cur)[1] = tmp;
			else
				h = tmp;
			cur = tmp;
		}
		if( !FindNextFile(handle,&d) )
			break;
	}
	FindClose(handle);
#else
	DIR *d;
	struct dirent *e;
	val_check(path,string);
	d = opendir(val_string(path));
	if( d == NULL )
		neko_error();
	while( true ) {
		e = readdir(d);
		if( e == NULL )
			break;
		// skip magic dirs
		if( e->d_name[0] == '.' && (e->d_name[1] == 0 || (e->d_name[1] == '.' && e->d_name[2] == 0)) )
			continue;
		tmp = alloc_array(2);
		val_array_ptr(tmp)[0] = alloc_string(e->d_name);
		val_array_ptr(tmp)[1] = val_null;
		if( cur )
			val_array_ptr(cur)[1] = tmp;
		else
			h = tmp;
		cur = tmp;
	}
	closedir(d);
#endif
	return h;
}
Exemplo n.º 23
0
/**
	sys_remove_dir : string -> void
	<doc>Remove a directory. Exception on error</doc>
**/
static value sys_remove_dir( value path ) {
	val_check(path,string);
	if( rmdir(val_string(path)) != 0 )
		neko_error();
	return val_true;
}
Exemplo n.º 24
0
/**
	set_cwd : string -> void
	<doc>Set current working directory</doc>
**/
static value set_cwd( value d ) {
	val_check(d,string);
	if( chdir(val_string(d)) )
		neko_error();
	return val_true;
}
Exemplo n.º 25
0
/**
	file_delete : string -> void
	<doc>Delete the file. Exception on error.</doc>
**/
static value file_delete( value path ) {
	val_check(path,string);
	if( unlink(val_string(path)) != 0 )
		neko_error();
	return val_true;
}
Exemplo n.º 26
0
/**
	process_run : cmd:string -> args:string array -> 'process
	<doc>
	Start a process using a command and the specified arguments.
	</doc>
**/
CAMLprim value process_run( value cmd, value vargs ) {
	int i;
	vprocess *p;
	val_check(cmd,string);
	val_check(vargs,array);
#	ifdef _WIN32
	{
		SECURITY_ATTRIBUTES sattr;
		STARTUPINFO sinf;
		HANDLE proc = GetCurrentProcess();
		HANDLE oread,eread,iwrite;
		// creates commandline
		buffer b = alloc_buffer(NULL);
		char *sargs;
		buffer_append_char(b,'"');
		buffer_append_str(b,val_string(cmd));
		buffer_append_char(b,'"');
		for(i=0;i<val_array_size(vargs);i++) {
			value v = val_array_ptr(vargs)[i];
			int j,len;
			val_check(v,string);
			len = val_strlen(v);
			buffer_append_str(b," \"");
			for(j=0;j<len;j++) {
				char c = val_string(v)[j];
				switch( c ) {
				case '"':
					buffer_append_str(b,"\\\"");
					break;
				case '\\':
					buffer_append_str(b,"\\\\");
					break;
				default:
					buffer_append_char(b,c);
					break;
				}
			}
			buffer_append_char(b,'"');
		}
		sargs = buffer_to_string(b);
		p = (vprocess*)alloc_private(sizeof(vprocess));
		// startup process
		sattr.nLength = sizeof(sattr);
		sattr.bInheritHandle = TRUE;
		sattr.lpSecurityDescriptor = NULL;
		memset(&sinf,0,sizeof(sinf));
		sinf.cb = sizeof(sinf);
		sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
		sinf.wShowWindow = SW_HIDE;
		CreatePipe(&oread,&sinf.hStdOutput,&sattr,0);
		CreatePipe(&eread,&sinf.hStdError,&sattr,0);
		CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0);
		DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS);
		CloseHandle(oread);
		CloseHandle(eread);
		CloseHandle(iwrite);
		
		if( !CreateProcess(NULL,val_string(sargs),NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) ) {
			CloseHandle(p->eread);
			CloseHandle(p->oread);
			CloseHandle(p->iwrite);
			free(sargs);
			neko_error();
		}
		free(sargs);
		// close unused pipes
		CloseHandle(sinf.hStdOutput);
		CloseHandle(sinf.hStdError);
		CloseHandle(sinf.hStdInput);
	}
#	else
	char **argv = (char**)alloc_private(sizeof(char*)*(val_array_size(vargs)+2));
	argv[0] = val_string(cmd);
	for(i=0;i<val_array_size(vargs);i++) {
		value v = val_array_ptr(vargs)[i];
		val_check(v,string);
		argv[i+1] = val_string(v);
	}
	argv[i+1] = NULL;
	int input[2], output[2], error[2];
	if( pipe(input) || pipe(output) || pipe(error) )
		neko_error();
	p = (vprocess*)alloc_private(sizeof(vprocess));
	p->pid = fork();
	if( p->pid == -1 ) {
		do_close(input[0]);
		do_close(input[1]);
		do_close(output[0]);
		do_close(output[1]);
		do_close(error[0]);
		do_close(error[1]);
		neko_error();
	}
	// child
	if( p->pid == 0 ) {
		close(input[1]);
		close(output[0]);
		close(error[0]);
		dup2(input[0],0);
		dup2(output[1],1);
		dup2(error[1],2);
		execvp(val_string(cmd),argv);
		fprintf(stderr,"Command not found : %s\n",val_string(cmd));
		exit(1);
	}
	// parent
	do_close(input[0]);
	do_close(output[1]);
	do_close(error[1]);
	p->iwrite = input[1];
	p->oread = output[0];
	p->eread = error[0];
#	endif
	{
		value vp = alloc_abstract(k_process,p);
		val_gc(vp,free_process);
		return vp;
	}
}
Exemplo n.º 27
0
/**
	process_run : cmd:string -> args:string array -> 'process
	<doc>
	Start a process using a command and the specified arguments.
	When args is not null, cmd and args will be auto-quoted/escaped.
	If no auto-quoting/escaping is desired, you should append necessary 
	arguments to cmd as if it is inputted to the shell directly, and pass
	null as args.
	</doc>
**/
static value process_run( value cmd, value vargs ) {
	int i, isRaw;
	vprocess *p;
	val_check(cmd,string);
	isRaw = val_is_null(vargs);
	if (!isRaw) {
		val_check(vargs,array);
	}
#	ifdef NEKO_WINDOWS
	{		 
		SECURITY_ATTRIBUTES sattr;		
		STARTUPINFO sinf;
		HANDLE proc = GetCurrentProcess();
		HANDLE oread,eread,iwrite;
		// creates commandline
		buffer b = alloc_buffer(NULL);
		value sargs;
		if (isRaw) {
			char* cmdexe = getenv("COMSPEC");
			if (!cmdexe) cmdexe = "cmd.exe";
			buffer_append(b,"\"");
			buffer_append(b,cmdexe);
			buffer_append(b,"\" /C \"");
			buffer_append(b,val_string(cmd));
			buffer_append_char(b,'"');
		} else {
			buffer_append_char(b,'"');
			val_buffer(b,cmd);
			buffer_append_char(b,'"');
			for(i=0;i<val_array_size(vargs);i++) {
				value v = val_array_ptr(vargs)[i];
				int j,len;
				unsigned int bs_count = 0;
				unsigned int k;
				val_check(v,string);
				len = val_strlen(v);
				buffer_append(b," \"");
				for(j=0;j<len;j++) {
					char c = val_string(v)[j];
					switch( c ) {
					case '"':
						// Double backslashes.
						for (k=0;k<bs_count*2;k++) {
							buffer_append_char(b,'\\');
						}
						bs_count = 0;
						buffer_append(b, "\\\"");
						break;
					case '\\':
						// Don't know if we need to double yet.
						bs_count++;
						break;
					default:
						// Normal char
						for (k=0;k<bs_count;k++) {
							buffer_append_char(b,'\\');
						}
						bs_count = 0;
						buffer_append_char(b,c);
						break;
					}
				}
				// Add remaining backslashes, if any.
				for (k=0;k<bs_count*2;k++) {
					buffer_append_char(b,'\\');
				}
				buffer_append_char(b,'"');
			}
		}
		sargs = buffer_to_string(b);
		p = (vprocess*)alloc_private(sizeof(vprocess));
		// startup process
		sattr.nLength = sizeof(sattr);
		sattr.bInheritHandle = TRUE;
		sattr.lpSecurityDescriptor = NULL;
		memset(&sinf,0,sizeof(sinf));
		sinf.cb = sizeof(sinf);
		sinf.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
		sinf.wShowWindow = SW_HIDE;
		CreatePipe(&oread,&sinf.hStdOutput,&sattr,0);
		CreatePipe(&eread,&sinf.hStdError,&sattr,0);
		CreatePipe(&sinf.hStdInput,&iwrite,&sattr,0);
		DuplicateHandle(proc,oread,proc,&p->oread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,eread,proc,&p->eread,0,FALSE,DUPLICATE_SAME_ACCESS);
		DuplicateHandle(proc,iwrite,proc,&p->iwrite,0,FALSE,DUPLICATE_SAME_ACCESS);
		CloseHandle(oread);
		CloseHandle(eread);
		CloseHandle(iwrite);
		if( !CreateProcess(NULL,val_string(sargs),NULL,NULL,TRUE,0,NULL,NULL,&sinf,&p->pinf) )			
			neko_error();
		// close unused pipes
		CloseHandle(sinf.hStdOutput);
		CloseHandle(sinf.hStdError);
		CloseHandle(sinf.hStdInput);
	}
#	else
	char **argv;
	if (isRaw) {
		argv = (char**)alloc_private(sizeof(char*)*4);
		argv[0] = "/bin/sh";
		argv[1] = "-c";
		argv[2] = val_string(cmd);
		argv[3] = NULL;
	} else {
		argv = (char**)alloc_private(sizeof(char*)*(val_array_size(vargs)+2));
		argv[0] = val_string(cmd);
		for(i=0;i<val_array_size(vargs);i++) {
			value v = val_array_ptr(vargs)[i];
			val_check(v,string);
			argv[i+1] = val_string(v);
		}
		argv[i+1] = NULL;
	}
	int input[2], output[2], error[2];
	if( pipe(input) || pipe(output) || pipe(error) )
		neko_error();
	p = (vprocess*)alloc_private(sizeof(vprocess));
	p->pid = fork();
	if( p->pid == -1 ) {
		do_close(input[0]);
		do_close(input[1]);
		do_close(output[0]);
		do_close(output[1]);
		do_close(error[0]);
		do_close(error[1]);
		neko_error();
	}
	// child
	if( p->pid == 0 ) {
		close(input[1]);
		close(output[0]);
		close(error[0]);
		dup2(input[0],0);
		dup2(output[1],1);
		dup2(error[1],2);
		execvp(argv[0],argv);
		fprintf(stderr,"Command not found : %s\n",val_string(cmd));
		exit(1);
	}
	// parent
	do_close(input[0]);
	do_close(output[1]);
	do_close(error[1]);
	p->iwrite = input[1];
	p->oread = output[0];
	p->eread = error[0];
#	endif
	{
		value vp = alloc_abstract(k_process,p);
		val_gc(vp,free_process);
		return vp;
	}
}
Exemplo n.º 28
0
/**
	host_local : void -> string
	<doc>Return the local host name.</doc>
**/
static value host_local() {
	char buf[256];
	if( gethostname(buf,256) == SOCKET_ERROR )
		neko_error();
	return alloc_string(buf);
}