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