1*cca5f0e8Smmcc /* $OpenBSD: parsenfsfh.c,v 1.14 2016/01/15 18:02:18 mmcc Exp $ */ 2dd9ede83Sitojun 3dd9ede83Sitojun /* 4dd9ede83Sitojun * Copyright (c) 1993, 1994 Jeffrey C. Mogul, Digital Equipment Corporation, 5dd9ede83Sitojun * Western Research Laboratory. All rights reserved. 6dd9ede83Sitojun * Copyright (c) 2001 Compaq Computer Corporation. All rights reserved. 7dd9ede83Sitojun * 8dd9ede83Sitojun * Permission to use, copy, and modify this software and its 9dd9ede83Sitojun * documentation is hereby granted only under the following terms and 10dd9ede83Sitojun * conditions. Both the above copyright notice and this permission 11dd9ede83Sitojun * notice must appear in all copies of the software, derivative works 12dd9ede83Sitojun * or modified versions, and any portions thereof, and both notices 13dd9ede83Sitojun * must appear in supporting documentation. 14dd9ede83Sitojun * 15dd9ede83Sitojun * Redistribution and use in source and binary forms, with or without 16dd9ede83Sitojun * modification, are permitted provided that the following conditions 17dd9ede83Sitojun * are met: 18dd9ede83Sitojun * 1. Redistributions of source code must retain the above copyright 19dd9ede83Sitojun * notice, this list of conditions and the following disclaimer. 20dd9ede83Sitojun * 2. Redistributions in binary form must reproduce the above copyright 21dd9ede83Sitojun * notice, this list of conditions and the following disclaimer in 22dd9ede83Sitojun * the documentation and/or other materials provided with the 23dd9ede83Sitojun * distribution. 24dd9ede83Sitojun * 25dd9ede83Sitojun * THE SOFTWARE IS PROVIDED "AS IS" AND COMPAQ COMPUTER CORPORATION 26dd9ede83Sitojun * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 27dd9ede83Sitojun * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 28dd9ede83Sitojun * EVENT SHALL COMPAQ COMPUTER CORPORATION BE LIABLE FOR ANY 29dd9ede83Sitojun * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 30dd9ede83Sitojun * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 31dd9ede83Sitojun * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 32dd9ede83Sitojun * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 33dd9ede83Sitojun * SOFTWARE. 34dd9ede83Sitojun */ 35cf4e9b47Sho 36df930be7Sderaadt /* 37df930be7Sderaadt * parsenfsfh.c - portable parser for NFS file handles 38df930be7Sderaadt * uses all sorts of heuristics 39df930be7Sderaadt * 40df930be7Sderaadt * Jeffrey C. Mogul 41df930be7Sderaadt * Digital Equipment Corporation 42df930be7Sderaadt * Western Research Laboratory 43df930be7Sderaadt */ 44df930be7Sderaadt 45df930be7Sderaadt #include <sys/types.h> 46df930be7Sderaadt #include <sys/time.h> 47df930be7Sderaadt 48df930be7Sderaadt #include <ctype.h> 49c15d59edSmickey #include <stdio.h> 50df930be7Sderaadt #include <string.h> 51df930be7Sderaadt 52df930be7Sderaadt #include "interface.h" 53df930be7Sderaadt #include "nfsfh.h" 54df930be7Sderaadt 55df930be7Sderaadt /* 56df930be7Sderaadt * This routine attempts to parse a file handle (in network byte order), 57df930be7Sderaadt * using heuristics to guess what kind of format it is in. See the 58df930be7Sderaadt * file "fhandle_layouts" for a detailed description of the various 59df930be7Sderaadt * patterns we know about. 60df930be7Sderaadt * 61df930be7Sderaadt * The file handle is parsed into our internal representation of a 62df930be7Sderaadt * file-system id, and an internal representation of an inode-number. 63df930be7Sderaadt */ 64df930be7Sderaadt 65df930be7Sderaadt #define FHT_UNKNOWN 0 66df930be7Sderaadt #define FHT_AUSPEX 1 67df930be7Sderaadt #define FHT_DECOSF 2 68df930be7Sderaadt #define FHT_IRIX4 3 69df930be7Sderaadt #define FHT_IRIX5 4 70df930be7Sderaadt #define FHT_SUNOS3 5 71df930be7Sderaadt #define FHT_SUNOS4 6 72df930be7Sderaadt #define FHT_ULTRIX 7 73df930be7Sderaadt #define FHT_VMSUCX 8 74df930be7Sderaadt #define FHT_SUNOS5 9 75df930be7Sderaadt #define FHT_AIX32 10 76df930be7Sderaadt #define FHT_HPUX9 11 77df930be7Sderaadt 78df930be7Sderaadt #define make_uint32(msb,b,c,lsb)\ 79*cca5f0e8Smmcc ((lsb) + ((c)<<8) + ((b)<<16) + ((msb)<<24)) 80df930be7Sderaadt 81df930be7Sderaadt #define make_uint24(msb,b, lsb)\ 82*cca5f0e8Smmcc ((lsb) + ((b)<<8) + ((msb)<<16)) 83df930be7Sderaadt 84df930be7Sderaadt #define make_uint16(msb,lsb)\ 85*cca5f0e8Smmcc ((lsb) + ((msb)<<8)) 86df930be7Sderaadt 87df930be7Sderaadt #ifdef __alpha 88df930be7Sderaadt /* or other 64-bit systems */ 89df930be7Sderaadt #define make_uint48(msb,b,c,d,e,lsb)\ 90df930be7Sderaadt ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24) + ((b)<<32) + ((msb)<<40)) 91df930be7Sderaadt #else 92df930be7Sderaadt /* on 32-bit systems ignore high-order bits */ 93df930be7Sderaadt #define make_uint48(msb,b,c,d,e,lsb)\ 94df930be7Sderaadt ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24)) 95df930be7Sderaadt #endif 96df930be7Sderaadt 97df930be7Sderaadt static int is_UCX(unsigned char *); 98df930be7Sderaadt 99df930be7Sderaadt void 10054098794Smmcc Parse_fh(fh, fsidp, inop, osnamep, fsnamep) 1010d5f83f3Smmcc caddr_t *fh; 102df930be7Sderaadt my_fsid *fsidp; 103df930be7Sderaadt ino_t *inop; 104df930be7Sderaadt char **osnamep; /* if non-NULL, return OS name here */ 105df930be7Sderaadt char **fsnamep; /* if non-NULL, return server fs name here (for VMS) */ 106df930be7Sderaadt { 1070d5f83f3Smmcc unsigned char *fhp = (unsigned char *)fh; 108c15d59edSmickey u_int32_t temp; 109df930be7Sderaadt int fhtype = FHT_UNKNOWN; 110df930be7Sderaadt 111df930be7Sderaadt /* 112df930be7Sderaadt * This is basically a big decision tree 113df930be7Sderaadt */ 11454098794Smmcc if ((fhp[0] == 0) && (fhp[1] == 0)) { 115df930be7Sderaadt /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */ 116df930be7Sderaadt /* probably rules out HP-UX, AIX unless they allow major=0 */ 117df930be7Sderaadt if ((fhp[2] == 0) && (fhp[3] == 0)) { 118df930be7Sderaadt /* bytes[2,3] == (0,0); must be Auspex */ 119df930be7Sderaadt /* XXX or could be Ultrix+MASSBUS "hp" disk? */ 120df930be7Sderaadt fhtype = FHT_AUSPEX; 121df930be7Sderaadt } 122df930be7Sderaadt else { 123df930be7Sderaadt /* 124df930be7Sderaadt * bytes[2,3] != (0,0); rules out Auspex, could be 125df930be7Sderaadt * DECOSF, SUNOS4, or IRIX4 126df930be7Sderaadt */ 127df930be7Sderaadt if ((fhp[4] != 0) && (fhp[5] == 0) && 128df930be7Sderaadt (fhp[8] == 12) && (fhp[9] == 0)) { 129df930be7Sderaadt /* seems to be DECOSF, with minor == 0 */ 130df930be7Sderaadt fhtype = FHT_DECOSF; 131df930be7Sderaadt } 132df930be7Sderaadt else { 133df930be7Sderaadt /* could be SUNOS4 or IRIX4 */ 134df930be7Sderaadt /* XXX the test of fhp[5] == 8 could be wrong */ 135df930be7Sderaadt if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) && 136df930be7Sderaadt (fhp[7] == 0)) { 137df930be7Sderaadt /* looks like a length, not a file system typecode */ 138df930be7Sderaadt fhtype = FHT_IRIX4; 139df930be7Sderaadt } 140df930be7Sderaadt else { 141df930be7Sderaadt /* by elimination */ 142df930be7Sderaadt fhtype = FHT_SUNOS4; 143df930be7Sderaadt } 144df930be7Sderaadt } 145df930be7Sderaadt } 146df930be7Sderaadt } 147df930be7Sderaadt else { 148df930be7Sderaadt /* 149df930be7Sderaadt * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4 150df930be7Sderaadt * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 151df930be7Sderaadt * could be AIX, HP-UX 152df930be7Sderaadt */ 153df930be7Sderaadt if ((fhp[2] == 0) && (fhp[3] == 0)) { 154df930be7Sderaadt /* 155df930be7Sderaadt * bytes[2,3] == (0,0); rules out OSF, probably not UCX 156df930be7Sderaadt * (unless the exported device name is just one letter!), 157df930be7Sderaadt * could be Ultrix, IRIX5, AIX, or SUNOS5 158df930be7Sderaadt * might be HP-UX (depends on their values for minor devs) 159df930be7Sderaadt */ 160df930be7Sderaadt /*XXX we probably only need to test of these two bytes */ 161df930be7Sderaadt if ((fhp[21] == 0) && (fhp[23] == 0)) { 162df930be7Sderaadt fhtype = FHT_ULTRIX; 163df930be7Sderaadt } 164df930be7Sderaadt else { 165df930be7Sderaadt /* Could be SUNOS5/IRIX5, maybe AIX */ 166df930be7Sderaadt /* XXX no obvious difference between SUNOS5 and IRIX5 */ 167df930be7Sderaadt if (fhp[9] == 10) 168df930be7Sderaadt fhtype = FHT_SUNOS5; 169df930be7Sderaadt /* XXX what about AIX? */ 170df930be7Sderaadt } 171df930be7Sderaadt } 172df930be7Sderaadt else { 173df930be7Sderaadt /* 174df930be7Sderaadt * bytes[2,3] != (0,0); rules out Ultrix, could be 175df930be7Sderaadt * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX 176df930be7Sderaadt */ 177df930be7Sderaadt if ((fhp[8] == 12) && (fhp[9] == 0)) { 178df930be7Sderaadt fhtype = FHT_DECOSF; 179df930be7Sderaadt } 180df930be7Sderaadt else if ((fhp[8] == 0) && (fhp[9] == 10)) { 181df930be7Sderaadt /* could be SUNOS5/IRIX5, AIX, HP-UX */ 182df930be7Sderaadt if ((fhp[7] == 0) && (fhp[6] == 0) && 183df930be7Sderaadt (fhp[5] == 0) && (fhp[4] == 0)) { 184df930be7Sderaadt /* XXX is this always true of HP-UX? */ 185df930be7Sderaadt fhtype = FHT_HPUX9; 186df930be7Sderaadt } 187df930be7Sderaadt else if (fhp[7] == 2) { 188df930be7Sderaadt /* This would be MNT_NFS on AIX, which is impossible */ 189df930be7Sderaadt fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ 190df930be7Sderaadt } 191df930be7Sderaadt else { 192df930be7Sderaadt /* 193df930be7Sderaadt * XXX Could be SUNOS5/IRIX5 or AIX. I don't 194df930be7Sderaadt * XXX see any way to disambiguate these, so 195df930be7Sderaadt * XXX I'm going with the more likely guess. 196df930be7Sderaadt * XXX Sorry, Big Blue. 197df930be7Sderaadt */ 198df930be7Sderaadt fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ 199df930be7Sderaadt } 200df930be7Sderaadt } 201df930be7Sderaadt else { 202df930be7Sderaadt if (is_UCX(fhp)) { 203df930be7Sderaadt fhtype = FHT_VMSUCX; 204df930be7Sderaadt } 205df930be7Sderaadt else { 206df930be7Sderaadt fhtype = FHT_UNKNOWN; 207df930be7Sderaadt } 208df930be7Sderaadt } 209df930be7Sderaadt } 210df930be7Sderaadt } 211df930be7Sderaadt 212df930be7Sderaadt /* XXX still needs to handle SUNOS3 */ 213df930be7Sderaadt 214df930be7Sderaadt switch (fhtype) { 215df930be7Sderaadt case FHT_AUSPEX: 216dc709136Sbitblt fsidp->Fsid_dev.Minor = fhp[7]; 217dc709136Sbitblt fsidp->Fsid_dev.Major = fhp[6]; 218df930be7Sderaadt fsidp->fsid_code = 0; 219df930be7Sderaadt 220df930be7Sderaadt temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 221df930be7Sderaadt *inop = temp; 222df930be7Sderaadt 223df930be7Sderaadt if (osnamep) 224df930be7Sderaadt *osnamep = "Auspex"; 225df930be7Sderaadt break; 226df930be7Sderaadt 227df930be7Sderaadt case FHT_DECOSF: 228df930be7Sderaadt fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); 229df930be7Sderaadt /* XXX could ignore 3 high-order bytes */ 230df930be7Sderaadt 231df930be7Sderaadt temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]); 232dc709136Sbitblt fsidp->Fsid_dev.Minor = temp & 0xFFFFF; 233dc709136Sbitblt fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF; 234df930be7Sderaadt 235df930be7Sderaadt temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); 236df930be7Sderaadt *inop = temp; 237df930be7Sderaadt if (osnamep) 238df930be7Sderaadt *osnamep = "OSF"; 239df930be7Sderaadt break; 240df930be7Sderaadt 241df930be7Sderaadt case FHT_IRIX4: 242dc709136Sbitblt fsidp->Fsid_dev.Minor = fhp[3]; 243dc709136Sbitblt fsidp->Fsid_dev.Major = fhp[2]; 244df930be7Sderaadt fsidp->fsid_code = 0; 245df930be7Sderaadt 246df930be7Sderaadt temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]); 247df930be7Sderaadt *inop = temp; 248df930be7Sderaadt 249df930be7Sderaadt if (osnamep) 250df930be7Sderaadt *osnamep = "IRIX4"; 251df930be7Sderaadt break; 252df930be7Sderaadt 253df930be7Sderaadt case FHT_IRIX5: 254dc709136Sbitblt fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); 255dc709136Sbitblt fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); 256df930be7Sderaadt fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 257df930be7Sderaadt 258df930be7Sderaadt temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 259df930be7Sderaadt *inop = temp; 260df930be7Sderaadt 261df930be7Sderaadt if (osnamep) 262df930be7Sderaadt *osnamep = "IRIX5"; 263df930be7Sderaadt break; 264df930be7Sderaadt 265df930be7Sderaadt case FHT_SUNOS3: 266df930be7Sderaadt if (osnamep) 267df930be7Sderaadt *osnamep = "SUNOS3"; 268df930be7Sderaadt break; 269df930be7Sderaadt 270df930be7Sderaadt case FHT_SUNOS4: 271dc709136Sbitblt fsidp->Fsid_dev.Minor = fhp[3]; 272dc709136Sbitblt fsidp->Fsid_dev.Major = fhp[2]; 273df930be7Sderaadt fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 274df930be7Sderaadt 275df930be7Sderaadt temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 276df930be7Sderaadt *inop = temp; 277df930be7Sderaadt 278df930be7Sderaadt if (osnamep) 279df930be7Sderaadt *osnamep = "SUNOS4"; 280df930be7Sderaadt break; 281df930be7Sderaadt 282df930be7Sderaadt case FHT_SUNOS5: 283df930be7Sderaadt temp = make_uint16(fhp[0], fhp[1]); 284dc709136Sbitblt fsidp->Fsid_dev.Major = (temp>>2) & 0x3FFF; 285df930be7Sderaadt temp = make_uint24(fhp[1], fhp[2], fhp[3]); 286dc709136Sbitblt fsidp->Fsid_dev.Minor = temp & 0x3FFFF; 287df930be7Sderaadt fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 288df930be7Sderaadt 289df930be7Sderaadt temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 290df930be7Sderaadt *inop = temp; 291df930be7Sderaadt 292df930be7Sderaadt if (osnamep) 293df930be7Sderaadt *osnamep = "SUNOS5"; 294df930be7Sderaadt break; 295df930be7Sderaadt 296df930be7Sderaadt case FHT_ULTRIX: 297df930be7Sderaadt fsidp->fsid_code = 0; 298dc709136Sbitblt fsidp->Fsid_dev.Minor = fhp[0]; 299dc709136Sbitblt fsidp->Fsid_dev.Major = fhp[1]; 300df930be7Sderaadt 301df930be7Sderaadt temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); 302df930be7Sderaadt *inop = temp; 303df930be7Sderaadt if (osnamep) 304df930be7Sderaadt *osnamep = "Ultrix"; 305df930be7Sderaadt break; 306df930be7Sderaadt 307df930be7Sderaadt case FHT_VMSUCX: 308df930be7Sderaadt /* No numeric file system ID, so hash on the device-name */ 309df930be7Sderaadt if (sizeof(*fsidp) >= 14) { 310df930be7Sderaadt if (sizeof(*fsidp) > 14) 311c15d59edSmickey memset((char *)fsidp, 0, sizeof(*fsidp)); 312da08816cSjakob /* just use the whole thing */ 313da08816cSjakob memcpy((char *)fsidp, (char *)fh, 14); 314df930be7Sderaadt } 315df930be7Sderaadt else { 316c15d59edSmickey u_int32_t tempa[4]; /* at least 16 bytes, maybe more */ 317df930be7Sderaadt 318c15d59edSmickey memset((char *)tempa, 0, sizeof(tempa)); 319da08816cSjakob memcpy((char *)tempa, (char *)fh, 14); /* ensure alignment */ 320dc709136Sbitblt fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1); 321dc709136Sbitblt fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1); 322df930be7Sderaadt fsidp->fsid_code = 0; 323df930be7Sderaadt } 324df930be7Sderaadt 325df930be7Sderaadt /* VMS file ID is: (RVN, FidHi, FidLo) */ 326df930be7Sderaadt *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]); 327df930be7Sderaadt 328df930be7Sderaadt /* Caller must save (and null-terminate?) this value */ 329df930be7Sderaadt if (fsnamep) 330df930be7Sderaadt *fsnamep = (char *)&(fhp[1]); 331df930be7Sderaadt 332df930be7Sderaadt if (osnamep) 333df930be7Sderaadt *osnamep = "VMS"; 334df930be7Sderaadt break; 335df930be7Sderaadt 336df930be7Sderaadt case FHT_AIX32: 337dc709136Sbitblt fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); 338dc709136Sbitblt fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); 339df930be7Sderaadt fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 340df930be7Sderaadt 341df930be7Sderaadt temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 342df930be7Sderaadt *inop = temp; 343df930be7Sderaadt 344df930be7Sderaadt if (osnamep) 345df930be7Sderaadt *osnamep = "AIX32"; 346df930be7Sderaadt break; 347df930be7Sderaadt 348df930be7Sderaadt case FHT_HPUX9: 349dc709136Sbitblt fsidp->Fsid_dev.Major = fhp[0]; 350df930be7Sderaadt temp = make_uint24(fhp[1], fhp[2], fhp[3]); 351dc709136Sbitblt fsidp->Fsid_dev.Minor = temp; 352df930be7Sderaadt fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); 353df930be7Sderaadt 354df930be7Sderaadt temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); 355df930be7Sderaadt *inop = temp; 356df930be7Sderaadt 357df930be7Sderaadt if (osnamep) 358df930be7Sderaadt *osnamep = "HPUX9"; 359df930be7Sderaadt break; 360df930be7Sderaadt 361df930be7Sderaadt case FHT_UNKNOWN: 362df930be7Sderaadt #ifdef DEBUG 363df930be7Sderaadt { 364df930be7Sderaadt int i; 365c15d59edSmickey for (i = 0; i < 32; i++) 366c15d59edSmickey (void)fprintf(stderr, "%x.", fhp[i]); 367c15d59edSmickey (void)fprintf(stderr, "\n"); 368df930be7Sderaadt } 369df930be7Sderaadt #endif 370df930be7Sderaadt /* XXX for now, give "bogus" values to aid debugging */ 371df930be7Sderaadt fsidp->fsid_code = 0; 372dc709136Sbitblt fsidp->Fsid_dev.Minor = 257; 373dc709136Sbitblt fsidp->Fsid_dev.Major = 257; 374df930be7Sderaadt *inop = 1; 375df930be7Sderaadt 376df930be7Sderaadt /* display will show this string instead of (257,257) */ 377df930be7Sderaadt if (fsnamep) 378df930be7Sderaadt *fsnamep = "Unknown"; 379df930be7Sderaadt 380df930be7Sderaadt if (osnamep) 381df930be7Sderaadt *osnamep = "Unknown"; 382df930be7Sderaadt break; 383df930be7Sderaadt 384df930be7Sderaadt } 385df930be7Sderaadt } 386df930be7Sderaadt 387df930be7Sderaadt /* 388df930be7Sderaadt * Is this a VMS UCX file handle? 389df930be7Sderaadt * Check for: 390df930be7Sderaadt * (1) leading code byte [XXX not yet] 391df930be7Sderaadt * (2) followed by string of printing chars & spaces 392df930be7Sderaadt * (3) followed by string of nulls 393df930be7Sderaadt */ 394df930be7Sderaadt static int 395df930be7Sderaadt is_UCX(fhp) 396df930be7Sderaadt unsigned char *fhp; 397df930be7Sderaadt { 3980d5f83f3Smmcc int i; 399df930be7Sderaadt int seen_null = 0; 400df930be7Sderaadt 401df930be7Sderaadt for (i = 1; i < 14; i++) { 402df930be7Sderaadt if (isprint(fhp[i])) { 403df930be7Sderaadt if (seen_null) 404df930be7Sderaadt return(0); 405df930be7Sderaadt else 406df930be7Sderaadt continue; 407df930be7Sderaadt } 408df930be7Sderaadt else if (fhp[i] == 0) { 409df930be7Sderaadt seen_null = 1; 410df930be7Sderaadt continue; 411df930be7Sderaadt } 412df930be7Sderaadt else 413df930be7Sderaadt return(0); 414df930be7Sderaadt } 415df930be7Sderaadt 416df930be7Sderaadt return(1); 417df930be7Sderaadt } 418