126 u_int32_t temp; 127 int fhtype = FHT_UNKNOWN; 128 int i; 129 130 if (ourself) { 131 /* File handle generated on this host, no need for guessing */ 132#if defined(IRIX40) 133 fhtype = FHT_IRIX4; 134#endif 135#if defined(IRIX50) 136 fhtype = FHT_IRIX5; 137#endif 138#if defined(IRIX51) 139 fhtype = FHT_IRIX5; 140#endif 141#if defined(SUNOS4) 142 fhtype = FHT_SUNOS4; 143#endif 144#if defined(SUNOS5) 145 fhtype = FHT_SUNOS5; 146#endif 147#if defined(ultrix) 148 fhtype = FHT_ULTRIX; 149#endif 150#if defined(__osf__) 151 fhtype = FHT_DECOSF; 152#endif 153 } 154 /* 155 * This is basically a big decision tree 156 */ 157 else if ((fhp[0] == 0) && (fhp[1] == 0)) { 158 /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */ 159 /* probably rules out HP-UX, AIX unless they allow major=0 */ 160 if ((fhp[2] == 0) && (fhp[3] == 0)) { 161 /* bytes[2,3] == (0,0); must be Auspex */ 162 /* XXX or could be Ultrix+MASSBUS "hp" disk? */ 163 fhtype = FHT_AUSPEX; 164 } 165 else { 166 /* 167 * bytes[2,3] != (0,0); rules out Auspex, could be 168 * DECOSF, SUNOS4, or IRIX4 169 */ 170 if ((fhp[4] != 0) && (fhp[5] == 0) && 171 (fhp[8] == 12) && (fhp[9] == 0)) { 172 /* seems to be DECOSF, with minor == 0 */ 173 fhtype = FHT_DECOSF; 174 } 175 else { 176 /* could be SUNOS4 or IRIX4 */ 177 /* XXX the test of fhp[5] == 8 could be wrong */ 178 if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) && 179 (fhp[7] == 0)) { 180 /* looks like a length, not a file system typecode */ 181 fhtype = FHT_IRIX4; 182 } 183 else { 184 /* by elimination */ 185 fhtype = FHT_SUNOS4; 186 } 187 } 188 } 189 } 190 else { 191 /* 192 * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4 193 * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 194 * could be AIX, HP-UX 195 */ 196 if ((fhp[2] == 0) && (fhp[3] == 0)) { 197 /* 198 * bytes[2,3] == (0,0); rules out OSF, probably not UCX 199 * (unless the exported device name is just one letter!), 200 * could be Ultrix, IRIX5, AIX, or SUNOS5 201 * might be HP-UX (depends on their values for minor devs) 202 */ 203 /*XXX we probably only need to test of these two bytes */ 204 if ((fhp[21] == 0) && (fhp[23] == 0)) { 205 fhtype = FHT_ULTRIX; 206 } 207 else { 208 /* Could be SUNOS5/IRIX5, maybe AIX */ 209 /* XXX no obvious difference between SUNOS5 and IRIX5 */ 210 if (fhp[9] == 10) 211 fhtype = FHT_SUNOS5; 212 /* XXX what about AIX? */ 213 } 214 } 215 else { 216 /* 217 * bytes[2,3] != (0,0); rules out Ultrix, could be 218 * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX 219 */ 220 if ((fhp[8] == 12) && (fhp[9] == 0)) { 221 fhtype = FHT_DECOSF; 222 } 223 else if ((fhp[8] == 0) && (fhp[9] == 10)) { 224 /* could be SUNOS5/IRIX5, AIX, HP-UX */ 225 if ((fhp[7] == 0) && (fhp[6] == 0) && 226 (fhp[5] == 0) && (fhp[4] == 0)) { 227 /* XXX is this always true of HP-UX? */ 228 fhtype = FHT_HPUX9; 229 } 230 else if (fhp[7] == 2) { 231 /* This would be MNT_NFS on AIX, which is impossible */ 232 fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ 233 } 234 else { 235 /* 236 * XXX Could be SUNOS5/IRIX5 or AIX. I don't 237 * XXX see any way to disambiguate these, so 238 * XXX I'm going with the more likely guess. 239 * XXX Sorry, Big Blue. 240 */ 241 fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ 242 } 243 } 244 else { 245 if (is_UCX(fhp)) { 246 fhtype = FHT_VMSUCX; 247 } 248 else { 249 fhtype = FHT_UNKNOWN; 250 } 251 } 252 } 253 } 254 255 /* XXX still needs to handle SUNOS3 */ 256 257 switch (fhtype) { 258 case FHT_AUSPEX: 259 fsidp->Fsid_dev.Minor = fhp[7]; 260 fsidp->Fsid_dev.Major = fhp[6]; 261 fsidp->fsid_code = 0; 262 263 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 264 *inop = temp; 265 266 if (osnamep) 267 *osnamep = "Auspex"; 268 break; 269 270 case FHT_DECOSF: 271 fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); 272 /* XXX could ignore 3 high-order bytes */ 273 274 temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]); 275 fsidp->Fsid_dev.Minor = temp & 0xFFFFF; 276 fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF; 277 278 temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); 279 *inop = temp; 280 if (osnamep) 281 *osnamep = "OSF"; 282 break; 283 284 case FHT_IRIX4: 285 fsidp->Fsid_dev.Minor = fhp[3]; 286 fsidp->Fsid_dev.Major = fhp[2]; 287 fsidp->fsid_code = 0; 288 289 temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]); 290 *inop = temp; 291 292 if (osnamep) 293 *osnamep = "IRIX4"; 294 break; 295 296 case FHT_IRIX5: 297 fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); 298 fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); 299 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 300 301 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 302 *inop = temp; 303 304 if (osnamep) 305 *osnamep = "IRIX5"; 306 break; 307 308 case FHT_SUNOS3: 309 if (osnamep) 310 *osnamep = "SUNOS3"; 311 break; 312 313 case FHT_SUNOS4: 314 fsidp->Fsid_dev.Minor = fhp[3]; 315 fsidp->Fsid_dev.Major = fhp[2]; 316 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 317 318 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 319 *inop = temp; 320 321 if (osnamep) 322 *osnamep = "SUNOS4"; 323 break; 324 325 case FHT_SUNOS5: 326 temp = make_uint16(fhp[0], fhp[1]); 327 fsidp->Fsid_dev.Major = (temp>>2) & 0x3FFF; 328 temp = make_uint24(fhp[1], fhp[2], fhp[3]); 329 fsidp->Fsid_dev.Minor = temp & 0x3FFFF; 330 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 331 332 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 333 *inop = temp; 334 335 if (osnamep) 336 *osnamep = "SUNOS5"; 337 break; 338 339 case FHT_ULTRIX: 340 fsidp->fsid_code = 0; 341 fsidp->Fsid_dev.Minor = fhp[0]; 342 fsidp->Fsid_dev.Major = fhp[1]; 343 344 temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); 345 *inop = temp; 346 if (osnamep) 347 *osnamep = "Ultrix"; 348 break; 349 350 case FHT_VMSUCX: 351 /* No numeric file system ID, so hash on the device-name */ 352 if (sizeof(*fsidp) >= 14) { 353 if (sizeof(*fsidp) > 14) 354 memset((char *)fsidp, 0, sizeof(*fsidp)); 355 /* just use the whole thing */ 356 memcpy((char *)fsidp, (char *)fh, 14); 357 } 358 else { 359 u_int32_t tempa[4]; /* at least 16 bytes, maybe more */ 360 361 memset((char *)tempa, 0, sizeof(tempa)); 362 memcpy((char *)tempa, (char *)fh, 14); /* ensure alignment */ 363 fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1); 364 fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1); 365 fsidp->fsid_code = 0; 366 } 367 368 /* VMS file ID is: (RVN, FidHi, FidLo) */ 369 *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]); 370 371 /* Caller must save (and null-terminate?) this value */ 372 if (fsnamep) 373 *fsnamep = (char *)&(fhp[1]); 374 375 if (osnamep) 376 *osnamep = "VMS"; 377 break; 378 379 case FHT_AIX32: 380 fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); 381 fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); 382 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 383 384 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 385 *inop = temp; 386 387 if (osnamep) 388 *osnamep = "AIX32"; 389 break; 390 391 case FHT_HPUX9: 392 fsidp->Fsid_dev.Major = fhp[0]; 393 temp = make_uint24(fhp[1], fhp[2], fhp[3]); 394 fsidp->Fsid_dev.Minor = temp; 395 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 396 397 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 398 *inop = temp; 399 400 if (osnamep) 401 *osnamep = "HPUX9"; 402 break; 403 404 case FHT_UNKNOWN: 405#ifdef DEBUG 406 /* XXX debugging */ 407 for (i = 0; i < 32; i++) 408 (void)fprintf(stderr, "%x.", fhp[i]); 409 (void)fprintf(stderr, "\n"); 410#endif 411 /* Save the actual handle, so it can be display with -u */ 412 for (i = 0; i < 32; i++) 413 (void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X", fhp[i]); 414 415 /* XXX for now, give "bogus" values to aid debugging */ 416 fsidp->fsid_code = 0; 417 fsidp->Fsid_dev.Minor = 257; 418 fsidp->Fsid_dev.Major = 257; 419 *inop = 1; 420 421 /* display will show this string instead of (257,257) */ 422 if (fsnamep) 423 *fsnamep = "Unknown"; 424 425 if (osnamep) 426 *osnamep = "Unknown"; 427 break; 428 429 } 430} 431 432/* 433 * Is this a VMS UCX file handle? 434 * Check for: 435 * (1) leading code byte [XXX not yet] 436 * (2) followed by string of printing chars & spaces 437 * (3) followed by string of nulls 438 */ 439static int 440is_UCX(fhp)
| 124 u_int32_t temp; 125 int fhtype = FHT_UNKNOWN; 126 int i; 127 128 if (ourself) { 129 /* File handle generated on this host, no need for guessing */ 130#if defined(IRIX40) 131 fhtype = FHT_IRIX4; 132#endif 133#if defined(IRIX50) 134 fhtype = FHT_IRIX5; 135#endif 136#if defined(IRIX51) 137 fhtype = FHT_IRIX5; 138#endif 139#if defined(SUNOS4) 140 fhtype = FHT_SUNOS4; 141#endif 142#if defined(SUNOS5) 143 fhtype = FHT_SUNOS5; 144#endif 145#if defined(ultrix) 146 fhtype = FHT_ULTRIX; 147#endif 148#if defined(__osf__) 149 fhtype = FHT_DECOSF; 150#endif 151 } 152 /* 153 * This is basically a big decision tree 154 */ 155 else if ((fhp[0] == 0) && (fhp[1] == 0)) { 156 /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */ 157 /* probably rules out HP-UX, AIX unless they allow major=0 */ 158 if ((fhp[2] == 0) && (fhp[3] == 0)) { 159 /* bytes[2,3] == (0,0); must be Auspex */ 160 /* XXX or could be Ultrix+MASSBUS "hp" disk? */ 161 fhtype = FHT_AUSPEX; 162 } 163 else { 164 /* 165 * bytes[2,3] != (0,0); rules out Auspex, could be 166 * DECOSF, SUNOS4, or IRIX4 167 */ 168 if ((fhp[4] != 0) && (fhp[5] == 0) && 169 (fhp[8] == 12) && (fhp[9] == 0)) { 170 /* seems to be DECOSF, with minor == 0 */ 171 fhtype = FHT_DECOSF; 172 } 173 else { 174 /* could be SUNOS4 or IRIX4 */ 175 /* XXX the test of fhp[5] == 8 could be wrong */ 176 if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) && 177 (fhp[7] == 0)) { 178 /* looks like a length, not a file system typecode */ 179 fhtype = FHT_IRIX4; 180 } 181 else { 182 /* by elimination */ 183 fhtype = FHT_SUNOS4; 184 } 185 } 186 } 187 } 188 else { 189 /* 190 * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4 191 * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 192 * could be AIX, HP-UX 193 */ 194 if ((fhp[2] == 0) && (fhp[3] == 0)) { 195 /* 196 * bytes[2,3] == (0,0); rules out OSF, probably not UCX 197 * (unless the exported device name is just one letter!), 198 * could be Ultrix, IRIX5, AIX, or SUNOS5 199 * might be HP-UX (depends on their values for minor devs) 200 */ 201 /*XXX we probably only need to test of these two bytes */ 202 if ((fhp[21] == 0) && (fhp[23] == 0)) { 203 fhtype = FHT_ULTRIX; 204 } 205 else { 206 /* Could be SUNOS5/IRIX5, maybe AIX */ 207 /* XXX no obvious difference between SUNOS5 and IRIX5 */ 208 if (fhp[9] == 10) 209 fhtype = FHT_SUNOS5; 210 /* XXX what about AIX? */ 211 } 212 } 213 else { 214 /* 215 * bytes[2,3] != (0,0); rules out Ultrix, could be 216 * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX 217 */ 218 if ((fhp[8] == 12) && (fhp[9] == 0)) { 219 fhtype = FHT_DECOSF; 220 } 221 else if ((fhp[8] == 0) && (fhp[9] == 10)) { 222 /* could be SUNOS5/IRIX5, AIX, HP-UX */ 223 if ((fhp[7] == 0) && (fhp[6] == 0) && 224 (fhp[5] == 0) && (fhp[4] == 0)) { 225 /* XXX is this always true of HP-UX? */ 226 fhtype = FHT_HPUX9; 227 } 228 else if (fhp[7] == 2) { 229 /* This would be MNT_NFS on AIX, which is impossible */ 230 fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ 231 } 232 else { 233 /* 234 * XXX Could be SUNOS5/IRIX5 or AIX. I don't 235 * XXX see any way to disambiguate these, so 236 * XXX I'm going with the more likely guess. 237 * XXX Sorry, Big Blue. 238 */ 239 fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ 240 } 241 } 242 else { 243 if (is_UCX(fhp)) { 244 fhtype = FHT_VMSUCX; 245 } 246 else { 247 fhtype = FHT_UNKNOWN; 248 } 249 } 250 } 251 } 252 253 /* XXX still needs to handle SUNOS3 */ 254 255 switch (fhtype) { 256 case FHT_AUSPEX: 257 fsidp->Fsid_dev.Minor = fhp[7]; 258 fsidp->Fsid_dev.Major = fhp[6]; 259 fsidp->fsid_code = 0; 260 261 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 262 *inop = temp; 263 264 if (osnamep) 265 *osnamep = "Auspex"; 266 break; 267 268 case FHT_DECOSF: 269 fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); 270 /* XXX could ignore 3 high-order bytes */ 271 272 temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]); 273 fsidp->Fsid_dev.Minor = temp & 0xFFFFF; 274 fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF; 275 276 temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); 277 *inop = temp; 278 if (osnamep) 279 *osnamep = "OSF"; 280 break; 281 282 case FHT_IRIX4: 283 fsidp->Fsid_dev.Minor = fhp[3]; 284 fsidp->Fsid_dev.Major = fhp[2]; 285 fsidp->fsid_code = 0; 286 287 temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]); 288 *inop = temp; 289 290 if (osnamep) 291 *osnamep = "IRIX4"; 292 break; 293 294 case FHT_IRIX5: 295 fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); 296 fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); 297 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 298 299 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 300 *inop = temp; 301 302 if (osnamep) 303 *osnamep = "IRIX5"; 304 break; 305 306 case FHT_SUNOS3: 307 if (osnamep) 308 *osnamep = "SUNOS3"; 309 break; 310 311 case FHT_SUNOS4: 312 fsidp->Fsid_dev.Minor = fhp[3]; 313 fsidp->Fsid_dev.Major = fhp[2]; 314 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 315 316 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 317 *inop = temp; 318 319 if (osnamep) 320 *osnamep = "SUNOS4"; 321 break; 322 323 case FHT_SUNOS5: 324 temp = make_uint16(fhp[0], fhp[1]); 325 fsidp->Fsid_dev.Major = (temp>>2) & 0x3FFF; 326 temp = make_uint24(fhp[1], fhp[2], fhp[3]); 327 fsidp->Fsid_dev.Minor = temp & 0x3FFFF; 328 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 329 330 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 331 *inop = temp; 332 333 if (osnamep) 334 *osnamep = "SUNOS5"; 335 break; 336 337 case FHT_ULTRIX: 338 fsidp->fsid_code = 0; 339 fsidp->Fsid_dev.Minor = fhp[0]; 340 fsidp->Fsid_dev.Major = fhp[1]; 341 342 temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); 343 *inop = temp; 344 if (osnamep) 345 *osnamep = "Ultrix"; 346 break; 347 348 case FHT_VMSUCX: 349 /* No numeric file system ID, so hash on the device-name */ 350 if (sizeof(*fsidp) >= 14) { 351 if (sizeof(*fsidp) > 14) 352 memset((char *)fsidp, 0, sizeof(*fsidp)); 353 /* just use the whole thing */ 354 memcpy((char *)fsidp, (char *)fh, 14); 355 } 356 else { 357 u_int32_t tempa[4]; /* at least 16 bytes, maybe more */ 358 359 memset((char *)tempa, 0, sizeof(tempa)); 360 memcpy((char *)tempa, (char *)fh, 14); /* ensure alignment */ 361 fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1); 362 fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1); 363 fsidp->fsid_code = 0; 364 } 365 366 /* VMS file ID is: (RVN, FidHi, FidLo) */ 367 *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]); 368 369 /* Caller must save (and null-terminate?) this value */ 370 if (fsnamep) 371 *fsnamep = (char *)&(fhp[1]); 372 373 if (osnamep) 374 *osnamep = "VMS"; 375 break; 376 377 case FHT_AIX32: 378 fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); 379 fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); 380 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 381 382 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 383 *inop = temp; 384 385 if (osnamep) 386 *osnamep = "AIX32"; 387 break; 388 389 case FHT_HPUX9: 390 fsidp->Fsid_dev.Major = fhp[0]; 391 temp = make_uint24(fhp[1], fhp[2], fhp[3]); 392 fsidp->Fsid_dev.Minor = temp; 393 fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 394 395 temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 396 *inop = temp; 397 398 if (osnamep) 399 *osnamep = "HPUX9"; 400 break; 401 402 case FHT_UNKNOWN: 403#ifdef DEBUG 404 /* XXX debugging */ 405 for (i = 0; i < 32; i++) 406 (void)fprintf(stderr, "%x.", fhp[i]); 407 (void)fprintf(stderr, "\n"); 408#endif 409 /* Save the actual handle, so it can be display with -u */ 410 for (i = 0; i < 32; i++) 411 (void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X", fhp[i]); 412 413 /* XXX for now, give "bogus" values to aid debugging */ 414 fsidp->fsid_code = 0; 415 fsidp->Fsid_dev.Minor = 257; 416 fsidp->Fsid_dev.Major = 257; 417 *inop = 1; 418 419 /* display will show this string instead of (257,257) */ 420 if (fsnamep) 421 *fsnamep = "Unknown"; 422 423 if (osnamep) 424 *osnamep = "Unknown"; 425 break; 426 427 } 428} 429 430/* 431 * Is this a VMS UCX file handle? 432 * Check for: 433 * (1) leading code byte [XXX not yet] 434 * (2) followed by string of printing chars & spaces 435 * (3) followed by string of nulls 436 */ 437static int 438is_UCX(fhp)
|