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 #include <stdio.h> 30 #include <string.h> 31 32 #include "db_headers.h" 33 #include "db_vers.h" 34 #include "nisdb_mt.h" 35 36 const long unsigned MAXLOW = 32768*32768; 37 38 /* Constructor that makes copy of 'other'. */ 39 vers::vers(vers* other) 40 { 41 INITRW(vers); 42 assign(other); 43 } 44 45 void 46 vers::assign(vers* other) 47 { 48 WRITELOCKV(this, "w vers::assign"); 49 if (other == NULL) { 50 syslog(LOG_ERR, "vers::vers: making copy of null vers?"); 51 vers_high = vers_low = time_sec = time_usec = 0; 52 } else { 53 time_sec = other->time_sec; 54 time_usec = other->time_usec; 55 vers_low = other->vers_low; 56 vers_high = other->vers_high; 57 } 58 WRITEUNLOCKV(this, "wu vers::assign"); 59 } 60 61 /* 62 * Creates new 'vers' with next higher minor version. 63 * If minor version exceeds MAXLOW, bump up major version instead. 64 * Set timestamp to that of the current time. 65 */ 66 vers* 67 vers::nextminor() 68 { 69 READLOCK(this, NULL, "r vers::nextminor"); 70 71 vers * newvers = new vers; 72 73 if (newvers == NULL) { 74 READUNLOCK(this, NULL, "ru vers::nextminor DB_MEMORY_LIMIT"); 75 FATAL3("vers::nextminor: cannot allocation space", 76 DB_MEMORY_LIMIT, NULL); 77 } 78 79 struct timeval mt; 80 gettimeofday(&mt, NULL); 81 82 newvers->time_sec = (unsigned int) mt.tv_sec; 83 newvers->time_usec = (unsigned int) mt.tv_usec; 84 newvers->vers_low = (this->vers_low + 1); 85 newvers->vers_high = (this->vers_high); 86 87 if (newvers->vers_low >= MAXLOW){ 88 newvers->vers_high++; 89 newvers->vers_low = 0; 90 } 91 92 READUNLOCK(this, newvers, "ru vers::nextminor"); 93 return (newvers); 94 } 95 96 /* 97 * Creates new 'vers' with next higher major version. 98 * Set timestamp to that of the current time. 99 */ 100 vers* 101 vers::nextmajor() 102 { 103 READLOCK(this, NULL, "r vers::nextmajor"); 104 105 vers * newvers = new vers; 106 107 if (newvers == NULL) { 108 READUNLOCK(this, NULL, "ru vers::nextmajor DB_MEMORY_LIMIT"); 109 FATAL3("vers::nextminor: cannot allocation space", 110 DB_MEMORY_LIMIT, NULL); 111 } 112 113 struct timeval mt; 114 gettimeofday(&mt, NULL); 115 116 newvers->time_sec = (unsigned int) mt.tv_sec; 117 newvers->time_usec = (unsigned int) mt.tv_usec; 118 newvers->vers_low = 0; 119 newvers->vers_high = (this->vers_high+1); 120 121 READUNLOCK(this, newvers, "ru vers::nextmajor"); 122 return (newvers); 123 } 124 125 /* 126 * Predicate indicating whether this vers is earlier than 'other' in 127 * terms of version numbers. 128 */ 129 bool_t 130 vers::earlier_than(vers *other) 131 { 132 int ret, lret; 133 134 if (other == NULL) { 135 syslog(LOG_ERR, 136 "vers::earlier_than: comparing against null vers"); 137 return (FALSE); 138 } 139 140 READLOCK(this, FALSE, "r vers::earlier_than"); 141 READLOCKNR(other, lret, "r other vers::earlier_than"); 142 if (lret != 0) { 143 READUNLOCK(this, FALSE, "ru + r other vers::earlier_than"); 144 return (FALSE); 145 } 146 147 if (other->vers_high > vers_high) ret = TRUE; 148 else if (other->vers_high < vers_high) ret = FALSE; 149 else if (other->vers_low > vers_low) ret = TRUE; 150 else ret = FALSE; 151 152 READUNLOCKNR(other, lret, "ru other vers::earlier_than"); 153 READUNLOCK(this, ret, ((lret != 0) ? 154 "ru + ru other vers::earlier_than" : 155 "ru vers::earlier_than")); 156 return (ret); 157 } 158 159 /* Print the value of this 'vers' to specified file. */ 160 void 161 vers::print(FILE* file) 162 { 163 char *thetime; 164 thetime = ctime((long *) (&(time_sec))); 165 thetime[strlen(thetime)-1] = 0; 166 167 READLOCKV(this, "r vers::print"); 168 fprintf(file, "version=%u.%u %s:%u", 169 vers_high, 170 vers_low, 171 /* time_sec, */ 172 thetime, 173 time_usec); 174 READUNLOCKV(this, "ru vers::print"); 175 } 176 177 void 178 vers::zero() { 179 WRITELOCKV(this, "r vers::zero"); 180 vers_high = vers_low = time_sec = time_usec = 0; 181 WRITEUNLOCKV(this, "ru vers::zero"); 182 } 183 184 bool_t 185 vers::equal( vers *other) { 186 READLOCK(this, FALSE, "r vers::equal"); 187 bool_t ret = other != NULL && 188 vers_high == other->vers_high && 189 vers_low == other->vers_low && 190 time_sec == other->time_sec && 191 time_usec == other->time_usec; 192 READUNLOCK(this, ret, "ru vers::equal"); 193 return (ret); 194 }; 195