getrpc_test.c revision 251818
160484Sobrien/*-
2130561Sobrien * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
378828Sobrien *
460484Sobrien * Redistribution and use in source and binary forms, with or without
577298Sobrien * modification, are permitted provided that the following conditions
660484Sobrien * are met:
760484Sobrien * 1. Redistributions of source code must retain the above copyright
860484Sobrien *    notice, this list of conditions and the following disclaimer.
960484Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1060484Sobrien *    notice, this list of conditions and the following disclaimer in the
1160484Sobrien *    documentation and/or other materials provided with the distribution.
1260484Sobrien *
1360484Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1460484Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1560484Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1660484Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1760484Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1860484Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1960484Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2060484Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2160484Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2289857Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2389857Sobrien * SUCH DAMAGE.
2460484Sobrien *
25130561Sobrien */
2689857Sobrien
2789857Sobrien#include <sys/cdefs.h>
2889857Sobrien__FBSDID("$FreeBSD: head/tools/regression/lib/libc/nss/test-getrpc.c 251818 2013-06-16 19:35:01Z eadler $");
2989857Sobrien
3089857Sobrien#include <arpa/inet.h>
3189857Sobrien#include <rpc/rpc.h>
3289857Sobrien#include <assert.h>
3389857Sobrien#include <errno.h>
3489857Sobrien#include <stdio.h>
3589857Sobrien#include <stdlib.h>
3689857Sobrien#include <string.h>
3789857Sobrien#include <stringlist.h>
3889857Sobrien#include <unistd.h>
3989857Sobrien#include "testutil.h"
4089857Sobrien
4160484Sobrienenum test_methods {
4260484Sobrien	TEST_GETRPCENT,
4360484Sobrien	TEST_GETRPCBYNAME,
4460484Sobrien	TEST_GETRPCBYNUMBER,
4560484Sobrien	TEST_GETRPCENT_2PASS,
4689857Sobrien	TEST_BUILD_SNAPSHOT
4760484Sobrien};
4860484Sobrien
4960484Sobrienstatic int debug = 0;
5060484Sobrienstatic enum test_methods method = TEST_BUILD_SNAPSHOT;
5160484Sobrien
5260484SobrienDECLARE_TEST_DATA(rpcent)
5360484SobrienDECLARE_TEST_FILE_SNAPSHOT(rpcent)
5460484SobrienDECLARE_1PASS_TEST(rpcent)
5560484SobrienDECLARE_2PASS_TEST(rpcent)
5660484Sobrien
57130561Sobrienstatic void clone_rpcent(struct rpcent *, struct rpcent const *);
5889857Sobrienstatic int compare_rpcent(struct rpcent *, struct rpcent *, void *);
5989857Sobrienstatic void dump_rpcent(struct rpcent *);
6089857Sobrienstatic void free_rpcent(struct rpcent *);
6189857Sobrien
6289857Sobrienstatic void sdump_rpcent(struct rpcent *, char *, size_t);
6389857Sobrienstatic int rpcent_read_snapshot_func(struct rpcent *, char *);
6489857Sobrien
6589857Sobrienstatic int rpcent_check_ambiguity(struct rpcent_test_data *,
6689857Sobrien	struct rpcent *);
6789857Sobrienstatic int rpcent_fill_test_data(struct rpcent_test_data *);
6889857Sobrienstatic int rpcent_test_correctness(struct rpcent *, void *);
6989857Sobrienstatic int rpcent_test_getrpcbyname(struct rpcent *, void *);
7089857Sobrienstatic int rpcent_test_getrpcbynumber(struct rpcent *, void *);
7189857Sobrienstatic int rpcent_test_getrpcent(struct rpcent *, void *);
7289857Sobrien
7389857Sobrienstatic void usage(void)  __attribute__((__noreturn__));
7489857Sobrien
7589857SobrienIMPLEMENT_TEST_DATA(rpcent)
7689857SobrienIMPLEMENT_TEST_FILE_SNAPSHOT(rpcent)
7789857SobrienIMPLEMENT_1PASS_TEST(rpcent)
7889857SobrienIMPLEMENT_2PASS_TEST(rpcent)
7960484Sobrien
8089857Sobrienstatic void
8189857Sobrienclone_rpcent(struct rpcent *dest, struct rpcent const *src)
8289857Sobrien{
83130561Sobrien	assert(dest != NULL);
84130561Sobrien	assert(src != NULL);
85130561Sobrien
86130561Sobrien	char **cp;
87130561Sobrien	int aliases_num;
88130561Sobrien
89130561Sobrien	memset(dest, 0, sizeof(struct rpcent));
90130561Sobrien
91130561Sobrien	if (src->r_name != NULL) {
92130561Sobrien		dest->r_name = strdup(src->r_name);
93130561Sobrien		assert(dest->r_name != NULL);
94130561Sobrien	}
95130561Sobrien
96130561Sobrien	dest->r_number = src->r_number;
97130561Sobrien
98130561Sobrien	if (src->r_aliases != NULL) {
99130561Sobrien		aliases_num = 0;
10089857Sobrien		for (cp = src->r_aliases; *cp; ++cp)
101130561Sobrien			++aliases_num;
102130561Sobrien
103130561Sobrien		dest->r_aliases = (char **)malloc((aliases_num+1) * (sizeof(char *)));
104130561Sobrien		assert(dest->r_aliases != NULL);
10589857Sobrien		memset(dest->r_aliases, 0, (aliases_num+1) * (sizeof(char *)));
10660484Sobrien
10760484Sobrien		for (cp = src->r_aliases; *cp; ++cp) {
10860484Sobrien			dest->r_aliases[cp - src->r_aliases] = strdup(*cp);
10960484Sobrien			assert(dest->r_aliases[cp - src->r_aliases] != NULL);
11060484Sobrien		}
11177298Sobrien	}
11260484Sobrien}
11360484Sobrien
11460484Sobrienstatic void
11560484Sobrienfree_rpcent(struct rpcent *rpc)
11660484Sobrien{
11760484Sobrien	char **cp;
11860484Sobrien
11960484Sobrien	assert(rpc != NULL);
12060484Sobrien
12160484Sobrien	free(rpc->r_name);
12260484Sobrien
12360484Sobrien	for (cp = rpc->r_aliases; *cp; ++cp)
12460484Sobrien		free(*cp);
12560484Sobrien	free(rpc->r_aliases);
12660484Sobrien}
12760484Sobrien
12860484Sobrienstatic  int
12960484Sobriencompare_rpcent(struct rpcent *rpc1, struct rpcent *rpc2, void *mdata)
13060484Sobrien{
13160484Sobrien	char **c1, **c2;
13260484Sobrien
13360484Sobrien	if (rpc1 == rpc2)
13460484Sobrien		return 0;
13560484Sobrien
13660484Sobrien	if ((rpc1 == NULL) || (rpc2 == NULL))
13760484Sobrien		goto errfin;
13860484Sobrien
13960484Sobrien	if ((strcmp(rpc1->r_name, rpc2->r_name) != 0) ||
14060484Sobrien		(rpc1->r_number != rpc2->r_number))
14160484Sobrien			goto errfin;
14260484Sobrien
14360484Sobrien	c1 = rpc1->r_aliases;
14460484Sobrien	c2 = rpc2->r_aliases;
14560484Sobrien
14660484Sobrien	if ((rpc1->r_aliases == NULL) || (rpc2->r_aliases == NULL))
14760484Sobrien		goto errfin;
14860484Sobrien
14960484Sobrien	for (;*c1 && *c2; ++c1, ++c2)
15060484Sobrien		if (strcmp(*c1, *c2) != 0)
15160484Sobrien			goto errfin;
15277298Sobrien
15360484Sobrien	if ((*c1 != '\0') || (*c2 != '\0'))
15460484Sobrien		goto errfin;
15560484Sobrien
15660484Sobrien	return 0;
15777298Sobrien
15860484Sobrienerrfin:
15960484Sobrien	if ((debug) && (mdata == NULL)) {
16060484Sobrien		printf("following structures are not equal:\n");
16189857Sobrien		dump_rpcent(rpc1);
16260484Sobrien		dump_rpcent(rpc2);
16360484Sobrien	}
16460484Sobrien
16560484Sobrien	return (-1);
16660484Sobrien}
16760484Sobrien
16860484Sobrienstatic void
16960484Sobriensdump_rpcent(struct rpcent *rpc, char *buffer, size_t buflen)
17089857Sobrien{
17189857Sobrien	char **cp;
17260484Sobrien	int written;
17377298Sobrien
17460484Sobrien	written = snprintf(buffer, buflen, "%s %d",
17560484Sobrien		rpc->r_name, rpc->r_number);
17660484Sobrien	buffer += written;
17789857Sobrien	if (written > buflen)
17889857Sobrien		return;
17989857Sobrien	buflen -= written;
18060484Sobrien
18160484Sobrien	if (rpc->r_aliases != NULL) {
18260484Sobrien		if (*(rpc->r_aliases) != '\0') {
18360484Sobrien			for (cp = rpc->r_aliases; *cp; ++cp) {
18460484Sobrien				written = snprintf(buffer, buflen, " %s",*cp);
18560484Sobrien				buffer += written;
18660484Sobrien				if (written > buflen)
18760484Sobrien					return;
18860484Sobrien				buflen -= written;
18960484Sobrien
19060484Sobrien				if (buflen == 0)
19160484Sobrien					return;
19260484Sobrien			}
19360484Sobrien		} else
19460484Sobrien			snprintf(buffer, buflen, " noaliases");
19560484Sobrien	} else
19660484Sobrien		snprintf(buffer, buflen, " (null)");
19760484Sobrien}
19860484Sobrien
19960484Sobrienstatic int
20060484Sobrienrpcent_read_snapshot_func(struct rpcent *rpc, char *line)
20160484Sobrien{
20260484Sobrien	StringList *sl;
20377298Sobrien	char *s, *ps, *ts;
20460484Sobrien	int i;
20577298Sobrien
20660484Sobrien	if (debug)
20760484Sobrien		printf("1 line read from snapshot:\n%s\n", line);
20877298Sobrien
20960484Sobrien	i = 0;
21060484Sobrien	sl = NULL;
21160484Sobrien	ps = line;
21260484Sobrien	memset(rpc, 0, sizeof(struct rpcent));
21360484Sobrien	while ( (s = strsep(&ps, " ")) != NULL) {
21460484Sobrien		switch (i) {
21560484Sobrien			case 0:
21660484Sobrien				rpc->r_name = strdup(s);
21777298Sobrien				assert(rpc->r_name != NULL);
21860484Sobrien			break;
21960484Sobrien
22060484Sobrien			case 1:
22177298Sobrien				rpc->r_number = (int)strtol(s, &ts, 10);
22260484Sobrien				if (*ts != '\0') {
22360484Sobrien					free(rpc->r_name);
22460484Sobrien					return (-1);
22560484Sobrien				}
22660484Sobrien			break;
22760484Sobrien
22860484Sobrien			default:
22960484Sobrien				if (sl == NULL) {
23060484Sobrien					if (strcmp(s, "(null)") == 0)
23160484Sobrien						return (0);
23260484Sobrien
23360484Sobrien					sl = sl_init();
23460484Sobrien					assert(sl != NULL);
23560484Sobrien
23660484Sobrien					if (strcmp(s, "noaliases") != 0) {
23760484Sobrien						ts = strdup(s);
23860484Sobrien						assert(ts != NULL);
23960484Sobrien						sl_add(sl, ts);
24077298Sobrien					}
24160484Sobrien				} else {
24260484Sobrien					ts = strdup(s);
24360484Sobrien					assert(ts != NULL);
24460484Sobrien					sl_add(sl, ts);
24560484Sobrien				}
24660484Sobrien			break;
24760484Sobrien		};
24860484Sobrien		++i;
24960484Sobrien	}
25060484Sobrien
25160484Sobrien	if (i < 3) {
25260484Sobrien		free(rpc->r_name);
25360484Sobrien		memset(rpc, 0, sizeof(struct rpcent));
25460484Sobrien		return (-1);
25560484Sobrien	}
25660484Sobrien
25760484Sobrien	sl_add(sl, NULL);
25860484Sobrien	rpc->r_aliases = sl->sl_str;
25960484Sobrien
26060484Sobrien	/* NOTE: is it a dirty hack or not? */
26160484Sobrien	free(sl);
26260484Sobrien	return (0);
26360484Sobrien}
26460484Sobrien
26560484Sobrienstatic void
26660484Sobriendump_rpcent(struct rpcent *result)
26760484Sobrien{
26860484Sobrien	if (result != NULL) {
26960484Sobrien		char buffer[1024];
27089857Sobrien		sdump_rpcent(result, buffer, sizeof(buffer));
27160484Sobrien		printf("%s\n", buffer);
27277298Sobrien	} else
27389857Sobrien		printf("(null)\n");
27460484Sobrien}
27560484Sobrien
27660484Sobrienstatic int
27760484Sobrienrpcent_fill_test_data(struct rpcent_test_data *td)
27860484Sobrien{
27960484Sobrien	struct rpcent *rpc;
28060484Sobrien
28160484Sobrien	setrpcent(1);
28260484Sobrien	while ((rpc = getrpcent()) != NULL) {
28360484Sobrien		if (rpcent_test_correctness(rpc, NULL) == 0)
28460484Sobrien			TEST_DATA_APPEND(rpcent, td, rpc);
28589857Sobrien		else
28660484Sobrien			return (-1);
28760484Sobrien	}
28860484Sobrien	endrpcent();
28960484Sobrien
29060484Sobrien	return (0);
29160484Sobrien}
29260484Sobrien
29360484Sobrienstatic int
29460484Sobrienrpcent_test_correctness(struct rpcent *rpc, void *mdata)
29560484Sobrien{
29689857Sobrien	if (debug) {
29760484Sobrien		printf("testing correctness with the following data:\n");
29860484Sobrien		dump_rpcent(rpc);
29960484Sobrien	}
30060484Sobrien
30160484Sobrien	if (rpc == NULL)
30289857Sobrien		goto errfin;
30360484Sobrien
30460484Sobrien	if (rpc->r_name == NULL)
30589857Sobrien		goto errfin;
30660484Sobrien
30760484Sobrien	if (rpc->r_number < 0)
30860484Sobrien		goto errfin;
30960484Sobrien
31060484Sobrien	if (rpc->r_aliases == NULL)
31160484Sobrien		goto errfin;
31277298Sobrien
31360484Sobrien	if (debug)
31460484Sobrien		printf("correct\n");
31560484Sobrien
31660484Sobrien	return (0);
31777298Sobrienerrfin:
31860484Sobrien	if (debug)
31960484Sobrien		printf("incorrect\n");
32060484Sobrien
32160484Sobrien	return (-1);
32260484Sobrien}
32360484Sobrien
32460484Sobrien/* rpcent_check_ambiguity() is needed when one port+rpc is associated with
32560484Sobrien * more than one peice (these cases are usually marked as PROBLEM in
32660484Sobrien * /etc/peices. This functions is needed also when one peice+rpc is
32760484Sobrien * associated with several ports. We have to check all the rpcent structures
32889857Sobrien * to make sure that rpc really exists and correct */
32989857Sobrienstatic int
33060484Sobrienrpcent_check_ambiguity(struct rpcent_test_data *td, struct rpcent *rpc)
33160484Sobrien{
33260484Sobrien
33360484Sobrien	return (TEST_DATA_FIND(rpcent, td, rpc, compare_rpcent,
33460484Sobrien		NULL) != NULL ? 0 : -1);
33560484Sobrien}
33660484Sobrien
33760484Sobrienstatic int
33860484Sobrienrpcent_test_getrpcbyname(struct rpcent *rpc_model, void *mdata)
33960484Sobrien{
34089857Sobrien	char **alias;
34189857Sobrien	struct rpcent *rpc;
34260484Sobrien
34360484Sobrien	if (debug) {
34460484Sobrien		printf("testing getrpcbyname() with the following data:\n");
34560484Sobrien		dump_rpcent(rpc_model);
34660484Sobrien	}
34760484Sobrien
34860484Sobrien	rpc = getrpcbyname(rpc_model->r_name);
34960484Sobrien	if (rpcent_test_correctness(rpc, NULL) != 0)
35060484Sobrien		goto errfin;
35160484Sobrien
35260484Sobrien	if ((compare_rpcent(rpc, rpc_model, NULL) != 0) &&
35360484Sobrien	    (rpcent_check_ambiguity((struct rpcent_test_data *)mdata, rpc)
35460484Sobrien	    !=0))
35560484Sobrien	    goto errfin;
35660484Sobrien
35760484Sobrien	for (alias = rpc_model->r_aliases; *alias; ++alias) {
35860484Sobrien		rpc = getrpcbyname(*alias);
35960484Sobrien
36060484Sobrien		if (rpcent_test_correctness(rpc, NULL) != 0)
36160484Sobrien			goto errfin;
36260484Sobrien
36360484Sobrien		if ((compare_rpcent(rpc, rpc_model, NULL) != 0) &&
36460484Sobrien		    (rpcent_check_ambiguity(
36560484Sobrien		    (struct rpcent_test_data *)mdata, rpc) != 0))
36660484Sobrien		    goto errfin;
36789857Sobrien	}
36860484Sobrien
36960484Sobrien	if (debug)
37060484Sobrien		printf("ok\n");
37160484Sobrien	return (0);
37260484Sobrien
37360484Sobrienerrfin:
37460484Sobrien	if (debug)
37560484Sobrien		printf("not ok\n");
37660484Sobrien
37760484Sobrien	return (-1);
37860484Sobrien}
37960484Sobrien
38060484Sobrienstatic int
38160484Sobrienrpcent_test_getrpcbynumber(struct rpcent *rpc_model, void *mdata)
38260484Sobrien{
38360484Sobrien	struct rpcent *rpc;
38460484Sobrien
38560484Sobrien	if (debug) {
38660484Sobrien		printf("testing getrpcbyport() with the following data...\n");
38760484Sobrien		dump_rpcent(rpc_model);
38860484Sobrien	}
38960484Sobrien
39060484Sobrien	rpc = getrpcbynumber(rpc_model->r_number);
39160484Sobrien	if ((rpcent_test_correctness(rpc, NULL) != 0) ||
39260484Sobrien	    ((compare_rpcent(rpc, rpc_model, NULL) != 0) &&
39360484Sobrien	    (rpcent_check_ambiguity((struct rpcent_test_data *)mdata, rpc)
39460484Sobrien	    != 0))) {
39560484Sobrien	    if (debug)
39660484Sobrien		printf("not ok\n");
39760484Sobrien	    return (-1);
39860484Sobrien	} else {
39960484Sobrien	    if (debug)
40060484Sobrien		printf("ok\n");
40160484Sobrien	    return (0);
40260484Sobrien	}
40360484Sobrien}
40460484Sobrien
40560484Sobrienstatic int
40660484Sobrienrpcent_test_getrpcent(struct rpcent *rpc, void *mdata)
40760484Sobrien{
40860484Sobrien	/* Only correctness can be checked when doing 1-pass test for
40977298Sobrien	 * getrpcent(). */
41060484Sobrien	return (rpcent_test_correctness(rpc, NULL));
41160484Sobrien}
41260484Sobrien
41360484Sobrienstatic void
41460484Sobrienusage(void)
41560484Sobrien{
41660484Sobrien	(void)fprintf(stderr,
41760484Sobrien	    "Usage: %s -nve2 [-d] [-s <file>]\n",
41860484Sobrien	    getprogname());
41960484Sobrien	exit(1);
42060484Sobrien}
42160484Sobrien
42260484Sobrienint
42360484Sobrienmain(int argc, char **argv)
42460484Sobrien{
42560484Sobrien	struct rpcent_test_data td, td_snap, td_2pass;
42660484Sobrien	char *snapshot_file;
42760484Sobrien	int rv;
42860484Sobrien	int c;
42960484Sobrien
43060484Sobrien	if (argc < 2)
43160484Sobrien		usage();
43260484Sobrien
43360484Sobrien	snapshot_file = NULL;
43460484Sobrien	while ((c = getopt(argc, argv, "nve2ds:")) != -1)
43560484Sobrien		switch (c) {
43689857Sobrien		case 'd':
43760484Sobrien			debug++;
43860484Sobrien			break;
43960484Sobrien		case 'n':
44060484Sobrien			method = TEST_GETRPCBYNAME;
44160484Sobrien			break;
44289857Sobrien		case 'v':
44360484Sobrien			method = TEST_GETRPCBYNUMBER;
44460484Sobrien			break;
44560484Sobrien		case 'e':
44660484Sobrien			method = TEST_GETRPCENT;
44760484Sobrien			break;
44860484Sobrien		case '2':
44989857Sobrien			method = TEST_GETRPCENT_2PASS;
45060484Sobrien			break;
45160484Sobrien		case 's':
45260484Sobrien			snapshot_file = strdup(optarg);
45360484Sobrien			break;
45489857Sobrien		default:
45560484Sobrien			usage();
45660484Sobrien		}
45760484Sobrien
45860484Sobrien	TEST_DATA_INIT(rpcent, &td, clone_rpcent, free_rpcent);
45960484Sobrien	TEST_DATA_INIT(rpcent, &td_snap, clone_rpcent, free_rpcent);
46060484Sobrien	if (snapshot_file != NULL) {
46160484Sobrien		if (access(snapshot_file, W_OK | R_OK) != 0) {
46260484Sobrien			if (errno == ENOENT)
46360484Sobrien				method = TEST_BUILD_SNAPSHOT;
46460484Sobrien			else {
46560484Sobrien				if (debug)
46660484Sobrien					printf("can't access the file %s\n",
46760484Sobrien				snapshot_file);
46860484Sobrien
46960484Sobrien				rv = -1;
47060484Sobrien				goto fin;
47160484Sobrien			}
47260484Sobrien		} else {
47360484Sobrien			if (method == TEST_BUILD_SNAPSHOT) {
47460484Sobrien				rv = 0;
47560484Sobrien				goto fin;
47660484Sobrien			}
47760484Sobrien
47860484Sobrien			TEST_SNAPSHOT_FILE_READ(rpcent, snapshot_file,
47960484Sobrien				&td_snap, rpcent_read_snapshot_func);
48060484Sobrien		}
48160484Sobrien	}
48260484Sobrien
48360484Sobrien	rv = rpcent_fill_test_data(&td);
48460484Sobrien	if (rv == -1)
48560484Sobrien		return (-1);
48689857Sobrien	switch (method) {
48789857Sobrien	case TEST_GETRPCBYNAME:
48889857Sobrien		if (snapshot_file == NULL)
48989857Sobrien			rv = DO_1PASS_TEST(rpcent, &td,
49089857Sobrien				rpcent_test_getrpcbyname, (void *)&td);
49189857Sobrien		else
49289857Sobrien			rv = DO_1PASS_TEST(rpcent, &td_snap,
49389857Sobrien				rpcent_test_getrpcbyname, (void *)&td_snap);
49489857Sobrien		break;
49589857Sobrien	case TEST_GETRPCBYNUMBER:
49689857Sobrien		if (snapshot_file == NULL)
49789857Sobrien			rv = DO_1PASS_TEST(rpcent, &td,
49889857Sobrien				rpcent_test_getrpcbynumber, (void *)&td);
49989857Sobrien		else
50089857Sobrien			rv = DO_1PASS_TEST(rpcent, &td_snap,
50189857Sobrien				rpcent_test_getrpcbynumber, (void *)&td_snap);
50289857Sobrien		break;
50389857Sobrien	case TEST_GETRPCENT:
50489857Sobrien		if (snapshot_file == NULL)
50589857Sobrien			rv = DO_1PASS_TEST(rpcent, &td, rpcent_test_getrpcent,
50689857Sobrien				(void *)&td);
50789857Sobrien		else
50889857Sobrien			rv = DO_2PASS_TEST(rpcent, &td, &td_snap,
50989857Sobrien				compare_rpcent, NULL);
51060484Sobrien		break;
51189857Sobrien	case TEST_GETRPCENT_2PASS:
51289857Sobrien			TEST_DATA_INIT(rpcent, &td_2pass, clone_rpcent, free_rpcent);
51389857Sobrien			rv = rpcent_fill_test_data(&td_2pass);
51489857Sobrien			if (rv != -1)
51589857Sobrien				rv = DO_2PASS_TEST(rpcent, &td, &td_2pass,
51689857Sobrien					compare_rpcent, NULL);
51789857Sobrien			TEST_DATA_DESTROY(rpcent, &td_2pass);
51889857Sobrien		break;
51989857Sobrien	case TEST_BUILD_SNAPSHOT:
52060484Sobrien		if (snapshot_file != NULL)
52189857Sobrien		    rv = TEST_SNAPSHOT_FILE_WRITE(rpcent, snapshot_file, &td,
52277298Sobrien			sdump_rpcent);
52389857Sobrien		break;
52489857Sobrien	default:
52560484Sobrien		rv = 0;
52660484Sobrien		break;
52789857Sobrien	};
52889857Sobrien
52989857Sobrienfin:
53089857Sobrien	TEST_DATA_DESTROY(rpcent, &td_snap);
53189857Sobrien	TEST_DATA_DESTROY(rpcent, &td);
53289857Sobrien	free(snapshot_file);
53389857Sobrien	return (rv);
53489857Sobrien}
53589857Sobrien