// put the control on screen at x,y struct variable *sys_ui_put(struct context *context) { struct variable *arguments = (struct variable*)stack_pop(context->operand_stack); struct variable *widget = (struct variable*)array_get(arguments->list.ordered, 1); int32_t x = param_int(arguments, 2); int32_t y = param_int(arguments, 3); int32_t w = param_int(arguments, 4); int32_t h = param_int(arguments, 5); hal_ui_put(widget->ptr, x, y, w, h); return NULL; }
struct variable *sys_write(struct context *context) { struct variable *args = (struct variable*)stack_pop(context->operand_stack); struct variable *path = param_var(args, 1); struct variable *v = param_var(args, 2); uint32_t from = param_int(args, 3); uint32_t timestamp = param_int(args, 4); int w = write_file(path->str, v->str, from, timestamp); return variable_new_int(context, w); }
struct variable *sys_sleep(struct context *context) { struct variable *args = (struct variable*)stack_pop(context->operand_stack); int32_t milliseconds = param_int(args, 1); hal_sleep(milliseconds); return NULL; }
struct variable *sys_exit(struct context *context) { struct variable *args = (struct variable*)stack_pop(context->operand_stack); int32_t ret = param_int(args, 1); //printf("\nexit %d\n", ret); exit(ret); return NULL; }
struct variable *sys_listen(struct context *context) { struct variable *arguments = (struct variable*)stack_pop(context->operand_stack); struct listen_arguments *la = (struct listen_arguments*)malloc(sizeof(struct listen_arguments)); la->serverport = param_int(arguments, 1); la->listener = variable_copy(context, (struct variable*)array_get(arguments->list, 2)); pthread_t child; pthread_create(&child, NULL, sys_listen2, la); return NULL; }
// returns contents and modification time of file struct variable *sys_read(struct context *context) { struct variable *args = (struct variable*)stack_pop(context->operand_stack); struct variable *path = param_var(args, 1); uint32_t offset = param_int(args, 2); uint32_t length = param_int(args, 3); struct byte_array *bytes = read_file(path->str, offset, length); DEBUGPRINT("read %d bytes\n", bytes ? bytes->length : 0); struct variable *content = NULL; if (NULL != bytes) { content = variable_new_str(context, bytes); byte_array_del(bytes); } else { context->error = variable_new_str_chars(context, "could not load file"); content = variable_new_nil(context); } return content; }
struct variable *sys_timer(struct context *context) { struct variable *args = (struct variable*)stack_pop(context->operand_stack); int32_t milliseconds = param_int(args, 1); struct variable *logic = param_var(args, 2); bool repeats = false; if (args->list.ordered->length > 3) { struct variable *arg3 = array_get(args->list.ordered, 3); repeats = arg3->integer; } hal_timer(context, milliseconds, logic, repeats); return NULL; }
// deletes file or folder struct variable *sys_mv(struct context *context) { struct variable *value = (struct variable*)stack_pop(context->operand_stack); const char *src = param_str(value, 1); const char *dst = param_str(value, 2); long timestamp = param_int(value, 3); assert_message((strlen(src)>1) && (strlen(dst)>1), "oops"); //printf("mv %s to %s\n", src, dst); create_parent_folder_if_needed(dst); if (rename(src, dst)) perror("rename"); if (timestamp) // to prevent unwanted timestamp updates resulting from the mv file_set_timestamp(dst, timestamp); return NULL; }
struct variable *sys_disconnect(struct context *context) { struct variable *arguments = (struct variable*)stack_pop(context->operand_stack); if (arguments->list->length < 2) { struct variable *sockets = (struct variable *)array_get(arguments->list, 1); assert_message(sockets->type == VAR_LST, "non list of sockets"); for (int i=0; i<sockets->list->length; i++) { struct thread_argument *tc = (struct thread_argument *)array_get(sockets->list, i); close(tc->fd); CyaSSL_free(tc->ssl); } } else { const int32_t fd = param_int(arguments, 1); close(fd); map_remove(socket_listeners, (void*)(VOID_INT)fd); } return NULL; }
struct variable *sys_connect(struct context *context) { struct variable *arguments = (struct variable*)stack_pop(context->operand_stack); const char *serveraddr = param_str(arguments, 1); const int32_t serverport = param_int(arguments, 2); struct variable *listener = ((struct variable*)array_get(arguments->list, 2)); int sockfd; struct sockaddr_in servaddr; CYASSL_CTX* ctx; CYASSL* ssl; node_init(); // Create and initialize CYASSL_CTX structure if ( (ctx = CyaSSL_CTX_new(CyaTLSv1_client_method())) == NULL) { context->vm_exception = variable_new_str(context, byte_array_from_string("SSL_CTX_new error")); CyaSSL_Cleanup(); return NULL; } // Load CA certificates into CYASSL_CTX if (CyaSSL_CTX_load_verify_locations(ctx, "./conf/ca-cert.pem", 0) != SSL_SUCCESS) { context->vm_exception = variable_new_str(context, byte_array_from_string("Error loading ca-cert.pem, please check the file.\n")); CyaSSL_CTX_free(ctx); CyaSSL_Cleanup(); return NULL; } // Create Socket file descriptor sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(serverport); inet_pton(AF_INET, serveraddr, &servaddr.sin_addr); // Blocking Connect to socket file descriptor connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); // Create CYASSL object if ((ssl = CyaSSL_new(ctx)) == NULL) { context->vm_exception = variable_new_str(context, byte_array_from_string("CyaSSL_new error")); CyaSSL_CTX_free(ctx); CyaSSL_Cleanup(); return NULL; } CyaSSL_set_fd(ssl, sockfd); fprintf(stderr, "Connected on %d -- %p\n", sockfd, ssl); struct thread_argument *ta = (struct thread_argument *)malloc(sizeof(struct thread_argument)); ta->find = context->find; ta->listener = listener; ta->ssl = ssl; ta->fd = sockfd; ta->cya = ctx; if (socket_listeners == NULL) socket_listeners = map_new_ex(NULL, &int_compare, &int_hash, &int_copy, &int_del); map_insert(socket_listeners, (void*)(VOID_INT)sockfd, (void*)(VOID_INT)ta); return variable_new_int(context, sockfd); }