/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/*
 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
 * Use is subject to license terms.
 */
/*
 * Copyright 2009-2019 J. Schilling
 *
 * @(#)getser.c	1.6 19/11/06 J. Schilling
 */
#if defined(sun)
#pragma ident "@(#)getser.c 1.6 19/11/06 J. Schilling"
#endif
/*
 * @(#)getser.c 1.7 06/12/12
 */

#if defined(sun)
#pragma ident	"@(#)sidtoser.c"
#pragma ident	"@(#)sccs:lib/comobj/sidtoser.c"
#endif
#include <defines.h>
#include <had.h>

int
getser(pkt)
register struct packet *pkt;
{
	register struct idel *rdp;
	int n, ser, def;
	char *p;

	def = 0;
	if (pkt->p_reqsid.s_rel == 0) {
		if ((p = pkt->p_sflags[DEFTFLAG - 'a']) != NULL)
			chksid(sid_ab(p, &pkt->p_reqsid), &pkt->p_reqsid);
		else {
			pkt->p_reqsid.s_rel = MAXR;
			def = 1;
		}
	}
	ser = 0;
	if (pkt->p_reqsid.s_lev == 0) {
		for (n = maxser(pkt); n; n--) {
			rdp = &pkt->p_idel[n];
			if ((rdp->i_sid.s_br == 0 || HADT) &&
				pkt->p_reqsid.s_rel >= rdp->i_sid.s_rel &&
				rdp->i_sid.s_rel > pkt->p_gotsid.s_rel) {
					ser = n;
					pkt->p_gotsid.s_rel = rdp->i_sid.s_rel;
			}
		}
	}
	/*
	 * If had '-t' keyletter and R.L SID type, find
	 * the youngest SID
	 */
	else if ((pkt->p_reqsid.s_br == 0) && HADT) {
		for (n = maxser(pkt); n; n--) {
			rdp = &pkt->p_idel[n];
			if (rdp->i_sid.s_rel == pkt->p_reqsid.s_rel &&
			    rdp->i_sid.s_lev == pkt->p_reqsid.s_lev)
				break;
		}
		ser = n;
	} else if (pkt->p_reqsid.s_br && pkt->p_reqsid.s_seq == 0) {
		for (n = maxser(pkt); n; n--) {
			rdp = &pkt->p_idel[n];
			if (rdp->i_sid.s_rel == pkt->p_reqsid.s_rel &&
				rdp->i_sid.s_lev == pkt->p_reqsid.s_lev) {
				/*
				 * If release, level and branch are equal,
				 * this is the serial number to use, otherwise
				 * if the release and level are equal, it might
				 * be the case that there are no deltas on
				 * the branch specified by the default delta.
				 * If this is the case, store this serial
				 * number, it is the one we want
				 */
				if (rdp->i_sid.s_br == pkt->p_reqsid.s_br) {
					ser = n;
					break;
				} else {
					ser = n;
				}
			}
		}
	} else {
		ser = sidtoser(&pkt->p_reqsid, pkt);
	}
	if (ser == 0)
		fatal(gettext("nonexistent sid (ge5)"));
	rdp = &pkt->p_idel[ser];
	pkt->p_gotsid = rdp->i_sid;
	if (def ||
	    (pkt->p_reqsid.s_lev == 0 &&
	    pkt->p_reqsid.s_rel == pkt->p_gotsid.s_rel)) {
		pkt->p_reqsid = pkt->p_gotsid;
	}
	return (ser);
}
