static void stats_top_output_diff(struct top_context *ctx, const struct top_line *line, unsigned int i) { uint64_t prev_num, cur_num; double prev_double, cur_double, prev_time, cur_time; char numstr[MAX_INT_STRLEN]; if (str_to_uint64(line->prev_values[i], &prev_num) == 0 && str_to_uint64(line->cur_values[i], &cur_num) == 0) { if (i_snprintf(numstr, sizeof(numstr), "%llu", (unsigned long long)(cur_num - prev_num)) < 0) i_unreached(); doveadm_print(numstr); } else if (get_double(line->prev_values[i], &prev_double) == 0 && get_double(line->cur_values[i], &cur_double) == 0 && get_double(line->prev_values[ctx->last_update_idx], &prev_time) == 0 && get_double(line->cur_values[ctx->last_update_idx], &cur_time) == 0) { /* %CPU */ if (i_snprintf(numstr, sizeof(numstr), "%d", (int)((cur_double - prev_double) * (cur_time - prev_time) * 100)) < 0) i_unreached(); doveadm_print(numstr); } else { doveadm_print(line->cur_values[i]); } }
static int fts_mail_get_special(struct mail *_mail, enum mail_fetch_field field, const char **value_r) { struct mail_private *mail = (struct mail_private *)_mail; struct fts_mail *fmail = FTS_MAIL_CONTEXT(mail); struct fts_transaction_context *ft = FTS_CONTEXT(_mail->transaction); const struct fts_score_map *scores; if (field != MAIL_FETCH_SEARCH_RELEVANCY || ft->scores == NULL) scores = NULL; else { scores = array_bsearch(&ft->scores->score_map, &_mail->uid, fts_score_cmp); } if (scores != NULL) { i_assert(scores->uid == _mail->uid); (void)i_snprintf(fmail->score, sizeof(fmail->score), "%f", scores->score); *value_r = fmail->score; return 0; } return fmail->module_ctx.super.get_special(_mail, field, value_r); }
static int index_mailbox_precache(struct master_connection *conn, struct mailbox *box) { struct mail_storage *storage = mailbox_get_storage(box); const char *username = mail_storage_get_user(storage)->username; const char *box_vname = mailbox_get_vname(box); struct mailbox_status status; struct mailbox_transaction_context *trans; struct mail_search_args *search_args; struct mail_search_context *ctx; struct mail *mail; struct mailbox_metadata metadata; uint32_t seq; char percentage_str[2+1+1]; unsigned int counter = 0, max, percentage, percentage_sent = 0; int ret = 0; if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS, &metadata) < 0 || mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, &status) < 0) return -1; seq = status.last_cached_seq + 1; trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC); search_args = mail_search_build_init(); mail_search_build_add_seqset(search_args, seq, status.messages); ctx = mailbox_search_init(trans, search_args, NULL, metadata.precache_fields, NULL); mail_search_args_unref(&search_args); max = status.messages - seq + 1; while (mailbox_search_next(ctx, &mail)) { mail_precache(mail); if (++counter % 100 == 0) { percentage = counter*100 / max; if (percentage != percentage_sent && percentage < 100) { percentage_sent = percentage; if (i_snprintf(percentage_str, sizeof(percentage_str), "%u\n", percentage) < 0) i_unreached(); (void)write_full(conn->fd, percentage_str, strlen(percentage_str)); } indexer_worker_refresh_proctitle(username, box_vname, counter, max); } } if (mailbox_search_deinit(&ctx) < 0) ret = -1; if (mailbox_transaction_commit(&trans) < 0) ret = -1; if (ret == 0) { i_info("Indexed %u messages in %s", counter, mailbox_get_vname(box)); } return ret; }
static void vpopmail_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { enum passdb_result result; const char *scheme, *tmp_pass; char *crypted_pass; bool cleartext = FALSE; int ret; crypted_pass = vpopmail_password_lookup(request, &cleartext, &result); if (crypted_pass == NULL) { callback(result, request); return; } tmp_pass = crypted_pass; if (cleartext) scheme = "CLEARTEXT"; else { scheme = password_get_scheme(&tmp_pass); if (scheme == NULL) scheme = request->passdb->passdb->default_pass_scheme; } ret = auth_request_password_verify(request, password, tmp_pass, scheme, AUTH_SUBSYS_DB); safe_memset(crypted_pass, 0, strlen(crypted_pass)); if (ret <= 0) { callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; } #ifdef POP_AUTH_OPEN_RELAY if (strcasecmp(request->service, "POP3") == 0 || strcasecmp(request->service, "IMAP") == 0) { const char *host = net_ip2addr(&request->remote_ip); /* vpopmail 5.4 does not understand IPv6 */ if (host[0] != '\0' && IPADDR_IS_V4(&request->remote_ip)) { /* use putenv() directly rather than env_put() which would leak memory every time we got here. use a static buffer for putenv() as SUSv2 requirements would otherwise corrupt our environment later. */ static char ip_env[256]; i_snprintf(ip_env, sizeof(ip_env), "TCPREMOTEIP=%s", host); putenv(ip_env); open_smtp_relay(); } } #endif callback(PASSDB_RESULT_OK, request); }
static const char * file_lock_find_proc_locks(int lock_fd ATTR_UNUSED) { /* do anything except Linux support this? don't bother trying it for OSes we don't know about. */ #ifdef __linux__ static bool have_proc_locks = TRUE; struct stat st; char node_buf[MAX_INT_STRLEN*3 + 2 + 1]; struct istream *input; const char *line, *lock_type = ""; pid_t pid = 0; int fd; if (!have_proc_locks) return FALSE; if (fstat(lock_fd, &st) < 0) return ""; i_snprintf(node_buf, sizeof(node_buf), "%02x:%02x:%llu", major(st.st_dev), minor(st.st_dev), (unsigned long long)st.st_ino); fd = open("/proc/locks", O_RDONLY); if (fd == -1) { have_proc_locks = FALSE; return ""; } input = i_stream_create_fd_autoclose(&fd, 512); while (pid == 0 && (line = i_stream_read_next_line(input)) != NULL) T_BEGIN { const char *const *args = t_strsplit_spaces(line, " "); /* number: FLOCK/POSIX ADVISORY READ/WRITE pid major:minor:inode region-start region-end */ if (str_array_length(args) < 8) continue; if (strcmp(args[5], node_buf) == 0) { lock_type = strcmp(args[3], "READ") == 0 ? "READ" : "WRITE"; if (str_to_pid(args[4], &pid) < 0) pid = 0; } } T_END; i_stream_destroy(&input); if (pid == 0) { /* not found */ return ""; } if (pid == getpid()) return " (BUG: lock is held by our own process)"; return t_strdup_printf(" (%s lock held by pid %ld)", lock_type, (long)pid); #else return ""; #endif }
uint32_t mailbox_uidvalidity_next(struct mailbox_list *list, const char *path) { char buf[8+1]; uint32_t cur_value; int fd, ret; fd = open(path, O_RDWR); if (fd == -1) { if (errno != ENOENT) i_error("open(%s) failed: %m", path); return mailbox_uidvalidity_next_rescan(list, path); } ret = read_full(fd, buf, sizeof(buf)-1); if (ret < 0) { i_error("read(%s) failed: %m", path); i_close_fd(&fd); return mailbox_uidvalidity_next_rescan(list, path); } buf[sizeof(buf)-1] = 0; if (ret == 0 || str_to_uint32_hex(buf, &cur_value) < 0 || cur_value == 0) { /* broken value */ i_close_fd(&fd); return mailbox_uidvalidity_next_rescan(list, path); } /* we now have the current uidvalidity value that's hopefully correct */ if (mailbox_uidvalidity_rename(path, &cur_value, FALSE) < 0) { i_close_fd(&fd); return mailbox_uidvalidity_next_rescan(list, path); } /* fast path succeeded. write the current value to the main uidvalidity file. */ if (i_snprintf(buf, sizeof(buf), "%08x", cur_value) < 0) i_unreached(); if (pwrite_full(fd, buf, strlen(buf), 0) < 0) i_error("write(%s) failed: %m", path); if (close(fd) < 0) i_error("close(%s) failed: %m", path); return cur_value; }
static void mailbox_uidvalidity_write(struct mailbox_list *list, const char *path, uint32_t uid_validity) { char buf[8+1]; int fd; struct mailbox_permissions perm; mode_t old_mask; mailbox_list_get_root_permissions(list, &perm); old_mask = umask(0666 & ~perm.file_create_mode); fd = open(path, O_RDWR | O_CREAT, 0666); umask(old_mask); if (fd == -1) { i_error("open(%s) failed: %m", path); return; } if (perm.file_create_gid != (gid_t)-1 && fchown(fd, (uid_t)-1, perm.file_create_gid) < 0) { if (errno == EPERM) { i_error("%s", eperm_error_get_chgrp("fchown", path, perm.file_create_gid, perm.file_create_gid_origin)); } else { i_error("fchown(%s, -1, %ld) failed: %m", path, (long)perm.file_create_gid); } } if (i_snprintf(buf, sizeof(buf), "%08x", uid_validity) < 0) i_unreached(); if (pwrite_full(fd, buf, strlen(buf), 0) < 0) i_error("write(%s) failed: %m", path); if (close(fd) < 0) i_error("close(%s) failed: %m", path); }
static int index_mailbox_precache(struct master_connection *conn, struct mailbox *box) { struct mail_storage *storage = mailbox_get_storage(box); const char *username = mail_storage_get_user(storage)->username; const char *box_vname = mailbox_get_vname(box); struct mailbox_status status; struct mailbox_transaction_context *trans; struct mail_search_args *search_args; struct mail_search_context *ctx; struct mail *mail; struct mailbox_metadata metadata; uint32_t seq, first_uid = 0, last_uid = 0; char percentage_str[2+1+1]; unsigned int counter = 0, max, percentage, percentage_sent = 0; int ret = 0; if (mailbox_get_metadata(box, MAILBOX_METADATA_PRECACHE_FIELDS, &metadata) < 0) { i_error("Mailbox %s: Precache-fields lookup failed: %s", mailbox_get_vname(box), mailbox_get_last_internal_error(box, NULL)); return -1; } if (mailbox_get_status(box, STATUS_MESSAGES | STATUS_LAST_CACHED_SEQ, &status) < 0) { i_error("Mailbox %s: Status lookup failed: %s", mailbox_get_vname(box), mailbox_get_last_internal_error(box, NULL)); return -1; } seq = status.last_cached_seq + 1; trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC, "indexing"); search_args = mail_search_build_init(); mail_search_build_add_seqset(search_args, seq, status.messages); ctx = mailbox_search_init(trans, search_args, NULL, metadata.precache_fields, NULL); mail_search_args_unref(&search_args); max = status.messages + 1 - seq; while (mailbox_search_next(ctx, &mail)) { if (first_uid == 0) first_uid = mail->uid; last_uid = mail->uid; mail_precache(mail); if (++counter % 100 == 0) { percentage = counter*100 / max; if (percentage != percentage_sent && percentage < 100) { percentage_sent = percentage; if (i_snprintf(percentage_str, sizeof(percentage_str), "%u\n", percentage) < 0) i_unreached(); (void)write_full(conn->fd, percentage_str, strlen(percentage_str)); } indexer_worker_refresh_proctitle(username, box_vname, counter, max); } } if (mailbox_search_deinit(&ctx) < 0) { i_error("Mailbox %s: Mail search failed: %s", mailbox_get_vname(box), mailbox_get_last_internal_error(box, NULL)); ret = -1; } const char *uids = first_uid == 0 ? "" : t_strdup_printf(" (UIDs %u..%u)", first_uid, last_uid); if (mailbox_transaction_commit(&trans) < 0) { i_error("Mailbox %s: Transaction commit failed: %s" " (attempted to index %u messages%s)", mailbox_get_vname(box), mailbox_get_last_internal_error(box, NULL), counter, uids); ret = -1; } else { i_info("Indexed %u messages in %s%s", counter, mailbox_get_vname(box), uids); } return ret; }