Home | History | Annotate | Download | only in libnisdb
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  *	db_vers.cc
     24  *
     25  *	Copyright (c) 1988-2000 by Sun Microsystems, Inc.
     26  *	All Rights Reserved.
     27  */
     28 
     29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     30 
     31 #include <stdio.h>
     32 #include <string.h>
     33 
     34 #include "db_headers.h"
     35 #include "db_vers.h"
     36 #include "nisdb_mt.h"
     37 
     38 const long unsigned MAXLOW = 32768*32768;
     39 
     40 /* Constructor that makes copy of 'other'. */
     41 vers::vers(vers* other)
     42 {
     43 	INITRW(vers);
     44 	assign(other);
     45 }
     46 
     47 void
     48 vers::assign(vers* other)
     49 {
     50 	WRITELOCKV(this, "w vers::assign");
     51 	if (other == NULL) {
     52 		syslog(LOG_ERR, "vers::vers: making copy of null vers?");
     53 		vers_high = vers_low = time_sec = time_usec = 0;
     54 	} else {
     55 		time_sec = other->time_sec;
     56 		time_usec = other->time_usec;
     57 		vers_low = other->vers_low;
     58 		vers_high = other->vers_high;
     59 	}
     60 	WRITEUNLOCKV(this, "wu vers::assign");
     61 }
     62 
     63 /*
     64  * Creates new 'vers' with next higher minor version.
     65  * If minor version exceeds MAXLOW, bump up major version instead.
     66  * Set timestamp to that of the current time.
     67  */
     68 vers*
     69 vers::nextminor()
     70 {
     71 	READLOCK(this, NULL, "r vers::nextminor");
     72 
     73 	vers * newvers = new vers;
     74 
     75 	if (newvers == NULL) {
     76 		READUNLOCK(this, NULL, "ru vers::nextminor DB_MEMORY_LIMIT");
     77 		FATAL3("vers::nextminor: cannot allocation space",
     78 			DB_MEMORY_LIMIT, NULL);
     79 	}
     80 
     81 	struct timeval mt;
     82 	gettimeofday(&mt, NULL);
     83 
     84 	newvers->time_sec = (unsigned int) mt.tv_sec;
     85 	newvers->time_usec = (unsigned int) mt.tv_usec;
     86 	newvers->vers_low = (this->vers_low + 1);
     87 	newvers->vers_high = (this->vers_high);
     88 
     89 	if (newvers->vers_low >= MAXLOW){
     90 		newvers->vers_high++;
     91 		newvers->vers_low = 0;
     92 	}
     93 
     94 	READUNLOCK(this, newvers, "ru vers::nextminor");
     95 	return (newvers);
     96 }
     97 
     98 /*
     99  * Creates new 'vers' with next higher major version.
    100  * Set timestamp to that of the current time.
    101  */
    102 vers*
    103 vers::nextmajor()
    104 {
    105 	READLOCK(this, NULL, "r vers::nextmajor");
    106 
    107 	vers * newvers = new vers;
    108 
    109 	if (newvers == NULL) {
    110 		READUNLOCK(this, NULL, "ru vers::nextmajor DB_MEMORY_LIMIT");
    111 		FATAL3("vers::nextminor: cannot allocation space",
    112 			DB_MEMORY_LIMIT, NULL);
    113 	}
    114 
    115 	struct timeval mt;
    116 	gettimeofday(&mt, NULL);
    117 
    118 	newvers->time_sec = (unsigned int) mt.tv_sec;
    119 	newvers->time_usec = (unsigned int) mt.tv_usec;
    120 	newvers->vers_low = 0;
    121 	newvers->vers_high = (this->vers_high+1);
    122 
    123 	READUNLOCK(this, newvers, "ru vers::nextmajor");
    124 	return (newvers);
    125 }
    126 
    127 /*
    128  * Predicate indicating whether this vers is earlier than 'other' in
    129  * terms of version numbers.
    130 */
    131 bool_t
    132 vers::earlier_than(vers *other)
    133 {
    134 	int	ret, lret;
    135 
    136 	if (other == NULL) {
    137 		syslog(LOG_ERR,
    138 			"vers::earlier_than: comparing against null vers");
    139 		return (FALSE);
    140 	}
    141 
    142 	READLOCK(this, FALSE, "r vers::earlier_than");
    143 	READLOCKNR(other, lret, "r other vers::earlier_than");
    144 	if (lret != 0) {
    145 		READUNLOCK(this, FALSE, "ru + r other vers::earlier_than");
    146 		return (FALSE);
    147 	}
    148 
    149 	if (other->vers_high > vers_high) ret = TRUE;
    150 	else if (other->vers_high < vers_high) ret = FALSE;
    151 	else if (other->vers_low > vers_low) ret = TRUE;
    152 	else ret = FALSE;
    153 
    154 	READUNLOCKNR(other, lret, "ru other vers::earlier_than");
    155 	READUNLOCK(this, ret, ((lret != 0) ?
    156 				"ru + ru other vers::earlier_than" :
    157 				"ru vers::earlier_than"));
    158 	return (ret);
    159 }
    160 
    161 /* Print the value of this 'vers' to specified file. */
    162 void
    163 vers::print(FILE* file)
    164 {
    165 	char *thetime;
    166 	thetime = ctime((long *) (&(time_sec)));
    167 	thetime[strlen(thetime)-1] = 0;
    168 
    169 	READLOCKV(this, "r vers::print");
    170 	fprintf(file, "version=%u.%u %s:%u",
    171 		vers_high,
    172 		vers_low,
    173 		/* time_sec, */
    174 		thetime,
    175 		time_usec);
    176 	READUNLOCKV(this, "ru vers::print");
    177 }
    178 
    179 void
    180 vers::zero() {
    181 	WRITELOCKV(this, "r vers::zero");
    182 	vers_high = vers_low = time_sec = time_usec = 0;
    183 	WRITEUNLOCKV(this, "ru vers::zero");
    184 }
    185 
    186 bool_t
    187 vers::equal( vers *other) {
    188 	READLOCK(this, FALSE, "r vers::equal");
    189 	bool_t ret = other != NULL &&
    190 		vers_high == other->vers_high &&
    191 		vers_low == other->vers_low &&
    192 		time_sec == other->time_sec &&
    193 		time_usec == other->time_usec;
    194 	READUNLOCK(this, ret, "ru vers::equal");
    195 	return (ret);
    196 };
    197