Example #1
0
static void
cmd_director_status_user(struct director_context *ctx, char *argv[])
{
	const char *user = argv[0], *tag = argv[1];
	const char *line, *const *args;
	unsigned int expires;

	director_send(ctx, t_strdup_printf("USER-LOOKUP\t%s\t%s\n", user,
					   tag != NULL ? tag : ""));
	line = i_stream_read_next_line(ctx->input);
	if (line == NULL) {
		i_error("Lookup failed");
		doveadm_exit_code = EX_TEMPFAIL;
		return;
	}

	args = t_strsplit_tab(line);
	if (str_array_length(args) != 4 ||
	    str_to_uint(args[1], &expires) < 0) {
		i_error("Invalid reply from director");
		doveadm_exit_code = EX_PROTOCOL;
		return;
	}

	if (args[0][0] != '\0') {
		printf("Current: %s (expires %s)\n",
		       args[0], unixdate2str(expires));
	} else {
		printf("Current: not assigned\n");
	}
	printf("Hashed: %s\n", args[2]);
	printf("Initial config: %s\n", args[3]);
	director_disconnect(ctx);
}
Example #2
0
static void cmd_instance_list(int argc, char *argv[])
{
	struct master_instance_list *list;
	struct master_instance_list_iter *iter;
	const struct master_instance *inst;
	const char *instance_path, *pidfile_path;
	bool show_config = FALSE;
	int c;

	while ((c = getopt(argc, argv, "c")) > 0) {
		switch (c) {
		case 'c':
			show_config = TRUE;
			break;
		default:
			help(&doveadm_cmd_instance[0]);
		}
	}
	argv += optind;

	if (!show_config) {
		doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
		doveadm_print_header("path", "path", DOVEADM_PRINT_HEADER_FLAG_EXPAND);
		doveadm_print_header_simple("name");
		doveadm_print_header_simple("last used");
		doveadm_print_header_simple("running");
	}

	instance_path = t_strconcat(service_set->state_dir,
				    "/"MASTER_INSTANCE_FNAME, NULL);
	list = master_instance_list_init(instance_path);
	iter = master_instance_list_iterate_init(list);
	while ((inst = master_instance_iterate_list_next(iter)) != NULL) {
		if (argv[0] != NULL && strcmp(argv[0], inst->name) != 0)
			continue;

		if (show_config) {
			printf("%s\n", inst->config_path == NULL ? "" :
			       inst->config_path);
			continue;
		}
		doveadm_print(inst->base_dir);
		doveadm_print(inst->name);
		doveadm_print(unixdate2str(inst->last_used));
		pidfile_path = t_strconcat(inst->base_dir, "/master.pid", NULL);
		if (pid_file_read(pidfile_path))
			doveadm_print("yes");
		else
			doveadm_print("no");
	}
	master_instance_iterate_list_deinit(&iter);
	master_instance_list_deinit(&list);
}
Example #3
0
static void cmd_director_status(int argc, char *argv[])
{
	struct director_context *ctx;
	const char *line, *const *args;

	ctx = cmd_director_init(argc, argv, "a:t:", cmd_director_status);
	if (argv[optind] != NULL) {
		cmd_director_status_user(ctx, argv+optind);
		return;
	}

	doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
	doveadm_print_header_simple("mail server ip");
	doveadm_print_header_simple("tag");
	doveadm_print_header_simple("vhosts");
	doveadm_print_header_simple("state");
	doveadm_print_header("state-changed", "state changed", 0);
	doveadm_print_header_simple("users");

	director_send(ctx, "HOST-LIST\n");
	while ((line = i_stream_read_next_line(ctx->input)) != NULL) {
		if (*line == '\0')
			break;
		T_BEGIN {
			unsigned int arg_count;
			time_t ts;

			args = t_strsplit_tab(line);
			arg_count = str_array_length(args);
			if (arg_count >= 6) {
				/* ip vhosts users tag updown updown-ts */
				doveadm_print(args[0]); 
				doveadm_print(args[3]);
				doveadm_print(args[1]);
				doveadm_print(args[4][0] == 'D' ? "down" : "up");
				if (str_to_time(args[5], &ts) < 0 ||
				    ts <= 0)
					doveadm_print("-");
				else
					doveadm_print(unixdate2str(ts));
				doveadm_print(args[2]);
			}
		} T_END;
	}
	if (line == NULL) {
		i_error("Director disconnected unexpectedly");
		doveadm_exit_code = EX_TEMPFAIL;
	}
	director_disconnect(ctx);
}
Example #4
0
static void
dump_timestamp(struct istream *input, const char *name, const char *value)
{
	time_t t;

	if (strcmp(value, "0") == 0)
		t = 0;
	else {
		t = hex2dec((const void *)value, strlen(value));
		if (t == 0) {
			i_fatal("Invalid %s at %"PRIuUOFF_T": %s",
				name, input->v_offset, value);
		}
	}
	printf("%s = %ld (%s)\n", name, (long)t, unixdate2str(t));
}
Example #5
0
static void
penalty_print_line(struct penalty_context *ctx,
		   const struct penalty_line *line)
{
	const struct tm *tm;
	char buf[10];

	if (ctx->net_bits > 0) {
		if (!net_is_in_network(&line->ip, &ctx->net_ip, ctx->net_bits))
			return;
	}

	tm = localtime(&line->last_update);
	strftime(buf, sizeof(buf), "%H:%M:%S", tm);

	printf("%-16s %7u %s %s\n", net_ip2addr(&line->ip), line->penalty,
	       unixdate2str(line->last_penalty), buf);
}
Example #6
0
static void log_record_print(const struct mail_transaction_header *hdr,
			     const void *data, size_t data_size,
			     uint64_t *modseq)
{
	unsigned int size = hdr->size - sizeof(*hdr);

	switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
	case MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT: {
		const struct mail_transaction_expunge *exp = data;

		printf(" - uids=");
		for (; size > 0; size -= sizeof(*exp), exp++) {
			printf("%u-%u,", exp->uid1, exp->uid2);
		}
		printf("\n");
		break;
	}
	case MAIL_TRANSACTION_EXPUNGE_GUID|MAIL_TRANSACTION_EXPUNGE_PROT: {
		const struct mail_transaction_expunge_guid *exp = data;

		for (; size > 0; size -= sizeof(*exp), exp++) {
			printf(" - uid=%u (guid ", exp->uid);
			print_data(exp->guid_128, sizeof(exp->guid_128));
			printf(")\n");
		}
		break;
	}
	case MAIL_TRANSACTION_APPEND: {
		const struct mail_index_record *rec = data;

		printf(" - uids=");
		for (; size > 0; size -= sizeof(*rec), rec++) {
			printf("%u", rec->uid);
			if (rec->flags != 0)
				printf(" (flags=%x)", rec->flags);
			printf(",");
		}
		printf("\n");
		break;
	}
	case MAIL_TRANSACTION_FLAG_UPDATE: {
		const struct mail_transaction_flag_update *u = data;

		for (; size > 0; size -= sizeof(*u), u++) {
			printf(" - uids=%u-%u (flags +%x-%x, modseq_inc_flag=%d)\n",
			       u->uid1, u->uid2, u->add_flags, u->remove_flags, u->modseq_inc_flag);
		}
		break;
	}
	case MAIL_TRANSACTION_HEADER_UPDATE: {
		const struct mail_transaction_header_update *u = data;

		log_header_update(u, data_size);
		break;
	}
	case MAIL_TRANSACTION_EXT_INTRO: {
		const struct mail_transaction_ext_intro *intro = data;

		prev_intro = *intro;
		printf(" - ext_id = %u\n", intro->ext_id);
		printf(" - reset_id = %u\n", intro->reset_id);
		printf(" - hdr_size = %u\n", intro->hdr_size);
		printf(" - record_size = %u\n", intro->record_size);
		printf(" - record_align = %u\n", intro->record_align);
		printf(" - flags = %u\n", intro->flags);
		printf(" - name_size = %u\n", intro->name_size);
		if (intro->name_size > 0) {
			const char *name = (const char *)(intro+1);

			printf(" - name = '%.*s'\n", intro->name_size, name);
			if (*modseq == 0 && intro->name_size == 6 &&
			    memcmp(name, "modseq", 6) == 0)
				*modseq = 1;
		}
		break;
	}
	case MAIL_TRANSACTION_EXT_RESET: {
		const struct mail_transaction_ext_reset *reset = data;

		printf(" - new_reset_id = %u\n", reset->new_reset_id);
		printf(" - preserve_data = %u\n", reset->preserve_data);
		break;
	}
	case MAIL_TRANSACTION_EXT_HDR_UPDATE: {
		const struct mail_transaction_ext_hdr_update *u = data;

		printf(" - offset = %u, size = %u", u->offset, u->size);
		if (sizeof(*u) + u->size <= data_size) {
			printf(": ");
			print_data(u + 1, u->size);
		} else {
			printf(" (too large)");
		}
		printf("\n");
		break;
	}
	case MAIL_TRANSACTION_EXT_HDR_UPDATE32: {
		const struct mail_transaction_ext_hdr_update32 *u = data;

		printf(" - offset = %u, size = %u", u->offset, u->size);
		if (sizeof(*u) + u->size <= data_size) {
			printf(": ");
			print_data(u + 1, u->size);
		} else {
			printf(" (too large)");
		}
		printf("\n");
		break;
	}
	case MAIL_TRANSACTION_EXT_REC_UPDATE: {
		const struct mail_transaction_ext_rec_update *rec = data, *end;
		size_t record_size;

		end = CONST_PTR_OFFSET(data, size);
		record_size = (sizeof(*rec) + prev_intro.record_size + 3) & ~3;
		while (rec < end) {
			printf(" - uid=%u: ", rec->uid);
			if (prev_intro.record_size <= (char*)end - (char *)(rec+1))
				print_data(rec + 1, prev_intro.record_size);
			else
				printf("(record_size too large)");
			printf("\n");
			rec = CONST_PTR_OFFSET(rec, record_size);
		}
		break;
	}
	case MAIL_TRANSACTION_EXT_ATOMIC_INC: {
		const struct mail_transaction_ext_atomic_inc *rec = data, *end;

		end = CONST_PTR_OFFSET(data, size);
		for (; rec < end; rec++) {
			printf(" - uid=%u: ", rec->uid);
			if (rec->diff > 0)
				printf("+%d\n", rec->diff);
			else
				printf("%d\n", rec->diff);
		}
		break;
	}
	case MAIL_TRANSACTION_KEYWORD_UPDATE: {
		const struct mail_transaction_keyword_update *u = data;
		const uint32_t *uid;
		unsigned int uid_offset;

		printf(" - modify=%d, name=%.*s, uids=",
		       u->modify_type, u->name_size, (const char *)(u+1));

		uid_offset = sizeof(*u) + u->name_size +
			((u->name_size % 4) == 0 ? 0 : 4 - (u->name_size%4));
		uid = (const uint32_t *)((const char *)u + uid_offset);
		size -= uid_offset;

		for (; size > 0; size -= sizeof(*uid)*2, uid += 2) {
			printf("%u-%u,", uid[0], uid[1]);
		}
		printf("\n");
		break;
	}
	case MAIL_TRANSACTION_KEYWORD_RESET: {
		const struct mail_transaction_keyword_reset *u = data;

		printf(" - uids=");
		for (; size > 0; size -= sizeof(*u), u++) {
			printf("%u-%u, ", u->uid1, u->uid2);
		}
		printf("\n");
		break;
	}
	case MAIL_TRANSACTION_MODSEQ_UPDATE: {
		const struct mail_transaction_modseq_update *rec, *end;

		end = CONST_PTR_OFFSET(data, size);
		for (rec = data; rec < end; rec++) {
			printf(" - uid=%u modseq=%llu\n", rec->uid,
			       ((unsigned long long)rec->modseq_high32 << 32) |
			       rec->modseq_low32);
		}
		break;
	}
	case MAIL_TRANSACTION_INDEX_DELETED:
	case MAIL_TRANSACTION_INDEX_UNDELETED:
		break;
	case MAIL_TRANSACTION_BOUNDARY: {
		const struct mail_transaction_boundary *rec = data;

		printf(" - size=%u\n", rec->size);
		break;
	}
	case MAIL_TRANSACTION_ATTRIBUTE_UPDATE: {
		const char *keys = data;
		const uint32_t *extra;
		unsigned int i, extra_pos, extra_count = 0;

		for (i = 0; i < size && keys[i] != '\0'; ) {
			if (keys[i] == '+')
				extra_count++;
			extra_count++;
			i += strlen(keys+i) + 1;
		}
		if (i % sizeof(uint32_t) != 0)
			i += sizeof(uint32_t) - i%sizeof(uint32_t);
		extra = (const void *)(keys+i);

		if ((size-i) != extra_count*sizeof(uint32_t)) {
			printf(" - broken entry\n");
			break;
		}

		extra_pos = 0;
		for (i = 0; i < size && keys[i] != '\0'; ) {
			printf(" - %s: %s/%s : timestamp=%s",
			       keys[i] == '+' ? "add" : keys[i] == '-' ? "remove" : "?",
			       keys[i+1] == 'p' ? "private" :
			       keys[i+1] == 's' ? "shared" : "?error?",
			       keys+i+2, unixdate2str(extra[extra_pos++]));
			if (keys[i] == '+')
				printf(" value_len=%u", extra[extra_pos++]);
			printf("\n");
			i += strlen(keys+i) + 1;
		}

		break;
	}
	default:
		break;
	}
}