/*
 * Copyright (c) 2002-2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: id.c,v 1.19 2005/02/03 23:42:15 ca Exp $")

#include "sm/assert.h"
#include "sm/error.h"
#include "sm/io.h"
#if !SMTPS2_CDB
#include "smtps-str.h"
#include "smtps.h"
#include "statethreads/st.h"
#endif /* !SMTPS2_CDB */

#if HAVE_ST_INTERRUPTIBLE
static st_mutex_t id_mutex = NULL;
#endif
static id_count_T id_count;

/*
**  SS_ID_INIT -- initialize session/transaction id counter for SMTPSPC
**
**	Parameters:
**		id_val -- initial value
**		(access some globals)
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
ss_id_init(id_count_T id_val)
{
#if HAVE_ST_INTERRUPTIBLE
	int r;

	id_mutex = st_mutex_new();
	if (id_mutex == NULL)
		return sm_error_perm(SM_EM_SMTPS, ENOMEM);
	r = st_mutex_lock(id_mutex);
	if (r != 0)
		return sm_error_perm(SM_EM_SMTPS, r);
#endif /* HAVE_ST_INTERRUPTIBLE */

	id_count = id_val;

#if HAVE_ST_INTERRUPTIBLE
	r = st_mutex_unlock(id_mutex);
	if (r != 0)
		return sm_error_perm(SM_EM_SMTPS, r);
#endif
	return SM_SUCCESS;
}

/*
**  SS_ID_END -- end using session/transaction id counter for SMTPS
**
**	Parameters:
**		none. (access globals)
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
ss_id_end(void)
{
	sm_ret_T ret;

	ret = SM_SUCCESS;
#if HAVE_ST_INTERRUPTIBLE
	if (id_mutex != NULL)
	{
		int r;

		r = st_mutex_destroy(id_mutex);
		if (r != 0)
			ret = sm_error_perm(SM_EM_SMTPS, errno);
		else
			id_mutex = NULL;
	}
#endif /* HAVE_ST_INTERRUPTIBLE */
	return ret;
}

#if 0
/*
**  SS_ID_SET -- set session/transaction id counter for SMTPS
**
**	Parameters:
**		id_val -- new value to use for id counter
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
ss_id_set(id_count_T id_val)
{
#if HAVE_ST_INTERRUPTIBLE
	int r;

	SM_REQUIRE(id_mutex != NULL);
	r = st_mutex_lock(id_mutex);
	if (r != 0)
		return sm_error_perm(SM_EM_SMTPS, r);
#endif /* HAVE_ST_INTERRUPTIBLE */

	id_count = id_val;

#if HAVE_ST_INTERRUPTIBLE
	r = st_mutex_unlock(id_mutex);
	if (r != 0)
		return sm_error_perm(SM_EM_SMTPS, r);
#endif
	return SM_SUCCESS;
}
#endif /* 0 */

/*
**  SS_ID_NEXT -- get next session/transaction id for SMTPS
**
**	Parameters:
**		smtpsid -- SMTPS id
**		id -- session/transaction id (output)
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
ss_id_next(int smtpsid, ss_id_T id)
{
	id_count_T idc;
#if HAVE_ST_INTERRUPTIBLE
	int r;

	SM_REQUIRE(id_mutex != NULL);
	r = st_mutex_lock(id_mutex);
	if (r != 0)
		return sm_error_perm(SM_EM_SMTPS, r);
#endif /* HAVE_ST_INTERRUPTIBLE */

	/*
	**  avoid potential race condition if sm_snprintf() would have
	**  a scheduling point
	*/

	idc = id_count++;
	sm_snprintf(id, SMTP_STID_SIZE, SMTPS_STID_FORMAT, idc, smtpsid);

#if HAVE_ST_INTERRUPTIBLE
	r = st_mutex_unlock(id_mutex);
	if (r != 0)
		return sm_error_perm(SM_EM_SMTPS, r);
#endif
	return SM_SUCCESS;
}


syntax highlighted by Code2HTML, v. 0.9.1