{"Workspace Left", BB_WORKSPACE, BBWS_DESKLEFT}, {"Workspace Right", BB_WORKSPACE, BBWS_DESKRIGHT}, {"Workspace Move Left", BB_WORKSPACE, BBWS_MOVEWINDOWLEFT }, {"Workspace Move Right", BB_WORKSPACE, BBWS_MOVEWINDOWRIGHT }, {"Workspace Gather", BB_WORKSPACE, BBWS_GATHERWINDOWS}, {"Previous Window", BB_WORKSPACE, BBWS_PREVWINDOW }, {"Next Window", BB_WORKSPACE, BBWS_NEXTWINDOW } }; #define array_count(ary) (sizeof(ary) / sizeof(ary[0])) const int agenttype_system_touple_count = array_count(agenttype_system_touples); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //controltype_button_startup //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int agenttype_system_startup() { //Register this type with the ControlMaster agent_registertype( "System/Shell", //Friendly name of agent type "System", //Name of agent type CONTROL_FORMAT_TRIGGER, //Control type true, &agenttype_system_create, &agenttype_system_destroy, &agenttype_system_message,
void unload_chunk(TerrainChunk *chunk) { for (u32 i=0; i<array_count(chunk->models); i++) { Model *model = chunk->models + i; unload_model(model); } }
va_end(va); } bool mail_transaction_log_view_is_corrupted(struct mail_transaction_log_view *view) { return view->broken; } static bool log_view_is_uid_range_valid(struct mail_transaction_log_file *file, enum mail_transaction_type rec_type, const ARRAY_TYPE(seq_range) *uids) { const struct seq_range *rec, *prev = NULL; unsigned int i, count = array_count(uids); if ((uids->arr.buffer->used % uids->arr.element_size) != 0) { mail_transaction_log_file_set_corrupted(file, "Invalid record size (type=0x%x)", rec_type); return FALSE; } else if (count == 0) { mail_transaction_log_file_set_corrupted(file, "No UID ranges (type=0x%x)", rec_type); return FALSE; } for (i = 0; i < count; i++, prev = rec) { rec = array_idx(uids, i); if (rec->seq1 > rec->seq2 || rec->seq1 == 0) { mail_transaction_log_file_set_corrupted(file,
int mail_transaction_log_view_set(struct mail_transaction_log_view *view, uint32_t min_file_seq, uoff_t min_file_offset, uint32_t max_file_seq, uoff_t max_file_offset, bool *reset_r) { struct mail_transaction_log_file *file, *const *files; uoff_t start_offset, end_offset; unsigned int i; uint32_t seq; int ret; *reset_r = FALSE; if (view->log == NULL) { /* transaction log is closed already. this log view shouldn't be used anymore. */ return -1; } if (min_file_seq == 0) { /* index file doesn't exist yet. this transaction log should start from the beginning */ if (view->log->files->hdr.prev_file_seq != 0) { /* but it doesn't */ return 0; } min_file_seq = view->log->files->hdr.file_seq; min_file_offset = 0; if (max_file_seq == 0) { max_file_seq = min_file_seq; max_file_offset = min_file_offset; } } for (file = view->log->files; file != NULL; file = file->next) { if (file->hdr.prev_file_seq == min_file_seq) break; } if (file != NULL && min_file_offset == file->hdr.prev_file_offset) { /* we can (and sometimes must) skip to the next file */ min_file_seq = file->hdr.file_seq; min_file_offset = file->hdr.hdr_size; } for (file = view->log->files; file != NULL; file = file->next) { if (file->hdr.prev_file_seq == max_file_seq) break; } if (file != NULL && max_file_offset == file->hdr.prev_file_offset) { /* we can skip to the next file. we've delayed checking for min_file_seq <= max_file_seq until now, because it's not really an error to specify the same position twice (even if in "wrong" order) */ i_assert(min_file_seq <= max_file_seq || min_file_seq <= file->hdr.file_seq); max_file_seq = file->hdr.file_seq; max_file_offset = file->hdr.hdr_size; } else { i_assert(min_file_seq <= max_file_seq); } if (min_file_seq == max_file_seq && min_file_offset > max_file_offset) { /* log file offset is probably corrupted in the index file. */ mail_transaction_log_view_set_corrupted(view, "file_seq=%u, min_file_offset (%"PRIuUOFF_T ") > max_file_offset (%"PRIuUOFF_T")", min_file_seq, min_file_offset, max_file_offset); return -1; } view->tail = view->head = file = NULL; for (seq = min_file_seq; seq <= max_file_seq; seq++) { if (file == NULL || file->hdr.file_seq != seq) { /* see if we could find the missing file. if we know the max. file sequence, make sure NFS attribute cache gets flushed if necessary. */ bool nfs_flush = max_file_seq != (uint32_t)-1; ret = mail_transaction_log_find_file(view->log, seq, nfs_flush, &file); if (ret <= 0) { if (ret < 0) return -1; /* not found / corrupted */ file = NULL; } } if (file == NULL || file->hdr.file_seq != seq) { if (file == NULL && max_file_seq == (uint32_t)-1 && view->head == view->log->head) { /* we just wanted to sync everything */ i_assert(max_file_offset == (uoff_t)-1); max_file_seq = seq-1; break; } /* if any of the found files reset the index, ignore any missing files up to it */ file = view->tail != NULL ? view->tail : view->log->files; for (;; file = file->next) { if (file == NULL || file->hdr.file_seq > max_file_seq) { /* missing files in the middle */ return 0; } if (file->hdr.file_seq >= seq && file->hdr.prev_file_seq == 0) { /* we can ignore the missing file */ break; } } seq = file->hdr.file_seq; view->tail = NULL; } if (view->tail == NULL) view->tail = file; view->head = file; file = file->next; } i_assert(view->tail != NULL); if (min_file_offset == 0) { /* beginning of the file */ min_file_offset = view->tail->hdr.hdr_size; if (min_file_offset > max_file_offset && min_file_seq == max_file_seq) { /* we don't actually want to show anything */ max_file_offset = min_file_offset; } } if (min_file_offset < view->tail->hdr.hdr_size) { /* log file offset is probably corrupted in the index file. */ mail_transaction_log_view_set_corrupted(view, "file_seq=%u, min_file_offset (%"PRIuUOFF_T ") < hdr_size (%u)", min_file_seq, min_file_offset, view->tail->hdr.hdr_size); return -1; } if (max_file_offset < view->head->hdr.hdr_size) { /* log file offset is probably corrupted in the index file. */ mail_transaction_log_view_set_corrupted(view, "file_seq=%u, min_file_offset (%"PRIuUOFF_T ") < hdr_size (%u)", max_file_seq, max_file_offset, view->head->hdr.hdr_size); return -1; } /* we have all of them. update refcounts. */ mail_transaction_log_view_unref_all(view); /* Reference all used files. */ for (file = view->tail;; file = file->next) { array_append(&view->file_refs, &file, 1); file->refcount++; if (file == view->head) break; } view->cur = view->tail; view->cur_offset = view->cur->hdr.file_seq == min_file_seq ? min_file_offset : view->cur->hdr.hdr_size; /* Map the files only after we've found them all. Otherwise if we map one file and then another file just happens to get rotated, we could include both files in the view but skip the last transactions from the first file. We're mapping the files in reverse order so that _log_file_map() can verify that prev_file_offset matches how far it actually managed to sync the file. */ files = array_idx(&view->file_refs, 0); for (i = array_count(&view->file_refs); i > 0; i--) { file = files[i-1]; start_offset = file->hdr.file_seq == min_file_seq ? min_file_offset : file->hdr.hdr_size; end_offset = file->hdr.file_seq == max_file_seq ? max_file_offset : (uoff_t)-1; ret = mail_transaction_log_file_map(file, start_offset, end_offset); if (ret <= 0) return ret; if (file->hdr.prev_file_seq == 0) { /* this file resets the index. don't bother reading the others. */ if (view->cur != file || view->cur_offset == file->hdr.hdr_size) { view->cur = file; view->cur_offset = file->hdr.hdr_size; *reset_r = TRUE; break; } i_assert(i == 1); } } if (min_file_seq == view->head->hdr.file_seq && min_file_offset > view->head->sync_offset) { /* log file offset is probably corrupted in the index file. */ mail_transaction_log_view_set_corrupted(view, "file_seq=%u, min_file_offset (%"PRIuUOFF_T ") > sync_offset (%"PRIuUOFF_T")", min_file_seq, min_file_offset, view->head->sync_offset); return -1; } i_assert(max_file_seq == (uint32_t)-1 || max_file_seq == view->head->hdr.file_seq); i_assert(max_file_offset == (uoff_t)-1 || max_file_offset <= view->head->sync_offset); i_assert(min_file_seq != max_file_seq || max_file_seq != view->head->hdr.file_seq || max_file_offset != (uoff_t)-1 || min_file_offset <= view->head->sync_offset); view->prev_file_seq = view->cur->hdr.file_seq; view->prev_file_offset = view->cur_offset; view->min_file_seq = min_file_seq; view->min_file_offset = min_file_offset; view->max_file_seq = max_file_seq; view->max_file_offset = I_MIN(max_file_offset, view->head->sync_offset); view->broken = FALSE; if (mail_transaction_log_file_get_highest_modseq_at(view->cur, view->cur_offset, &view->prev_modseq) < 0) return -1; i_assert(view->cur_offset <= view->cur->sync_offset); return 1; }
#include "string.h" #include "utils.h" #ifdef CYGWIN static char const CYGPATH[] = "cygpath -w"; #endif typedef struct {char const * mime, * extension;} Entry; static Entry mime_to_extensions[] = { {"image/xexr", "exr"}, {"image/png", "png"}, {"image/jpeg", "jpg"} }; static int const type_count = array_count(mime_to_extensions); static char const * mime_to_extension(char const mime[]) { for (int i = 0; i != type_count; ++ i) { Entry const * entry = &mime_to_extensions[i]; if (streq(entry->mime, mime)) { return entry->extension; } } return NULL; }
#include <sys/types.h> #include <sys/wait.h> #include <errno.h> #include <string.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <dpkg/i18n.h> #include <dpkg/dpkg.h> #include <dpkg/subproc.h> static int signo_ignores[] = { SIGQUIT, SIGINT }; static struct sigaction sa_save[array_count(signo_ignores)]; void subproc_signals_setup(const char *name) { struct sigaction sa; size_t i; onerr_abort++; memset(&sa, 0, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; for (i = 0; i < array_count(signo_ignores); i++) if (sigaction(signo_ignores[i], &sa, &sa_save[i]))
CONTROL_FORMAT_TEXT, CONTROL_FORMAT_TEXT, CONTROL_FORMAT_TEXT, CONTROL_FORMAT_TEXT, CONTROL_FORMAT_TEXT, CONTROL_FORMAT_TEXT }; //Variables const char* agenttype_compoundtext_commons[] = { "Usage: $", "CPU: $ MEM: $" }; #define array_count(ary) (sizeof(ary) / sizeof(ary[0])) const int agenttype_compoundtext_commoncount = array_count(agenttype_compoundtext_commons); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //controltype_button_startup //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int agenttype_compoundtext_startup() { //Register this type with the ControlMaster agent_registertype( "Compound Text", //Friendly name of agent type "CompoundText", //Name of agent type CONTROL_FORMAT_TEXT, //Control format true, &agenttype_compoundtext_create, &agenttype_compoundtext_destroy, &agenttype_compoundtext_message,
static int virtual_config_parse_line(struct virtual_parse_context *ctx, const char *line, const char **error_r) { struct mail_user *user = ctx->mbox->storage->storage.user; struct virtual_backend_box *bbox; const char *name; if (*line == ' ' || *line == '\t') { /* continues the previous search rule */ if (ctx->rule_idx == array_count(&ctx->mbox->backend_boxes)) { *error_r = "Search rule without a mailbox"; return -1; } while (*line == ' ' || *line == '\t') line++; str_append_c(ctx->rule, ' '); str_append(ctx->rule, line); return 0; } /* if there is no rule yet, it means we want the previous mailboxes to use the rule that comes later */ if (str_len(ctx->rule) > 0) { if (virtual_config_add_rule(ctx, error_r) < 0) return -1; } /* new mailbox. the search args are added to it later. */ bbox = p_new(ctx->pool, struct virtual_backend_box, 1); if (strcasecmp(line, "INBOX") == 0) line = "INBOX"; bbox->name = p_strdup(ctx->pool, line); if (*line == '-' || *line == '+' || *line == '!') line++; bbox->ns = strcasecmp(line, "INBOX") == 0 ? mail_namespace_find_inbox(user->namespaces) : mail_namespace_find(user->namespaces, line); if (!uni_utf8_str_is_valid(bbox->name)) { *error_r = t_strdup_printf("Mailbox name not UTF-8: %s", bbox->name); return -1; } if (bbox->ns == NULL) { *error_r = t_strdup_printf("Namespace not found for %s", bbox->name); return -1; } if (bbox->name[0] == '+') { bbox->name++; bbox->clear_recent = TRUE; } if (strchr(bbox->name, '*') != NULL || strchr(bbox->name, '%') != NULL) { name = bbox->name[0] == '-' ? bbox->name + 1 : bbox->name; bbox->glob = imap_match_init(ctx->pool, name, TRUE, ctx->sep); ctx->have_wildcards = TRUE; } else if (bbox->name[0] == '!') { /* save messages here */ if (ctx->mbox->save_bbox != NULL) { *error_r = "Multiple save mailboxes defined"; return -1; } bbox->name++; ctx->mbox->save_bbox = bbox; } if (strcmp(bbox->name, ctx->mbox->box.vname) == 0) { *error_r = "Virtual mailbox can't point to itself"; return -1; } ctx->have_mailbox_defines = TRUE; array_append(&ctx->mbox->backend_boxes, &bbox, 1); return 0; }
IpConn* IpConnTrack_track_pkt(IpConnTrack *self, struct netpkt *pkt, int track_flags) { IpConnAddr key; IpConn *conn=0; IpConnTcpQueue *queue=0; int tmp_port; //int err=-1; int i; int flags=0, local=0; hash_node_t *node=0; u32 tmp_addr; u32 *addr; netpkt_ip *ip=0; netpkt_tcp *tcp=0; netpkt_udp *udp=0; //netpkt_icmp *icmp=0; ip = pkt->pkt_ip; tcp = pkt->pkt_tcp; udp = pkt->pkt_udp; //icmp = pkt->pkt_icmp; if( !ip || (!tcp && !udp) ) { return 0; } do { /* check if this matches one of my local addresses */ local = 0; for(i=array_count(&self->m_local_addrs), addr=(u32*)array_get(&self->m_local_addrs, 0); i>0; i--, addr++) { if( ip->src == *addr ) { flags |= CONN_PKT_LOCAL_SRC; local = 1; } if( ip->dst == *addr ) { flags |= CONN_PKT_LOCAL_DST; local = 1; } } // ignore non-local packets if( (track_flags & IPCONN_TRACK_LOCAL) && !local ) { break; } /* The canonical hash key in self->conn_hash is client_ip/server_ip/client_port/server_port */ memset(&key, 0, sizeof(key)); /* see if this packet is from server to client. */ flags |= CONN_PKT_FROM_SERVER; key.proto = ip->p; key.client_addr = ip->dst; key.server_addr = ip->src; if( tcp ) { key.client_port = ntohs(tcp->dest); key.server_port = ntohs(tcp->source); } else if( udp ) { key.client_port = ntohs(udp->dest); key.server_port = ntohs(udp->source); } node = hash_get(&self->m_conn_hash, &key); if( node ) { //debug(("track_pkt: packet from server conn=%p\n", node->hash_val)); break; } /* otherwise, this packet is from client to server */ flags &= ~CONN_PKT_FROM_SERVER; flags |= CONN_PKT_FROM_CLIENT; SWAP(key.client_addr, key.server_addr, tmp_addr); SWAP(key.client_port, key.server_port, tmp_port); node = hash_get(&self->m_conn_hash, &key); if( node ) { //debug(("track_pkt: packet from client conn=%p\n", node->hash_val)); break; } // Only start connections on a pure TCP SYN, not a SYN,ACK //if( tcp && (!tcp_syn(tcp) || tcp_ack(tcp)) ) { // break; //} /* doesn't match anything, start a new connection */ flags |= CONN_PKT_FIRST; conn = (IpConn*)malloc(sizeof(*conn)); assertb(conn); IpConn_init(conn); conn->conn_addr = key; conn->conn_state = CONN_STATE_SYN; conn->conn_time_first = mstime(); if( flags & CONN_PKT_LOCAL_DST ) { conn->conn_flags |= CONN_LOCAL_SERVER; } if( flags & CONN_PKT_LOCAL_SRC ) { conn->conn_flags |= CONN_LOCAL_CLIENT; } //debug(("track_pkt: new connection conn=%p\n", conn)); node = hash_put(&self->m_conn_hash, conn, conn); //err = 0; } while(0); if( !node ) { return 0; } conn = (IpConn*)node->node_val; conn->conn_pkt_flags = flags; IpConnTrack_track_state(self, conn, pkt); // track the stream itself if( conn->conn_pkt_flags & CONN_PKT_FROM_SERVER ) { queue = &conn->queue_server; } else if( conn->conn_pkt_flags & CONN_PKT_FROM_CLIENT ) { queue = &conn->queue_client; } if( queue ) { IpConnTrack_track_stream(self, conn, queue, pkt, track_flags & IPCONN_TRACK_BUFFER); } return conn; }
static bool _sieve_binary_save (struct sieve_binary *sbin, struct ostream *stream) { struct sieve_binary_header header; struct sieve_binary_extension_reg *const *regs; struct sieve_binary_block *ext_block; unsigned int ext_count, blk_count, i; uoff_t block_index; blk_count = sieve_binary_block_count(sbin); /* Signal all extensions to finish generating their blocks */ regs = array_get(&sbin->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { const struct sieve_binary_extension *binext = regs[i]->binext; if ( binext != NULL && binext->binary_save != NULL ) binext->binary_save(regs[i]->extension, sbin, regs[i]->context); } /* Create header */ header.magic = SIEVE_BINARY_MAGIC; header.version_major = SIEVE_BINARY_VERSION_MAJOR; header.version_minor = SIEVE_BINARY_VERSION_MINOR; header.blocks = blk_count; if ( !_save_aligned(sbin, stream, &header, sizeof(header), NULL) ) { sieve_sys_error(sbin->svinst, "binary save: failed to save header"); return FALSE; } /* Skip block index for now */ if ( !_save_skip_aligned(sbin, stream, sizeof(struct sieve_binary_block_index) * blk_count, &block_index) ) return FALSE; /* Create block containing all used extensions */ ext_block = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_EXTENSIONS); i_assert( ext_block != NULL ); sieve_binary_block_clear(ext_block); ext_count = array_count(&sbin->linked_extensions); sieve_binary_emit_unsigned(ext_block, ext_count); for ( i = 0; i < ext_count; i++ ) { struct sieve_binary_extension_reg * const *ext = array_idx(&sbin->linked_extensions, i); sieve_binary_emit_cstring (ext_block, sieve_extension_name((*ext)->extension)); sieve_binary_emit_unsigned (ext_block, sieve_extension_version((*ext)->extension)); sieve_binary_emit_unsigned(ext_block, (*ext)->block_id); } /* Save all blocks into the binary */ for ( i = 0; i < blk_count; i++ ) { if ( !_save_block(sbin, stream, i) ) return FALSE; } /* Create the block index */ o_stream_seek(stream, block_index); for ( i = 0; i < blk_count; i++ ) { if ( !_save_block_index_record(sbin, stream, i) ) return FALSE; } return TRUE; }
bool test_dirscan(){ int buffer_test[10000]; for(size_t i = 0; i <array_count(buffer_test); i++){ buffer_test[i] = i; } allocator * _allocator = trace_allocator_make(); allocator * old_allocator = iron_get_allocator(); iron_set_allocator(_allocator); dirscan ds = {0}; //size_t max_diff_cnt = 0; //size_t max_file_cnt = 0; mkdir("dir test 1", 0777); mkdir("dir test 1/sub dir", 0777); memset(buffer_test, 10, sizeof(buffer_test)); udpc_dirscan_update("dir test 1", &ds, false); ASSERT(ds.cnt == 0); write_buffer_to_file(buffer_test, sizeof(buffer_test), "dir test 1/test1" ); buffer_test[0] += 10; write_buffer_to_file(buffer_test, sizeof(buffer_test), "dir test 1/test2" ); iron_usleep(30000); size_t s = 0; void * buffer = dirscan_to_buffer(ds, &s); dirscan copy = dirscan_from_buffer(buffer); dealloc(buffer); udpc_dirscan_update("dir test 1", &ds, false); dirscan_diff diff = udpc_dirscan_diff(copy, ds); ASSERT(diff.cnt == 2); ASSERT(diff.states[0] == DIRSCAN_NEW); udpc_dirscan_clear_diff(&diff); ASSERT(ds.type[0] == UDPC_DIRSCAN_FILE); remove("dir test 1/test1"); iron_usleep(20000); udpc_dirscan_update("dir test 1", &ds, false); int idx = -1; if(strcmp(ds.files[0], "test1") == 0) idx = 0; else if(strcmp(ds.files[1], "test1") == 0) idx = 1; ASSERT(idx != -1); iron_usleep(30000); ASSERT(ds.cnt == 2); ASSERT(ds.type[idx] == UDPC_DIRSCAN_DELETED); buffer_test[0] += 10; write_buffer_to_file(buffer_test, sizeof(buffer_test), "dir test 1/test1" ); udpc_dirscan_update("dir test 1", ©, false); diff = udpc_dirscan_diff(ds, copy); ASSERT(diff.cnt == 1); ASSERT(diff.states[0] == DIRSCAN_NEW); udpc_dirscan_clear_diff(&diff); dirscan_clean(©); write_buffer_to_file(buffer_test, sizeof(buffer_test), "dir test 1/sub dir/test3" ); udpc_dirscan_update("dir test 1", &ds, false); ASSERT(ds.cnt == 3); ASSERT(udpc_md5_compare(ds.md5s[idx], ds.md5s[2])); for(int i = 0; i < 10; i++){ char filename[40]; sprintf(filename, "dir test 1/sub dir/testx_%i", i); write_buffer_to_file(buffer_test, sizeof(buffer_test), filename ); } udpc_dirscan_update("dir test 1", &ds, false); ASSERT(ds.cnt == 13); dirscan_clean(&ds); for(int i = 0; i < 10; i++){ char filename[40]; sprintf(filename, "dir test 1/sub dir/testx_%i", i); remove(filename); } ASSERT(!remove("dir test 1/test2")); ASSERT(!remove("dir test 1/sub dir/test3")); ASSERT(!remove("dir test 1/sub dir")); ASSERT(!remove("dir test 1/test1")); ASSERT(!remove("dir test 1")); iron_set_allocator(old_allocator); int used_pointers = (int) trace_allocator_allocated_pointers(_allocator); trace_allocator_release(_allocator); ASSERT(used_pointers == 0); return TEST_SUCCESS; }
void prim_parsepropex(PRIM_PROTOTYPE) { struct inst* oper1 = NULL; /* prevents reentrancy issues! */ struct inst* oper2 = NULL; /* prevents reentrancy issues! */ struct inst* oper3 = NULL; /* prevents reentrancy issues! */ struct inst* oper4 = NULL; /* prevents reentrancy issues! */ stk_array* vars; const char* mpi; char* str = 0; array_iter idx; extern int varc; /* from msgparse.c */ int mvarcnt = 0; char* buffers = NULL; int novars; int hashow = 0; int i; int len; char tname[BUFFER_LEN]; char buf[BUFFER_LEN]; CHECKOP(4); oper4 = POP(); /* int:Private */ oper3 = POP(); /* dict:Vars */ oper2 = POP(); /* str:Prop */ oper1 = POP(); /* ref:Object */ if (mlev < 3) abort_interp("Mucker level 3 or greater required."); if (oper1->type != PROG_OBJECT) abort_interp("Non-object argument. (1)"); if (oper2->type != PROG_STRING) abort_interp("Non-string argument. (2)"); if (oper3->type != PROG_ARRAY) abort_interp("Non-array argument. (3)"); if (oper3->data.array && (oper3->data.array->type != ARRAY_DICTIONARY)) abort_interp("Dictionary array expected. (3)"); if (oper4->type != PROG_INTEGER) abort_interp("Non-integer argument. (4)"); if (!valid_object(oper1)) abort_interp("Invalid object. (1)"); if (!oper2->data.string) abort_interp("Empty string argument. (2)"); if ((oper4->data.number != 0) && (oper4->data.number != 1)) abort_interp("Integer of 0 or 1 expected. (4)"); CHECKREMOTE(oper1->data.objref); if (!prop_read_perms(ProgUID, oper1->data.objref, oper2->data.string->data, mlev)) abort_interp("Permission denied."); len = oper2->data.string->length; strcpyn(tname, sizeof(tname), oper2->data.string->data); while (len-- > 0 && tname[len] == PROPDIR_DELIMITER) { tname[len] = '\0'; } mpi = get_property_class(oper1->data.objref, tname); vars = oper3->data.array; novars = array_count(vars); if (check_mvar_overflow(novars)) abort_interp("Out of MPI variables. (3)"); if (array_first(vars, &idx)) { do { array_data* val = array_getitem(vars, &idx); if (idx.type != PROG_STRING) { CLEAR(&idx); abort_interp("Only string keys supported. (3)"); } if (idx.data.string == NULL) { CLEAR(&idx); abort_interp("Empty string keys not supported. (3)"); } if (strlen(idx.data.string->data) > MAX_MFUN_NAME_LEN) { CLEAR(&idx); abort_interp("Key too long to be an MPI variable. (3)"); } switch(val->type) { case PROG_INTEGER: case PROG_FLOAT: case PROG_OBJECT: case PROG_STRING: case PROG_LOCK: break; default: CLEAR(&idx); abort_interp("Only integer, float, dbref, string and lock values supported. (3)"); break; } if (string_compare(idx.data.string->data, "how") == 0) hashow = 1; } while(array_next(vars, &idx)); } if (mpi && *mpi) { if (novars > 0) { mvarcnt = varc; if ((buffers = (char*)malloc(novars * BUFFER_LEN)) == NULL) abort_interp("Out of memory."); if (array_first(vars, &idx)) { i = 0; do { char* var_buf = buffers + (i++ * BUFFER_LEN); array_data* val; val = array_getitem(vars, &idx); switch(val->type) { case PROG_INTEGER: snprintf(var_buf, BUFFER_LEN, "%i", val->data.number); break; case PROG_FLOAT: snprintf(var_buf, BUFFER_LEN, "%g", val->data.fnumber); break; case PROG_OBJECT: snprintf(var_buf, BUFFER_LEN, "#%i", val->data.objref); break; case PROG_STRING: strncpy(var_buf, DoNullInd(val->data.string), BUFFER_LEN); break; case PROG_LOCK: strncpy(var_buf, unparse_boolexp(ProgUID, val->data.lock, 1), BUFFER_LEN); break; default: var_buf[0] = '\0'; break; } var_buf[BUFFER_LEN - 1] = '\0'; new_mvar(idx.data.string->data, var_buf); } while(array_next(vars, &idx)); } } result = 0; if (oper4->data.number) result |= MPI_ISPRIVATE; if (Prop_Blessed(oper1->data.objref, oper2->data.string->data)) result |= MPI_ISBLESSED; if (hashow) result |= MPI_NOHOW; str = do_parse_mesg(fr->descr, player, oper1->data.objref, mpi, "(parsepropex)", buf, sizeof(buf), result); if (novars > 0) { if (array_first(vars, &idx)) { i = 0; do { char* var_buf = buffers + (i++ * BUFFER_LEN); struct inst temp; temp.type = PROG_STRING; temp.data.string = alloc_prog_string(var_buf); array_setitem(&vars, &idx, &temp); CLEAR(&temp); } while(array_next(vars, &idx)); } free(buffers); varc = mvarcnt; } } oper3->data.array = NULL; CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); CLEAR(oper4); PushArrayRaw(vars); PushString(str); }
static int config_connection_request(struct config_connection *conn, const char *const *args) { struct config_export_context *ctx; struct master_service_settings_output output; struct config_filter filter; const char *path, *error, *module, *const *wanted_modules; ARRAY(const char *) modules; bool is_master = FALSE; /* [<args>] */ t_array_init(&modules, 4); memset(&filter, 0, sizeof(filter)); for (; *args != NULL; args++) { if (strncmp(*args, "service=", 8) == 0) filter.service = *args + 8; else if (strncmp(*args, "module=", 7) == 0) { module = *args + 7; if (strcmp(module, "master") == 0) is_master = TRUE; array_append(&modules, &module, 1); } else if (strncmp(*args, "lname=", 6) == 0) filter.local_name = *args + 6; else if (strncmp(*args, "lip=", 4) == 0) { if (net_addr2ip(*args + 4, &filter.local_net) == 0) { filter.local_bits = IPADDR_IS_V4(&filter.local_net) ? 32 : 128; } } else if (strncmp(*args, "rip=", 4) == 0) { if (net_addr2ip(*args + 4, &filter.remote_net) == 0) { filter.remote_bits = IPADDR_IS_V4(&filter.remote_net) ? 32 : 128; } } } array_append_zero(&modules); wanted_modules = array_count(&modules) == 1 ? NULL : array_idx(&modules, 0); if (is_master) { /* master reads configuration only when reloading settings */ path = master_service_get_config_path(master_service); if (config_parse_file(path, TRUE, NULL, &error) <= 0) { o_stream_nsend_str(conn->output, t_strconcat("\nERROR ", error, "\n", NULL)); config_connection_destroy(conn); return -1; } } o_stream_cork(conn->output); ctx = config_export_init(wanted_modules, CONFIG_DUMP_SCOPE_SET, 0, config_request_output, conn->output); config_export_by_filter(ctx, &filter); config_export_get_output(ctx, &output); if (output.specific_services != NULL) { const char *const *s; for (s = output.specific_services; *s != NULL; s++) { o_stream_nsend_str(conn->output, t_strdup_printf("service=%s\t", *s)); } } if (output.service_uses_local) o_stream_nsend_str(conn->output, "service-uses-local\t"); if (output.service_uses_remote) o_stream_nsend_str(conn->output, "service-uses-remote\t"); if (output.used_local) o_stream_nsend_str(conn->output, "used-local\t"); if (output.used_remote) o_stream_nsend_str(conn->output, "used-remote\t"); o_stream_nsend_str(conn->output, "\n"); if (config_export_finish(&ctx) < 0) { config_connection_destroy(conn); return -1; } o_stream_nsend_str(conn->output, "\n"); o_stream_uncork(conn->output); return 0; }