static void send_msg_data(msg_data_t *msg_data)
{
	const char *push_notify_path = PUSH_NOTIFY_PATH;

	int soc = socket( AF_UNIX, SOCK_STREAM, 0 );
	if ( soc < 0 ) {
		i_warning( "open notify socket failed(%d): %m", soc );
		return;
	}

	struct sockaddr_un sock_addr;
	memset( &sock_addr, 0, sizeof(struct sockaddr_un));
	sock_addr.sun_family = AF_UNIX;
	i_strocpy( sock_addr.sun_path, push_notify_path, sizeof(sock_addr.sun_path) );
	socklen_t sock_len = sizeof(sock_addr.sun_family) + strlen(sock_addr.sun_path) + 1;
	int rc = connect(soc, (struct sockaddr *) &sock_addr, sock_len);
	if ( rc < 0 ) {
		i_warning("connect to notify socket %s failed: %m",
			  push_notify_path);
		close(soc);
		return;
	}

	rc = send(soc, msg_data, sizeof(*msg_data), 0);
	if ( rc < 0 )
		i_warning("send to notify socket %s failed: %m",
			  push_notify_path);

	close(soc);
}
示例#2
0
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;
}
示例#3
0
static int cmd_id_handle_args(struct imap_client *client,
			      const struct imap_arg *arg)
{
	struct imap_client_cmd_id *id = client->cmd_id;
	const char *key, *value;

	switch (id->state) {
	case IMAP_CLIENT_ID_STATE_LIST:
		if (arg->type == IMAP_ARG_NIL)
			return 1;
		if (arg->type != IMAP_ARG_LIST)
			return -1;
		if (client->set->imap_id_log[0] == '\0') {
			/* no ID logging */
		} else if (client->id_logged) {
			/* already logged the ID reply */
		} else {
			id->log_reply = str_new(default_pool, 64);
			if (strcmp(client->set->imap_id_log, "*") == 0) {
				/* log all keys */
			} else {
				/* log only specified keys */
				id->log_keys = p_strsplit_spaces(default_pool,
					client->set->imap_id_log, " ");
			}
		}
		id->state = IMAP_CLIENT_ID_STATE_KEY;
		break;
	case IMAP_CLIENT_ID_STATE_KEY:
		if (!imap_arg_get_string(arg, &key))
			return -1;
		if (i_strocpy(id->key, key, sizeof(id->key)) < 0)
			return -1;
		id->state = IMAP_CLIENT_ID_STATE_VALUE;
		break;
	case IMAP_CLIENT_ID_STATE_VALUE:
		if (!imap_arg_get_nstring(arg, &value))
			return -1;
		cmd_id_handle_keyvalue(client, id->key, value);
		id->state = IMAP_CLIENT_ID_STATE_KEY;
		break;
	}
	return 0;
}
static bool cmd_x_apple_push_service(struct client_command_context *cmd)
{
	const struct imap_arg *args;
	
	struct mail_user *user = cmd->client->user;
	const char *aps_topic = mail_user_plugin_getenv(user, "push_notify_aps_topic");

	if (!client_read_args(cmd, 0, 0, &args))
		return FALSE;

	const char *aps_ver=NULL;
	const char *aps_acct_id=NULL;
	const char *aps_dev_token=NULL;
	const char *aps_sub_topic=NULL;
	const struct imap_arg *mailbox_list=NULL;
	unsigned int mailbox_count=NULL;
	bool mailbox_subscriptions=FALSE;

	const char *key, *value;

	/* must have a topic */
	if (aps_topic == NULL || *aps_topic == '\0')
		return FALSE;

	/* scarf off the aps keys/values */
	while (imap_arg_get_astring(&args[0], &key)) {
		if (imap_arg_get_astring(&args[1], &value)) {
			if (strcasecmp(key, "aps-version") == 0)
				aps_ver = t_strdup(value);
			else if (strcasecmp(key, "aps-account-id") == 0)
				aps_acct_id = t_strdup(value);
			else if (strcasecmp(key, "aps-device-token") == 0)
				aps_dev_token = t_strdup(value);
			else if (strcasecmp(key, "aps-subtopic") == 0)
				aps_sub_topic = t_strdup(value);
			else 
				return FALSE;
		}
		else if (strcasecmp(key, "mailboxes") == 0) {
			mailbox_subscriptions = imap_arg_get_list_full(&args[1], &mailbox_list, &mailbox_count);
		}
		args += 2;
	}

	/* save notification settings */
	if ( aps_ver && aps_acct_id && aps_dev_token && aps_sub_topic ) {
		msg_data_t msg_data;
		
		/* subscribe to notification node */
		memset(&msg_data, 0, sizeof(struct msg_data_s));
		msg_data.msg = 2;
		i_strocpy(msg_data.d1, user->username, sizeof(msg_data.d1));
		i_strocpy(msg_data.d2, aps_acct_id, sizeof(msg_data.d2));
		i_strocpy(msg_data.d3, aps_dev_token, sizeof(msg_data.d3));
		i_strocpy(msg_data.d4, aps_sub_topic, sizeof(msg_data.d4));
		send_msg_data(&msg_data);

		if(mailbox_subscriptions) {
			const char *mailbox;
			while (imap_arg_get_astring(&mailbox_list[0], &mailbox)) {
				T_BEGIN;
				string_t *mailbox_str = t_str_new(256);
				imap_append_quoted( mailbox_str, "mailbox");
				str_append_c( mailbox_str, ' ');
				imap_append_quoted( mailbox_str, mailbox);
				send_response(cmd->client, mailbox_str);

				msg_data.msg = 4;
				i_strocpy(msg_data.d4, mailbox, sizeof(msg_data.d4));
				send_msg_data(&msg_data);
				T_END;
				mailbox_list += 1;
			}
		}

		/* generate aps response */
		string_t *str = t_str_new(256);
		imap_append_quoted( str, "aps-version" );
		str_append_c(str, ' ');
		imap_append_quoted( str, APS_VERSION );
		str_append_c(str, ' ');
		imap_append_quoted( str, "aps-topic" );
		str_append_c(str, ' ');
		imap_append_quoted( str, aps_topic );
		send_response(cmd->client, str);
	}

	client_send_tagline(cmd, "OK Provisioned");

	return TRUE;
}