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