/* Open the part NAME. NAME consists of a partition number, a ':', a another store class name, a ':' and a name for to by passed to the store class. E.g. "2:device:hd0" would open the second partition on a DEVICE store named "hd0". FLAGS indicate how to open the store. CLASSES is used to select classes specified by the type NAME; if it is 0, STORE_STD_CLASSES is used. The new store is returned in *STORE. */ error_t store_part_open (const char *name, int flags, const struct store_class *const *classes, struct store **store) { int part; char *endp; struct store *source; error_t err; part = strtol (name, &endp, 0); if (endp == name || *endp != ':') return EINVAL; name = endp + 1; if (*name == '\0') return EINVAL; err = store_typed_open (name, flags, classes, &source); if (! err) { err = store_part_create (source, part, flags, store); if (err) store_free (source); } return err; }
void ipv4_exec_reply_get_addr(struct finsFrame *ff, uint64_t src_mac, uint64_t dst_mac) { PRINT_DEBUG("Entered: ff=%p, src_mac=%llx, dst_mac=%llx", ff, src_mac, dst_mac); struct ip4_store *store = store_list_find(ff->ctrlFrame.serial_num); if (store) { store_list_remove(store); metadata *params = store->ff->metaData; uint32_t ether_type = IP4_ETH_TYPE; metadata_writeToElement(params, "send_dst_mac", &dst_mac, META_TYPE_INT64); metadata_writeToElement(params, "send_src_mac", &src_mac, META_TYPE_INT64); metadata_writeToElement(params, "send_ether_type", ðer_type, META_TYPE_INT32); PRINT_DEBUG("recv frame: dst=0x%12.12llx, src=0x%12.12llx, type=0x%x", dst_mac, src_mac, ether_type); //print_finsFrame(fins_frame); ipv4_to_switch(store->ff); store->ff = NULL; store_free(store); freeFinsFrame(ff); } else { PRINT_ERROR("todo error"); //TODO error sending back FDF as FCF? saved pdu for that } }
void* channel_read (channel_t *channel) { ensure(pthread_mutex_lock(&channel->mutex) == 0); channel->readers++; while (channel->backlog == 0) ensure(pthread_cond_wait(&channel->cond_read, &channel->mutex) == 0); channel->backlog--; channel_node_t *node = channel->list; channel->list = node->next; if (node == channel->last) channel->last = NULL; if (channel->writers) ensure(pthread_cond_signal(&channel->cond_write) == 0); channel->readers--; ensure(pthread_mutex_unlock(&channel->mutex) == 0); void *msg = malloc(node->length); memmove(msg, node->payload, node->length); store_free(global.store, node); return msg; }
void channel_free (channel_t *channel) { if (channel->used) { while (channel->list) { channel_node_t *node = channel->list; channel->list = node->next; store_free(global.store, node); } pthread_mutex_destroy(&channel->mutex); pthread_cond_destroy(&channel->cond_read); pthread_cond_destroy(&channel->cond_write); store_free(global.store, channel->list); channel->used = 0; } }
void ipv4_release(void) { PRINT_DEBUG("Entered"); //TODO free all module related mem struct ip4_store *store; while (!store_list_is_empty()) { store = store_list; store_list_remove(store); store_free(store); } struct ip4_routing_table *table; while (routing_table) { table = routing_table; routing_table = routing_table->next_entry; free(table); } term_queue(IPv4_to_Switch_Queue); //TODO uncomment term_queue(Switch_to_IPv4_Queue); }
void ipv4_exec_reply(struct finsFrame *ff) { PRINT_DEBUG("Entered: ff=%p, meta=%p", ff, ff->metaData); int ret = 0; metadata *params = ff->metaData; if (params) { switch (ff->ctrlFrame.param_id) { case EXEC_ARP_GET_ADDR: PRINT_DEBUG("param_id=EXEC_ARP_GET_ADDR (%d)", ff->ctrlFrame.param_id); if (ff->ctrlFrame.ret_val) { uint64_t src_mac, dst_mac; ret += metadata_readFromElement(params, "src_mac", &src_mac) == META_FALSE; ret += metadata_readFromElement(params, "dst_mac", &dst_mac) == META_FALSE; if (ret) { PRINT_ERROR("ret=%d", ret); //TODO send nack } else { //ipv4_exec_reply_get_addr(ff, src_mac, dst_mac); struct ip4_store *store = store_list_find(ff->ctrlFrame.serial_num); if (store) { PRINT_DEBUG("store=%p, ff=%p, serial_num=%u", store, store->ff, store->serial_num); store_list_remove(store); uint32_t ether_type = IP4_ETH_TYPE; metadata_writeToElement(store->ff->metaData, "send_ether_type", ðer_type, META_TYPE_INT32); metadata_writeToElement(store->ff->metaData, "send_dst_mac", &dst_mac, META_TYPE_INT64); metadata_writeToElement(store->ff->metaData, "send_src_mac", &src_mac, META_TYPE_INT64); PRINT_DEBUG("recv frame: dst=0x%12.12llx, src=0x%12.12llx, type=0x%x", dst_mac, src_mac, ether_type); //print_finsFrame(fins_frame); ipv4_to_switch(store->ff); store->ff = NULL; store_free(store); freeFinsFrame(ff); } else { PRINT_ERROR("todo error"); } } } else { //TODO error sending back FDF as FCF? saved pdu for that PRINT_ERROR("todo error"); } break; default: PRINT_ERROR("Error unknown param_id=%d", ff->ctrlFrame.param_id); //TODO implement? freeFinsFrame(ff); break; } } else { //TODO send nack PRINT_ERROR("Error fcf.metadata==NULL"); freeFinsFrame(ff); } }
static void ActOnMessage(uschar *id, uschar *action, uschar *address_arg) { int pid; int pipe_fd[2]; int delivery = Ustrcmp(action + Ustrlen(action) - 2, "-M") == 0; uschar *quote = US""; uschar *at = US""; uschar *qualify = US""; uschar buffer[256]; queue_item *qq; Widget text = NULL; /* If the address arg is not empty and does not contain @ and there is a qualify domain, qualify it. (But don't qualify '<>'.)*/ if (address_arg[0] != 0) { quote = US"\'"; if (Ustrchr(address_arg, '@') == NULL && Ustrcmp(address_arg, "<>") != 0 && qualify_domain != NULL && qualify_domain[0] != 0) { at = US"@"; qualify = qualify_domain; } } sprintf(CS buffer, "%s %s %s %s %s %s%s%s%s%s", exim_path, (alternate_config == NULL)? US"" : US"-C", (alternate_config == NULL)? US"" : alternate_config, action, id, quote, address_arg, at, qualify, quote); /* If we know we are going to need the window, create it now. */ if (action_output || delivery) { text = text_create(id, text_depth); text_showf(text, "%s\n", buffer); } /* Create the pipe for output. Remember, on most systems pipe[0] is for reading and pipe[1] is for writing! Solaris, with its two-way pipes is a trap! */ if (pipe(pipe_fd) != 0) { if (text == NULL) { text = text_create(id, text_depth); text_showf(text, "%s\n", buffer); } text_show(text, US"*** Failed to create pipe ***\n"); return; } if ( fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK) || fcntl(pipe_fd[1], F_SETFL, O_NONBLOCK)) { perror("set nonblocking on pipe"); exit(1); } /* Delivering a message can take some time, and we want to show the output as it goes along. This requires subprocesses and is coded below. For other commands, we can assume an immediate response, and so need not waste resources with subprocesses. If action_output is FALSE, don't show the output at all. */ if (!delivery) { int count, rc; int save_stdout = dup(1); int save_stderr = dup(2); close(1); close(2); dup2(pipe_fd[1], 1); dup2(pipe_fd[1], 2); close(pipe_fd[1]); rc = system(CS buffer); close(1); close(2); if (action_output || rc != 0) { if (text == NULL) { text = text_create(id, text_depth); text_showf(text, "%s\n", buffer); } while ((count = read(pipe_fd[0], buffer, 254)) > 0) { buffer[count] = 0; text_show(text, buffer); } } close(pipe_fd[0]); dup2(save_stdout, 1); dup2(save_stderr, 2); close(save_stdout); close(save_stderr); /* If action was to change the sender, and it succeeded, we have to update the in-store data. */ if (rc == 0 && Ustrcmp(action + Ustrlen(action) - 4, "-Mes") == 0) { queue_item *q = find_queue(id, queue_noop, 0); if (q) { if (q->sender) store_free(q->sender); q->sender = store_malloc(Ustrlen(address_arg) + 1); Ustrcpy(q->sender, address_arg); } } /* If configured, cause a display update and return */ if (action_queue_update) tick_queue_accumulator = 999999; return; } /* Message is to be delivered. Ensure that it is marked unfrozen, because nothing will get written to the log to show that this has happened. (Other freezing/unfreezings get logged and picked up from there.) */ qq = find_queue(id, queue_noop, 0); if (qq != NULL) qq->frozen = FALSE; /* New, asynchronous code runs in a subprocess for commands that will take some time. The main process does not wait. There is a SIGCHLD handler in the main program that cleans up any terminating sub processes. */ if ((pid = fork()) == 0) { close(1); close(2); dup2(pipe_fd[1], 1); dup2(pipe_fd[1], 2); close(pipe_fd[1]); system(CS buffer); close(1); close(2); close(pipe_fd[0]); _exit(0); } /* Main process - set up an item for the main ticker to watch. */ if (pid < 0) text_showf(text, "Failed to fork: %s\n", strerror(errno)); else { pipe_item *p = (pipe_item *)store_malloc(sizeof(pipe_item)); if (p == NULL) { text_show(text, US"Run out of store\n"); return; } p->widget = text; p->fd = pipe_fd[0]; p->next = pipe_chain; pipe_chain = p; close(pipe_fd[1]); } }
void auth_heimdal_gssapi_init(auth_instance *ablock) { krb5_context context; krb5_keytab keytab; krb5_kt_cursor cursor; krb5_keytab_entry entry; krb5_error_code krc; char *principal, *enctype_s; const char *k_keytab_typed_name = NULL; auth_heimdal_gssapi_options_block *ob = (auth_heimdal_gssapi_options_block *)(ablock->options_block); ablock->server = FALSE; ablock->client = FALSE; if (!ob->server_service || !*ob->server_service) { HDEBUG(D_auth) debug_printf("heimdal: missing server_service\n"); return; } krc = krb5_init_context(&context); if (krc != 0) { int kerr = errno; HDEBUG(D_auth) debug_printf("heimdal: failed to initialise krb5 context: %s\n", strerror(kerr)); return; } if (ob->server_keytab) { k_keytab_typed_name = CCS string_sprintf("file:%s", expand_string(ob->server_keytab)); HDEBUG(D_auth) debug_printf("heimdal: using keytab %s\n", k_keytab_typed_name); krc = krb5_kt_resolve(context, k_keytab_typed_name, &keytab); if (krc) { HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_resolve", context, krc); return; } } else { HDEBUG(D_auth) debug_printf("heimdal: using system default keytab\n"); krc = krb5_kt_default(context, &keytab); if (krc) { HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_default", context, krc); return; } } HDEBUG(D_auth) { /* http://www.h5l.org/manual/HEAD/krb5/krb5_keytab_intro.html */ krc = krb5_kt_start_seq_get(context, keytab, &cursor); if (krc) exim_heimdal_error_debug("krb5_kt_start_seq_get", context, krc); else { while ((krc = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) { principal = enctype_s = NULL; krb5_unparse_name(context, entry.principal, &principal); krb5_enctype_to_string(context, entry.keyblock.keytype, &enctype_s); debug_printf("heimdal: keytab principal: %s vno=%d type=%s\n", principal ? principal : "??", entry.vno, enctype_s ? enctype_s : "??"); free(principal); free(enctype_s); krb5_kt_free_entry(context, &entry); } krc = krb5_kt_end_seq_get(context, keytab, &cursor); if (krc) exim_heimdal_error_debug("krb5_kt_end_seq_get", context, krc); } } krc = krb5_kt_close(context, keytab); if (krc) HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_close", context, krc); krb5_free_context(context); /* RFC 4121 section 5.2, SHOULD support 64K input buffers */ if (big_buffer_size < (64 * 1024)) { uschar *newbuf; big_buffer_size = 64 * 1024; newbuf = store_malloc(big_buffer_size); store_free(big_buffer); big_buffer = newbuf; } ablock->server = TRUE; }
void init_lookup_list(void) { #ifdef LOOKUP_MODULE_DIR DIR *dd; struct dirent *ent; int countmodules = 0; int moduleerrors = 0; #endif struct lookupmodulestr *p; const pcre *regex_islookupmod = regex_must_compile( US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE); if (lookup_list_init_done) return; lookup_list_init_done = 1; #if defined(LOOKUP_CDB) && LOOKUP_CDB!=2 addlookupmodule(NULL, &cdb_lookup_module_info); #endif #if defined(LOOKUP_DBM) && LOOKUP_DBM!=2 addlookupmodule(NULL, &dbmdb_lookup_module_info); #endif #if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2 addlookupmodule(NULL, &dnsdb_lookup_module_info); #endif #if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2 addlookupmodule(NULL, &dsearch_lookup_module_info); #endif #if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2 addlookupmodule(NULL, &ibase_lookup_module_info); #endif #ifdef LOOKUP_LDAP addlookupmodule(NULL, &ldap_lookup_module_info); #endif #if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2 addlookupmodule(NULL, &lsearch_lookup_module_info); #endif #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2 addlookupmodule(NULL, &mysql_lookup_module_info); #endif #if defined(LOOKUP_NIS) && LOOKUP_NIS!=2 addlookupmodule(NULL, &nis_lookup_module_info); #endif #if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2 addlookupmodule(NULL, &nisplus_lookup_module_info); #endif #if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2 addlookupmodule(NULL, &oracle_lookup_module_info); #endif #if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2 addlookupmodule(NULL, &passwd_lookup_module_info); #endif #if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2 addlookupmodule(NULL, &pgsql_lookup_module_info); #endif #ifdef EXPERIMENTAL_REDIS addlookupmodule(NULL, &redis_lookup_module_info); #endif #ifdef EXPERIMENTAL_SPF addlookupmodule(NULL, &spf_lookup_module_info); #endif #if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2 addlookupmodule(NULL, &sqlite_lookup_module_info); #endif #if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2 addlookupmodule(NULL, &testdb_lookup_module_info); #endif #if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2 addlookupmodule(NULL, &whoson_lookup_module_info); #endif #ifdef LOOKUP_MODULE_DIR dd = opendir(LOOKUP_MODULE_DIR); if (dd == NULL) { DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR); log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR); } else { DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR); while ((ent = readdir(dd)) != NULL) { char *name = ent->d_name; int len = (int)strlen(name); if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) { int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2; void *dl; struct lookup_module_info *info; const char *errormsg; /* SRH: am I being paranoid here or what? */ if (pathnamelen > big_buffer_size) { fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name); log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name); continue; } /* SRH: snprintf here? */ sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name); dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY if (dl == NULL) { fprintf(stderr, "Error loading %s: %s\n", name, dlerror()); moduleerrors++; log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror()); continue; } /* FreeBSD nsdispatch() can trigger dlerror() errors about * _nss_cache_cycle_prevention_function; we need to clear the dlerror() * state before calling dlsym(), so that any error afterwards only * comes from dlsym(). */ errormsg = dlerror(); info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info"); if ((errormsg = dlerror()) != NULL) { fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg); dlclose(dl); moduleerrors++; log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg); continue; } if (info->magic != LOOKUP_MODULE_INFO_MAGIC) { fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name); dlclose(dl); moduleerrors++; log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name); continue; } addlookupmodule(dl, info); DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount); countmodules++; } } closedir(dd); } DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules); #endif store_free((void*)regex_islookupmod); DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count); lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count); memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count); /* now add all lookups to the real list */ p = lookupmodules; while (p) { int j; struct lookupmodulestr *pnext; for (j = 0; j < p->info->lookupcount; j++) add_lookup_to_list(p->info->lookups[j]); pnext = p->next; store_free(p); p = pnext; } /* just to be sure */ lookupmodules = NULL; }
error_t trivfs_S_file_get_storage_info (struct trivfs_protid *cred, mach_port_t reply, mach_msg_type_name_t reply_type, mach_port_t **ports, mach_msg_type_name_t *ports_type, mach_msg_type_number_t *num_ports, int **ints, mach_msg_type_number_t *num_ints, off_t **offsets, mach_msg_type_number_t *num_offsets, char **data, mach_msg_type_number_t *data_len) { *ports_type = MACH_MSG_TYPE_COPY_SEND; if (! cred || ! cred->po->hook) return EOPNOTSUPP; else { error_t err; struct dev *dev = ((struct open *)cred->po->hook)->dev; struct store *store = dev->store; if (dev->enforced && !(store->flags & STORE_ENFORCED)) { /* The --enforced switch tells us not to let anyone get at the device, no matter how trustable they are. */ size_t name_len = (store->name ? strlen (store->name) + 1 : 0); int i; *num_ports = 0; i = 0; (*ints)[i++] = STORAGE_OTHER; (*ints)[i++] = store->flags; (*ints)[i++] = store->block_size; (*ints)[i++] = 1; /* num_runs */ (*ints)[i++] = name_len; (*ints)[i++] = 0; /* misc_len */ *num_ints = i; i = 0; (*offsets)[i++] = 0; (*offsets)[i++] = store->size; *num_offsets = i; if (store->name) memcpy (*data, store->name, name_len); *data_len = name_len; return 0; } if (!cred->isroot && !store_is_securely_returnable (store, cred->po->openmodes)) { struct store *clone; err = store_clone (store, &clone); if (! err) { err = store_set_flags (clone, STORE_INACTIVE); if (err == EINVAL) err = EACCES; else err = store_return (clone, ports, num_ports, ints, num_ints, offsets, num_offsets, data, data_len); store_free (clone); } } else err = store_return (store, ports, num_ports, ints, num_ints, offsets, num_offsets, data, data_len); return err; } }