Skip to content
GitLab
Explore
Sign in
Commits on Source (4)
Implement load_jsfile() for duktape
· 046b2a2a
Andrew Price
authored
Jul 09, 2017
046b2a2a
Implement js_bind() and js_exec() with duktape
· 91c9c0c7
Andrew Price
authored
Jul 10, 2017
91c9c0c7
duktape: define 'whoami'
· 7273bb23
Andrew Price
authored
Jul 10, 2017
7273bb23
Build duktape with debugging symbols
· e2de6c24
Andrew Price
authored
Jul 10, 2017
e2de6c24
Hide whitespace changes
Inline
Side-by-side
duktape/Makefile
View file @
e2de6c24
...
...
@@ -5,7 +5,7 @@ include $(DEPTH)Makefile.common
build
:
duktape.o
duktape.o
:
duktape.c duktape.h duk_config.h
$(
CC
)
-std
=
c99
$(
CCSEC
)
duktape.c
-c
$(
CC
)
-std
=
c99
-g
$(
CCSEC
)
duktape.c
-c
clean
:
-
rm
-f
*
.o .
*
.d
*
.d
src/client/js-duk.c
View file @
e2de6c24
#include
<sys/types.h>
#include
<sys/stat.h>
#include
<unistd.h>
#include
<stdio.h>
#include
<errno.h>
#include
<duktape.h>
#include
"js.h"
#include
"alias.h"
#include
"user.h"
extern
struct
user
*
const
user
;
duk_context
*
ctx
;
struct
binding
{
int
type
;
int
name_required
;
alias
**
list
;
const
char
*
name
;
};
const
struct
binding
bindings
[]
=
{
{
K_BIND
,
1
,
&
bind_list
,
"Bind"
},
{
K_BIND_ALIAS
,
1
,
&
alias_list
,
"Alias"
},
{
K_BIND_RPC
,
1
,
&
rpc_list
,
"RPC bind"
},
{
K_BIND_EVENT
,
0
,
&
event_list
,
"Event bind"
},
{
K_BIND_ONOFF
,
0
,
&
onoff_list
,
"Check on/off bind"
},
{
K_BIND_IPC
,
0
,
&
ipc_list
,
"IPC bind"
},
{
K_BIND_FORCE
,
0
,
&
force_list
,
"Force bind"
},
{
K_BIND_SHUTDOWN
,
0
,
&
shutdown_list
,
"Shutdown bind"
},
{
K_BIND_INPUT
,
0
,
&
eventin_list
,
"Input event bind"
},
{
0
,
0
,
NULL
,
NULL
}
};
static
duk_ret_t
js_bind
(
duk_context
*
cx
)
{
const
char
*
bind_name
=
NULL
;
const
char
*
func_name
=
NULL
;
const
struct
binding
*
bind
;
int
bind_type
=
-
1
;
if
(
duk_is_undefined
(
cx
,
-
2
)
||
duk_is_undefined
(
cx
,
-
3
))
{
fprintf
(
stderr
,
"mwjs error: bind() expects 2 or 3 arguments
\n
"
);
return
DUK_RET_SYNTAX_ERROR
;
}
if
(
duk_is_string
(
cx
,
-
3
))
{
bind_name
=
duk_get_string
(
cx
,
-
3
);
bind_type
=
K_BIND
;
if
(
!
duk_is_undefined
(
cx
,
-
1
))
{
fprintf
(
stderr
,
"mwjs error: bind(str, str) expects 2 arguments
\n
"
);
return
DUK_RET_SYNTAX_ERROR
;
}
duk_pop
(
cx
);
}
else
if
(
duk_is_number
(
cx
,
-
3
))
{
bind_type
=
duk_get_int_default
(
cx
,
-
3
,
-
1
);
if
(
bind_type
==
K_BIND
||
bind_type
==
K_BIND_ALIAS
||
bind_type
==
K_BIND_RPC
)
{
bind_name
=
duk_get_string
(
cx
,
-
2
);
}
else
{
duk_pop
(
cx
);
}
}
else
{
fprintf
(
stderr
,
"mwjs error: first argument to bind() must be a "
"string or bind id
\n
"
);
return
DUK_RET_SYNTAX_ERROR
;
}
func_name
=
duk_get_string
(
cx
,
-
1
);
if
(
func_name
==
NULL
)
{
fprintf
(
stderr
,
"mwjs error: bind(): invalid function name
\n
"
);
return
DUK_RET_SYNTAX_ERROR
;
}
for
(
bind
=
&
bindings
[
0
];
bind
->
list
!=
NULL
&&
bind
->
type
!=
bind_type
;
bind
++
);
if
(
bind
->
list
==
NULL
)
{
fprintf
(
stderr
,
"Bind type %d not recognised
\n
"
,
bind_type
);
return
DUK_RET_ERROR
;
}
if
(
bind
->
name_required
)
{
if
(
bind_name
==
NULL
||
bind_name
[
0
]
==
'\0'
)
{
fprintf
(
stderr
,
"Bind name is empty
\n
"
);
return
DUK_RET_ERROR
;
}
}
else
{
bind_name
=
func_name
;
func_name
=
""
;
}
if
(
AddLink
(
bind
->
list
,
bind_name
,
func_name
))
{
fprintf
(
stderr
,
"Warning: %s %s already exists.
\n
"
,
bind
->
name
,
bind_name
);
}
return
0
;
}
int
js_isrunning
(
void
)
{
return
0
;
}
int
js_exec
(
char
*
name
,
int
argc
,
const
char
**
argv
c
)
int
js_exec
(
char
*
name
,
int
argc
,
const
char
**
argv
)
{
int
i
;
if
(
duk_get_global_string
(
ctx
,
name
)
&&
duk_is_function
(
ctx
,
-
1
))
{
for
(
i
=
0
;
i
<
argc
;
i
++
)
duk_push_string
(
ctx
,
argv
[
i
]);
if
(
duk_pcall
(
ctx
,
argc
)
!=
DUK_EXEC_SUCCESS
)
{
if
(
duk_is_error
(
ctx
,
-
1
))
{
duk_get_prop_string
(
ctx
,
-
1
,
"stack"
);
fprintf
(
stderr
,
"mwjs error: %s
\n
"
,
duk_safe_to_string
(
ctx
,
-
1
));
duk_pop
(
ctx
);
}
else
{
fprintf
(
stderr
,
"mwjs error: %s
\n
"
,
duk_safe_to_string
(
ctx
,
-
1
));
}
}
}
duk_pop
(
ctx
);
return
0
;
}
/* This limit is fairly arbitrary but a limit is needed and 256K
seems a reasonable file and (temporary) buffer size */
#define MWJS_FILE_MAX_SIZE (256*1024)
int
load_jsfile
(
FILE
*
f
,
const
char
*
filename
)
{
char
buf
[
MWJS_FILE_MAX_SIZE
+
1
];
int
fd
=
fileno
(
f
);
struct
stat
st
;
size_t
ret
;
if
(
fd
==
-
1
)
{
fprintf
(
stderr
,
"Failed to open '%s': %s
\n
"
,
filename
,
strerror
(
errno
));
return
1
;
}
if
(
fstat
(
fd
,
&
st
)
!=
0
)
{
fprintf
(
stderr
,
"Failed to stat '%s': %s
\n
"
,
filename
,
strerror
(
errno
));
return
1
;
}
errno
=
EFBIG
;
if
(
st
.
st_size
>
MWJS_FILE_MAX_SIZE
)
{
fprintf
(
stderr
,
"Failed to load '%s': %s
\n
"
,
filename
,
strerror
(
errno
));
return
1
;
}
ret
=
fread
(
buf
,
sizeof
(
char
),
st
.
st_size
,
f
);
if
(
ret
!=
st
.
st_size
)
{
fprintf
(
stderr
,
"Failed to read '%s': %llu bytes read
\n
"
,
filename
,
(
unsigned
long
long
)
ret
);
return
1
;
}
buf
[
MWJS_FILE_MAX_SIZE
]
=
'\0'
;
if
(
duk_peval_string
(
ctx
,
buf
)
!=
0
)
{
printf
(
"Failed to execute '%s': %s
\n
"
,
filename
,
duk_safe_to_string
(
ctx
,
-
1
));
}
duk_pop
(
ctx
);
return
0
;
}
int
is_js
(
char
*
name
)
{
return
0
;
int
ret
=
0
;
if
(
duk_get_global_string
(
ctx
,
name
)
&&
duk_is_function
(
ctx
,
-
1
))
ret
=
1
;
duk_pop
(
ctx
);
return
ret
;
}
void
js_stop_execution
(
void
)
...
...
@@ -29,11 +177,59 @@ void js_stop_execution(void)
int
stop_js
(
void
)
{
duk_destroy_heap
(
ctx
);
return
0
;
}
/* The owning object must be at the top of the stack when calling this */
static
void
define_func
(
const
char
*
name
,
duk_c_function
func
,
int
nargs
)
{
duk_push_string
(
ctx
,
name
);
duk_push_c_function
(
ctx
,
func
,
nargs
);
duk_def_prop
(
ctx
,
-
3
,
DUK_DEFPROP_HAVE_VALUE
);
}
/* The owning object must be at the top of the stack when calling this */
static
void
define_number
(
const
char
*
name
,
duk_double_t
num
)
{
duk_push_string
(
ctx
,
name
);
duk_push_number
(
ctx
,
num
);
duk_def_prop
(
ctx
,
-
3
,
DUK_DEFPROP_HAVE_VALUE
);
}
/* The owning object must be at the top of the stack when calling this */
static
void
define_string
(
const
char
*
name
,
const
char
*
value
)
{
duk_push_string
(
ctx
,
name
);
duk_push_string
(
ctx
,
value
);
duk_def_prop
(
ctx
,
-
3
,
DUK_DEFPROP_HAVE_VALUE
);
}
/* The owning object must be at the top of the stack when calling this */
static
void
define_constants
(
void
)
{
define_number
(
"K_BIND_EVENT"
,
(
duk_double_t
)
K_BIND_EVENT
);
define_number
(
"K_BIND_IPC"
,
(
duk_double_t
)
K_BIND_IPC
);
define_number
(
"K_BIND_ONOFF"
,
(
duk_double_t
)
K_BIND_ONOFF
);
define_number
(
"K_BIND_FORCE"
,
(
duk_double_t
)
K_BIND_FORCE
);
define_number
(
"K_BIND_SHUTDOWN"
,
(
duk_double_t
)
K_BIND_SHUTDOWN
);
define_number
(
"K_BIND_RPC"
,
(
duk_double_t
)
K_BIND_RPC
);
define_number
(
"K_BIND_ALIAS"
,
(
duk_double_t
)
K_BIND_ALIAS
);
define_number
(
"K_BIND_INPUT"
,
(
duk_double_t
)
K_BIND_INPUT
);
define_number
(
"K_BROADCAST"
,
(
duk_double_t
)
K_BROADCAST
);
define_string
(
"whoami"
,
user
->
record
.
name
);
}
int
setup_js
(
void
)
{
ctx
=
duk_create_heap_default
();
if
(
ctx
==
NULL
)
return
-
1
;
duk_push_global_object
(
ctx
);
define_constants
();
define_func
(
"bind"
,
js_bind
,
3
);
duk_pop
(
ctx
);
return
0
;
}
...
...
src/client/js-moz.c
View file @
e2de6c24
...
...
@@ -48,9 +48,6 @@ static JSObject *jsroot = NULL;
int
js_interrupted
=
1
;
struct
alarm
*
js_timeout_event
=
NULL
;
enum
bindtype
{
K_BIND
=
0
,
K_BIND_EVENT
,
K_BIND_ONOFF
,
K_BIND_IPC
,
K_BIND_FORCE
,
K_BIND_SHUTDOWN
,
K_BIND_ALIAS
,
K_BIND_RPC
,
K_BIND_INPUT
};
#define K_BROADCAST 1
JSClass
globclass
=
{
"milliways"
,
JSCLASS_GLOBAL_FLAGS
,
JS_PropertyStub
,
JS_PropertyStub
,
JS_PropertyStub
,
JS_StrictPropertyStub
,
...
...
src/client/js.h
View file @
e2de6c24
...
...
@@ -13,4 +13,17 @@ int setup_js(void);
size_t
urldata
(
void
*
ptr
,
size_t
size
,
size_t
nmemb
,
void
*
stream
);
size_t
headlimit
(
void
*
ptr
,
size_t
size
,
size_t
nmemb
,
void
*
stream
);
enum
bindtype
{
K_BIND
=
0
,
K_BIND_EVENT
,
K_BIND_ONOFF
,
K_BIND_IPC
,
K_BIND_FORCE
,
K_BIND_SHUTDOWN
,
K_BIND_ALIAS
,
K_BIND_RPC
,
K_BIND_INPUT
};
#define K_BROADCAST 1
#endif
/* JS_H */