1*08ca345cSEnji Cooper /*- 2*08ca345cSEnji Cooper * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org> 3*08ca345cSEnji Cooper * All rights reserved. 4*08ca345cSEnji Cooper * 5*08ca345cSEnji Cooper * Redistribution and use in source and binary forms, with or without 6*08ca345cSEnji Cooper * modification, are permitted provided that the following conditions 7*08ca345cSEnji Cooper * are met: 8*08ca345cSEnji Cooper * 1. Redistributions of source code must retain the above copyright 9*08ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer. 10*08ca345cSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 11*08ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer in the 12*08ca345cSEnji Cooper * documentation and/or other materials provided with the distribution. 13*08ca345cSEnji Cooper * 14*08ca345cSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*08ca345cSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*08ca345cSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*08ca345cSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*08ca345cSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*08ca345cSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*08ca345cSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*08ca345cSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*08ca345cSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*08ca345cSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*08ca345cSEnji Cooper * SUCH DAMAGE. 25*08ca345cSEnji Cooper * 26*08ca345cSEnji Cooper */ 27*08ca345cSEnji Cooper 28*08ca345cSEnji Cooper #include <sys/cdefs.h> 29*08ca345cSEnji Cooper __FBSDID("$FreeBSD$"); 30*08ca345cSEnji Cooper 31*08ca345cSEnji Cooper #include <arpa/inet.h> 32*08ca345cSEnji Cooper #include <errno.h> 33*08ca345cSEnji Cooper #include <netdb.h> 34*08ca345cSEnji Cooper #include <stdio.h> 35*08ca345cSEnji Cooper #include <stdlib.h> 36*08ca345cSEnji Cooper #include <string.h> 37*08ca345cSEnji Cooper #include <stringlist.h> 38*08ca345cSEnji Cooper #include <unistd.h> 39*08ca345cSEnji Cooper 40*08ca345cSEnji Cooper #include <atf-c.h> 41*08ca345cSEnji Cooper 42*08ca345cSEnji Cooper #include "testutil.h" 43*08ca345cSEnji Cooper 44*08ca345cSEnji Cooper enum test_methods { 45*08ca345cSEnji Cooper TEST_GETSERVENT, 46*08ca345cSEnji Cooper TEST_GETSERVBYNAME, 47*08ca345cSEnji Cooper TEST_GETSERVBYPORT, 48*08ca345cSEnji Cooper TEST_GETSERVENT_2PASS, 49*08ca345cSEnji Cooper TEST_BUILD_SNAPSHOT 50*08ca345cSEnji Cooper }; 51*08ca345cSEnji Cooper 52*08ca345cSEnji Cooper DECLARE_TEST_DATA(servent) 53*08ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(servent) 54*08ca345cSEnji Cooper DECLARE_1PASS_TEST(servent) 55*08ca345cSEnji Cooper DECLARE_2PASS_TEST(servent) 56*08ca345cSEnji Cooper 57*08ca345cSEnji Cooper static void clone_servent(struct servent *, struct servent const *); 58*08ca345cSEnji Cooper static int compare_servent(struct servent *, struct servent *, void *); 59*08ca345cSEnji Cooper static void dump_servent(struct servent *); 60*08ca345cSEnji Cooper static void free_servent(struct servent *); 61*08ca345cSEnji Cooper 62*08ca345cSEnji Cooper static void sdump_servent(struct servent *, char *, size_t); 63*08ca345cSEnji Cooper static int servent_read_snapshot_func(struct servent *, char *); 64*08ca345cSEnji Cooper 65*08ca345cSEnji Cooper static int servent_check_ambiguity(struct servent_test_data *, 66*08ca345cSEnji Cooper struct servent *); 67*08ca345cSEnji Cooper static int servent_fill_test_data(struct servent_test_data *); 68*08ca345cSEnji Cooper static int servent_test_correctness(struct servent *, void *); 69*08ca345cSEnji Cooper static int servent_test_getservbyname(struct servent *, void *); 70*08ca345cSEnji Cooper static int servent_test_getservbyport(struct servent *, void *); 71*08ca345cSEnji Cooper static int servent_test_getservent(struct servent *, void *); 72*08ca345cSEnji Cooper 73*08ca345cSEnji Cooper IMPLEMENT_TEST_DATA(servent) 74*08ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(servent) 75*08ca345cSEnji Cooper IMPLEMENT_1PASS_TEST(servent) 76*08ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(servent) 77*08ca345cSEnji Cooper 78*08ca345cSEnji Cooper static void 79*08ca345cSEnji Cooper clone_servent(struct servent *dest, struct servent const *src) 80*08ca345cSEnji Cooper { 81*08ca345cSEnji Cooper ATF_REQUIRE(dest != NULL); 82*08ca345cSEnji Cooper ATF_REQUIRE(src != NULL); 83*08ca345cSEnji Cooper 84*08ca345cSEnji Cooper char **cp; 85*08ca345cSEnji Cooper int aliases_num; 86*08ca345cSEnji Cooper 87*08ca345cSEnji Cooper memset(dest, 0, sizeof(struct servent)); 88*08ca345cSEnji Cooper 89*08ca345cSEnji Cooper if (src->s_name != NULL) { 90*08ca345cSEnji Cooper dest->s_name = strdup(src->s_name); 91*08ca345cSEnji Cooper ATF_REQUIRE(dest->s_name != NULL); 92*08ca345cSEnji Cooper } 93*08ca345cSEnji Cooper 94*08ca345cSEnji Cooper if (src->s_proto != NULL) { 95*08ca345cSEnji Cooper dest->s_proto = strdup(src->s_proto); 96*08ca345cSEnji Cooper ATF_REQUIRE(dest->s_proto != NULL); 97*08ca345cSEnji Cooper } 98*08ca345cSEnji Cooper dest->s_port = src->s_port; 99*08ca345cSEnji Cooper 100*08ca345cSEnji Cooper if (src->s_aliases != NULL) { 101*08ca345cSEnji Cooper aliases_num = 0; 102*08ca345cSEnji Cooper for (cp = src->s_aliases; *cp; ++cp) 103*08ca345cSEnji Cooper ++aliases_num; 104*08ca345cSEnji Cooper 105*08ca345cSEnji Cooper dest->s_aliases = calloc(1, (aliases_num + 1) * sizeof(char *)); 106*08ca345cSEnji Cooper ATF_REQUIRE(dest->s_aliases != NULL); 107*08ca345cSEnji Cooper 108*08ca345cSEnji Cooper for (cp = src->s_aliases; *cp; ++cp) { 109*08ca345cSEnji Cooper dest->s_aliases[cp - src->s_aliases] = strdup(*cp); 110*08ca345cSEnji Cooper ATF_REQUIRE(dest->s_aliases[cp - src->s_aliases] != NULL); 111*08ca345cSEnji Cooper } 112*08ca345cSEnji Cooper } 113*08ca345cSEnji Cooper } 114*08ca345cSEnji Cooper 115*08ca345cSEnji Cooper static void 116*08ca345cSEnji Cooper free_servent(struct servent *serv) 117*08ca345cSEnji Cooper { 118*08ca345cSEnji Cooper char **cp; 119*08ca345cSEnji Cooper 120*08ca345cSEnji Cooper ATF_REQUIRE(serv != NULL); 121*08ca345cSEnji Cooper 122*08ca345cSEnji Cooper free(serv->s_name); 123*08ca345cSEnji Cooper free(serv->s_proto); 124*08ca345cSEnji Cooper 125*08ca345cSEnji Cooper for (cp = serv->s_aliases; *cp; ++cp) 126*08ca345cSEnji Cooper free(*cp); 127*08ca345cSEnji Cooper free(serv->s_aliases); 128*08ca345cSEnji Cooper } 129*08ca345cSEnji Cooper 130*08ca345cSEnji Cooper static int 131*08ca345cSEnji Cooper compare_servent(struct servent *serv1, struct servent *serv2, void *mdata) 132*08ca345cSEnji Cooper { 133*08ca345cSEnji Cooper char **c1, **c2; 134*08ca345cSEnji Cooper 135*08ca345cSEnji Cooper if (serv1 == serv2) 136*08ca345cSEnji Cooper return 0; 137*08ca345cSEnji Cooper 138*08ca345cSEnji Cooper if ((serv1 == NULL) || (serv2 == NULL)) 139*08ca345cSEnji Cooper goto errfin; 140*08ca345cSEnji Cooper 141*08ca345cSEnji Cooper if ((strcmp(serv1->s_name, serv2->s_name) != 0) || 142*08ca345cSEnji Cooper (strcmp(serv1->s_proto, serv2->s_proto) != 0) || 143*08ca345cSEnji Cooper (serv1->s_port != serv2->s_port)) 144*08ca345cSEnji Cooper goto errfin; 145*08ca345cSEnji Cooper 146*08ca345cSEnji Cooper c1 = serv1->s_aliases; 147*08ca345cSEnji Cooper c2 = serv2->s_aliases; 148*08ca345cSEnji Cooper 149*08ca345cSEnji Cooper if ((serv1->s_aliases == NULL) || (serv2->s_aliases == NULL)) 150*08ca345cSEnji Cooper goto errfin; 151*08ca345cSEnji Cooper 152*08ca345cSEnji Cooper for (;*c1 && *c2; ++c1, ++c2) 153*08ca345cSEnji Cooper if (strcmp(*c1, *c2) != 0) 154*08ca345cSEnji Cooper goto errfin; 155*08ca345cSEnji Cooper 156*08ca345cSEnji Cooper if ((*c1 != '\0') || (*c2 != '\0')) 157*08ca345cSEnji Cooper goto errfin; 158*08ca345cSEnji Cooper 159*08ca345cSEnji Cooper return 0; 160*08ca345cSEnji Cooper 161*08ca345cSEnji Cooper errfin: 162*08ca345cSEnji Cooper if (mdata == NULL) { 163*08ca345cSEnji Cooper printf("following structures are not equal:\n"); 164*08ca345cSEnji Cooper dump_servent(serv1); 165*08ca345cSEnji Cooper dump_servent(serv2); 166*08ca345cSEnji Cooper } 167*08ca345cSEnji Cooper 168*08ca345cSEnji Cooper return (-1); 169*08ca345cSEnji Cooper } 170*08ca345cSEnji Cooper 171*08ca345cSEnji Cooper static void 172*08ca345cSEnji Cooper sdump_servent(struct servent *serv, char *buffer, size_t buflen) 173*08ca345cSEnji Cooper { 174*08ca345cSEnji Cooper char **cp; 175*08ca345cSEnji Cooper int written; 176*08ca345cSEnji Cooper 177*08ca345cSEnji Cooper written = snprintf(buffer, buflen, "%s %d %s", 178*08ca345cSEnji Cooper serv->s_name, ntohs(serv->s_port), serv->s_proto); 179*08ca345cSEnji Cooper buffer += written; 180*08ca345cSEnji Cooper if (written > buflen) 181*08ca345cSEnji Cooper return; 182*08ca345cSEnji Cooper buflen -= written; 183*08ca345cSEnji Cooper 184*08ca345cSEnji Cooper if (serv->s_aliases != NULL) { 185*08ca345cSEnji Cooper if (*(serv->s_aliases) != '\0') { 186*08ca345cSEnji Cooper for (cp = serv->s_aliases; *cp; ++cp) { 187*08ca345cSEnji Cooper written = snprintf(buffer, buflen, " %s",*cp); 188*08ca345cSEnji Cooper buffer += written; 189*08ca345cSEnji Cooper if (written > buflen) 190*08ca345cSEnji Cooper return; 191*08ca345cSEnji Cooper buflen -= written; 192*08ca345cSEnji Cooper 193*08ca345cSEnji Cooper if (buflen == 0) 194*08ca345cSEnji Cooper return; 195*08ca345cSEnji Cooper } 196*08ca345cSEnji Cooper } else 197*08ca345cSEnji Cooper snprintf(buffer, buflen, " noaliases"); 198*08ca345cSEnji Cooper } else 199*08ca345cSEnji Cooper snprintf(buffer, buflen, " (null)"); 200*08ca345cSEnji Cooper } 201*08ca345cSEnji Cooper 202*08ca345cSEnji Cooper static int 203*08ca345cSEnji Cooper servent_read_snapshot_func(struct servent *serv, char *line) 204*08ca345cSEnji Cooper { 205*08ca345cSEnji Cooper StringList *sl; 206*08ca345cSEnji Cooper char *s, *ps, *ts; 207*08ca345cSEnji Cooper int i; 208*08ca345cSEnji Cooper 209*08ca345cSEnji Cooper printf("1 line read from snapshot:\n%s\n", line); 210*08ca345cSEnji Cooper 211*08ca345cSEnji Cooper i = 0; 212*08ca345cSEnji Cooper sl = NULL; 213*08ca345cSEnji Cooper ps = line; 214*08ca345cSEnji Cooper memset(serv, 0, sizeof(struct servent)); 215*08ca345cSEnji Cooper while ( (s = strsep(&ps, " ")) != NULL) { 216*08ca345cSEnji Cooper switch (i) { 217*08ca345cSEnji Cooper case 0: 218*08ca345cSEnji Cooper serv->s_name = strdup(s); 219*08ca345cSEnji Cooper ATF_REQUIRE(serv->s_name != NULL); 220*08ca345cSEnji Cooper break; 221*08ca345cSEnji Cooper 222*08ca345cSEnji Cooper case 1: 223*08ca345cSEnji Cooper serv->s_port = htons( 224*08ca345cSEnji Cooper (int)strtol(s, &ts, 10)); 225*08ca345cSEnji Cooper if (*ts != '\0') { 226*08ca345cSEnji Cooper free(serv->s_name); 227*08ca345cSEnji Cooper return (-1); 228*08ca345cSEnji Cooper } 229*08ca345cSEnji Cooper break; 230*08ca345cSEnji Cooper 231*08ca345cSEnji Cooper case 2: 232*08ca345cSEnji Cooper serv->s_proto = strdup(s); 233*08ca345cSEnji Cooper ATF_REQUIRE(serv->s_proto != NULL); 234*08ca345cSEnji Cooper break; 235*08ca345cSEnji Cooper 236*08ca345cSEnji Cooper default: 237*08ca345cSEnji Cooper if (sl == NULL) { 238*08ca345cSEnji Cooper if (strcmp(s, "(null)") == 0) 239*08ca345cSEnji Cooper return (0); 240*08ca345cSEnji Cooper 241*08ca345cSEnji Cooper sl = sl_init(); 242*08ca345cSEnji Cooper ATF_REQUIRE(sl != NULL); 243*08ca345cSEnji Cooper 244*08ca345cSEnji Cooper if (strcmp(s, "noaliases") != 0) { 245*08ca345cSEnji Cooper ts = strdup(s); 246*08ca345cSEnji Cooper ATF_REQUIRE(ts != NULL); 247*08ca345cSEnji Cooper sl_add(sl, ts); 248*08ca345cSEnji Cooper } 249*08ca345cSEnji Cooper } else { 250*08ca345cSEnji Cooper ts = strdup(s); 251*08ca345cSEnji Cooper ATF_REQUIRE(ts != NULL); 252*08ca345cSEnji Cooper sl_add(sl, ts); 253*08ca345cSEnji Cooper } 254*08ca345cSEnji Cooper break; 255*08ca345cSEnji Cooper } 256*08ca345cSEnji Cooper ++i; 257*08ca345cSEnji Cooper } 258*08ca345cSEnji Cooper 259*08ca345cSEnji Cooper if (i < 3) { 260*08ca345cSEnji Cooper free(serv->s_name); 261*08ca345cSEnji Cooper free(serv->s_proto); 262*08ca345cSEnji Cooper memset(serv, 0, sizeof(struct servent)); 263*08ca345cSEnji Cooper return (-1); 264*08ca345cSEnji Cooper } 265*08ca345cSEnji Cooper 266*08ca345cSEnji Cooper sl_add(sl, NULL); 267*08ca345cSEnji Cooper serv->s_aliases = sl->sl_str; 268*08ca345cSEnji Cooper 269*08ca345cSEnji Cooper /* NOTE: is it a dirty hack or not? */ 270*08ca345cSEnji Cooper free(sl); 271*08ca345cSEnji Cooper return (0); 272*08ca345cSEnji Cooper } 273*08ca345cSEnji Cooper 274*08ca345cSEnji Cooper static void 275*08ca345cSEnji Cooper dump_servent(struct servent *result) 276*08ca345cSEnji Cooper { 277*08ca345cSEnji Cooper if (result != NULL) { 278*08ca345cSEnji Cooper char buffer[1024]; 279*08ca345cSEnji Cooper sdump_servent(result, buffer, sizeof(buffer)); 280*08ca345cSEnji Cooper printf("%s\n", buffer); 281*08ca345cSEnji Cooper } else 282*08ca345cSEnji Cooper printf("(null)\n"); 283*08ca345cSEnji Cooper } 284*08ca345cSEnji Cooper 285*08ca345cSEnji Cooper static int 286*08ca345cSEnji Cooper servent_fill_test_data(struct servent_test_data *td) 287*08ca345cSEnji Cooper { 288*08ca345cSEnji Cooper struct servent *serv; 289*08ca345cSEnji Cooper 290*08ca345cSEnji Cooper setservent(1); 291*08ca345cSEnji Cooper while ((serv = getservent()) != NULL) { 292*08ca345cSEnji Cooper if (servent_test_correctness(serv, NULL) == 0) 293*08ca345cSEnji Cooper TEST_DATA_APPEND(servent, td, serv); 294*08ca345cSEnji Cooper else 295*08ca345cSEnji Cooper return (-1); 296*08ca345cSEnji Cooper } 297*08ca345cSEnji Cooper endservent(); 298*08ca345cSEnji Cooper 299*08ca345cSEnji Cooper return (0); 300*08ca345cSEnji Cooper } 301*08ca345cSEnji Cooper 302*08ca345cSEnji Cooper static int 303*08ca345cSEnji Cooper servent_test_correctness(struct servent *serv, void *mdata) 304*08ca345cSEnji Cooper { 305*08ca345cSEnji Cooper printf("testing correctness with the following data:\n"); 306*08ca345cSEnji Cooper dump_servent(serv); 307*08ca345cSEnji Cooper 308*08ca345cSEnji Cooper if (serv == NULL) 309*08ca345cSEnji Cooper goto errfin; 310*08ca345cSEnji Cooper 311*08ca345cSEnji Cooper if (serv->s_name == NULL) 312*08ca345cSEnji Cooper goto errfin; 313*08ca345cSEnji Cooper 314*08ca345cSEnji Cooper if (serv->s_proto == NULL) 315*08ca345cSEnji Cooper goto errfin; 316*08ca345cSEnji Cooper 317*08ca345cSEnji Cooper if (ntohs(serv->s_port < 0)) 318*08ca345cSEnji Cooper goto errfin; 319*08ca345cSEnji Cooper 320*08ca345cSEnji Cooper if (serv->s_aliases == NULL) 321*08ca345cSEnji Cooper goto errfin; 322*08ca345cSEnji Cooper 323*08ca345cSEnji Cooper printf("correct\n"); 324*08ca345cSEnji Cooper 325*08ca345cSEnji Cooper return (0); 326*08ca345cSEnji Cooper errfin: 327*08ca345cSEnji Cooper printf("incorrect\n"); 328*08ca345cSEnji Cooper 329*08ca345cSEnji Cooper return (-1); 330*08ca345cSEnji Cooper } 331*08ca345cSEnji Cooper 332*08ca345cSEnji Cooper /* servent_check_ambiguity() is needed when one port+proto is associated with 333*08ca345cSEnji Cooper * more than one service (these cases are usually marked as PROBLEM in 334*08ca345cSEnji Cooper * /etc/services. This functions is needed also when one service+proto is 335*08ca345cSEnji Cooper * associated with several ports. We have to check all the servent structures 336*08ca345cSEnji Cooper * to make sure that serv really exists and correct */ 337*08ca345cSEnji Cooper static int 338*08ca345cSEnji Cooper servent_check_ambiguity(struct servent_test_data *td, struct servent *serv) 339*08ca345cSEnji Cooper { 340*08ca345cSEnji Cooper 341*08ca345cSEnji Cooper return (TEST_DATA_FIND(servent, td, serv, compare_servent, 342*08ca345cSEnji Cooper NULL) != NULL ? 0 : -1); 343*08ca345cSEnji Cooper } 344*08ca345cSEnji Cooper 345*08ca345cSEnji Cooper static int 346*08ca345cSEnji Cooper servent_test_getservbyname(struct servent *serv_model, void *mdata) 347*08ca345cSEnji Cooper { 348*08ca345cSEnji Cooper char **alias; 349*08ca345cSEnji Cooper struct servent *serv; 350*08ca345cSEnji Cooper 351*08ca345cSEnji Cooper printf("testing getservbyname() with the following data:\n"); 352*08ca345cSEnji Cooper dump_servent(serv_model); 353*08ca345cSEnji Cooper 354*08ca345cSEnji Cooper serv = getservbyname(serv_model->s_name, serv_model->s_proto); 355*08ca345cSEnji Cooper if (servent_test_correctness(serv, NULL) != 0) 356*08ca345cSEnji Cooper goto errfin; 357*08ca345cSEnji Cooper 358*08ca345cSEnji Cooper if ((compare_servent(serv, serv_model, NULL) != 0) && 359*08ca345cSEnji Cooper (servent_check_ambiguity((struct servent_test_data *)mdata, serv) 360*08ca345cSEnji Cooper !=0)) 361*08ca345cSEnji Cooper goto errfin; 362*08ca345cSEnji Cooper 363*08ca345cSEnji Cooper for (alias = serv_model->s_aliases; *alias; ++alias) { 364*08ca345cSEnji Cooper serv = getservbyname(*alias, serv_model->s_proto); 365*08ca345cSEnji Cooper 366*08ca345cSEnji Cooper if (servent_test_correctness(serv, NULL) != 0) 367*08ca345cSEnji Cooper goto errfin; 368*08ca345cSEnji Cooper 369*08ca345cSEnji Cooper if ((compare_servent(serv, serv_model, NULL) != 0) && 370*08ca345cSEnji Cooper (servent_check_ambiguity( 371*08ca345cSEnji Cooper (struct servent_test_data *)mdata, serv) != 0)) 372*08ca345cSEnji Cooper goto errfin; 373*08ca345cSEnji Cooper } 374*08ca345cSEnji Cooper 375*08ca345cSEnji Cooper printf("ok\n"); 376*08ca345cSEnji Cooper return (0); 377*08ca345cSEnji Cooper 378*08ca345cSEnji Cooper errfin: 379*08ca345cSEnji Cooper printf("not ok\n"); 380*08ca345cSEnji Cooper 381*08ca345cSEnji Cooper return (-1); 382*08ca345cSEnji Cooper } 383*08ca345cSEnji Cooper 384*08ca345cSEnji Cooper static int 385*08ca345cSEnji Cooper servent_test_getservbyport(struct servent *serv_model, void *mdata) 386*08ca345cSEnji Cooper { 387*08ca345cSEnji Cooper struct servent *serv; 388*08ca345cSEnji Cooper 389*08ca345cSEnji Cooper printf("testing getservbyport() with the following data...\n"); 390*08ca345cSEnji Cooper dump_servent(serv_model); 391*08ca345cSEnji Cooper 392*08ca345cSEnji Cooper serv = getservbyport(serv_model->s_port, serv_model->s_proto); 393*08ca345cSEnji Cooper if ((servent_test_correctness(serv, NULL) != 0) || 394*08ca345cSEnji Cooper ((compare_servent(serv, serv_model, NULL) != 0) && 395*08ca345cSEnji Cooper (servent_check_ambiguity((struct servent_test_data *)mdata, serv) 396*08ca345cSEnji Cooper != 0))) { 397*08ca345cSEnji Cooper printf("not ok\n"); 398*08ca345cSEnji Cooper return (-1); 399*08ca345cSEnji Cooper } else { 400*08ca345cSEnji Cooper printf("ok\n"); 401*08ca345cSEnji Cooper return (0); 402*08ca345cSEnji Cooper } 403*08ca345cSEnji Cooper } 404*08ca345cSEnji Cooper 405*08ca345cSEnji Cooper static int 406*08ca345cSEnji Cooper servent_test_getservent(struct servent *serv, void *mdata) 407*08ca345cSEnji Cooper { 408*08ca345cSEnji Cooper /* Only correctness can be checked when doing 1-pass test for 409*08ca345cSEnji Cooper * getservent(). */ 410*08ca345cSEnji Cooper return (servent_test_correctness(serv, NULL)); 411*08ca345cSEnji Cooper } 412*08ca345cSEnji Cooper 413*08ca345cSEnji Cooper int 414*08ca345cSEnji Cooper run_tests(const char *snapshot_file, enum test_methods method) 415*08ca345cSEnji Cooper { 416*08ca345cSEnji Cooper struct servent_test_data td, td_snap, td_2pass; 417*08ca345cSEnji Cooper int rv; 418*08ca345cSEnji Cooper 419*08ca345cSEnji Cooper TEST_DATA_INIT(servent, &td, clone_servent, free_servent); 420*08ca345cSEnji Cooper TEST_DATA_INIT(servent, &td_snap, clone_servent, free_servent); 421*08ca345cSEnji Cooper if (snapshot_file != NULL) { 422*08ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 423*08ca345cSEnji Cooper if (errno == ENOENT) 424*08ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 425*08ca345cSEnji Cooper else { 426*08ca345cSEnji Cooper printf("can't access the file %s\n", 427*08ca345cSEnji Cooper snapshot_file); 428*08ca345cSEnji Cooper 429*08ca345cSEnji Cooper rv = -1; 430*08ca345cSEnji Cooper goto fin; 431*08ca345cSEnji Cooper } 432*08ca345cSEnji Cooper } else { 433*08ca345cSEnji Cooper if (method == TEST_BUILD_SNAPSHOT) { 434*08ca345cSEnji Cooper rv = 0; 435*08ca345cSEnji Cooper goto fin; 436*08ca345cSEnji Cooper } 437*08ca345cSEnji Cooper 438*08ca345cSEnji Cooper TEST_SNAPSHOT_FILE_READ(servent, snapshot_file, 439*08ca345cSEnji Cooper &td_snap, servent_read_snapshot_func); 440*08ca345cSEnji Cooper } 441*08ca345cSEnji Cooper } 442*08ca345cSEnji Cooper 443*08ca345cSEnji Cooper rv = servent_fill_test_data(&td); 444*08ca345cSEnji Cooper if (rv == -1) 445*08ca345cSEnji Cooper return (-1); 446*08ca345cSEnji Cooper switch (method) { 447*08ca345cSEnji Cooper case TEST_GETSERVBYNAME: 448*08ca345cSEnji Cooper if (snapshot_file == NULL) 449*08ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td, 450*08ca345cSEnji Cooper servent_test_getservbyname, (void *)&td); 451*08ca345cSEnji Cooper else 452*08ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td_snap, 453*08ca345cSEnji Cooper servent_test_getservbyname, (void *)&td_snap); 454*08ca345cSEnji Cooper break; 455*08ca345cSEnji Cooper case TEST_GETSERVBYPORT: 456*08ca345cSEnji Cooper if (snapshot_file == NULL) 457*08ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td, 458*08ca345cSEnji Cooper servent_test_getservbyport, (void *)&td); 459*08ca345cSEnji Cooper else 460*08ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td_snap, 461*08ca345cSEnji Cooper servent_test_getservbyport, (void *)&td_snap); 462*08ca345cSEnji Cooper break; 463*08ca345cSEnji Cooper case TEST_GETSERVENT: 464*08ca345cSEnji Cooper if (snapshot_file == NULL) 465*08ca345cSEnji Cooper rv = DO_1PASS_TEST(servent, &td, servent_test_getservent, 466*08ca345cSEnji Cooper (void *)&td); 467*08ca345cSEnji Cooper else 468*08ca345cSEnji Cooper rv = DO_2PASS_TEST(servent, &td, &td_snap, 469*08ca345cSEnji Cooper compare_servent, NULL); 470*08ca345cSEnji Cooper break; 471*08ca345cSEnji Cooper case TEST_GETSERVENT_2PASS: 472*08ca345cSEnji Cooper TEST_DATA_INIT(servent, &td_2pass, clone_servent, free_servent); 473*08ca345cSEnji Cooper rv = servent_fill_test_data(&td_2pass); 474*08ca345cSEnji Cooper if (rv != -1) 475*08ca345cSEnji Cooper rv = DO_2PASS_TEST(servent, &td, &td_2pass, 476*08ca345cSEnji Cooper compare_servent, NULL); 477*08ca345cSEnji Cooper TEST_DATA_DESTROY(servent, &td_2pass); 478*08ca345cSEnji Cooper break; 479*08ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 480*08ca345cSEnji Cooper if (snapshot_file != NULL) 481*08ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_WRITE(servent, snapshot_file, &td, 482*08ca345cSEnji Cooper sdump_servent); 483*08ca345cSEnji Cooper break; 484*08ca345cSEnji Cooper default: 485*08ca345cSEnji Cooper rv = 0; 486*08ca345cSEnji Cooper break; 487*08ca345cSEnji Cooper } 488*08ca345cSEnji Cooper 489*08ca345cSEnji Cooper fin: 490*08ca345cSEnji Cooper TEST_DATA_DESTROY(servent, &td_snap); 491*08ca345cSEnji Cooper TEST_DATA_DESTROY(servent, &td); 492*08ca345cSEnji Cooper 493*08ca345cSEnji Cooper return (rv); 494*08ca345cSEnji Cooper } 495*08ca345cSEnji Cooper 496*08ca345cSEnji Cooper #define SNAPSHOT_FILE "snapshot_serv" 497*08ca345cSEnji Cooper 498*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(build_snapshot); 499*08ca345cSEnji Cooper ATF_TC_BODY(build_snapshot, tc) 500*08ca345cSEnji Cooper { 501*08ca345cSEnji Cooper 502*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 503*08ca345cSEnji Cooper } 504*08ca345cSEnji Cooper 505*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyname); 506*08ca345cSEnji Cooper ATF_TC_BODY(getservbyname, tc) 507*08ca345cSEnji Cooper { 508*08ca345cSEnji Cooper 509*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETSERVBYNAME) == 0); 510*08ca345cSEnji Cooper } 511*08ca345cSEnji Cooper 512*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyname_with_snapshot); 513*08ca345cSEnji Cooper ATF_TC_BODY(getservbyname_with_snapshot, tc) 514*08ca345cSEnji Cooper { 515*08ca345cSEnji Cooper 516*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 517*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVBYNAME) == 0); 518*08ca345cSEnji Cooper } 519*08ca345cSEnji Cooper 520*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyport); 521*08ca345cSEnji Cooper ATF_TC_BODY(getservbyport, tc) 522*08ca345cSEnji Cooper { 523*08ca345cSEnji Cooper 524*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETSERVBYPORT) == 0); 525*08ca345cSEnji Cooper } 526*08ca345cSEnji Cooper 527*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyport_with_snapshot); 528*08ca345cSEnji Cooper ATF_TC_BODY(getservbyport_with_snapshot, tc) 529*08ca345cSEnji Cooper { 530*08ca345cSEnji Cooper 531*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 532*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVBYPORT) == 0); 533*08ca345cSEnji Cooper } 534*08ca345cSEnji Cooper 535*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyent); 536*08ca345cSEnji Cooper ATF_TC_BODY(getservbyent, tc) 537*08ca345cSEnji Cooper { 538*08ca345cSEnji Cooper 539*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETSERVENT) == 0); 540*08ca345cSEnji Cooper } 541*08ca345cSEnji Cooper 542*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyent_with_snapshot); 543*08ca345cSEnji Cooper ATF_TC_BODY(getservbyent_with_snapshot, tc) 544*08ca345cSEnji Cooper { 545*08ca345cSEnji Cooper 546*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 547*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVENT) == 0); 548*08ca345cSEnji Cooper } 549*08ca345cSEnji Cooper 550*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getservbyent_with_two_pass); 551*08ca345cSEnji Cooper ATF_TC_BODY(getservbyent_with_two_pass, tc) 552*08ca345cSEnji Cooper { 553*08ca345cSEnji Cooper 554*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETSERVENT_2PASS) == 0); 555*08ca345cSEnji Cooper } 556*08ca345cSEnji Cooper 557*08ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 558*08ca345cSEnji Cooper { 559*08ca345cSEnji Cooper 560*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, build_snapshot); 561*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyent); 562*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyent_with_snapshot); 563*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyent_with_two_pass); 564*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyname); 565*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyname_with_snapshot); 566*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyport); 567*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getservbyport_with_snapshot); 568*08ca345cSEnji Cooper 569*08ca345cSEnji Cooper return (atf_no_error()); 570*08ca345cSEnji Cooper } 571