108ca345cSEnji Cooper /*- 208ca345cSEnji Cooper * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org> 308ca345cSEnji Cooper * All rights reserved. 408ca345cSEnji Cooper * 508ca345cSEnji Cooper * Redistribution and use in source and binary forms, with or without 608ca345cSEnji Cooper * modification, are permitted provided that the following conditions 708ca345cSEnji Cooper * are met: 808ca345cSEnji Cooper * 1. Redistributions of source code must retain the above copyright 908ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer. 1008ca345cSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1108ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer in the 1208ca345cSEnji Cooper * documentation and/or other materials provided with the distribution. 1308ca345cSEnji Cooper * 1408ca345cSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1508ca345cSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1608ca345cSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1708ca345cSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1808ca345cSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1908ca345cSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2008ca345cSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2108ca345cSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2208ca345cSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2308ca345cSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2408ca345cSEnji Cooper * SUCH DAMAGE. 2508ca345cSEnji Cooper * 2608ca345cSEnji Cooper */ 2708ca345cSEnji Cooper 2808ca345cSEnji Cooper #include <sys/cdefs.h> 2908ca345cSEnji Cooper __FBSDID("$FreeBSD$"); 3008ca345cSEnji Cooper 3108ca345cSEnji Cooper #include <arpa/inet.h> 3208ca345cSEnji Cooper #include <errno.h> 3308ca345cSEnji Cooper #include <netdb.h> 3408ca345cSEnji Cooper #include <stdio.h> 3508ca345cSEnji Cooper #include <stdlib.h> 3608ca345cSEnji Cooper #include <string.h> 3708ca345cSEnji Cooper #include <stringlist.h> 3808ca345cSEnji Cooper #include <unistd.h> 3908ca345cSEnji Cooper 4008ca345cSEnji Cooper #include <atf-c.h> 4108ca345cSEnji Cooper 4208ca345cSEnji Cooper #include "testutil.h" 4308ca345cSEnji Cooper 4408ca345cSEnji Cooper enum test_methods { 4508ca345cSEnji Cooper TEST_GETSERVENT, 4608ca345cSEnji Cooper TEST_GETSERVBYNAME, 4708ca345cSEnji Cooper TEST_GETSERVBYPORT, 4808ca345cSEnji Cooper TEST_GETSERVENT_2PASS, 4908ca345cSEnji Cooper TEST_BUILD_SNAPSHOT 5008ca345cSEnji Cooper }; 5108ca345cSEnji Cooper 5208ca345cSEnji Cooper DECLARE_TEST_DATA(servent) 5308ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(servent) 5408ca345cSEnji Cooper DECLARE_1PASS_TEST(servent) 5508ca345cSEnji Cooper DECLARE_2PASS_TEST(servent) 5608ca345cSEnji Cooper 5708ca345cSEnji Cooper static void clone_servent(struct servent *, struct servent const *); 5808ca345cSEnji Cooper static int compare_servent(struct servent *, struct servent *, void *); 5908ca345cSEnji Cooper static void dump_servent(struct servent *); 6008ca345cSEnji Cooper static void free_servent(struct servent *); 6108ca345cSEnji Cooper 6208ca345cSEnji Cooper static void sdump_servent(struct servent *, char *, size_t); 6308ca345cSEnji Cooper static int servent_read_snapshot_func(struct servent *, char *); 6408ca345cSEnji Cooper 6508ca345cSEnji Cooper static int servent_check_ambiguity(struct servent_test_data *, 6608ca345cSEnji Cooper struct servent *); 6708ca345cSEnji Cooper static int servent_fill_test_data(struct servent_test_data *); 6808ca345cSEnji Cooper static int servent_test_correctness(struct servent *, void *); 6908ca345cSEnji Cooper static int servent_test_getservbyname(struct servent *, void *); 7008ca345cSEnji Cooper static int servent_test_getservbyport(struct servent *, void *); 7108ca345cSEnji Cooper static int servent_test_getservent(struct servent *, void *); 7208ca345cSEnji Cooper 7308ca345cSEnji Cooper IMPLEMENT_TEST_DATA(servent) 7408ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(servent) 7508ca345cSEnji Cooper IMPLEMENT_1PASS_TEST(servent) 7608ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(servent) 7708ca345cSEnji Cooper 7808ca345cSEnji Cooper static void 7908ca345cSEnji Cooper clone_servent(struct servent *dest, struct servent const *src) 8008ca345cSEnji Cooper { 8108ca345cSEnji Cooper ATF_REQUIRE(dest != NULL); 8208ca345cSEnji Cooper ATF_REQUIRE(src != NULL); 8308ca345cSEnji Cooper 8408ca345cSEnji Cooper char **cp; 8508ca345cSEnji Cooper int aliases_num; 8608ca345cSEnji Cooper 8708ca345cSEnji Cooper memset(dest, 0, sizeof(struct servent)); 8808ca345cSEnji Cooper 8908ca345cSEnji Cooper if (src->s_name != NULL) { 9008ca345cSEnji Cooper dest->s_name = strdup(src->s_name); 9108ca345cSEnji Cooper ATF_REQUIRE(dest->s_name != NULL); 9208ca345cSEnji Cooper } 9308ca345cSEnji Cooper 9408ca345cSEnji Cooper if (src->s_proto != NULL) { 9508ca345cSEnji Cooper dest->s_proto = strdup(src->s_proto); 9608ca345cSEnji Cooper ATF_REQUIRE(dest->s_proto != NULL); 9708ca345cSEnji Cooper } 9808ca345cSEnji Cooper dest->s_port = src->s_port; 9908ca345cSEnji Cooper 10008ca345cSEnji Cooper if (src->s_aliases != NULL) { 10108ca345cSEnji Cooper aliases_num = 0; 10208ca345cSEnji Cooper for (cp = src->s_aliases; *cp; ++cp) 10308ca345cSEnji Cooper ++aliases_num; 10408ca345cSEnji Cooper 1053bdd6cf0SEnji Cooper dest->s_aliases = calloc(aliases_num + 1, sizeof(char *)); 10608ca345cSEnji Cooper ATF_REQUIRE(dest->s_aliases != NULL); 10708ca345cSEnji Cooper 10808ca345cSEnji Cooper for (cp = src->s_aliases; *cp; ++cp) { 10908ca345cSEnji Cooper dest->s_aliases[cp - src->s_aliases] = strdup(*cp); 11008ca345cSEnji Cooper ATF_REQUIRE(dest->s_aliases[cp - src->s_aliases] != NULL); 11108ca345cSEnji Cooper } 11208ca345cSEnji Cooper } 11308ca345cSEnji Cooper } 11408ca345cSEnji Cooper 11508ca345cSEnji Cooper static void 11608ca345cSEnji Cooper free_servent(struct servent *serv) 11708ca345cSEnji Cooper { 11808ca345cSEnji Cooper char **cp; 11908ca345cSEnji Cooper 12008ca345cSEnji Cooper ATF_REQUIRE(serv != NULL); 12108ca345cSEnji Cooper 12208ca345cSEnji Cooper free(serv->s_name); 12308ca345cSEnji Cooper free(serv->s_proto); 12408ca345cSEnji Cooper 12508ca345cSEnji Cooper for (cp = serv->s_aliases; *cp; ++cp) 12608ca345cSEnji Cooper free(*cp); 12708ca345cSEnji Cooper free(serv->s_aliases); 12808ca345cSEnji Cooper } 12908ca345cSEnji Cooper 13008ca345cSEnji Cooper static int 13108ca345cSEnji Cooper compare_servent(struct servent *serv1, struct servent *serv2, void *mdata) 13208ca345cSEnji Cooper { 13308ca345cSEnji Cooper char **c1, **c2; 13408ca345cSEnji Cooper 13508ca345cSEnji Cooper if (serv1 == serv2) 13608ca345cSEnji Cooper return 0; 13708ca345cSEnji Cooper 13808ca345cSEnji Cooper if ((serv1 == NULL) || (serv2 == NULL)) 13908ca345cSEnji Cooper goto errfin; 14008ca345cSEnji Cooper 14108ca345cSEnji Cooper if ((strcmp(serv1->s_name, serv2->s_name) != 0) || 14208ca345cSEnji Cooper (strcmp(serv1->s_proto, serv2->s_proto) != 0) || 14308ca345cSEnji Cooper (serv1->s_port != serv2->s_port)) 14408ca345cSEnji Cooper goto errfin; 14508ca345cSEnji Cooper 14608ca345cSEnji Cooper c1 = serv1->s_aliases; 14708ca345cSEnji Cooper c2 = serv2->s_aliases; 14808ca345cSEnji Cooper 14908ca345cSEnji Cooper if ((serv1->s_aliases == NULL) || (serv2->s_aliases == NULL)) 15008ca345cSEnji Cooper goto errfin; 15108ca345cSEnji Cooper 15208ca345cSEnji Cooper for (;*c1 && *c2; ++c1, ++c2) 15308ca345cSEnji Cooper if (strcmp(*c1, *c2) != 0) 15408ca345cSEnji Cooper goto errfin; 15508ca345cSEnji Cooper 15608ca345cSEnji Cooper if ((*c1 != '\0') || (*c2 != '\0')) 15708ca345cSEnji Cooper goto errfin; 15808ca345cSEnji Cooper 15908ca345cSEnji Cooper return 0; 16008ca345cSEnji Cooper 16108ca345cSEnji Cooper errfin: 16208ca345cSEnji Cooper if (mdata == NULL) { 16308ca345cSEnji Cooper printf("following structures are not equal:\n"); 16408ca345cSEnji Cooper dump_servent(serv1); 16508ca345cSEnji Cooper dump_servent(serv2); 16608ca345cSEnji Cooper } 16708ca345cSEnji Cooper 16808ca345cSEnji Cooper return (-1); 16908ca345cSEnji Cooper } 17008ca345cSEnji Cooper 17108ca345cSEnji Cooper static void 17208ca345cSEnji Cooper sdump_servent(struct servent *serv, char *buffer, size_t buflen) 17308ca345cSEnji Cooper { 17408ca345cSEnji Cooper char **cp; 17508ca345cSEnji Cooper int written; 17608ca345cSEnji Cooper 17708ca345cSEnji Cooper written = snprintf(buffer, buflen, "%s %d %s", 17808ca345cSEnji Cooper serv->s_name, ntohs(serv->s_port), serv->s_proto); 17908ca345cSEnji Cooper buffer += written; 180*93936a06SEnji Cooper if (written > (int)buflen) 18108ca345cSEnji Cooper return; 18208ca345cSEnji Cooper buflen -= written; 18308ca345cSEnji Cooper 18408ca345cSEnji Cooper if (serv->s_aliases != NULL) { 18508ca345cSEnji Cooper if (*(serv->s_aliases) != '\0') { 18608ca345cSEnji Cooper for (cp = serv->s_aliases; *cp; ++cp) { 18708ca345cSEnji Cooper written = snprintf(buffer, buflen, " %s", *cp); 18808ca345cSEnji Cooper buffer += written; 189*93936a06SEnji Cooper if (written > (int)buflen) 19008ca345cSEnji Cooper return; 19108ca345cSEnji Cooper buflen -= written; 19208ca345cSEnji Cooper 19308ca345cSEnji Cooper if (buflen == 0) 19408ca345cSEnji Cooper return; 19508ca345cSEnji Cooper } 19608ca345cSEnji Cooper } else 19708ca345cSEnji Cooper snprintf(buffer, buflen, " noaliases"); 19808ca345cSEnji Cooper } else 19908ca345cSEnji Cooper snprintf(buffer, buflen, " (null)"); 20008ca345cSEnji Cooper } 20108ca345cSEnji Cooper 20208ca345cSEnji Cooper static int 20308ca345cSEnji Cooper servent_read_snapshot_func(struct servent *serv, char *line) 20408ca345cSEnji Cooper { 20508ca345cSEnji Cooper StringList *sl; 20608ca345cSEnji Cooper char *s, *ps, *ts; 20708ca345cSEnji Cooper int i; 20808ca345cSEnji Cooper 20908ca345cSEnji Cooper printf("1 line read from snapshot:\n%s\n", line); 21008ca345cSEnji Cooper 21108ca345cSEnji Cooper i = 0; 21208ca345cSEnji Cooper sl = NULL; 21308ca345cSEnji Cooper ps = line; 21408ca345cSEnji Cooper memset(serv, 0, sizeof(struct servent)); 21508ca345cSEnji Cooper while ( (s = strsep(&ps, " ")) != NULL) { 21608ca345cSEnji Cooper switch (i) { 21708ca345cSEnji Cooper case 0: 21808ca345cSEnji Cooper serv->s_name = strdup(s); 21908ca345cSEnji Cooper ATF_REQUIRE(serv->s_name != NULL); 22008ca345cSEnji Cooper break; 22108ca345cSEnji Cooper 22208ca345cSEnji Cooper case 1: 22308ca345cSEnji Cooper serv->s_port = htons( 22408ca345cSEnji Cooper (int)strtol(s, &ts, 10)); 22508ca345cSEnji Cooper if (*ts != '\0') { 22608ca345cSEnji Cooper free(serv->s_name); 22708ca345cSEnji Cooper return (-1); 22808ca345cSEnji Cooper } 22908ca345cSEnji Cooper break; 23008ca345cSEnji Cooper 23108ca345cSEnji Cooper case 2: 23208ca345cSEnji Cooper serv->s_proto = strdup(s); 23308ca345cSEnji Cooper ATF_REQUIRE(serv->s_proto != NULL); 23408ca345cSEnji Cooper break; 23508ca345cSEnji Cooper 23608ca345cSEnji Cooper default: 23708ca345cSEnji Cooper if (sl == NULL) { 23808ca345cSEnji Cooper if (strcmp(s, "(null)") == 0) 23908ca345cSEnji Cooper return (0); 24008ca345cSEnji Cooper 24108ca345cSEnji Cooper sl = sl_init(); 24208ca345cSEnji Cooper ATF_REQUIRE(sl != NULL); 24308ca345cSEnji Cooper 24408ca345cSEnji Cooper if (strcmp(s, "noaliases") != 0) { 24508ca345cSEnji Cooper ts = strdup(s); 24608ca345cSEnji Cooper ATF_REQUIRE(ts != NULL); 24708ca345cSEnji Cooper sl_add(sl, ts); 24808ca345cSEnji Cooper } 24908ca345cSEnji Cooper } else { 25008ca345cSEnji Cooper ts = strdup(s); 25108ca345cSEnji Cooper ATF_REQUIRE(ts != NULL); 25208ca345cSEnji Cooper sl_add(sl, ts); 25308ca345cSEnji Cooper } 25408ca345cSEnji Cooper break; 25508ca345cSEnji Cooper } 25608ca345cSEnji Cooper ++i; 25708ca345cSEnji Cooper } 25808ca345cSEnji Cooper 25908ca345cSEnji Cooper if (i < 3) { 26008ca345cSEnji Cooper free(serv->s_name); 26108ca345cSEnji Cooper free(serv->s_proto); 26208ca345cSEnji Cooper memset(serv, 0, sizeof(struct servent)); 26308ca345cSEnji Cooper return (-1); 26408ca345cSEnji Cooper } 26508ca345cSEnji Cooper 26608ca345cSEnji Cooper sl_add(sl, NULL); 26708ca345cSEnji Cooper serv->s_aliases = sl->sl_str; 26808ca345cSEnji Cooper 26908ca345cSEnji Cooper /* NOTE: is it a dirty hack or not? */ 27008ca345cSEnji Cooper free(sl); 27108ca345cSEnji Cooper return (0); 27208ca345cSEnji Cooper } 27308ca345cSEnji Cooper 27408ca345cSEnji Cooper static void 27508ca345cSEnji Cooper dump_servent(struct servent *result) 27608ca345cSEnji Cooper { 27708ca345cSEnji Cooper if (result != NULL) { 27808ca345cSEnji Cooper char buffer[1024]; 27908ca345cSEnji Cooper sdump_servent(result, buffer, sizeof(buffer)); 28008ca345cSEnji Cooper printf("%s\n", buffer); 28108ca345cSEnji Cooper } else 28208ca345cSEnji Cooper printf("(null)\n"); 28308ca345cSEnji Cooper } 28408ca345cSEnji Cooper 28508ca345cSEnji Cooper static int 28608ca345cSEnji Cooper servent_fill_test_data(struct servent_test_data *td) 28708ca345cSEnji Cooper { 28808ca345cSEnji Cooper struct servent *serv; 28908ca345cSEnji Cooper 29008ca345cSEnji Cooper setservent(1); 29108ca345cSEnji Cooper while ((serv = getservent()) != NULL) { 29208ca345cSEnji Cooper if (servent_test_correctness(serv, NULL) == 0) 29308ca345cSEnji Cooper TEST_DATA_APPEND(servent, td, serv); 29408ca345cSEnji Cooper else 29508ca345cSEnji Cooper return (-1); 29608ca345cSEnji Cooper } 29708ca345cSEnji Cooper endservent(); 29808ca345cSEnji Cooper 29908ca345cSEnji Cooper return (0); 30008ca345cSEnji Cooper } 30108ca345cSEnji Cooper 30208ca345cSEnji Cooper static int 30308ca345cSEnji Cooper servent_test_correctness(struct servent *serv, void *mdata) 30408ca345cSEnji Cooper { 30508ca345cSEnji Cooper printf("testing correctness with the following data:\n"); 30608ca345cSEnji Cooper dump_servent(serv); 30708ca345cSEnji Cooper 30808ca345cSEnji Cooper if (serv == NULL) 30908ca345cSEnji Cooper goto errfin; 31008ca345cSEnji Cooper 31108ca345cSEnji Cooper if (serv->s_name == NULL) 31208ca345cSEnji Cooper goto errfin; 31308ca345cSEnji Cooper 31408ca345cSEnji Cooper if (serv->s_proto == NULL) 31508ca345cSEnji Cooper goto errfin; 31608ca345cSEnji Cooper 31708ca345cSEnji Cooper if (ntohs(serv->s_port < 0)) 31808ca345cSEnji Cooper goto errfin; 31908ca345cSEnji Cooper 32008ca345cSEnji Cooper if (serv->s_aliases == NULL) 32108ca345cSEnji Cooper goto errfin; 32208ca345cSEnji Cooper 32308ca345cSEnji Cooper printf("correct\n"); 32408ca345cSEnji Cooper 32508ca345cSEnji Cooper return (0); 32608ca345cSEnji Cooper errfin: 32708ca345cSEnji Cooper printf("incorrect\n"); 32808ca345cSEnji Cooper 32908ca345cSEnji Cooper return (-1); 33008ca345cSEnji Cooper } 33108ca345cSEnji Cooper 33208ca345cSEnji Cooper /* servent_check_ambiguity() is needed when one port+proto is associated with 33308ca345cSEnji Cooper * more than one service (these cases are usually marked as PROBLEM in 33408ca345cSEnji Cooper * /etc/services. This functions is needed also when one service+proto is 33508ca345cSEnji Cooper * associated with several ports. We have to check all the servent structures 33608ca345cSEnji Cooper * to make sure that serv really exists and correct */ 33708ca345cSEnji Cooper static int 33808ca345cSEnji Cooper servent_check_ambiguity(struct servent_test_data *td, struct servent *serv) 33908ca345cSEnji Cooper { 34008ca345cSEnji Cooper 34108ca345cSEnji Cooper return (TEST_DATA_FIND(servent, td, serv, compare_servent, 34208ca345cSEnji Cooper NULL) != NULL ? 0 : -1); 34308ca345cSEnji Cooper } 34408ca345cSEnji Cooper 34508ca345cSEnji Cooper static int 34608ca345cSEnji Cooper servent_test_getservbyname(struct servent *serv_model, void *mdata) 34708ca345cSEnji Cooper { 34808ca345cSEnji Cooper char **alias; 34908ca345cSEnji Cooper struct servent *serv; 35008ca345cSEnji Cooper 35108ca345cSEnji Cooper printf("testing getservbyname() with the following data:\n"); 35208ca345cSEnji Cooper dump_servent(serv_model); 35308ca345cSEnji Cooper 35408ca345cSEnji Cooper serv = getservbyname(serv_model->s_name, serv_model->s_proto); 35508ca345cSEnji Cooper if (servent_test_correctness(serv, NULL) != 0) 35608ca345cSEnji Cooper goto errfin; 35708ca345cSEnji Cooper 35808ca345cSEnji Cooper if ((compare_servent(serv, serv_model, NULL) != 0) && 35908ca345cSEnji Cooper (servent_check_ambiguity((struct servent_test_data *)mdata, serv) 36008ca345cSEnji Cooper !=0)) 36108ca345cSEnji Cooper goto errfin; 36208ca345cSEnji Cooper 36308ca345cSEnji Cooper for (alias = serv_model->s_aliases; *alias; ++alias) { 36408ca345cSEnji Cooper serv = getservbyname(*alias, serv_model->s_proto); 36508ca345cSEnji Cooper 36608ca345cSEnji Cooper if (servent_test_correctness(serv, NULL) != 0) 36708ca345cSEnji Cooper goto errfin; 36808ca345cSEnji Cooper 36908ca345cSEnji Cooper if ((compare_servent(serv, serv_model, NULL) != 0) && 37008ca345cSEnji Cooper (servent_check_ambiguity( 37108ca345cSEnji Cooper (struct servent_test_data *)mdata, serv) != 0)) 37208ca345cSEnji Cooper goto errfin; 37308ca345cSEnji Cooper } 37408ca345cSEnji Cooper 37508ca345cSEnji Cooper printf("ok\n"); 37608ca345cSEnji Cooper return (0); 37708ca345cSEnji Cooper 37808ca345cSEnji Cooper errfin: 37908ca345cSEnji Cooper printf("not ok\n"); 38008ca345cSEnji Cooper 38108ca345cSEnji Cooper return (-1); 38208ca345cSEnji Cooper } 38308ca345cSEnji Cooper 38408ca345cSEnji Cooper static int 38508ca345cSEnji Cooper servent_test_getservbyport(struct servent *serv_model, void *mdata) 38608ca345cSEnji Cooper { 38708ca345cSEnji Cooper struct servent *serv; 38808ca345cSEnji Cooper 38908ca345cSEnji Cooper printf("testing getservbyport() with the following data...\n"); 39008ca345cSEnji Cooper dump_servent(serv_model); 39108ca345cSEnji Cooper 39208ca345cSEnji Cooper serv = getservbyport(serv_model->s_port, serv_model->s_proto); 39308ca345cSEnji Cooper if ((servent_test_correctness(serv, NULL) != 0) || 39408ca345cSEnji Cooper ((compare_servent(serv, serv_model, NULL) != 0) && 39508ca345cSEnji Cooper (servent_check_ambiguity((struct servent_test_data *)mdata, serv) 39608ca345cSEnji Cooper != 0))) { 39708ca345cSEnji Cooper printf("not ok\n"); 39808ca345cSEnji Cooper return (-1); 39908ca345cSEnji Cooper } else { 40008ca345cSEnji Cooper printf("ok\n"); 40108ca345cSEnji Cooper return (0); 40208ca345cSEnji Cooper } 40308ca345cSEnji Cooper } 40408ca345cSEnji Cooper 40508ca345cSEnji Cooper static int 40608ca345cSEnji Cooper servent_test_getservent(struct servent *serv, void *mdata) 40708ca345cSEnji Cooper { 40808ca345cSEnji Cooper /* Only correctness can be checked when doing 1-pass test for 40908ca345cSEnji Cooper * getservent(). */ 41008ca345cSEnji Cooper return (servent_test_correctness(serv, NULL)); 41108ca345cSEnji Cooper } 41208ca345cSEnji Cooper 413*93936a06SEnji Cooper static int 41408ca345cSEnji Cooper run_tests(const char *snapshot_file, enum test_methods method) 41508ca345cSEnji Cooper { 41608ca345cSEnji Cooper struct servent_test_data td, td_snap, td_2pass; 41708ca345cSEnji Cooper int rv; 41808ca345cSEnji Cooper 41908ca345cSEnji Cooper TEST_DATA_INIT(servent, &td, clone_servent, free_servent); 42008ca345cSEnji Cooper TEST_DATA_INIT(servent, &td_snap, clone_servent, free_servent); 42108ca345cSEnji Cooper if (snapshot_file != NULL) { 42208ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 42308ca345cSEnji Cooper if (errno == ENOENT) 42408ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 42508ca345cSEnji Cooper else { 42608ca345cSEnji Cooper printf("can't access the file %s\n", 42708ca345cSEnji Cooper snapshot_file); 42808ca345cSEnji Cooper 42908ca345cSEnji Cooper rv = -1; 43008ca345cSEnji Cooper goto fin; 43108ca345cSEnji Cooper } 43208ca345cSEnji Cooper } else { 43308ca345cSEnji Cooper if (method == TEST_BUILD_SNAPSHOT) { 43408ca345cSEnji Cooper rv = 0; 43508ca345cSEnji Cooper goto fin; 43608ca345cSEnji Cooper } 43708ca345cSEnji Cooper 43808ca345cSEnji Cooper TEST_SNAPSHOT_FILE_READ(servent, snapshot_file, 43908ca345cSEnji Cooper &td_snap, servent_read_snapshot_func); 44008ca345cSEnji Cooper } 44108ca345cSEnji Cooper } 44208ca345cSEnji Cooper 44308ca345cSEnji Cooper rv = servent_fill_test_data(&td); 44408ca345cSEnji Cooper if (rv == -1) 44508ca345cSEnji Cooper return (-1); 44608ca345cSEnji Cooper switch (method) { 44708ca345cSEnji Cooper case TEST_GETSERVBYNAME: 44808ca345cSEnji Cooper if (snapshot_file == NULL) 44908ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td, 45008ca345cSEnji Cooper servent_test_getservbyname, (void *)&td); 45108ca345cSEnji Cooper else 45208ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td_snap, 45308ca345cSEnji Cooper servent_test_getservbyname, (void *)&td_snap); 45408ca345cSEnji Cooper break; 45508ca345cSEnji Cooper case TEST_GETSERVBYPORT: 45608ca345cSEnji Cooper if (snapshot_file == NULL) 45708ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td, 45808ca345cSEnji Cooper servent_test_getservbyport, (void *)&td); 45908ca345cSEnji Cooper else 46008ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td_snap, 46108ca345cSEnji Cooper servent_test_getservbyport, (void *)&td_snap); 46208ca345cSEnji Cooper break; 46308ca345cSEnji Cooper case TEST_GETSERVENT: 46408ca345cSEnji Cooper if (snapshot_file == NULL) 46508ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td, servent_test_getservent, 46608ca345cSEnji Cooper (void *)&td); 46708ca345cSEnji Cooper else 46808ca345cSEnji Cooper rv = DO_2PASS_TEST(servent, &td, &td_snap, 46908ca345cSEnji Cooper compare_servent, NULL); 47008ca345cSEnji Cooper break; 47108ca345cSEnji Cooper case TEST_GETSERVENT_2PASS: 47208ca345cSEnji Cooper TEST_DATA_INIT(servent, &td_2pass, clone_servent, free_servent); 47308ca345cSEnji Cooper rv = servent_fill_test_data(&td_2pass); 47408ca345cSEnji Cooper if (rv != -1) 47508ca345cSEnji Cooper rv = DO_2PASS_TEST(servent, &td, &td_2pass, 47608ca345cSEnji Cooper compare_servent, NULL); 47708ca345cSEnji Cooper TEST_DATA_DESTROY(servent, &td_2pass); 47808ca345cSEnji Cooper break; 47908ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 48008ca345cSEnji Cooper if (snapshot_file != NULL) 48108ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_WRITE(servent, snapshot_file, &td, 48208ca345cSEnji Cooper sdump_servent); 48308ca345cSEnji Cooper break; 48408ca345cSEnji Cooper default: 48508ca345cSEnji Cooper rv = 0; 48608ca345cSEnji Cooper break; 48708ca345cSEnji Cooper } 48808ca345cSEnji Cooper 48908ca345cSEnji Cooper fin: 49008ca345cSEnji Cooper TEST_DATA_DESTROY(servent, &td_snap); 49108ca345cSEnji Cooper TEST_DATA_DESTROY(servent, &td); 49208ca345cSEnji Cooper 49308ca345cSEnji Cooper return (rv); 49408ca345cSEnji Cooper } 49508ca345cSEnji Cooper 49608ca345cSEnji Cooper #define SNAPSHOT_FILE "snapshot_serv" 49708ca345cSEnji Cooper 49808ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(build_snapshot); 49908ca345cSEnji Cooper ATF_TC_BODY(build_snapshot, tc) 50008ca345cSEnji Cooper { 50108ca345cSEnji Cooper 50208ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 50308ca345cSEnji Cooper } 50408ca345cSEnji Cooper 50508ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyname); 50608ca345cSEnji Cooper ATF_TC_BODY(getservbyname, tc) 50708ca345cSEnji Cooper { 50808ca345cSEnji Cooper 50908ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETSERVBYNAME) == 0); 51008ca345cSEnji Cooper } 51108ca345cSEnji Cooper 51208ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyname_with_snapshot); 51308ca345cSEnji Cooper ATF_TC_BODY(getservbyname_with_snapshot, tc) 51408ca345cSEnji Cooper { 51508ca345cSEnji Cooper 51608ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 51708ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVBYNAME) == 0); 51808ca345cSEnji Cooper } 51908ca345cSEnji Cooper 52008ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyport); 52108ca345cSEnji Cooper ATF_TC_BODY(getservbyport, tc) 52208ca345cSEnji Cooper { 52308ca345cSEnji Cooper 52408ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETSERVBYPORT) == 0); 52508ca345cSEnji Cooper } 52608ca345cSEnji Cooper 52708ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyport_with_snapshot); 52808ca345cSEnji Cooper ATF_TC_BODY(getservbyport_with_snapshot, tc) 52908ca345cSEnji Cooper { 53008ca345cSEnji Cooper 53108ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 53208ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVBYPORT) == 0); 53308ca345cSEnji Cooper } 53408ca345cSEnji Cooper 53508ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyent); 53608ca345cSEnji Cooper ATF_TC_BODY(getservbyent, tc) 53708ca345cSEnji Cooper { 53808ca345cSEnji Cooper 53908ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETSERVENT) == 0); 54008ca345cSEnji Cooper } 54108ca345cSEnji Cooper 54208ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyent_with_snapshot); 54308ca345cSEnji Cooper ATF_TC_BODY(getservbyent_with_snapshot, tc) 54408ca345cSEnji Cooper { 54508ca345cSEnji Cooper 54608ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 54708ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVENT) == 0); 54808ca345cSEnji Cooper } 54908ca345cSEnji Cooper 55008ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyent_with_two_pass); 55108ca345cSEnji Cooper ATF_TC_BODY(getservbyent_with_two_pass, tc) 55208ca345cSEnji Cooper { 55308ca345cSEnji Cooper 55408ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETSERVENT_2PASS) == 0); 55508ca345cSEnji Cooper } 55608ca345cSEnji Cooper 55708ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 55808ca345cSEnji Cooper { 55908ca345cSEnji Cooper 56008ca345cSEnji Cooper ATF_TP_ADD_TC(tp, build_snapshot); 56108ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyent); 56208ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyent_with_snapshot); 56308ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyent_with_two_pass); 56408ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyname); 56508ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyname_with_snapshot); 56608ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyport); 56708ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyport_with_snapshot); 56808ca345cSEnji Cooper 56908ca345cSEnji Cooper return (atf_no_error()); 57008ca345cSEnji Cooper } 571