117680Spst/*
298527Sfenner * Copyright (c) 1993, 1994 Jeffrey C. Mogul, Digital Equipment Corporation,
398527Sfenner * Western Research Laboratory. All rights reserved.
498527Sfenner * Copyright (c) 2001 Compaq Computer Corporation. All rights reserved.
598527Sfenner *
698527Sfenner *  Permission to use, copy, and modify this software and its
798527Sfenner *  documentation is hereby granted only under the following terms and
898527Sfenner *  conditions.  Both the above copyright notice and this permission
998527Sfenner *  notice must appear in all copies of the software, derivative works
1098527Sfenner *  or modified versions, and any portions thereof, and both notices
1198527Sfenner *  must appear in supporting documentation.
1298527Sfenner *
1398527Sfenner *  Redistribution and use in source and binary forms, with or without
1498527Sfenner *  modification, are permitted provided that the following conditions
1598527Sfenner *  are met:
1698527Sfenner *    1. Redistributions of source code must retain the above copyright
1798527Sfenner *    notice, this list of conditions and the following disclaimer.
1898527Sfenner *    2. Redistributions in binary form must reproduce the above copyright
1998527Sfenner *    notice, this list of conditions and the following disclaimer in
2098527Sfenner *    the documentation and/or other materials provided with the
2198527Sfenner *    distribution.
2298527Sfenner *
2398527Sfenner *  THE SOFTWARE IS PROVIDED "AS IS" AND COMPAQ COMPUTER CORPORATION
2498527Sfenner *  DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
2598527Sfenner *  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.   IN NO
2698527Sfenner *  EVENT SHALL COMPAQ COMPUTER CORPORATION BE LIABLE FOR ANY
2798527Sfenner *  SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2898527Sfenner *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
2998527Sfenner *  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
3098527Sfenner *  OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
3198527Sfenner *  SOFTWARE.
3298527Sfenner */
3398527Sfenner
3498527Sfenner/*
3517680Spst * parsenfsfh.c - portable parser for NFS file handles
3617680Spst *			uses all sorts of heuristics
3717680Spst *
3817680Spst * Jeffrey C. Mogul
3917680Spst * Digital Equipment Corporation
4017680Spst * Western Research Laboratory
4156896Sfenner *
4256896Sfenner * $FreeBSD$
4317680Spst */
4417680Spst
4526183Sfenner#ifndef lint
46127675Sbmsstatic const char rcsid[] _U_ =
47190207Srpaulo    "@(#) $Header: /tcpdump/master/tcpdump/parsenfsfh.c,v 1.29 2006-06-13 22:21:38 guy Exp $ (LBL)";
4826183Sfenner#endif
4926183Sfenner
5056896Sfenner#ifdef HAVE_CONFIG_H
5156896Sfenner#include "config.h"
5256896Sfenner#endif
5356896Sfenner
54127675Sbms#include <tcpdump-stdinc.h>
5517680Spst
5617680Spst#include <stdio.h>
5717680Spst#include <string.h>
5817680Spst
5917680Spst#include "interface.h"
6017680Spst#include "nfsfh.h"
6117680Spst
6217680Spst/*
6317680Spst * This routine attempts to parse a file handle (in network byte order),
6417680Spst * using heuristics to guess what kind of format it is in.  See the
6517680Spst * file "fhandle_layouts" for a detailed description of the various
6617680Spst * patterns we know about.
6717680Spst *
6817680Spst * The file handle is parsed into our internal representation of a
6917680Spst * file-system id, and an internal representation of an inode-number.
7017680Spst */
7117680Spst
7217680Spst#define	FHT_UNKNOWN	0
7317680Spst#define	FHT_AUSPEX	1
7417680Spst#define	FHT_DECOSF	2
7517680Spst#define	FHT_IRIX4	3
7617680Spst#define	FHT_IRIX5	4
7717680Spst#define	FHT_SUNOS3	5
7817680Spst#define	FHT_SUNOS4	6
7917680Spst#define	FHT_ULTRIX	7
8017680Spst#define	FHT_VMSUCX	8
8117680Spst#define	FHT_SUNOS5	9
8217680Spst#define	FHT_AIX32	10
8317680Spst#define	FHT_HPUX9	11
84172686Smlaier#define	FHT_BSD44	12
8517680Spst
8617680Spst#ifdef	ultrix
8717680Spst/* Nasty hack to keep the Ultrix C compiler from emitting bogus warnings */
8817680Spst#define	XFF(x)	((u_int32_t)(x))
8917680Spst#else
9017680Spst#define	XFF(x)	(x)
9117680Spst#endif
9217680Spst
9317680Spst#define	make_uint32(msb,b,c,lsb)\
9417680Spst	(XFF(lsb) + (XFF(c)<<8) + (XFF(b)<<16) + (XFF(msb)<<24))
9517680Spst
9617680Spst#define	make_uint24(msb,b, lsb)\
9717680Spst	(XFF(lsb) + (XFF(b)<<8) + (XFF(msb)<<16))
9817680Spst
9917680Spst#define	make_uint16(msb,lsb)\
10017680Spst	(XFF(lsb) + (XFF(msb)<<8))
10117680Spst
10217680Spst#ifdef	__alpha
10317680Spst	/* or other 64-bit systems */
10417680Spst#define	make_uint48(msb,b,c,d,e,lsb)\
10517680Spst	((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24) + ((b)<<32) + ((msb)<<40))
10617680Spst#else
10717680Spst	/* on 32-bit systems ignore high-order bits */
10817680Spst#define	make_uint48(msb,b,c,d,e,lsb)\
10917680Spst	((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24))
11017680Spst#endif
11117680Spst
112127675Sbmsstatic int is_UCX(const unsigned char *);
11317680Spst
11417680Spstvoid
11518976SdfrParse_fh(fh, len, fsidp, inop, osnamep, fsnamep, ourself)
116127675Sbmsregister const unsigned char *fh;
117146778Ssamint len _U_;
11817680Spstmy_fsid *fsidp;
11917680Spstino_t *inop;
12098527Sfennerconst char **osnamep;		/* if non-NULL, return OS name here */
12198527Sfennerconst char **fsnamep;		/* if non-NULL, return server fs name here (for VMS) */
12217680Spstint ourself;		/* true if file handle was generated on this host */
12317680Spst{
124127675Sbms	register const unsigned char *fhp = fh;
12517680Spst	u_int32_t temp;
12617680Spst	int fhtype = FHT_UNKNOWN;
12775118Sfenner	int i;
12817680Spst
12917680Spst	if (ourself) {
13017680Spst	    /* File handle generated on this host, no need for guessing */
13117680Spst#if	defined(IRIX40)
13217680Spst	    fhtype = FHT_IRIX4;
13317680Spst#endif
13417680Spst#if	defined(IRIX50)
13517680Spst	    fhtype = FHT_IRIX5;
13617680Spst#endif
13717680Spst#if	defined(IRIX51)
13817680Spst	    fhtype = FHT_IRIX5;
13917680Spst#endif
14017680Spst#if	defined(SUNOS4)
14117680Spst	    fhtype = FHT_SUNOS4;
14217680Spst#endif
14317680Spst#if	defined(SUNOS5)
14417680Spst	    fhtype = FHT_SUNOS5;
14517680Spst#endif
14617680Spst#if	defined(ultrix)
14717680Spst	    fhtype = FHT_ULTRIX;
14817680Spst#endif
14917680Spst#if	defined(__osf__)
15017680Spst	    fhtype = FHT_DECOSF;
15117680Spst#endif
152172686Smlaier#if	defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) \
153172686Smlaier     || defined(__OpenBSD__)
154172686Smlaier	    fhtype = FHT_BSD44;
155172686Smlaier#endif
15617680Spst	}
15717680Spst	/*
15817680Spst	 * This is basically a big decision tree
15917680Spst	 */
16017680Spst	else if ((fhp[0] == 0) && (fhp[1] == 0)) {
16117680Spst	    /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */
16217680Spst	    /* probably rules out HP-UX, AIX unless they allow major=0 */
16317680Spst	    if ((fhp[2] == 0) && (fhp[3] == 0)) {
16417680Spst		/* bytes[2,3] == (0,0); must be Auspex */
16517680Spst		/* XXX or could be Ultrix+MASSBUS "hp" disk? */
16617680Spst		fhtype = FHT_AUSPEX;
16717680Spst	    }
16817680Spst	    else {
16917680Spst		/*
17017680Spst		 * bytes[2,3] != (0,0); rules out Auspex, could be
17117680Spst		 * DECOSF, SUNOS4, or IRIX4
17217680Spst		 */
17317680Spst		if ((fhp[4] != 0) && (fhp[5] == 0) &&
17417680Spst			(fhp[8] == 12) && (fhp[9] == 0)) {
17517680Spst		    /* seems to be DECOSF, with minor == 0 */
17617680Spst		    fhtype = FHT_DECOSF;
17717680Spst		}
17817680Spst		else {
17917680Spst		    /* could be SUNOS4 or IRIX4 */
18017680Spst		    /* XXX the test of fhp[5] == 8 could be wrong */
18117680Spst		    if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) &&
18217680Spst			(fhp[7] == 0)) {
18317680Spst			/* looks like a length, not a file system typecode */
18417680Spst			fhtype = FHT_IRIX4;
18517680Spst		    }
18617680Spst		    else {
18717680Spst			/* by elimination */
18817680Spst			fhtype = FHT_SUNOS4;
18917680Spst		    }
19017680Spst		}
19117680Spst	    }
19217680Spst	}
19317680Spst	else {
19417680Spst	    /*
19517680Spst	     * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4
19617680Spst	     * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5
19717680Spst	     * could be AIX, HP-UX
19817680Spst	     */
19917680Spst	    if ((fhp[2] == 0) && (fhp[3] == 0)) {
20017680Spst		/*
20117680Spst		 * bytes[2,3] == (0,0); rules out OSF, probably not UCX
20217680Spst		 * (unless the exported device name is just one letter!),
20317680Spst		 * could be Ultrix, IRIX5, AIX, or SUNOS5
20417680Spst		 * might be HP-UX (depends on their values for minor devs)
20517680Spst		 */
206172686Smlaier		if ((fhp[6] == 0) && (fhp[7] == 0)) {
207172686Smlaier		    fhtype = FHT_BSD44;
208172686Smlaier		}
20917680Spst		/*XXX we probably only need to test of these two bytes */
210172686Smlaier		else if ((fhp[21] == 0) && (fhp[23] == 0)) {
21117680Spst		    fhtype = FHT_ULTRIX;
21217680Spst		}
21317680Spst		else {
21417680Spst		    /* Could be SUNOS5/IRIX5, maybe AIX */
21517680Spst		    /* XXX no obvious difference between SUNOS5 and IRIX5 */
21617680Spst		    if (fhp[9] == 10)
21717680Spst			fhtype = FHT_SUNOS5;
21817680Spst		    /* XXX what about AIX? */
21917680Spst		}
22017680Spst	    }
22117680Spst	    else {
22217680Spst		/*
22317680Spst		 * bytes[2,3] != (0,0); rules out Ultrix, could be
22417680Spst		 * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX
22517680Spst		 */
22617680Spst		if ((fhp[8] == 12) && (fhp[9] == 0)) {
22717680Spst		    fhtype = FHT_DECOSF;
22817680Spst		}
22917680Spst		else if ((fhp[8] == 0) && (fhp[9] == 10)) {
23017680Spst		    /* could be SUNOS5/IRIX5, AIX, HP-UX */
23117680Spst		    if ((fhp[7] == 0) && (fhp[6] == 0) &&
23217680Spst			(fhp[5] == 0) && (fhp[4] == 0)) {
23317680Spst			/* XXX is this always true of HP-UX? */
23417680Spst			fhtype = FHT_HPUX9;
23517680Spst		    }
23617680Spst		    else if (fhp[7] == 2) {
23717680Spst			/* This would be MNT_NFS on AIX, which is impossible */
23817680Spst			fhtype = FHT_SUNOS5;	/* or maybe IRIX5 */
23917680Spst		    }
24017680Spst		    else {
24117680Spst			/*
24217680Spst			 * XXX Could be SUNOS5/IRIX5 or AIX.  I don't
24317680Spst			 * XXX see any way to disambiguate these, so
24417680Spst			 * XXX I'm going with the more likely guess.
24517680Spst			 * XXX Sorry, Big Blue.
24617680Spst			 */
24717680Spst			fhtype = FHT_SUNOS5;	/* or maybe IRIX5 */
24817680Spst		    }
24917680Spst	        }
25017680Spst		else {
25117680Spst		    if (is_UCX(fhp)) {
25217680Spst			fhtype = FHT_VMSUCX;
25317680Spst		    }
25417680Spst		    else {
25517680Spst			fhtype = FHT_UNKNOWN;
25617680Spst		    }
25717680Spst		}
25817680Spst	    }
25917680Spst	}
26017680Spst
26117680Spst	/* XXX still needs to handle SUNOS3 */
26217680Spst
26317680Spst	switch (fhtype) {
26417680Spst	case FHT_AUSPEX:
26526183Sfenner	    fsidp->Fsid_dev.Minor = fhp[7];
26626183Sfenner	    fsidp->Fsid_dev.Major = fhp[6];
26717680Spst	    fsidp->fsid_code = 0;
26817680Spst
26917680Spst	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
27017680Spst	    *inop = temp;
27117680Spst
27217680Spst	    if (osnamep)
27317680Spst		*osnamep = "Auspex";
27417680Spst	    break;
27517680Spst
276172686Smlaier	case FHT_BSD44:
277172686Smlaier	    fsidp->Fsid_dev.Minor = fhp[0];
278172686Smlaier	    fsidp->Fsid_dev.Major = fhp[1];
279172686Smlaier	    fsidp->fsid_code = 0;
280172686Smlaier
281172686Smlaier	    temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]);
282172686Smlaier	    *inop = temp;
283172686Smlaier
284172686Smlaier	    if (osnamep)
285172686Smlaier		*osnamep = "BSD 4.4";
286172686Smlaier	    break;
287172686Smlaier
28817680Spst	case FHT_DECOSF:
28917680Spst	    fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]);
29017680Spst			/* XXX could ignore 3 high-order bytes */
29117680Spst
29217680Spst	    temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]);
29326183Sfenner	    fsidp->Fsid_dev.Minor = temp & 0xFFFFF;
29426183Sfenner	    fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF;
29517680Spst
29617680Spst	    temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]);
29717680Spst	    *inop = temp;
29817680Spst	    if (osnamep)
29917680Spst		*osnamep = "OSF";
30017680Spst	    break;
30117680Spst
30217680Spst	case FHT_IRIX4:
30326183Sfenner	    fsidp->Fsid_dev.Minor = fhp[3];
30426183Sfenner	    fsidp->Fsid_dev.Major = fhp[2];
30517680Spst	    fsidp->fsid_code = 0;
30617680Spst
30717680Spst	    temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]);
30817680Spst	    *inop = temp;
30917680Spst
31017680Spst	    if (osnamep)
31117680Spst		*osnamep = "IRIX4";
31217680Spst	    break;
31317680Spst
31417680Spst	case FHT_IRIX5:
31526183Sfenner	    fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]);
31626183Sfenner	    fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]);
31717680Spst	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
31817680Spst
31917680Spst	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
32017680Spst	    *inop = temp;
32117680Spst
32217680Spst	    if (osnamep)
32317680Spst		*osnamep = "IRIX5";
32417680Spst	    break;
32517680Spst
326172686Smlaier#ifdef notdef
32717680Spst	case FHT_SUNOS3:
328172686Smlaier	    /*
329172686Smlaier	     * XXX - none of the heuristics above return this.
330172686Smlaier	     * Are there any SunOS 3.x systems around to care about?
331172686Smlaier	     */
33217680Spst	    if (osnamep)
33317680Spst		*osnamep = "SUNOS3";
33417680Spst	    break;
335172686Smlaier#endif
33617680Spst
33717680Spst	case FHT_SUNOS4:
33826183Sfenner	    fsidp->Fsid_dev.Minor = fhp[3];
33926183Sfenner	    fsidp->Fsid_dev.Major = fhp[2];
34017680Spst	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
34117680Spst
34217680Spst	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
34317680Spst	    *inop = temp;
34417680Spst
34517680Spst	    if (osnamep)
34617680Spst		*osnamep = "SUNOS4";
34717680Spst	    break;
34817680Spst
34917680Spst	case FHT_SUNOS5:
35017680Spst	    temp = make_uint16(fhp[0], fhp[1]);
35126183Sfenner	    fsidp->Fsid_dev.Major = (temp>>2) &  0x3FFF;
35217680Spst	    temp = make_uint24(fhp[1], fhp[2], fhp[3]);
35326183Sfenner	    fsidp->Fsid_dev.Minor = temp & 0x3FFFF;
35417680Spst	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
35517680Spst
35617680Spst	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
35717680Spst	    *inop = temp;
35817680Spst
35917680Spst	    if (osnamep)
36017680Spst		*osnamep = "SUNOS5";
36117680Spst	    break;
36217680Spst
36317680Spst	case FHT_ULTRIX:
36417680Spst	    fsidp->fsid_code = 0;
36526183Sfenner	    fsidp->Fsid_dev.Minor = fhp[0];
36626183Sfenner	    fsidp->Fsid_dev.Major = fhp[1];
36717680Spst
36817680Spst	    temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]);
36917680Spst	    *inop = temp;
37017680Spst	    if (osnamep)
37117680Spst		*osnamep = "Ultrix";
37217680Spst	    break;
37317680Spst
37417680Spst	case FHT_VMSUCX:
37517680Spst	    /* No numeric file system ID, so hash on the device-name */
37617680Spst	    if (sizeof(*fsidp) >= 14) {
37717680Spst		if (sizeof(*fsidp) > 14)
37817680Spst		    memset((char *)fsidp, 0, sizeof(*fsidp));
37939300Sfenner		/* just use the whole thing */
38039300Sfenner		memcpy((char *)fsidp, (char *)fh, 14);
38117680Spst	    }
38217680Spst	    else {
38317680Spst		u_int32_t tempa[4];	/* at least 16 bytes, maybe more */
38417680Spst
38517680Spst		memset((char *)tempa, 0, sizeof(tempa));
38639300Sfenner		memcpy((char *)tempa, (char *)fh, 14); /* ensure alignment */
38726183Sfenner		fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1);
38826183Sfenner		fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1);
38917680Spst		fsidp->fsid_code = 0;
39017680Spst	    }
39117680Spst
39217680Spst	    /* VMS file ID is: (RVN, FidHi, FidLo) */
39317680Spst	    *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]);
39417680Spst
39517680Spst	    /* Caller must save (and null-terminate?) this value */
39617680Spst	    if (fsnamep)
39717680Spst		*fsnamep = (char *)&(fhp[1]);
39817680Spst
39917680Spst	    if (osnamep)
40017680Spst		*osnamep = "VMS";
40117680Spst	    break;
40217680Spst
40317680Spst	case FHT_AIX32:
40426183Sfenner	    fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]);
40526183Sfenner	    fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]);
40617680Spst	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
40717680Spst
40817680Spst	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
40917680Spst	    *inop = temp;
41017680Spst
41117680Spst	    if (osnamep)
41217680Spst		*osnamep = "AIX32";
41317680Spst	    break;
41417680Spst
41517680Spst	case FHT_HPUX9:
41626183Sfenner	    fsidp->Fsid_dev.Major = fhp[0];
41717680Spst	    temp = make_uint24(fhp[1], fhp[2], fhp[3]);
41826183Sfenner	    fsidp->Fsid_dev.Minor = temp;
41917680Spst	    fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
42017680Spst
42117680Spst	    temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
42217680Spst	    *inop = temp;
42317680Spst
42417680Spst	    if (osnamep)
42517680Spst		*osnamep = "HPUX9";
42617680Spst	    break;
42717680Spst
42817680Spst	case FHT_UNKNOWN:
42917680Spst#ifdef DEBUG
43075118Sfenner	    /* XXX debugging */
43175118Sfenner	    for (i = 0; i < 32; i++)
43275118Sfenner		(void)fprintf(stderr, "%x.", fhp[i]);
43375118Sfenner	    (void)fprintf(stderr, "\n");
43417680Spst#endif
43575118Sfenner	    /* Save the actual handle, so it can be display with -u */
43675118Sfenner	    for (i = 0; i < 32; i++)
43798527Sfenner	    	(void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X", fhp[i]);
43875118Sfenner
43998527Sfenner	    /* XXX for now, give "bogus" values to aid debugging */
44017680Spst	    fsidp->fsid_code = 0;
44126183Sfenner	    fsidp->Fsid_dev.Minor = 257;
44226183Sfenner	    fsidp->Fsid_dev.Major = 257;
44317680Spst	    *inop = 1;
44417680Spst
44517680Spst	    /* display will show this string instead of (257,257) */
44617680Spst	    if (fsnamep)
44717680Spst		*fsnamep = "Unknown";
44817680Spst
44917680Spst	    if (osnamep)
45017680Spst		*osnamep = "Unknown";
45117680Spst	    break;
45217680Spst
45317680Spst	}
45417680Spst}
45517680Spst
45617680Spst/*
45717680Spst * Is this a VMS UCX file handle?
45817680Spst *	Check for:
45917680Spst *	(1) leading code byte	[XXX not yet]
46017680Spst *	(2) followed by string of printing chars & spaces
46117680Spst *	(3) followed by string of nulls
46217680Spst */
46317680Spststatic int
46417680Spstis_UCX(fhp)
465127675Sbmsconst unsigned char *fhp;
46617680Spst{
46717680Spst	register int i;
46817680Spst	int seen_null = 0;
46917680Spst
47017680Spst	for (i = 1; i < 14; i++) {
47117680Spst	    if (isprint(fhp[i])) {
47217680Spst		if (seen_null)
47317680Spst		   return(0);
47417680Spst		else
47517680Spst		   continue;
47617680Spst	    }
47717680Spst	    else if (fhp[i] == 0) {
47817680Spst		seen_null = 1;
47917680Spst		continue;
48017680Spst	    }
48117680Spst	    else
48217680Spst		return(0);
48317680Spst	}
48417680Spst
48517680Spst	return(1);
48617680Spst}
487