void infix2rpn(char *expr, RPNEntry ***rpne, int *nrpne) { Array *rpn = array_new(32, 16); Stack *stack_ops = stack_new(16); //static char token[64]; char *token; int tokenlen; int i; int uminus = 1; int inoperand = 0; //printf("%s:-> ", expr); char lookahead; for(token = gettoken(expr, &tokenlen, &lookahead);token != NULL; token = gettoken(NULL, &tokenlen, &lookahead)) { if (uminus) { if (*token == T_MINUS) { *token = T_UMINUS; } uminus = 0; } if (is_function(token, tokenlen)) { stack_push(stack_ops, token); } else if (is_operand(token)) { array_add(rpn, token); } else if (is_arg_separator(token)) { while(!stack_empty(stack_ops) && !is_lparen(stack_peek(stack_ops))) { array_add(rpn, stack_pop(stack_ops)); } } else if (is_operator(token)) { uminus = 1; if (stack_empty(stack_ops)) { stack_push(stack_ops, token); } else { if (compare_ops(token, stack_peek(stack_ops))) { array_add(rpn, stack_pop(stack_ops)); } stack_push(stack_ops, token); } } else if (is_lparen(token)) { uminus = 1; stack_push(stack_ops, token); } else if (is_rparen(token)) { while(!stack_empty(stack_ops) && !is_lparen(stack_peek(stack_ops))) { array_add(rpn, stack_pop(stack_ops)); } stack_pop(stack_ops); } else { // errorski } } while (!stack_empty(stack_ops)) { array_add(rpn, stack_pop(stack_ops)); } stack_free(&stack_ops); *rpne = (RPNEntry **)malloc(rpn->count * sizeof(RPNEntry*)); for (i = 0; i < rpn->count; i++) { token = array_get(rpn, i); (*rpne)[i] = new_rpnentry(token, strlen(token)); } *nrpne = rpn->count; array_free(&rpn); }
static void service_dup_fds(struct service *service) { struct service_listener *const *listeners; ARRAY_TYPE(dup2) dups; string_t *listener_names; int fd = MASTER_LISTEN_FD_FIRST; unsigned int i, count, socket_listener_count, ssl_socket_count; /* stdin/stdout is already redirected to /dev/null. Other master fds should have been opened with fd_close_on_exec() so we don't have to worry about them. because the destination fd might be another one's source fd we have to be careful not to overwrite anything. dup() the fd when needed */ socket_listener_count = 0; listeners = array_get(&service->listeners, &count); t_array_init(&dups, count + 10); listener_names = t_str_new(256); switch (service->type) { case SERVICE_TYPE_LOG: i_assert(fd == MASTER_LISTEN_FD_FIRST); services_log_dup2(&dups, service->list, fd, &socket_listener_count); fd += socket_listener_count; break; case SERVICE_TYPE_ANVIL: dup2_append(&dups, service_anvil_global->log_fdpass_fd[0], MASTER_ANVIL_LOG_FDPASS_FD); /* nonblocking anvil fd must be the first one. anvil treats it as the master's fd */ dup2_append(&dups, service_anvil_global->nonblocking_fd[0], fd++); dup2_append(&dups, service_anvil_global->blocking_fd[0], fd++); socket_listener_count += 2; break; default: break; } /* anvil/log fds have no names */ for (i = MASTER_LISTEN_FD_FIRST; i < (unsigned int)fd; i++) str_append_c(listener_names, '\t'); /* first add non-ssl listeners */ for (i = 0; i < count; i++) { if (listeners[i]->fd != -1 && (listeners[i]->type != SERVICE_LISTENER_INET || !listeners[i]->set.inetset.set->ssl)) { str_append_tabescaped(listener_names, listeners[i]->name); str_append_c(listener_names, '\t'); dup2_append(&dups, listeners[i]->fd, fd++); socket_listener_count++; } } /* then ssl-listeners */ ssl_socket_count = 0; for (i = 0; i < count; i++) { if (listeners[i]->fd != -1 && listeners[i]->type == SERVICE_LISTENER_INET && listeners[i]->set.inetset.set->ssl) { str_append_tabescaped(listener_names, listeners[i]->name); str_append_c(listener_names, '\t'); dup2_append(&dups, listeners[i]->fd, fd++); socket_listener_count++; ssl_socket_count++; } } if (service->login_notify_fd != -1) { dup2_append(&dups, service->login_notify_fd, MASTER_LOGIN_NOTIFY_FD); } switch (service->type) { case SERVICE_TYPE_LOG: case SERVICE_TYPE_ANVIL: case SERVICE_TYPE_CONFIG: dup2_append(&dups, null_fd, MASTER_ANVIL_FD); break; case SERVICE_TYPE_UNKNOWN: case SERVICE_TYPE_LOGIN: case SERVICE_TYPE_STARTUP: dup2_append(&dups, service_anvil_global->blocking_fd[1], MASTER_ANVIL_FD); break; } dup2_append(&dups, service->status_fd[1], MASTER_STATUS_FD); if (service->type != SERVICE_TYPE_ANVIL) { dup2_append(&dups, service->list->master_dead_pipe_fd[1], MASTER_DEAD_FD); } else { dup2_append(&dups, global_master_dead_pipe_fd[1], MASTER_DEAD_FD); } if (service->type == SERVICE_TYPE_LOG) { /* keep stderr as-is. this is especially important when log_path=/dev/stderr, but might be helpful even in other situations for logging startup errors */ } else { /* set log file to stderr. dup2() here immediately so that we can set up logging to it without causing any log messages to be lost. */ i_assert(service->log_fd[1] != -1); env_put("LOG_SERVICE=1"); if (dup2(service->log_fd[1], STDERR_FILENO) < 0) i_fatal("dup2(log fd) failed: %m"); i_set_failure_internal(); } /* make sure we don't leak syslog fd. try to do it as late as possible, but also before dup2()s in case syslog fd is one of them. */ closelog(); if (dup2_array(&dups) < 0) i_fatal("service(%s): dup2s failed", service->set->name); i_assert(fd == MASTER_LISTEN_FD_FIRST + (int)socket_listener_count); env_put(t_strdup_printf("SOCKET_COUNT=%d", socket_listener_count)); env_put(t_strdup_printf("SSL_SOCKET_COUNT=%d", ssl_socket_count)); env_put(t_strdup_printf("SOCKET_NAMES=%s", str_c(listener_names))); }
static struct tagMap* tagMap_create(struct array* array, uint32_t nb_category, struct categoryDesc* desc_buffer, int32_t(*compare)(const void*,const void*)){ uint32_t i; uint32_t j; uint32_t k; struct array* element_array; uint32_t nb_tag = 0; void* tree_root = NULL; struct tagMapTreeToken* new_token = NULL; struct tagMapTreeToken** result; struct tagMap* tag_map = NULL; for (i = 0; i < nb_category; i++){ desc_buffer[i].tagMap_gateway = NULL; } for (i = 0; i < nb_category; i++){ if ((desc_buffer[i].tagMap_gateway = (void***)calloc(desc_buffer[i].nb_element, sizeof(void**))) == NULL){ log_err("unable to allocate memory"); goto exit; } for (j = 0; j < desc_buffer[i].nb_element; j++){ element_array = *(struct array**)array_get(array, desc_buffer[i].offset + j); if (!array_get_length(element_array)){ desc_buffer[i].tagMap_gateway[j] = NULL; } else{ if ((desc_buffer[i].tagMap_gateway[j] = malloc(array_get_length(element_array) * sizeof(void*))) == NULL){ log_err("unable to allocate memory"); goto exit; } for (k = 0; k < array_get_length(element_array); k++){ if (new_token == NULL){ if ((new_token = malloc(sizeof(struct tagMapTreeToken))) == NULL){ log_err("unable to allocate memory"); goto exit; } } new_token->element = array_get(element_array, k); new_token->idx = nb_tag; result = tsearch(new_token, &tree_root, compare); if (result == NULL){ log_err("tsearch failed to insert new item"); goto exit; } else if (*result == new_token){ new_token = NULL; nb_tag ++; } desc_buffer[i].tagMap_gateway[j][k] = *result; } } } } if (nb_tag){ if ((tag_map = malloc(sizeof(struct tagMap) + nb_tag * sizeof(uint32_t))) == NULL){ log_err("unable to allocate memory"); goto exit; } tag_map->nb_element = nb_tag; tag_map->map = (uint32_t*)(tag_map + 1); for (i = 0; i < nb_category; i++){ for (j = 0; j < desc_buffer[i].nb_element; j++){ element_array = *(struct array**)array_get(array, desc_buffer[i].offset + j); for (k = 0; k < array_get_length(element_array); k++){ desc_buffer[i].tagMap_gateway[j][k] = tag_map->map + ((struct tagMapTreeToken*)(desc_buffer[i].tagMap_gateway[j][k]))->idx; } } } } exit: if (new_token != NULL){ free(new_token); } tdestroy(tree_root, free); return tag_map; }
VALUE snow_arguments_get_by_index(SnArguments* args, intx idx) { return array_get(DATA, idx); }
static int zeqproc(i_ctx_t *i_ctx_p) { os_ptr op = osp; ref2_t stack[MAX_DEPTH + 1]; ref2_t *top = stack; make_array(&stack[0].proc1, 0, 1, op - 1); make_array(&stack[0].proc2, 0, 1, op); for (;;) { long i; if (r_size(&top->proc1) == 0) { /* Finished these arrays, go up to next level. */ if (top == stack) { /* We're done matching: it succeeded. */ make_true(op - 1); pop(1); return 0; } --top; continue; } /* Look at the next elements of the arrays. */ i = r_size(&top->proc1) - 1; array_get(imemory, &top->proc1, i, &top[1].proc1); array_get(imemory, &top->proc2, i, &top[1].proc2); r_dec_size(&top->proc1, 1); ++top; /* * Amazingly enough, the objects' executable attributes are not * required to match. This means { x load } will match { /x load }, * even though this is clearly wrong. */ #if 0 if (r_has_attr(&top->proc1, a_executable) != r_has_attr(&top->proc2, a_executable) ) break; #endif if (obj_eq(imemory, &top->proc1, &top->proc2)) { /* Names don't match strings. */ if (r_type(&top->proc1) != r_type(&top->proc2) && (r_type(&top->proc1) == t_name || r_type(&top->proc2) == t_name) ) break; --top; /* no recursion */ continue; } if (r_is_array(&top->proc1) && r_is_array(&top->proc2) && r_size(&top->proc1) == r_size(&top->proc2) && top < stack + (MAX_DEPTH - 1) ) { /* Descend into the arrays. */ continue; } break; } /* An exit from the loop indicates that matching failed. */ make_false(op - 1); pop(1); return 0; }
rstatus_t modula_update(struct server_pool *pool) { uint32_t nserver; /* # server - live and dead */ uint32_t nlive_server; /* # live server */ uint32_t pointer_per_server; /* pointers per server proportional to weight */ uint32_t pointer_counter; /* # pointers on continuum */ uint32_t points_per_server; /* points per server */ uint32_t continuum_index; /* continuum index */ uint32_t continuum_addition; /* extra space in the continuum */ uint32_t server_index; /* server index */ uint32_t weight_index; /* weight index */ uint32_t total_weight; /* total live server weight */ int64_t now; /* current timestamp in usec */ now = nc_usec_now(); if (now < 0) { return NC_ERROR; } nserver = array_n(&pool->server); nlive_server = 0; total_weight = 0; pool->next_rebuild = 0LL; for (server_index = 0; server_index < nserver; server_index++) { struct server *server = array_get(&pool->server, server_index); if (pool->auto_eject_hosts) { if (server->fail == 0) { nlive_server++; } } else { nlive_server++; } ASSERT(server->weight > 0); /* count weight only for live servers */ if (!pool->auto_eject_hosts || server->fail == 0) { total_weight += server->weight; } } pool->nlive_server = nlive_server; if (nlive_server == 0) { ASSERT(pool->continuum != NULL); ASSERT(pool->ncontinuum != 0); log_debug(LOG_DEBUG, "no live servers for pool %"PRIu32" '%.*s'", pool->idx, pool->name.len, pool->name.data); return NC_OK; } log_debug(LOG_DEBUG, "%"PRIu32" of %"PRIu32" servers are live for pool " "%"PRIu32" '%.*s'", nlive_server, nserver, pool->idx, pool->name.len, pool->name.data); continuum_addition = MODULA_CONTINUUM_ADDITION; points_per_server = MODULA_POINTS_PER_SERVER; /* * Allocate the continuum for the pool, the first time, and every time we * add a new server to the pool */ if (total_weight > pool->nserver_continuum) { struct continuum *continuum; uint32_t nserver_continuum = total_weight + MODULA_CONTINUUM_ADDITION; uint32_t ncontinuum = nserver_continuum * MODULA_POINTS_PER_SERVER; continuum = nc_realloc(pool->continuum, sizeof(*continuum) * ncontinuum); if (continuum == NULL) { return NC_ENOMEM; } pool->continuum = continuum; pool->nserver_continuum = nserver_continuum; /* pool->ncontinuum is initialized later as it could be <= ncontinuum */ } /* update the continuum with the servers that are live */ continuum_index = 0; pointer_counter = 0; for (server_index = 0; server_index < nserver; server_index++) { struct server *server = array_get(&pool->server, server_index); if (pool->auto_eject_hosts && server->next_retry > now) { continue; } for (weight_index = 0; weight_index < server->weight; weight_index++) { pointer_per_server = 1; pool->continuum[continuum_index].index = server_index; pool->continuum[continuum_index++].value = 0; pointer_counter += pointer_per_server; } } pool->ncontinuum = pointer_counter; log_debug(LOG_VERB, "updated pool %"PRIu32" '%.*s' with %"PRIu32" of " "%"PRIu32" servers live in %"PRIu32" slots and %"PRIu32" " "active points in %"PRIu32" slots", pool->idx, pool->name.len, pool->name.data, nlive_server, nserver, pool->nserver_continuum, pool->ncontinuum, (pool->nserver_continuum + continuum_addition) * points_per_server); return NC_OK; }
array_t * parse (lexer_t *lex) { unsigned i; array_t stack; array_init(&stack, sizeof(parser_stack_t)); parser_stack_t initial; bzero(&initial, sizeof(initial)); array_add(&stack, &initial); array_t *result = 0; while (stack.size > 0) { parser_stack_t *current = array_get(&stack, stack.size-1); const parser_state_t *state = parser_states + current->state; for (i = 0; i < state->num_actions; ++i) if (state->actions[i].token == lex->token) break; if (i >= state->num_actions) { char *msg = strdup("syntax error, expected"); for (i = 0; i < state->num_actions; ++i) { char *glue; if (i == 0) glue = " "; else if (i == state->num_actions-1) glue = ", or "; else glue = ", "; char *nmsg; asprintf(&nmsg, "%s%s\"%s\"", msg, glue, token_names[state->actions[i].token]); free(msg); msg = nmsg; } derror(&lex->loc, "%s\n", msg); free(msg); } const parser_action_t *action = &state->actions[i]; if (action->state_or_length < 0) { if (action->rule == 0) { result = current->token.ptr; break; } unsigned num_tokens = -action->state_or_length; parser_stack_t *target = array_get(&stack, stack.size-num_tokens); parser_stack_t *base = array_get(&stack, stack.size-num_tokens-1); const parser_state_t *base_state = parser_states + base->state; token_t reduced = target->token; reduced.id = action->rule; reduced.last = current->token.last; if (action->reducer) { token_t tokens[num_tokens]; for (i = 0; i < num_tokens; ++i) tokens[i] = (target+i)->token; action->reducer(&reduced, tokens, action->reducer_tag); } target->token = reduced; for (i = 0; i < base_state->num_gotos; ++i) { if (base_state->gotos[i].rule == action->rule) { target->state = base_state->gotos[i].state; break; } } array_resize(&stack, stack.size-num_tokens+1); } else { parser_stack_t *new_stack = array_add(&stack, 0); bzero(new_stack, sizeof(*new_stack)); new_stack->state = action->state_or_length; new_stack->token.id = lex->token; new_stack->token.first = lex->base; new_stack->token.last = lex->ptr; new_stack->token.loc = lex->loc; lexer_next(lex); } } array_dispose(&stack); return result; }
static bool ext_include_binary_pre_save (const struct sieve_extension *ext ATTR_UNUSED, struct sieve_binary *sbin ATTR_UNUSED, void *context, enum sieve_error *error_r) { struct ext_include_binary_context *binctx = (struct ext_include_binary_context *) context; struct ext_include_script_info *const *scripts; struct sieve_binary_block *sblock = binctx->dependency_block; unsigned int script_count, i; bool result = TRUE; sieve_binary_block_clear(sblock); scripts = array_get(&binctx->include_index, &script_count); sieve_binary_emit_unsigned(sblock, script_count); for ( i = 0; i < script_count; i++ ) { struct ext_include_script_info *incscript = scripts[i]; if ( incscript->block != NULL ) { sieve_binary_emit_unsigned (sblock, sieve_binary_block_get_id(incscript->block)); } else { sieve_binary_emit_unsigned(sblock, 0); } sieve_binary_emit_byte(sblock, incscript->location); sieve_binary_emit_cstring(sblock, sieve_script_name(incscript->script)); sieve_binary_emit_byte(sblock, incscript->flags);
int cmd_cd (Shell *shell, void *args) { char *new_pwd; if (!array_is_empty (args)) { if (0 == strcmp ("-", array_get (args, 0))) { if ( (new_pwd = getenv ("OLDPWD")) ) { new_pwd = strdup (new_pwd); } else { fprintf (stderr, "Failed to get previous directory.\n"); return -1; } } else { new_pwd = strdup (array_get (args, 0)); } } else if (!get_home_dir ()) { fprintf (stderr, "Failed to get home directory.\n"); return -1; } else { new_pwd = strdup (get_home_dir ()); } char *old_pwd = get_cwd (); if (0 != chdir (new_pwd)) { fprintf (stderr, "Failed to change directory to \"%s\".\n", new_pwd); return -1; } // Because new_cwd does not contain an absolute path. free (new_pwd); if (old_pwd) { setenv ("OLDPWD", old_pwd, 1); free (old_pwd); } else { unsetenv ("OLDPWD"); } if ( (new_pwd = get_cwd ()) ) { setenv ("PWD", new_pwd, 1); free (new_pwd); } else { unsetenv ("PWD"); } return 0; }
static void test_seq_range_array_random(void) { #define SEQ_RANGE_TEST_BUFSIZE 100 #define SEQ_RANGE_TEST_COUNT 20000 unsigned char shadowbuf[SEQ_RANGE_TEST_BUFSIZE]; ARRAY_TYPE(seq_range) range; const struct seq_range *seqs; uint32_t seq1, seq2; unsigned int i, j, ret, ret2, count; int test = -1; ret = ret2 = 0; i_array_init(&range, 1); memset(shadowbuf, 0, sizeof(shadowbuf)); for (i = 0; i < SEQ_RANGE_TEST_COUNT; i++) { seq1 = rand() % SEQ_RANGE_TEST_BUFSIZE; seq2 = seq1 + rand() % (SEQ_RANGE_TEST_BUFSIZE - seq1); test = rand() % 4; switch (test) { case 0: ret = seq_range_array_add(&range, seq1) ? 0 : 1; /* FALSE == added */ ret2 = shadowbuf[seq1] == 0 ? 1 : 0; shadowbuf[seq1] = 1; break; case 1: ret = seq_range_array_add_range_count(&range, seq1, seq2); for (ret2 = 0; seq1 <= seq2; seq1++) { if (shadowbuf[seq1] == 0) { ret2++; shadowbuf[seq1] = 1; } } break; case 2: ret = seq_range_array_remove(&range, seq1) ? 1 : 0; ret2 = shadowbuf[seq1] != 0 ? 1 : 0; shadowbuf[seq1] = 0; break; case 3: ret = seq_range_array_remove_range(&range, seq1, seq2); for (ret2 = 0; seq1 <= seq2; seq1++) { if (shadowbuf[seq1] != 0) { ret2++; shadowbuf[seq1] = 0; } } break; } if (ret != ret2) break; seqs = array_get(&range, &count); for (j = 0, seq1 = 0; j < count; j++) { if (j > 0 && seqs[j-1].seq2+1 >= seqs[j].seq1) goto fail; for (; seq1 < seqs[j].seq1; seq1++) { if (shadowbuf[seq1] != 0) goto fail; } for (; seq1 <= seqs[j].seq2; seq1++) { if (shadowbuf[seq1] == 0) goto fail; } } i_assert(seq1 <= SEQ_RANGE_TEST_BUFSIZE); for (; seq1 < SEQ_RANGE_TEST_BUFSIZE; seq1++) { if (shadowbuf[seq1] != 0) goto fail; } } fail: if (i == SEQ_RANGE_TEST_COUNT) test_out("seq_range_array random", TRUE); else { test_out_reason("seq_range_array random", FALSE, t_strdup_printf("round %u test %d failed", i, test)); } array_free(&range); }
struct fildes *ftab_get(struct array *OFtable, int fd) { return array_get(OFtable, fd); }
ARRAY_TYPE(uint32_t) qresync_sample_uidset; bool condstore:1; }; static int select_qresync_get_uids(struct imap_select_context *ctx, const ARRAY_TYPE(seq_range) *seqset, const ARRAY_TYPE(seq_range) *uidset) { const struct seq_range *uid_range; struct seq_range_iter seq_iter; unsigned int i, uid_count, diff, n = 0; uint32_t seq; /* change all n:m ranges to n,m and store the results */ uid_range = array_get(uidset, &uid_count); seq_range_array_iter_init(&seq_iter, seqset); i_array_init(&ctx->qresync_sample_uidset, uid_count); i_array_init(&ctx->qresync_sample_seqset, uid_count); for (i = 0; i < uid_count; i++) { if (!seq_range_array_iter_nth(&seq_iter, n++, &seq)) return -1; array_append(&ctx->qresync_sample_uidset, &uid_range[i].seq1, 1); array_append(&ctx->qresync_sample_seqset, &seq, 1); diff = uid_range[i].seq2 - uid_range[i].seq1; if (diff > 0) { n += diff - 1; if (!seq_range_array_iter_nth(&seq_iter, n++, &seq))
#include "index-storage.h" #include "index-search-result.h" static void search_result_range_remove(struct mail_search_result *result, const ARRAY_TYPE(seq_range) *changed_uids_arr, unsigned int *idx, uint32_t *next_uid, uint32_t last_uid) { const struct seq_range *uids; unsigned int i, count; uint32_t uid; /* remove full seq_ranges */ uid = *next_uid; uids = array_get(changed_uids_arr, &count); for (i = *idx; uids[i].seq2 < last_uid;) { i_assert(uids[i].seq1 <= uid); for (; uid <= uids[i].seq2; uid++) mailbox_search_result_remove(result, uid); i++; i_assert(i < count); uid = uids[i].seq1; } /* remove the last seq_range */ i_assert(uids[i].seq1 <= uid && uids[i].seq2 >= last_uid); for (; uid <= last_uid; uid++) mailbox_search_result_remove(result, uid); if (uid > uids[i].seq2) {
static struct ring_msg * dmsg_parse(struct dmsg *dmsg) { //rstatus_t status; uint8_t *p, *q, *start, *end, *pipe_p; uint8_t *host_id, *host_addr, *ts, *node_state; uint32_t k, delimlen, host_id_len, host_addr_len, ts_len, node_state_len; char delim[] = ",,,"; delimlen = 3; /* parse "host_id1,generation_ts1,host_state1,host_broadcast_address1|host_id2,generation_ts2,host_state2,host_broadcast_address2" */ /* host_id = dc-rack-token */ //p = dmsg->data + dmsg->mlen - 1; //p = dmsg->owner->pos + dmsg->owner->mlen - 1; p = dmsg->payload + dmsg->plen - 1; end = p; //start = dmsg->data; //start = dmsg->owner->pos; start = dmsg->payload; host_id = NULL; host_addr = NULL; ts = NULL; node_state = NULL; host_id_len = 0; host_addr_len = 0; ts_len = 0; node_state_len = 0; pipe_p = start; int count = 0; do { q = dn_strrchr(p, start, '|'); count++; p = q - 1; } while (q != NULL); struct ring_msg *ring_msg = create_ring_msg_with_size(count, true); if (ring_msg == NULL) { log_debug(LOG_ERR, "Error: unable to create a new ring msg!"); //we just drop this msg return NULL; } struct server_pool *sp = (struct server_pool *) dmsg->owner->owner->owner; ring_msg->sp = sp; ring_msg->cb = gossip_msg_peer_update; count = 0; //p = dmsg->data + dmsg->mlen - 1; p = dmsg->payload + dmsg->plen - 1; do { for (k = 0; k < sizeof(delim)-1; k++) { q = dn_strrchr(p, start, delim[k]); switch (k) { case 0: host_addr = q + 1; host_addr_len = (uint32_t)(p - host_addr + 1); break; case 1: node_state = q + 1; node_state_len = (uint32_t)(p - node_state + 1); break; case 2: ts = q + 1; ts_len = (uint32_t)(p - ts + 1); break; default: NOT_REACHED(); } p = q - 1; } if (k != delimlen) { loga("Error: this is insanely bad"); return NULL;// DN_ERROR; } pipe_p = dn_strrchr(p, start, '|'); if (pipe_p == NULL) { pipe_p = start; } else { pipe_p = pipe_p + 1; p = pipe_p - 2; } //host_id = dmsg->data; //host_id_len = dmsg->mlen - (host_addr_len + node_state_len + ts_len + 3); host_id = pipe_p; host_id_len = end - pipe_p - (host_addr_len + node_state_len + ts_len + 3) + 1; end = p; struct node *rnode = (struct node *) array_get(&ring_msg->nodes, count); dmsg_parse_host_id(host_id, host_id_len, &rnode->dc, &rnode->rack, &rnode->token); string_copy(&rnode->name, host_addr, host_addr_len); string_copy(&rnode->pname, host_addr, host_addr_len); //need to add port rnode->port = sp->d_port; rnode->is_local = false; rnode->is_seed = false; ts[ts_len] = '\0'; rnode->ts = atol(ts); node_state[node_state_len] = '\0'; rnode->state = (uint8_t) atoi(node_state); count++; } while (pipe_p != start); //TODOs: should move this outside dmsg_to_gossip(ring_msg); return ring_msg; }
bool array_pop_back(array_t *ar, void *dst) { if (!ar->count || !dst) return false; memcpy((uint8_t*)dst, (uint8_t*)array_get(ar, ar->count-1), ar->esize); ar->count -= 1; }
/* * Function called when user-level code hits a fatal fault. */ static void kill_curthread(vaddr_t epc, unsigned code, vaddr_t vaddr) { int sig = 0; KASSERT(code < NTRAPCODES); switch (code) { case EX_IRQ: case EX_IBE: case EX_DBE: case EX_SYS: /* should not be seen */ KASSERT(0); sig = SIGABRT; break; case EX_MOD: case EX_TLBL: case EX_TLBS: sig = SIGSEGV; break; case EX_ADEL: case EX_ADES: sig = SIGBUS; break; case EX_BP: sig = SIGTRAP; break; case EX_RI: sig = SIGILL; break; case EX_CPU: sig = SIGSEGV; break; case EX_OVF: sig = SIGFPE; break; } /* * You will probably want to change this. */ #if OPT_A3 (void)epc; (void)vaddr; struct addrspace *as; struct proc *p = curproc; int parentLocation = locatePid(p->p_pid); struct procStruct *parentProcStr = array_get(procStructArray, parentLocation); parentProcStr->exitcode = _MKWAIT_SIG(sig); cleanChildren(parentLocation); V(parentProcStr->proc_sem); KASSERT(curproc->p_addrspace != NULL); as_deactivate(); /* * clear p_addrspace before calling as_destroy. Otherwise if * as_destroy sleeps (which is quite possible) when we * come back we'll be calling as_activate on a * half-destroyed address space. This tends to be * messily fatal. */ as = curproc_setas(NULL); as_destroy(as); /* detach this thread from its process */ /* note: curproc cannot be used after this call */ proc_remthread(curthread); /* if this is the last user process in the system, proc_destroy() will wake up the kernel menu thread */ proc_destroy(p); thread_exit(); /* thread_exit() does not return, so we should never get here */ panic("return from thread_exit in sys_exit\n"); #else kprintf("Fatal user mode trap %u sig %d (%s, epc 0x%x, vaddr 0x%x)\n", code, sig, trapcodenames[code], epc, vaddr); panic("I don't know how to handle this\n"); #endif }
/* or a negative error code. */ int build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype, gs_memory_type_ptr_t pstype, const build_proc_refs * pbuild, build_font_options_t options) { ref kname; /* t_string */ ref *pftype; ref *pencoding = 0; bool bitmapwidths; int exactsize, inbetweensize, transformedchar; int wmode; int code; gs_font *pfont; ref *pfid; ref *aop = dict_access_ref(op); bool cpsi_mode = gs_currentcpsimode(imemory); get_font_name(imemory, &kname, op - 1); if (dict_find_string(op, "FontType", &pftype) <= 0 || !r_has_type(pftype, t_integer) || pftype->value.intval != (int)ftype ) return_error(e_invalidfont); if (dict_find_string(op, "Encoding", &pencoding) <= 0) { if (!(options & bf_Encoding_optional)) return_error(e_invalidfont); pencoding = 0; } else { if (!r_is_array(pencoding)) return_error(e_invalidfont); } if (pencoding) { /* observed Adobe behavior */ int count = r_size(pencoding); int type = ftype ? t_name : t_integer; bool fixit = false; while (count--) { ref r; if ((code = array_get(imemory, pencoding, count, &r)) < 0 || !(r_has_type(&r, type) || r_has_type(&r, t_null))) { if (!cpsi_mode && ftype == ft_user_defined) { if (code < 0 || r_has_type(&r, t_null)) { return_error(e_typecheck); } fixit = true; break; } else { return_error(e_typecheck); } } } /* For at least Type 3 fonts, Adobe Distiller will "fix" an Encoding array, as in, for example * Bug 692681 where the arrays contain integers rather than names. Once the font is instantiated * the integers have been converted to names. * It is preferable to to this manipulation here, rather than in Postscript, because we are less * restricted by read-only attributes and VM save levels. */ if (fixit) { ref penc; uint size = 0; char buf[32], *bptr; avm_space curglob = ialloc_space(idmemory); avm_space useglob = r_is_local(pencoding) ? avm_local : avm_global; ialloc_set_space(idmemory, useglob); count = r_size(pencoding); if ((code = ialloc_ref_array(&penc, (r_type_attrs(pencoding) & a_readonly), count, "build_gs_font")) < 0) return code; while (count--) { ref r; if (array_get(imemory, pencoding, count, &r) < 0){ return_error(e_typecheck); } /* For type 3, we know the Encoding entries must be names */ if (r_has_type(&r, t_name)){ ref_assign(&(penc.value.refs[count]), &r); } else { if ((code = obj_cvs(imemory, &r, (byte *)buf, 32, &size, (const byte **)(&bptr))) < 0) { return(code); } if ((code = name_ref(imemory, (const byte *)bptr, size, &r, true)) < 0) return code; ref_assign(&(penc.value.refs[count]), &r); } } if ((code = dict_put_string(osp, "Encoding", &penc, NULL)) < 0) return code; ialloc_set_space(idmemory, curglob); } } if ((code = dict_int_param(op, "WMode", 0, 1, 0, &wmode)) < 0 || (code = dict_bool_param(op, "BitmapWidths", false, &bitmapwidths)) < 0 || (code = dict_int_param(op, "ExactSize", 0, 2, fbit_use_bitmaps, &exactsize)) < 0 || (code = dict_int_param(op, "InBetweenSize", 0, 2, fbit_use_outlines, &inbetweensize)) < 0 || (code = dict_int_param(op, "TransformedChar", 0, 2, fbit_use_outlines, &transformedchar)) < 0 ) return code; code = dict_find_string(op, "FID", &pfid); if (code > 0 && r_has_type(pfid, t_fontID)) { /* silently ignore invalid FID per CET 13-05.ps */ /* * If this font has a FID entry already, it might be a scaled font * made by makefont or scalefont; in a Level 2 environment, it might * be an existing font being registered under a second name, or a * re-encoded font (which was invalid in Level 1, but dvips did it * anyway). */ pfont = r_ptr(pfid, gs_font); /* * If the following condition is false this is a re-encoded font, * or some other questionable situation in which the FID * was preserved. Pretend the FID wasn't there. */ if (obj_eq(pfont->memory, pfont_dict(pfont), op)) { if (pfont->base == pfont) { /* original font */ if (!level2_enabled) return_error(e_invalidfont); *ppfont = pfont; return 1; } else { /* This was made by makefont or scalefont. */ /* Just insert the new name. */ gs_matrix mat; ref fname; /* t_string */ code = sub_font_params(imemory, op, &mat, NULL, &fname); if (code < 0) return code; code = 1; copy_font_name(&pfont->font_name, &fname); goto set_name; } } } /* This is a new font. */ if (!r_has_attr(aop, a_write)) return_error(e_invalidaccess); { ref encoding; /* * Since add_FID may resize the dictionary and cause * pencoding to become invalid, save the Encoding. */ if (pencoding) { encoding = *pencoding; pencoding = &encoding; } code = build_gs_sub_font(i_ctx_p, op, &pfont, ftype, pstype, pbuild, pencoding, op); if (code < 0) return code; } pfont->BitmapWidths = bitmapwidths; pfont->ExactSize = (fbit_type)exactsize; pfont->InBetweenSize = (fbit_type)inbetweensize; pfont->TransformedChar = (fbit_type)transformedchar; pfont->WMode = wmode; pfont->procs.font_info = zfont_info; code = 0; set_name: copy_font_name(&pfont->key_name, &kname); *ppfont = pfont; return code; }
static int usb_enumerate(void) { int result = -1; libusb_device **devices; libusb_device *device; int rc; int i = 0; struct libusb_device_descriptor descriptor; uint8_t bus_number; uint8_t device_address; bool known; int k; USBStack *usb_stack; // get all devices rc = libusb_get_device_list(_context, &devices); if (rc < 0) { log_error("Could not get USB device list: %s (%d)", usb_get_error_name(rc), rc); return -1; } // check for stacks for (device = devices[0]; device != NULL; device = devices[++i]) { bus_number = libusb_get_bus_number(device); device_address = libusb_get_device_address(device); rc = libusb_get_device_descriptor(device, &descriptor); if (rc < 0) { log_warn("Could not get device descriptor for USB device (bus: %u, device: %u), ignoring USB device: %s (%d)", bus_number, device_address, usb_get_error_name(rc), rc); continue; } if (descriptor.idVendor == USB_BRICK_VENDOR_ID && descriptor.idProduct == USB_BRICK_PRODUCT_ID) { if (descriptor.bcdDevice < USB_BRICK_DEVICE_RELEASE) { log_warn("USB device (bus: %u, device: %u) has unsupported protocol 1.0 firmware, please update firmware, ignoring USB device", bus_number, device_address); continue; } } else if (descriptor.idVendor == USB_RED_BRICK_VENDOR_ID && descriptor.idProduct == USB_RED_BRICK_PRODUCT_ID) { if (descriptor.bcdDevice < USB_RED_BRICK_DEVICE_RELEASE) { log_warn("USB device (bus: %u, device: %u) has unexpected release version, ignoring USB device", bus_number, device_address); continue; } } else { continue; } // check all known stacks known = false; for (k = 0; k < _usb_stacks.count; ++k) { usb_stack = array_get(&_usb_stacks, k); if (usb_stack->bus_number == bus_number && usb_stack->device_address == device_address) { // mark known USBStack as connected usb_stack->connected = true; known = true; break; } } if (known) { continue; } // create new USBStack object log_debug("Found new USB device (bus: %u, device: %u)", bus_number, device_address); usb_stack = array_append(&_usb_stacks); if (usb_stack == NULL) { log_error("Could not append to USB stacks array: %s (%d)", get_errno_name(errno), errno); goto cleanup; } if (usb_stack_create(usb_stack, bus_number, device_address) < 0) { array_remove(&_usb_stacks, _usb_stacks.count - 1, NULL); log_warn("Ignoring USB device (bus: %u, device: %u) due to an error", bus_number, device_address); continue; } // mark new stack as connected usb_stack->connected = true; log_info("Added USB device (bus: %u, device: %u) at index %d: %s", usb_stack->bus_number, usb_stack->device_address, _usb_stacks.count - 1, usb_stack->base.name); } result = 0; cleanup: libusb_free_device_list(devices, 1); return result; }
int main(int argc, char* const* argv) { static int debug_mode = false; static int verbose_mode = false; static int interactive_mode = false; ObjectPtr<Array> require_files = create_array(); while (true) { int c; static struct option long_options[] = { {"debug", no_argument, &debug_mode, 'd'}, {"version", no_argument, NULL, 'v'}, {"require", required_argument, NULL, 'r'}, {"interactive", no_argument, &interactive_mode, 1 }, {"verbose", no_argument, &verbose_mode, 1 }, {0,0,0,0} }; int option_index = -1; c = getopt_long(argc, argv, "dvir:", long_options, &option_index); if (c < 0) break; switch (c) { case 'v': { print_version_info(); return 0; } case 'r': { ObjectPtr<String> filename = create_string_constant(optarg); array_push(require_files, filename); break; } case 'i': { interactive_mode = true; break; } case '?': TRAP(); // unknown argument default: break; } } // require first loose argument, unless -- was used if (optind < argc && strcmp("--", argv[optind-1]) != 0) { ObjectPtr<String> filename = create_string_constant(argv[optind++]); array_push(require_files, filename); } // stuff the rest in ARGV ObjectPtr<Array> ARGV = create_array_with_size(argc); while (optind < argc) { ObjectPtr<String> argument = create_string_constant(argv[optind++]); array_push(ARGV, argument); } set_global(snow::sym("ARGV"), ARGV); for (size_t i = 0; i < array_size(require_files); ++i) { ObjectPtr<String> str = array_get(require_files, i); ASSERT(str != NULL); load(str); } if (interactive_mode) { interactive_prompt(); } return 0; }
for (; seq <= message_count; seq++, rec++) { if ((rec->flags & flags_mask) == (uint8_t)flags) { *seq_r = seq; break; } } } static void keyword_index_add(ARRAY_TYPE(keyword_indexes) *keywords, unsigned int idx) { const unsigned int *indexes; unsigned int i, count; indexes = array_get(keywords, &count); for (i = 0; i < count; i++) { if (indexes[i] == idx) return; } array_append(keywords, &idx, 1); } static void keyword_index_remove(ARRAY_TYPE(keyword_indexes) *keywords, unsigned int idx) { const unsigned int *indexes; unsigned int i, count; indexes = array_get(keywords, &count); for (i = 0; i < count; i++) {
/* Finish building a FunctionType 3 (1-Input Stitching) function. */ int gs_build_function_3(i_ctx_t *i_ctx_p, const ref *op, const gs_function_params_t * mnDR, int depth, gs_function_t ** ppfn, gs_memory_t *mem) { gs_function_1ItSg_params_t params; int code; extern bool CPSI_mode; *(gs_function_params_t *) & params = *mnDR; params.Functions = 0; params.Bounds = 0; params.Encode = 0; { ref *pFunctions; gs_function_t **ptr; int i; if ((code = dict_find_string(op, "Functions", &pFunctions)) <= 0) return (code < 0 ? code : gs_note_error(e_rangecheck)); check_array_only(*pFunctions); params.k = r_size(pFunctions); code = alloc_function_array(params.k, &ptr, mem); if (code < 0) return code; params.Functions = (const gs_function_t * const *)ptr; for (i = 0; i < params.k; ++i) { ref subfn; array_get(mem, pFunctions, (long)i, &subfn); code = fn_build_sub_function(i_ctx_p, &subfn, &ptr[i], depth, mem, 0, 0); if (code < 0) goto fail; } } if ((code = fn_build_float_array(op, "Bounds", true, false, ¶ms.Bounds, mem)) != params.k - 1) goto fail; if (CPSI_mode) { /* Adobe implementation doesn't check the Encode length. */ /* Extra elements are ignored; missing elements are filled with 0. */ /* CET 12-14m.ps depends on this bug */ uint sz, k2 = 2 * params.k; ref *encode; float *p = (float *)gs_alloc_byte_array(mem, k2, sizeof(float), "Encode"); params.Encode = p; if (p == 0) { code = gs_note_error(e_VMerror); goto fail; } if (dict_find_string(op, "Encode", &encode) <= 0) { code = gs_note_error(e_undefined); goto fail; } if (!r_is_array(encode)) { code = gs_note_error(e_typecheck); goto fail; } sz = min(k2, r_size(encode)); code = process_float_array(mem, encode, sz, p); if (code < 0) goto fail; while (sz < k2) p[sz++] = 0.0; } else if ((code = fn_build_float_array(op, "Encode", true, true, ¶ms.Encode, mem)) != 2 * params.k) goto fail; if (params.Range == 0) params.n = params.Functions[0]->params.n; code = gs_function_1ItSg_init(ppfn, ¶ms, mem); if (code >= 0) return 0; fail: gs_function_1ItSg_free_params(¶ms, mem); return (code < 0 ? code : gs_note_error(e_rangecheck)); }
/** Find all declarations within an AST subtree */ void find_decls(heapptr_t expr, ast_fun_t* fun) { assert (expr != NULL); // Get the shape of the AST node shapeidx_t shape = get_shape(expr); // Constants and strings, do nothing if (shape == SHAPE_AST_CONST || shape == SHAPE_STRING) { return; } // Array literal expression if (shape == SHAPE_ARRAY) { array_t* array_expr = (array_t*)expr; for (size_t i = 0; i < array_expr->len; ++i) find_decls(array_get(array_expr, i).word.heapptr, fun); return; } // Object literal expression if (shape == SHAPE_AST_OBJ) { ast_obj_t* obj_expr = (ast_obj_t*)expr; if (obj_expr->proto_expr) find_decls(obj_expr->proto_expr, fun); for (size_t i = 0; i < obj_expr->val_exprs->len; ++i) find_decls(array_get(obj_expr->val_exprs, i).word.heapptr, fun); return; } // Variable or constant declaration (let/var) if (shape == SHAPE_AST_DECL) { ast_decl_t* decl = (ast_decl_t*)expr; // Mark the declaration as belonging to this function assert (fun != NULL); decl->fun = fun; // If this variable is already declared, do nothing for (size_t i = 0; i < fun->local_decls->len; ++i) { ast_decl_t* local = array_get(fun->local_decls, i).word.decl; if (local->name == decl->name) return; } decl->idx = fun->local_decls->len; array_set_obj(fun->local_decls, decl->idx, (heapptr_t)decl); return; } // Variable reference if (shape == SHAPE_AST_REF) { return; } // Sequence/block expression if (shape == SHAPE_AST_SEQ) { ast_seq_t* seqexpr = (ast_seq_t*)expr; array_t* expr_list = seqexpr->expr_list; for (size_t i = 0; i < expr_list->len; ++i) find_decls(array_get(expr_list, i).word.heapptr, fun); return; } // Binary operator (e.g. a + b) if (shape == SHAPE_AST_BINOP) { ast_binop_t* binop = (ast_binop_t*)expr; find_decls(binop->left_expr, fun); find_decls(binop->right_expr, fun); return; } // Unary operator (e.g. -1) if (shape == SHAPE_AST_UNOP) { ast_unop_t* unop = (ast_unop_t*)expr; find_decls(unop->expr, fun); return; } // If expression if (shape == SHAPE_AST_IF) { ast_if_t* ifexpr = (ast_if_t*)expr; find_decls(ifexpr->test_expr, fun); find_decls(ifexpr->then_expr, fun); find_decls(ifexpr->else_expr, fun); return; } // Function/closure expression if (shape == SHAPE_AST_FUN) { // Do nothing. Variables declared in the nested // function are not of this scope return; } // Function call if (shape == SHAPE_AST_CALL) { ast_call_t* callexpr = (ast_call_t*)expr; array_t* arg_exprs = callexpr->arg_exprs; find_decls(callexpr->fun_expr, fun); for (size_t i = 0; i < arg_exprs->len; ++i) find_decls(array_get_ptr(arg_exprs, i), fun); return; } // Unsupported AST node type assert (false); }
static int32_t array_compare(const uint32_t* index1, const uint32_t* index2, void** arg){ struct array* array = arg[0]; int32_t(*compare)(void*, void*) = arg[1]; return compare(array_get(array, *index1), array_get(array, *index2)); }
void var_res(heapptr_t expr, ast_fun_t* fun) { // Get the shape of the AST node shapeidx_t shape = get_shape(expr); // Constants and strings, do nothing if (shape == SHAPE_AST_CONST || shape == SHAPE_STRING) { return; } // Array literal expression if (shape == SHAPE_ARRAY) { array_t* array_expr = (array_t*)expr; for (size_t i = 0; i < array_expr->len; ++i) var_res(array_get(array_expr, i).word.heapptr, fun); return; } // Object literal expression if (shape == SHAPE_AST_OBJ) { ast_obj_t* obj_expr = (ast_obj_t*)expr; if (obj_expr->proto_expr) var_res(obj_expr->proto_expr, fun); for (size_t i = 0; i < obj_expr->val_exprs->len; ++i) var_res(array_get(obj_expr->val_exprs, i).word.heapptr, fun); return; } // Variable declaration, do nothing if (shape == SHAPE_AST_DECL) { return; } // Variable reference if (shape == SHAPE_AST_REF) { ast_ref_t* ref = (ast_ref_t*)expr; // Find the declaration for this reference ast_decl_t* decl = find_decl(ref, fun); if (decl == NULL) { printf("unresolved reference to \"%s\"\n", string_cstr(ref->name)); exit(-1); } // Store the declaration on the reference assert (decl->fun != NULL); ref->decl = decl; // If the variable is from this scope if (decl->fun == fun) { // Store the index of this local assert (decl->idx < fun->local_decls->len); ref->idx = decl->idx; } else { // Mark the variable as escaping decl->esc = true; // Thread the escaping variable through nested functions thread_esc_var(ref, fun, fun); // Find the mutable cell index for the variable ref->idx = array_indexof_ptr(fun->free_vars, (heapptr_t)ref->decl); assert (ref->idx < fun->free_vars->len); } return; } // Sequence/block expression if (shape == SHAPE_AST_SEQ) { ast_seq_t* seqexpr = (ast_seq_t*)expr; array_t* expr_list = seqexpr->expr_list; for (size_t i = 0; i < expr_list->len; ++i) var_res(array_get_ptr(expr_list, i), fun); return; } // Binary operator (e.g. a + b) if (shape == SHAPE_AST_BINOP) { ast_binop_t* binop = (ast_binop_t*)expr; var_res(binop->left_expr, fun); var_res(binop->right_expr, fun); return; } // Unary operator (e.g. -a) if (shape == SHAPE_AST_UNOP) { ast_unop_t* unop = (ast_unop_t*)expr; var_res(unop->expr, fun); return; } // If expression if (shape == SHAPE_AST_IF) { ast_if_t* ifexpr = (ast_if_t*)expr; var_res(ifexpr->test_expr, fun); var_res(ifexpr->then_expr, fun); var_res(ifexpr->else_expr, fun); return; } // Function/closure expression if (shape == SHAPE_AST_FUN) { ast_fun_t* child_fun = (ast_fun_t*)expr; // Resolve variable references in the nested child function var_res_pass(child_fun, fun); return; } // Function call if (shape == SHAPE_AST_CALL) { ast_call_t* callexpr = (ast_call_t*)expr; array_t* arg_exprs = callexpr->arg_exprs; var_res(callexpr->fun_expr, fun); for (size_t i = 0; i < arg_exprs->len; ++i) var_res(array_get_ptr(arg_exprs, i), fun); return; } // Unsupported AST node type assert (false); }
static int maildir_keywords_write_fd(struct maildir_keywords *mk, const char *path, int fd) { struct maildir_mailbox *mbox = mk->mbox; struct mailbox *box = &mbox->box; const struct mailbox_permissions *perm = mailbox_get_permissions(box); const char *const *keywords; unsigned int i, count; string_t *str; struct stat st; str = t_str_new(256); keywords = array_get(&mk->list, &count); for (i = 0; i < count; i++) { if (keywords[i] != NULL) str_printfa(str, "%u %s\n", i, keywords[i]); } if (write_full(fd, str_data(str), str_len(str)) < 0) { mail_storage_set_critical(mk->storage, "write_full(%s) failed: %m", path); return -1; } if (fstat(fd, &st) < 0) { mail_storage_set_critical(mk->storage, "fstat(%s) failed: %m", path); return -1; } if (st.st_gid != perm->file_create_gid && perm->file_create_gid != (gid_t)-1) { if (fchown(fd, (uid_t)-1, perm->file_create_gid) < 0) { if (errno == EPERM) { mail_storage_set_critical(mk->storage, "%s", eperm_error_get_chgrp("fchown", path, perm->file_create_gid, perm->file_create_gid_origin)); } else { mail_storage_set_critical(mk->storage, "fchown(%s) failed: %m", path); } } } /* mtime must grow every time */ if (st.st_mtime <= mk->synced_mtime) { struct utimbuf ut; mk->synced_mtime = ioloop_time <= mk->synced_mtime ? mk->synced_mtime + 1 : ioloop_time; ut.actime = ioloop_time; ut.modtime = mk->synced_mtime; if (utime(path, &ut) < 0) { mail_storage_set_critical(mk->storage, "utime(%s) failed: %m", path); return -1; } } if (fsync(fd) < 0) { mail_storage_set_critical(mk->storage, "fsync(%s) failed: %m", path); return -1; } return 0; }
/** Evaluate an expression in a given frame */ value_t eval_expr( heapptr_t expr, clos_t* clos, value_t* locals ) { //printf("eval_expr\n"); // Get the shape of the AST node // Note: AST nodes must match the shapes defined in init_parser, // otherwise this interpreter can't handle it shapeidx_t shape = get_shape(expr); // Variable or constant declaration (let/var) if (shape == SHAPE_AST_DECL) { ast_decl_t* decl = (ast_decl_t*)expr; // Let declarations should be initialized assert (decl->cst == false); return VAL_FALSE; } // Variable reference (read) if (shape == SHAPE_AST_REF) { ast_ref_t* ref = (ast_ref_t*)expr; assert (ref->decl != NULL); //printf("evaluating ref to %s\n", string_cstr(ref->name)); // If this is a variable from an outer function if (ref->decl->fun != clos->fun) { //printf("ref from outer fun\n"); assert (ref->idx < clos->fun->free_vars->len); cell_t* cell = clos->cells[ref->idx]; assert (cell != NULL); value_t value; value.word = cell->word; value.tag = cell->tag; return value; } // Check that the ref index is valid if (ref->idx > clos->fun->local_decls->len) { printf("invalid variable reference\n"); printf("ref->name=%s\n", string_cstr(ref->name)); printf("ref->idx=%d\n", ref->idx); printf("local_decls->len=%d\n", clos->fun->local_decls->len); exit(-1); } // If this an escaping variable (captured by a closure) if (ref->decl->esc) { // Free variables are stored in mutable cells // Pointers to the cells are found on the closure object cell_t* cell = locals[ref->idx].word.cell; value_t value; value.word = cell->word; value.tag = cell->tag; //printf("read value from cell\n"); return value; } /* printf("reading normal local\n"); string_print(ref->name); printf("\n"); */ // Read directly from the stack frame return locals[ref->idx]; } if (shape == SHAPE_AST_CONST) { //printf("constant\n"); ast_const_t* cst = (ast_const_t*)expr; return cst->val; } if (shape == SHAPE_STRING) { return value_from_heapptr(expr, TAG_STRING); } // Array literal expression if (shape == SHAPE_ARRAY) { array_t* array_expr = (array_t*)expr; // Array of values to be produced array_t* val_array = array_alloc(array_expr->len); for (size_t i = 0; i < array_expr->len; ++i) { heapptr_t expr = array_get(array_expr, i).word.heapptr; value_t value = eval_expr(expr, clos, locals); array_set(val_array, i, value); } return value_from_heapptr((heapptr_t)val_array, TAG_ARRAY); } // Object literal expression if (shape == SHAPE_AST_OBJ) { //printf("obj literal expr\n"); ast_obj_t* obj_expr = (ast_obj_t*)expr; object_t* obj = object_alloc(OBJ_MIN_CAP); // TODO: set prototype // Do this in object_alloc? for (size_t i = 0; i < obj_expr->name_strs->len; ++i) { string_t* prop_name = array_get(obj_expr->name_strs, i).word.string; heapptr_t val_expr = array_get(obj_expr->val_exprs, i).word.heapptr; value_t value = eval_expr(val_expr, clos, locals); object_set_prop( obj, prop_name, value, ATTR_DEFAULT ); } return value_from_obj((heapptr_t)obj); } // Binary operator (e.g. a + b) if (shape == SHAPE_AST_BINOP) { //printf("binop\n"); ast_binop_t* binop = (ast_binop_t*)expr; // Assignment if (binop->op == &OP_ASSIGN) { value_t val = eval_expr(binop->right_expr, clos, locals); return eval_assign( binop->left_expr, val, clos, locals ); } value_t v0 = eval_expr(binop->left_expr, clos, locals); value_t v1 = eval_expr(binop->right_expr, clos, locals); int64_t i0 = v0.word.int64; int64_t i1 = v1.word.int64; string_t* s0 = v0.word.string; string_t* s1 = v1.word.string; if (binop->op == &OP_MEMBER) return eval_get_prop(v0, v1); if (binop->op == &OP_INDEX) return eval_get_index(v0, v1); if (binop->op == &OP_ADD) return value_from_int64(i0 + i1); if (binop->op == &OP_SUB) return value_from_int64(i0 - i1); if (binop->op == &OP_MUL) return value_from_int64(i0 * i1); if (binop->op == &OP_DIV) return value_from_int64(i0 / i1); if (binop->op == &OP_MOD) return value_from_int64(i0 % i1); if (binop->op == &OP_LT) return (i0 < i1)? VAL_TRUE:VAL_FALSE; if (binop->op == &OP_LE) { if (v0.tag == TAG_STRING && v1.tag == TAG_STRING) return (strcmp(string_cstr(s0), string_cstr(s1)) <= 0)? VAL_TRUE:VAL_FALSE; if (v0.tag == TAG_INT64 && v1.tag == TAG_INT64) return (i0 <= i1)? VAL_TRUE:VAL_FALSE; assert (false); } if (binop->op == &OP_GT) return (i0 > i1)? VAL_TRUE:VAL_FALSE; if (binop->op == &OP_GE) { if (v0.tag == TAG_STRING && v1.tag == TAG_STRING) return (strcmp(string_cstr(s0), string_cstr(s1)) >= 0)? VAL_TRUE:VAL_FALSE; if (v0.tag == TAG_INT64 && v1.tag == TAG_INT64) return (i0 >= i1)? VAL_TRUE:VAL_FALSE; assert (false); } if (binop->op == &OP_EQ) return value_equals(v0, v1)? VAL_TRUE:VAL_FALSE; if (binop->op == &OP_NE) return value_equals(v0, v1)? VAL_FALSE:VAL_TRUE; printf("unimplemented binary operator: %s\n", binop->op->str); return VAL_FALSE; } // Unary operator (e.g.: -x, not a) if (shape == SHAPE_AST_UNOP) { ast_unop_t* unop = (ast_unop_t*)expr; value_t v0 = eval_expr(unop->expr, clos, locals); if (unop->op == &OP_NEG) return value_from_int64(-v0.word.int64); if (unop->op == &OP_NOT) return eval_truth(v0)? VAL_FALSE:VAL_TRUE; printf("unimplemented unary operator: %s\n", unop->op->str); return VAL_FALSE; } // Sequence/block expression if (shape == SHAPE_AST_SEQ) { ast_seq_t* seqexpr = (ast_seq_t*)expr; array_t* expr_list = seqexpr->expr_list; value_t value = VAL_TRUE; for (size_t i = 0; i < expr_list->len; ++i) { heapptr_t expr = array_get(expr_list, i).word.heapptr; value = eval_expr(expr, clos, locals); } // Return the value of the last expression return value; } // If expression if (shape == SHAPE_AST_IF) { ast_if_t* ifexpr = (ast_if_t*)expr; value_t t = eval_expr(ifexpr->test_expr, clos, locals); if (eval_truth(t)) return eval_expr(ifexpr->then_expr, clos, locals); else return eval_expr(ifexpr->else_expr, clos, locals); } // Function/closure expression if (shape == SHAPE_AST_FUN) { //printf("creating closure\n"); ast_fun_t* nested = (ast_fun_t*)expr; // Allocate a closure of the nested function clos_t* new_clos = clos_alloc(nested); // For each free (closure) variable of the nested function for (size_t i = 0; i < nested->free_vars->len; ++i) { ast_decl_t* decl = array_get(nested->free_vars, i).word.decl; // If the variable is from this function if (decl->fun == clos->fun) { new_clos->cells[i] = locals[decl->idx].word.cell; } else { uint32_t free_idx = array_indexof_ptr(clos->fun->free_vars, (heapptr_t)decl); assert (free_idx < clos->fun->free_vars->len); new_clos->cells[i] = clos->cells[free_idx]; } } assert (new_clos->fun == nested); return value_from_heapptr((heapptr_t)new_clos, TAG_CLOS); } // Call expression if (shape == SHAPE_AST_CALL) { //printf("evaluating call\n"); ast_call_t* callexpr = (ast_call_t*)expr; // Evaluate the closure expression value_t callee_clos = eval_expr(callexpr->fun_expr, clos, locals); if (callee_clos.tag == TAG_CLOS) { return eval_call( callee_clos.word.clos, callexpr->arg_exprs, clos, locals ); } if (callee_clos.tag == TAG_HOSTFN) { return eval_host_call( callee_clos.word.hostfn, callexpr->arg_exprs, clos, locals ); } printf("invalid callee in function call\n"); exit(-1); } printf("eval error, unknown expression type, shapeidx=%d\n", get_shape(expr)); exit(-1); }
static int client_handle_user_command(struct client *client, const char *cmd, const char *const *args, const char **error_r) { struct mail_storage_service_input input; struct imap_urlauth_worker_settings *set; struct mail_storage_service_user *user; struct imap_urlauth_config config; struct mail_user *mail_user; const char *error; unsigned int count; int ret; /* "USER\t"<username> */ *error_r = NULL; /* check command syntax */ if (strcmp(cmd, "USER") != 0) { *error_r = t_strconcat("Unknown or inappropriate command: ", cmd, NULL); return -1; } if (args[0] == NULL || args[1] != NULL) { *error_r = "USER: Invalid number of parameters"; return -1; } /* lookup user */ memset(&input, 0, sizeof(input)); input.module = "imap-urlauth-worker"; input.service = "imap-urlauth-worker"; input.username = args[0]; if (client->debug) i_debug("Looking up user %s", input.username); ret = mail_storage_service_lookup_next(storage_service, &input, &user, &mail_user, &error); if (ret < 0) { i_error("Failed to lookup user %s: %s", input.username, error); client_abort(client, "Session aborted: Failed to lookup user"); return 0; } else if (ret == 0) { if (client->debug) i_debug("User %s doesn't exist", input.username); client_send_line(client, "NO"); timeout_remove(&client->to_delay); return 1; } client->debug = mail_user->mail_debug = client->debug || mail_user->mail_debug; /* drop privileges */ restrict_access_allow_coredumps(TRUE); set = mail_storage_service_user_get_set(user)[1]; settings_var_expand(&imap_urlauth_worker_setting_parser_info, set, mail_user->pool, mail_user_var_expand_table(mail_user)); if (set->verbose_proctitle) { verbose_proctitle = TRUE; imap_urlauth_worker_refresh_proctitle(); } client->service_user = user; client->mail_user = mail_user; client->set = set; if (client->debug) { i_debug("Found user account `%s' on behalf of user `%s'", mail_user->username, client->access_user); } /* initialize urlauth context */ if (*set->imap_urlauth_host == '\0') { i_error("imap_urlauth_host setting is not configured for user %s", mail_user->username); client_send_line(client, "NO"); client_abort(client, "Session aborted: URLAUTH not configured"); return 0; } memset(&config, 0, sizeof(config)); config.url_host = set->imap_urlauth_host; config.url_port = set->imap_urlauth_port; config.access_user = client->access_user; config.access_anonymous = client->access_anonymous; config.access_applications = (const void *)array_get(&client->access_apps, &count); client->urlauth_ctx = imap_urlauth_init(client->mail_user, &config); if (client->debug) { i_debug("Providing access to user account `%s' on behalf of `%s'", mail_user->username, client->access_user); } i_set_failure_prefix("imap-urlauth[%s](%s->%s): ", my_pid, client->access_user, mail_user->username); client_send_line(client, "OK"); return 1; }
static rstatus_t conf_post_validate(struct conf *cf) { rstatus_t status; uint32_t i, npool; bool valid; ASSERT(cf->sound && cf->parsed); ASSERT(!cf->valid); npool = array_n(&cf->pool); if (npool == 0) { log_error("conf: '%.*s' has no pools", cf->fname); return NC_ERROR; } /* validate pool */ for (i = 0; i < npool; i++) { struct conf_pool *cp = array_get(&cf->pool, i); status = conf_validate_pool(cf, cp); if (status != NC_OK) { return status; } } /* disallow pools with duplicate listen: key values */ array_sort(&cf->pool, conf_pool_listen_cmp); for (valid = true, i = 0; i < npool - 1; i++) { struct conf_pool *p1, *p2; p1 = array_get(&cf->pool, i); p2 = array_get(&cf->pool, i + 1); if (string_compare(&p1->listen.pname, &p2->listen.pname) == 0) { log_error("conf: pools '%.*s' and '%.*s' have the same listen " "address '%.*s'", p1->name.len, p1->name.data, p2->name.len, p2->name.data, p1->listen.pname.len, p1->listen.pname.data); valid = false; break; } } if (!valid) { return NC_ERROR; } /* disallow pools with duplicate names */ array_sort(&cf->pool, conf_pool_name_cmp); for (valid = true, i = 0; i < npool - 1; i++) { struct conf_pool *p1, *p2; p1 = array_get(&cf->pool, i); p2 = array_get(&cf->pool, i + 1); if (string_compare(&p1->name, &p2->name) == 0) { log_error("conf: '%s' has pools with same name %.*s'", cf->fname, p1->name.len, p1->name.data); valid = false; break; } } if (!valid) { return NC_ERROR; } return NC_OK; }
static uint32_t arrayMinCoverage_reshape(struct array* array, uint32_t nb_category, struct categoryDesc* desc_buffer, uint32_t selection_value, uint32_t min_score, struct tagMap* tag_map){ uint32_t i; uint32_t j; uint32_t k; uint32_t l; uint32_t min_size; uint32_t size; struct array* element_array; uint32_t score; uint64_t complexity; uint32_t local_score; #if ARRAYMINCOVERAGE_DETERMINISTIC == 0 uint32_t proba_offset; #endif qsort(desc_buffer, nb_category, sizeof(struct categoryDesc), categoryDesc_compare_nb_element); for (i = 0, l = 0, score = 0, local_score = 0, complexity = 1; i < nb_category; i++){ complexity = complexity * (uint64_t)desc_buffer[i].nb_element; if (complexity > ARRAYMINCOVERAGE_COMPLEXITY_THRESHOLD){ if (i - l >= 2){ tagMap_deselect(tag_map, selection_value); local_score = arrayMinCoverage_exact(array, i - l, desc_buffer + l, selection_value, local_score); for (j = l; j < i; j++){ element_array = *(struct array**)array_get(array, desc_buffer[j].offset + desc_buffer[j].choice); for (k = 0; k < array_get_length(element_array); k++){ if (!*(uint32_t*)desc_buffer[j].tagMap_gateway[desc_buffer[j].choice][k]){ *(uint32_t*)desc_buffer[j].tagMap_gateway[desc_buffer[j].choice][k] = selection_value; } } } } score += local_score; complexity = (uint64_t)desc_buffer[i].nb_element; selection_value ++; local_score = 0; l = i; } #if ARRAYMINCOVERAGE_DETERMINISTIC == 0 proba_offset = 2; #endif for (j = 0, min_size = 0xffffffff, desc_buffer[i].choice = 0; j < desc_buffer[i].nb_element; j++){ element_array = *(struct array**)array_get(array, desc_buffer[i].offset + j); for (k = 0, size = 0; k < array_get_length(element_array); k++){ if (!*(uint32_t*)desc_buffer[i].tagMap_gateway[j][k]){ size ++; } } #if ARRAYMINCOVERAGE_DETERMINISTIC == 0 if (size < min_size || (size == min_size && !(rand() % proba_offset))){ if (size < min_size){ proba_offset = 2; } else{ proba_offset ++; } min_size = size; desc_buffer[i].choice = j; } #else if (size < min_size){ min_size = size; desc_buffer[i].choice = j; } #endif } element_array = *(struct array**)array_get(array, desc_buffer[i].offset + desc_buffer[i].choice); for (j = 0; j < array_get_length(element_array); j++){ if (!*(uint32_t*)desc_buffer[i].tagMap_gateway[desc_buffer[i].choice][j]){ *(uint32_t*)desc_buffer[i].tagMap_gateway[desc_buffer[i].choice][j] = selection_value; local_score ++; } } } if (nb_category - l >= 2){ tagMap_deselect(tag_map, selection_value); local_score = arrayMinCoverage_exact(array, nb_category - l, desc_buffer + l, selection_value, local_score); } score += local_score; return score; }
int sys_write(int fdesc,userptr_t ubuf,unsigned int nbytes,int *retval) { #if OPT_A2 struct iovec iov; struct uio u; int res; struct file* f; struct lock* rwlock; //check for invalid file descriptor: //anything above 127 or below 0 is a bad file descriptor if(fdesc > 127 || fdesc < 0) { return EBADF; } f = array_get(curproc->filetable, fdesc); //the file table index is null, thus it has not been opened. if(f == NULL) { return EBADF; } //read only if((f->flags & O_ACCMODE) == O_RDONLY) { return EBADF; } rwlock = f->readwritelock; lock_acquire(rwlock); //kprintf("LOCK NAME %d: %s ACQUIRED! \n", fdesc, rwlock->lk_name); //get the file again to get any updated changes. f = array_get(curproc->filetable, fdesc); if(f == NULL) { lock_release(rwlock); // kprintf("LOCK NAME %d: %s RELEASED! \n", fdesc, rwlock->lk_name); return EBADF; } if((f->flags & O_ACCMODE) == O_RDONLY) { lock_release(rwlock); // kprintf("LOCK NAME %d: %s RELEASED! \n", fdesc, rwlock->lk_name); return EBADF; } //kprintf("WRITING"); DEBUG(DB_SYSCALL,"Syscall: write(%d,%x,%d)\n",fdesc,(unsigned int)ubuf,nbytes); /* set up a uio structure to refer to the user program's buffer (ubuf) */ iov.iov_ubase = ubuf; iov.iov_len = nbytes; u.uio_iov = &iov; u.uio_iovcnt = 1; u.uio_offset = f->seekpsnwrite; u.uio_resid = nbytes; u.uio_segflg = UIO_USERSPACE; u.uio_rw = UIO_WRITE; u.uio_space = curproc->p_addrspace; KASSERT(f != NULL); res = VOP_WRITE(f->fvnode, &u); if (res) { //lock_release(f->readwritelock); lock_release(rwlock); // kprintf("LOCK NAME %d: %s RELEASED! \n", fdesc, rwlock->lk_name); return res; } /* pass back the number of bytes actually written */ *retval = nbytes - u.uio_resid; //don't need to increment seek positions for console if(fdesc > 2) f->seekpsnwrite = f->seekpsnwrite + *retval; KASSERT(*retval >= 0); lock_release(rwlock); //kprintf("LOCK NAME %d: %s RELEASED! \n", fdesc, rwlock->lk_name); return 0; /* * * *END OF MY IMPLEMENTATION *BELOW IS THE ORIGINAL IMPLEMENTATION */ #else struct iovec iov; struct uio u; int res; DEBUG(DB_SYSCALL,"Syscall: write(%d,%x,%d)\n",fdesc,(unsigned int)ubuf,nbytes); /* only stdout and stderr writes are currently implemented */ if (!((fdesc==STDOUT_FILENO)||(fdesc==STDERR_FILENO))) { return EUNIMP; } KASSERT(curproc != NULL); KASSERT(curproc->console != NULL); KASSERT(curproc->p_addrspace != NULL); /* set up a uio structure to refer to the user program's buffer (ubuf) */ iov.iov_ubase = ubuf; iov.iov_len = nbytes; u.uio_iov = &iov; u.uio_iovcnt = 1; u.uio_offset = 0; /* not needed for the console */ u.uio_resid = nbytes; u.uio_segflg = UIO_USERSPACE; u.uio_rw = UIO_WRITE; u.uio_space = curproc->p_addrspace; res = VOP_WRITE(curproc->console,&u); if (res) { return res; } /* pass back the number of bytes actually written */ *retval = nbytes - u.uio_resid; KASSERT(*retval >= 0); return 0; #endif }