void io_loop_handler_run(struct ioloop *ioloop) { struct ioloop_handler_context *ctx = ioloop->handler_context; struct kevent *events; const struct kevent *event; struct timeval tv; struct timespec ts; struct io_file *io; unsigned int events_count; int ret, i; /* get the time left for next timeout task */ io_loop_get_wait_time(ioloop, &tv); ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; /* wait for events */ events = array_get_modifiable(&ctx->events, &events_count); ret = kevent (ctx->kq, NULL, 0, events, events_count, &ts); if (ret < 0 && errno != EINTR) i_fatal("kevent(): %m"); /* reference all IOs */ for (i = 0; i < ret; i++) { io = (void *)events[i].udata; i_assert(io->refcount > 0); io->refcount++; } /* execute timeout handlers */ io_loop_handle_timeouts(ioloop); for (i = 0; i < ret; i++) { /* io_loop_handle_add() may cause events array reallocation, so we have use array_idx() */ event = array_idx(&ctx->events, i); io = (void *)event->udata; /* callback is NULL if io_remove() was already called */ if (io->io.callback != NULL) io_loop_call_io(&io->io); i_assert(io->refcount > 0); if (--io->refcount == 0) i_free(io); } }
static uoff_t dump_size(struct istream *input, const char *name, const char *value) { uoff_t size; if (strcmp(value, "0") == 0) size = 0; else { size = hex2dec((const void *)value, strlen(value)); if (size == 0) { i_fatal("Invalid %s at %"PRIuUOFF_T": %s", name, input->v_offset, value); } } printf("%s = %"PRIuUOFF_T"\n", name, size); return size; }
static void ssl_params_rebuild(struct ssl_params *param) { switch (fork()) { case -1: i_fatal("fork() failed: %m"); case 0: /* child - close listener fds so a long-running ssl-params doesn't cause Dovecot restart to fail */ ssl_params_close_listeners(); ssl_params_if_unchanged(param->path, param->last_mtime, param->set.ssl_dh_parameters_length); exit(0); default: /* parent */ break; } }
static void cmd_dump_log(int argc ATTR_UNUSED, char *argv[]) { uint64_t modseq; int fd, ret; fd = open(argv[1], O_RDONLY); if (fd < 0) i_fatal("open(%s) failed: %m", argv[1]); dump_hdr(fd, &modseq); do { T_BEGIN { ret = dump_record(fd, &modseq); } T_END; } while (ret > 0); i_close_fd(&fd); }
struct ostream *sieve_tool_open_output_stream(const char *filename) { struct ostream *outstream; int fd; if ( strcmp(filename, "-") == 0 ) outstream = o_stream_create_fd(1, 0, FALSE); else { if ( (fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0 ) { i_fatal("failed to open file for writing: %m"); } outstream = o_stream_create_fd_autoclose(&fd, 0); } return outstream; }
static struct passdb_module * bsdauth_preinit(pool_t pool, const char *args) { struct passdb_module *module; module = p_new(pool, struct passdb_module, 1); module->default_pass_scheme = "PLAIN"; /* same reason as PAM */ module->blocking = TRUE; if (strcmp(args, "blocking=no") == 0) module->blocking = FALSE; else if (strncmp(args, "cache_key=", 10) == 0) module->cache_key = auth_cache_parse_key(pool, args + 10); else if (*args != '\0') i_fatal("passdb bsdauth: Unknown setting: %s", args); return module; }
struct acl_backend * acl_backend_init(const char *data, struct mailbox_list *list, const char *acl_username, const char *const *groups, bool owner) { struct mail_user *user = mailbox_list_get_user(list); struct acl_backend *backend; unsigned int i, group_count; if (user->mail_debug) { i_debug("acl: initializing backend with data: %s", data); i_debug("acl: acl username = %s", acl_username); i_debug("acl: owner = %d", owner ? 1 : 0); } group_count = str_array_length(groups); if (strncmp(data, "vfile:", 6) == 0) data += 6; else if (strcmp(data, "vfile") == 0) data = ""; else i_fatal("Unknown ACL backend: %s", t_strcut(data, ':')); backend = acl_backend_vfile.alloc(); backend->debug = user->mail_debug; backend->v = acl_backend_vfile; backend->list = list; backend->username = p_strdup(backend->pool, acl_username); backend->owner = owner; backend->globals_only = mail_user_plugin_getenv_bool(user, "acl_globals_only"); if (group_count > 0) { backend->group_count = group_count; backend->groups = p_new(backend->pool, const char *, group_count); for (i = 0; i < group_count; i++) { backend->groups[i] = p_strdup(backend->pool, groups[i]); if (user->mail_debug) i_debug("acl: group added: %s", groups[i]); } i_qsort(backend->groups, group_count, sizeof(const char *), i_strcmp_p); }
static void test_server_read_fd(struct istream *input, int wanted_fd, unsigned int idx) { struct stat st1, st2; const unsigned char *data; size_t size; int recv_fd; test_assert_idx(i_stream_read_data(input, &data, &size, 0) == 1, idx); i_stream_skip(input, 1); test_assert_idx((recv_fd = i_stream_unix_get_read_fd(input)) != -1, idx); if (recv_fd != -1) { if (fstat(recv_fd, &st1) < 0 || fstat(wanted_fd, &st2) < 0) i_fatal("fstat() failed: %m"); test_assert_idx(st1.st_ino == st2.st_ino, idx); i_close_fd(&recv_fd); } }
void sieve_tool_dump_binary_to (struct sieve_binary *sbin, const char *filename, bool hexdump) { struct ostream *dumpstream; if ( filename == NULL ) return; dumpstream = sieve_tool_open_output_stream(filename); if ( dumpstream != NULL ) { if ( hexdump ) (void) sieve_hexdump(sbin, dumpstream); else (void) sieve_dump(sbin, dumpstream, FALSE); o_stream_destroy(&dumpstream); } else { i_fatal("Failed to create stream for sieve code dump."); } }
struct sql_db *sql_init(const char *db_driver, const char *connect_string) { const struct sql_db *driver; struct sql_db *db; i_assert(connect_string != NULL); driver = sql_driver_lookup(db_driver); if (driver == NULL) i_fatal("Unknown database driver '%s'", db_driver); if ((driver->flags & SQL_DB_FLAG_POOLED) == 0) db = driver->v.init(connect_string); else db = driver_sqlpool_init(connect_string, driver); i_array_init(&db->module_contexts, 5); return db; }
void hostpid_init(void) { static char hostname[256], pid[MAX_INT_STRLEN]; if (gethostname(hostname, sizeof(hostname)-1) == -1) i_strocpy(hostname, "unknown", sizeof(hostname)); hostname[sizeof(hostname)-1] = '\0'; my_hostname = hostname; if (strchr(hostname, '/') != NULL) i_fatal("Invalid system hostname: %s", hostname); /* allow calling hostpid_init() multiple times to reset hostname */ i_free_and_null(my_domain); i_strocpy(pid, dec2str(getpid()), sizeof(pid)); my_pid = pid; }
static void cmd_dump_fts_expunge_log(int argc ATTR_UNUSED, char *argv[]) { buffer_t *buf; int fd, ret; fd = open(argv[1], O_RDONLY); if (fd < 0) i_fatal("open(%s) failed: %m", argv[1]); buf = buffer_create_dynamic(default_pool, 1024); do { T_BEGIN { ret = dump_record(fd, buf); } T_END; } while (ret > 0); buffer_free(&buf); i_close_fd(&fd); }
static void doveadm_print_formatted_print(const char *value) { if (ctx.format == NULL) { i_fatal("formatted formatter cannot be used without a format."); } const char *error; struct var_expand_table *entry = array_idx_modifiable(&ctx.headers, ctx.idx++); entry->value = value; if (ctx.idx >= array_count(&ctx.headers)) { if (var_expand(ctx.buf, ctx.format, array_idx(&ctx.headers,0), &error) <= 0) { i_error("Failed to expand print format '%s': %s", ctx.format, error); } doveadm_print_formatted_flush(); ctx.idx = 0; } }
static void askpass_str(const char *prompt, buffer_t *pass) { struct termios old_tio, tio; bool tty, restore_tio = FALSE; char ch; int fd; tty = isatty(STDIN_FILENO); if (tty) { fputs(prompt, stderr); fflush(stderr); fd = open("/dev/tty", O_RDONLY); if (fd < 0) i_fatal("open(/dev/tty) failed: %m"); /* turn off echo */ if (tcgetattr(fd, &old_tio) == 0) { restore_tio = TRUE; tio = old_tio; tio.c_lflag &= ~(ECHO | ECHONL); (void)tcsetattr(fd, TCSAFLUSH, &tio); } } else { /* read it from stdin without showing a prompt */ fd = STDIN_FILENO; } /* read the password */ while (read(fd, &ch, 1) > 0) { if (ch == '\n' || ch == '\r') break; buffer_append_c(pass, ch); } if (tty) { if (restore_tio) (void)tcsetattr(fd, TCSAFLUSH, &old_tio); fputs("\n", stderr); fflush(stderr); i_close_fd(&fd); } }
static struct fs * fs_sis_init(const char *args, const struct fs_settings *set) { struct sis_fs *fs; const char *p; fs = i_new(struct sis_fs, 1); fs->fs = fs_class_sis; if (*args == '\0') i_fatal("fs-sis: Parent filesystem not given as parameter"); p = strchr(args, ':'); if (p == NULL) fs->super = fs_init(args, "", set); else fs->super = fs_init(t_strdup_until(args, p), p+1, set); return &fs->fs; }
static void test_istream_unix_client(int fd) { /* 1) */ write_one(fd); read_one(fd); /* 2) */ if (fd_send(fd, send_fd, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); /* 3) */ write_one(fd); read_one(fd); /* 4) */ if (fd_send(fd, send_fd2, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); /* 5) */ write_one(fd); read_one(fd); /* 6) */ if (fd_send(fd, send_fd, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); /* 7-8) */ if (fd_send(fd, send_fd, "1", 1) < 0) i_fatal("fd_send() failed: %m"); if (fd_send(fd, send_fd2, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); /* 9-10) */ if (fd_send(fd, send_fd, "1", 1) < 0) i_fatal("fd_send() failed: %m"); if (fd_send(fd, send_fd2, "1", 1) < 0) i_fatal("fd_send() failed: %m"); read_one(fd); i_close_fd(&fd); }
static bool stats_top_round(struct top_context *ctx) { #define TOP_CMD "EXPORT\tsession\tconnected\n" const char *const *args; pool_t tmp_pool; if (write_full(ctx->fd, TOP_CMD, strlen(TOP_CMD)) < 0) i_fatal("write(%s) failed: %m", ctx->path); /* read header */ if (ctx->headers != NULL) { args = read_next_line(ctx->input); if (args == NULL) i_fatal("read(%s) unexpectedly disconnected", ctx->path); if (*args == NULL) return TRUE; if (str_array_length(args) != ctx->headers_count) i_fatal("headers changed"); } else { ctx->headers = p_read_next_line(default_pool, ctx->input); if (ctx->headers == NULL) i_fatal("read(%s) unexpectedly disconnected", ctx->path); if (*ctx->headers == NULL) { i_free_and_null(ctx->headers); return FALSE; } ctx->headers_count = str_array_length((void *)ctx->headers); if (!stats_header_find(ctx, "last_update", &ctx->last_update_idx)) i_fatal("last_update header missing"); if (!stats_header_find(ctx, "user", &ctx->user_idx)) i_fatal("user header missing"); stats_top_get_sorting(ctx); } array_clear(&ctx->lines); p_clear(ctx->prev_pool); tmp_pool = ctx->prev_pool; ctx->prev_pool = ctx->cur_pool; ctx->cur_pool = tmp_pool; ctx->flip = !ctx->flip; stats_read(ctx); stats_drop_stale(ctx); sort_ctx = ctx; array_sort(&ctx->lines, *ctx->lines_sort); sort_ctx = NULL; return TRUE; }
void test_fs_async(const char *test_name, enum fs_properties properties, const char *driver, const char *args) { struct fs_settings fs_set; struct fs *fs; struct test_fs *test_fs; const char *error; i_zero(&fs_set); if (fs_init(driver, args, &fs_set, &fs, &error) < 0) i_fatal("fs_init() failed: %s", error); test_fs = test_fs_get(fs); test_fs->properties = properties; test_fs_async_write(test_name, fs); test_fs_async_copy(test_name, fs); fs_deinit(&fs); }
void io_loop_handle_add(struct io_file *io) { struct ioloop_handler_context *ctx = io->io.ioloop->handler_context; enum io_condition condition = io->io.condition; int fd = io->fd; i_assert(fd >= 0); if (fd >= FD_SETSIZE) i_fatal("fd %d too large for select()", fd); if ((condition & (IO_READ | IO_ERROR)) != 0) FD_SET(fd, &ctx->read_fds); if ((condition & IO_WRITE) != 0) FD_SET(fd, &ctx->write_fds); FD_SET(fd, &ctx->except_fds); if (io->fd > ctx->highest_fd) ctx->highest_fd = io->fd; }
void env_clean(void) { #ifdef HAVE_CLEARENV if (clearenv() < 0) i_fatal("clearenv() failed"); #else char ***environ_p = env_get_environ_p(); /* Try to clear the environment. a) environ = NULL crashes on OS X. b) *environ = NULL doesn't work on FreeBSD 7.0. c) environ = emptyenv doesn't work on Haiku OS d) environ = calloc() should work everywhere */ *environ_p = calloc(1, sizeof(**environ_p)); #endif if (env_pool != NULL) p_clear(env_pool); }
struct sieve_binary *sieve_tool_script_open (struct sieve_instance *svinst, const char *filename) { struct sieve_error_handler *ehandler; struct sieve_binary *sbin; ehandler = sieve_stderr_ehandler_create(svinst, 0); sieve_error_handler_accept_infolog(ehandler, TRUE); if ( (sbin = sieve_open (svinst, filename, NULL, ehandler, 0, NULL)) == NULL ) { sieve_error_handler_unref(&ehandler); i_fatal("failed to compile sieve script"); } sieve_error_handler_unref(&ehandler); sieve_save(sbin, FALSE, NULL); return sbin; }
static void cmd_flags_init(struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { struct flags_cmd_context *ctx = (struct flags_cmd_context *)_ctx; const char *const *tmp; enum mail_flags flag; ARRAY_TYPE(const_string) keywords; if (args[0] == NULL || args[1] == NULL) { switch (ctx->modify_type) { case MODIFY_ADD: doveadm_mail_help_name("flags add"); case MODIFY_REMOVE: doveadm_mail_help_name("flags remove"); case MODIFY_REPLACE: doveadm_mail_help_name("flags replace"); } i_unreached(); } p_array_init(&keywords, _ctx->pool, 8); for (tmp = t_strsplit(args[0], " "); *tmp != NULL; tmp++) { const char *str = *tmp; if (str[0] == '\\') { flag = imap_parse_system_flag(str); if (flag == 0) i_fatal("Invalid system flag: %s", str); ctx->flags |= flag; } else { str = p_strdup(_ctx->pool, str); array_append(&keywords, &str, 1); } } if (array_count(&keywords) > 0 || ctx->modify_type == MODIFY_REPLACE) { array_append_zero(&keywords); ctx->keywords = array_idx(&keywords, 0); } _ctx->search_args = doveadm_mail_build_search_args(args+1); }
static void read_parameters(const char *fname) { int fd; /* we'll wait until parameter file exists */ for (;;) { fd = open(fname, O_RDONLY); if (fd != -1) break; if (errno != ENOENT) i_fatal("Can't open SSL parameter file %s: %m", fname); sleep(1); } read_dh_parameters(fd, fname); read_rsa_parameters(fd, fname); (void)close(fd); }
im_slot_t im_context_slot_new(im_slot_destroy_t destructor) { im_slot_t new_slot; im_slot_destroy_t *new_destructors; if (!slot_mutex) slot_mutex = i_mutex_new(); i_mutex_lock(slot_mutex); new_slot = slot_count++; new_destructors = realloc(slot_destructors, sizeof(void *) * slot_count); if (!new_destructors) i_fatal(1, "Cannot allocate memory for slot destructors"); slot_destructors = new_destructors; slot_destructors[new_slot] = destructor; i_mutex_unlock(slot_mutex); return new_slot; }
static void acl_mailbox_list_init_default(struct mailbox_list *list) { struct mailbox_list_vfuncs *v = list->vlast; struct acl_mailbox_list *alist; if (list->mail_set->mail_full_filesystem_access) { /* not necessarily, but safer to do this for now. */ i_fatal("mail_full_filesystem_access=yes is " "incompatible with ACLs"); } alist = p_new(list->pool, struct acl_mailbox_list, 1); alist->module_ctx.super = *v; list->vlast = &alist->module_ctx.super; v->deinit = acl_mailbox_list_deinit; v->iter_init = acl_mailbox_list_iter_init; v->iter_next = acl_mailbox_list_iter_next; v->iter_deinit = acl_mailbox_list_iter_deinit; MODULE_CONTEXT_SET(list, acl_mailbox_list_module, alist); }
int main(int argc, char *argv[]) { const struct setting_parser_info *set_roots[] = { &doveadm_setting_parser_info, NULL }; enum master_service_flags service_flags = MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; const char *error; int c; master_service = master_service_init("doveadm", service_flags, &argc, &argv, "D"); while ((c = master_getopt(master_service)) > 0) { switch (c) { case 'D': doveadm_debug = TRUE; doveadm_verbose = TRUE; break; default: return FATAL_DEFAULT; } } if (master_service_settings_read_simple(master_service, set_roots, &error) < 0) i_fatal("Error reading configuration: %s", error); master_service_init_log(master_service, "doveadm: "); main_preinit(); master_service_set_die_callback(master_service, doveadm_die); main_init(); master_service_init_finish(master_service); master_service_run(master_service, client_connected); main_deinit(); master_service_deinit(&master_service); return 0; }
void io_loop_handle_add(struct io_file *io) { struct ioloop_handler_context *ctx = io->io.ioloop->handler_context; struct io_list **list; struct epoll_event event; int op; bool first; list = array_idx_modifiable(&ctx->fd_index, io->fd); if (*list == NULL) *list = i_new(struct io_list, 1); first = ioloop_iolist_add(*list, io); memset(&event, 0, sizeof(event)); event.data.ptr = *list; event.events = epoll_event_mask(*list); op = first ? EPOLL_CTL_ADD : EPOLL_CTL_MOD; if (epoll_ctl(ctx->epfd, op, io->fd, &event) < 0) { if (errno == EPERM && op == EPOLL_CTL_ADD) { i_fatal("epoll_ctl(add, %d) failed: %m " "(fd doesn't support epoll%s)", io->fd, io->fd != STDIN_FILENO ? "" : " - instead of '<file', try 'cat file|'"); } i_panic("epoll_ctl(%s, %d) failed: %m", op == EPOLL_CTL_ADD ? "add" : "mod", io->fd); } if (first) { /* allow epoll_wait() to return the maximum number of events by keeping space allocated for each file descriptor */ if (ctx->deleted_count > 0) ctx->deleted_count--; else array_append_zero(&ctx->events); } }
static void cmd_dump_dbox(int argc ATTR_UNUSED, char *argv[]) { struct istream *input; int fd; unsigned int hdr_size; bool ret; fd = open(argv[1], O_RDONLY); if (fd < 0) i_fatal("open(%s) failed: %m", argv[1]); input = i_stream_create_fd_autoclose(&fd, (size_t)-1); i_stream_set_name(input, argv[1]); hdr_size = dump_file_hdr(input); do { printf("\n"); T_BEGIN { ret = dump_msg(input, hdr_size); } T_END; } while (ret); i_stream_destroy(&input); }
static void timeout_update_next(struct timeout *timeout, struct timeval *tv_now) { if (tv_now == NULL) { if (gettimeofday(&timeout->next_run, NULL) < 0) i_fatal("gettimeofday(): %m"); } else { timeout->next_run.tv_sec = tv_now->tv_sec; timeout->next_run.tv_usec = tv_now->tv_usec; } /* we don't want microsecond accuracy or this function will be called all the time - millisecond is more than enough */ timeout->next_run.tv_usec -= timeout->next_run.tv_usec % 1000; timeout->next_run.tv_sec += timeout->msecs/1000; timeout->next_run.tv_usec += (timeout->msecs%1000)*1000; if (timeout->next_run.tv_usec > 1000000) { timeout->next_run.tv_sec++; timeout->next_run.tv_usec -= 1000000; } }
static void mbox_init_lock_settings(struct mbox_storage *storage) { enum mbox_lock_type read_locks[MBOX_LOCK_COUNT+1]; enum mbox_lock_type write_locks[MBOX_LOCK_COUNT+1]; int r, w; mbox_read_lock_methods(storage->set->mbox_read_locks, "mbox_read_locks", read_locks); mbox_read_lock_methods(storage->set->mbox_write_locks, "mbox_write_locks", write_locks); /* check that read/write list orders match. write_locks must contain at least read_locks and possibly more. */ for (r = w = 0; write_locks[w] != (enum mbox_lock_type)-1; w++) { if (read_locks[r] == (enum mbox_lock_type)-1) break; if (read_locks[r] == write_locks[w]) r++; } if (read_locks[r] != (enum mbox_lock_type)-1) { i_fatal("mbox read/write lock list settings are invalid. " "Lock ordering must be the same with both, " "and write locks must contain all read locks " "(and possibly more)"); } storage->read_locks = p_new(storage->storage.pool, enum mbox_lock_type, MBOX_LOCK_COUNT+1); memcpy(storage->read_locks, read_locks, sizeof(*storage->read_locks) * (MBOX_LOCK_COUNT+1)); storage->write_locks = p_new(storage->storage.pool, enum mbox_lock_type, MBOX_LOCK_COUNT+1); memcpy(storage->write_locks, write_locks, sizeof(*storage->write_locks) * (MBOX_LOCK_COUNT+1)); storage->lock_settings_initialized = TRUE; }