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 <assert.h> 33*08ca345cSEnji Cooper #include <errno.h> 34*08ca345cSEnji Cooper #include <netdb.h> 35*08ca345cSEnji Cooper #include <stdio.h> 36*08ca345cSEnji Cooper #include <stdlib.h> 37*08ca345cSEnji Cooper #include <string.h> 38*08ca345cSEnji Cooper #include <stringlist.h> 39*08ca345cSEnji Cooper #include <unistd.h> 40*08ca345cSEnji Cooper 41*08ca345cSEnji Cooper #include <atf-c.h> 42*08ca345cSEnji Cooper 43*08ca345cSEnji Cooper #include "testutil.h" 44*08ca345cSEnji Cooper 45*08ca345cSEnji Cooper enum test_methods { 46*08ca345cSEnji Cooper TEST_GETPROTOENT, 47*08ca345cSEnji Cooper TEST_GETPROTOBYNAME, 48*08ca345cSEnji Cooper TEST_GETPROTOBYNUMBER, 49*08ca345cSEnji Cooper TEST_GETPROTOENT_2PASS, 50*08ca345cSEnji Cooper TEST_BUILD_SNAPSHOT 51*08ca345cSEnji Cooper }; 52*08ca345cSEnji Cooper 53*08ca345cSEnji Cooper DECLARE_TEST_DATA(protoent) 54*08ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(protoent) 55*08ca345cSEnji Cooper DECLARE_1PASS_TEST(protoent) 56*08ca345cSEnji Cooper DECLARE_2PASS_TEST(protoent) 57*08ca345cSEnji Cooper 58*08ca345cSEnji Cooper static void clone_protoent(struct protoent *, struct protoent const *); 59*08ca345cSEnji Cooper static int compare_protoent(struct protoent *, struct protoent *, void *); 60*08ca345cSEnji Cooper static void dump_protoent(struct protoent *); 61*08ca345cSEnji Cooper static void free_protoent(struct protoent *); 62*08ca345cSEnji Cooper 63*08ca345cSEnji Cooper static void sdump_protoent(struct protoent *, char *, size_t); 64*08ca345cSEnji Cooper static int protoent_read_snapshot_func(struct protoent *, char *); 65*08ca345cSEnji Cooper 66*08ca345cSEnji Cooper static int protoent_check_ambiguity(struct protoent_test_data *, 67*08ca345cSEnji Cooper struct protoent *); 68*08ca345cSEnji Cooper static int protoent_fill_test_data(struct protoent_test_data *); 69*08ca345cSEnji Cooper static int protoent_test_correctness(struct protoent *, void *); 70*08ca345cSEnji Cooper static int protoent_test_getprotobyname(struct protoent *, void *); 71*08ca345cSEnji Cooper static int protoent_test_getprotobynumber(struct protoent *, void *); 72*08ca345cSEnji Cooper static int protoent_test_getprotoent(struct protoent *, void *); 73*08ca345cSEnji Cooper 74*08ca345cSEnji Cooper IMPLEMENT_TEST_DATA(protoent) 75*08ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(protoent) 76*08ca345cSEnji Cooper IMPLEMENT_1PASS_TEST(protoent) 77*08ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(protoent) 78*08ca345cSEnji Cooper 79*08ca345cSEnji Cooper static void 80*08ca345cSEnji Cooper clone_protoent(struct protoent *dest, struct protoent const *src) 81*08ca345cSEnji Cooper { 82*08ca345cSEnji Cooper assert(dest != NULL); 83*08ca345cSEnji Cooper assert(src != NULL); 84*08ca345cSEnji Cooper 85*08ca345cSEnji Cooper char **cp; 86*08ca345cSEnji Cooper int aliases_num; 87*08ca345cSEnji Cooper 88*08ca345cSEnji Cooper memset(dest, 0, sizeof(struct protoent)); 89*08ca345cSEnji Cooper 90*08ca345cSEnji Cooper if (src->p_name != NULL) { 91*08ca345cSEnji Cooper dest->p_name = strdup(src->p_name); 92*08ca345cSEnji Cooper assert(dest->p_name != NULL); 93*08ca345cSEnji Cooper } 94*08ca345cSEnji Cooper 95*08ca345cSEnji Cooper dest->p_proto = src->p_proto; 96*08ca345cSEnji Cooper 97*08ca345cSEnji Cooper if (src->p_aliases != NULL) { 98*08ca345cSEnji Cooper aliases_num = 0; 99*08ca345cSEnji Cooper for (cp = src->p_aliases; *cp; ++cp) 100*08ca345cSEnji Cooper ++aliases_num; 101*08ca345cSEnji Cooper 102*08ca345cSEnji Cooper dest->p_aliases = calloc(1, (aliases_num+1) * sizeof(char *)); 103*08ca345cSEnji Cooper assert(dest->p_aliases != NULL); 104*08ca345cSEnji Cooper 105*08ca345cSEnji Cooper for (cp = src->p_aliases; *cp; ++cp) { 106*08ca345cSEnji Cooper dest->p_aliases[cp - src->p_aliases] = strdup(*cp); 107*08ca345cSEnji Cooper assert(dest->p_aliases[cp - src->p_aliases] != NULL); 108*08ca345cSEnji Cooper } 109*08ca345cSEnji Cooper } 110*08ca345cSEnji Cooper } 111*08ca345cSEnji Cooper 112*08ca345cSEnji Cooper static void 113*08ca345cSEnji Cooper free_protoent(struct protoent *pe) 114*08ca345cSEnji Cooper { 115*08ca345cSEnji Cooper char **cp; 116*08ca345cSEnji Cooper 117*08ca345cSEnji Cooper assert(pe != NULL); 118*08ca345cSEnji Cooper 119*08ca345cSEnji Cooper free(pe->p_name); 120*08ca345cSEnji Cooper 121*08ca345cSEnji Cooper for (cp = pe->p_aliases; *cp; ++cp) 122*08ca345cSEnji Cooper free(*cp); 123*08ca345cSEnji Cooper free(pe->p_aliases); 124*08ca345cSEnji Cooper } 125*08ca345cSEnji Cooper 126*08ca345cSEnji Cooper static int 127*08ca345cSEnji Cooper compare_protoent(struct protoent *pe1, struct protoent *pe2, void *mdata) 128*08ca345cSEnji Cooper { 129*08ca345cSEnji Cooper char **c1, **c2; 130*08ca345cSEnji Cooper 131*08ca345cSEnji Cooper if (pe1 == pe2) 132*08ca345cSEnji Cooper return 0; 133*08ca345cSEnji Cooper 134*08ca345cSEnji Cooper if ((pe1 == NULL) || (pe2 == NULL)) 135*08ca345cSEnji Cooper goto errfin; 136*08ca345cSEnji Cooper 137*08ca345cSEnji Cooper if ((strcmp(pe1->p_name, pe2->p_name) != 0) || 138*08ca345cSEnji Cooper (pe1->p_proto != pe2->p_proto)) 139*08ca345cSEnji Cooper goto errfin; 140*08ca345cSEnji Cooper 141*08ca345cSEnji Cooper c1 = pe1->p_aliases; 142*08ca345cSEnji Cooper c2 = pe2->p_aliases; 143*08ca345cSEnji Cooper 144*08ca345cSEnji Cooper if ((pe1->p_aliases == NULL) || (pe2->p_aliases == NULL)) 145*08ca345cSEnji Cooper goto errfin; 146*08ca345cSEnji Cooper 147*08ca345cSEnji Cooper for (;*c1 && *c2; ++c1, ++c2) 148*08ca345cSEnji Cooper if (strcmp(*c1, *c2) != 0) 149*08ca345cSEnji Cooper goto errfin; 150*08ca345cSEnji Cooper 151*08ca345cSEnji Cooper if ((*c1 != '\0') || (*c2 != '\0')) 152*08ca345cSEnji Cooper goto errfin; 153*08ca345cSEnji Cooper 154*08ca345cSEnji Cooper return 0; 155*08ca345cSEnji Cooper 156*08ca345cSEnji Cooper errfin: 157*08ca345cSEnji Cooper if (mdata == NULL) { 158*08ca345cSEnji Cooper printf("following structures are not equal:\n"); 159*08ca345cSEnji Cooper dump_protoent(pe1); 160*08ca345cSEnji Cooper dump_protoent(pe2); 161*08ca345cSEnji Cooper } 162*08ca345cSEnji Cooper 163*08ca345cSEnji Cooper return (-1); 164*08ca345cSEnji Cooper } 165*08ca345cSEnji Cooper 166*08ca345cSEnji Cooper static void 167*08ca345cSEnji Cooper sdump_protoent(struct protoent *pe, char *buffer, size_t buflen) 168*08ca345cSEnji Cooper { 169*08ca345cSEnji Cooper char **cp; 170*08ca345cSEnji Cooper int written; 171*08ca345cSEnji Cooper 172*08ca345cSEnji Cooper written = snprintf(buffer, buflen, "%s %d", 173*08ca345cSEnji Cooper pe->p_name, pe->p_proto); 174*08ca345cSEnji Cooper buffer += written; 175*08ca345cSEnji Cooper if (written > buflen) 176*08ca345cSEnji Cooper return; 177*08ca345cSEnji Cooper buflen -= written; 178*08ca345cSEnji Cooper 179*08ca345cSEnji Cooper if (pe->p_aliases != NULL) { 180*08ca345cSEnji Cooper if (*(pe->p_aliases) != '\0') { 181*08ca345cSEnji Cooper for (cp = pe->p_aliases; *cp; ++cp) { 182*08ca345cSEnji Cooper written = snprintf(buffer, buflen, " %s",*cp); 183*08ca345cSEnji Cooper buffer += written; 184*08ca345cSEnji Cooper if (written > buflen) 185*08ca345cSEnji Cooper return; 186*08ca345cSEnji Cooper buflen -= written; 187*08ca345cSEnji Cooper 188*08ca345cSEnji Cooper if (buflen == 0) 189*08ca345cSEnji Cooper return; 190*08ca345cSEnji Cooper } 191*08ca345cSEnji Cooper } else 192*08ca345cSEnji Cooper snprintf(buffer, buflen, " noaliases"); 193*08ca345cSEnji Cooper } else 194*08ca345cSEnji Cooper snprintf(buffer, buflen, " (null)"); 195*08ca345cSEnji Cooper } 196*08ca345cSEnji Cooper 197*08ca345cSEnji Cooper static int 198*08ca345cSEnji Cooper protoent_read_snapshot_func(struct protoent *pe, char *line) 199*08ca345cSEnji Cooper { 200*08ca345cSEnji Cooper StringList *sl; 201*08ca345cSEnji Cooper char *s, *ps, *ts; 202*08ca345cSEnji Cooper int i; 203*08ca345cSEnji Cooper 204*08ca345cSEnji Cooper printf("1 line read from snapshot:\n%s\n", line); 205*08ca345cSEnji Cooper 206*08ca345cSEnji Cooper i = 0; 207*08ca345cSEnji Cooper sl = NULL; 208*08ca345cSEnji Cooper ps = line; 209*08ca345cSEnji Cooper memset(pe, 0, sizeof(struct protoent)); 210*08ca345cSEnji Cooper while ( (s = strsep(&ps, " ")) != NULL) { 211*08ca345cSEnji Cooper switch (i) { 212*08ca345cSEnji Cooper case 0: 213*08ca345cSEnji Cooper pe->p_name = strdup(s); 214*08ca345cSEnji Cooper assert(pe->p_name != NULL); 215*08ca345cSEnji Cooper break; 216*08ca345cSEnji Cooper 217*08ca345cSEnji Cooper case 1: 218*08ca345cSEnji Cooper pe->p_proto = (int)strtol(s, &ts, 10); 219*08ca345cSEnji Cooper if (*ts != '\0') { 220*08ca345cSEnji Cooper free(pe->p_name); 221*08ca345cSEnji Cooper return (-1); 222*08ca345cSEnji Cooper } 223*08ca345cSEnji Cooper break; 224*08ca345cSEnji Cooper 225*08ca345cSEnji Cooper default: 226*08ca345cSEnji Cooper if (sl == NULL) { 227*08ca345cSEnji Cooper if (strcmp(s, "(null)") == 0) 228*08ca345cSEnji Cooper return (0); 229*08ca345cSEnji Cooper 230*08ca345cSEnji Cooper sl = sl_init(); 231*08ca345cSEnji Cooper assert(sl != NULL); 232*08ca345cSEnji Cooper 233*08ca345cSEnji Cooper if (strcmp(s, "noaliases") != 0) { 234*08ca345cSEnji Cooper ts = strdup(s); 235*08ca345cSEnji Cooper assert(ts != NULL); 236*08ca345cSEnji Cooper sl_add(sl, ts); 237*08ca345cSEnji Cooper } 238*08ca345cSEnji Cooper } else { 239*08ca345cSEnji Cooper ts = strdup(s); 240*08ca345cSEnji Cooper assert(ts != NULL); 241*08ca345cSEnji Cooper sl_add(sl, ts); 242*08ca345cSEnji Cooper } 243*08ca345cSEnji Cooper break; 244*08ca345cSEnji Cooper } 245*08ca345cSEnji Cooper ++i; 246*08ca345cSEnji Cooper } 247*08ca345cSEnji Cooper 248*08ca345cSEnji Cooper if (i < 3) { 249*08ca345cSEnji Cooper free(pe->p_name); 250*08ca345cSEnji Cooper memset(pe, 0, sizeof(struct protoent)); 251*08ca345cSEnji Cooper return (-1); 252*08ca345cSEnji Cooper } 253*08ca345cSEnji Cooper 254*08ca345cSEnji Cooper sl_add(sl, NULL); 255*08ca345cSEnji Cooper pe->p_aliases = sl->sl_str; 256*08ca345cSEnji Cooper 257*08ca345cSEnji Cooper /* NOTE: is it a dirty hack or not? */ 258*08ca345cSEnji Cooper free(sl); 259*08ca345cSEnji Cooper return (0); 260*08ca345cSEnji Cooper } 261*08ca345cSEnji Cooper 262*08ca345cSEnji Cooper static void 263*08ca345cSEnji Cooper dump_protoent(struct protoent *result) 264*08ca345cSEnji Cooper { 265*08ca345cSEnji Cooper if (result != NULL) { 266*08ca345cSEnji Cooper char buffer[1024]; 267*08ca345cSEnji Cooper sdump_protoent(result, buffer, sizeof(buffer)); 268*08ca345cSEnji Cooper printf("%s\n", buffer); 269*08ca345cSEnji Cooper } else 270*08ca345cSEnji Cooper printf("(null)\n"); 271*08ca345cSEnji Cooper } 272*08ca345cSEnji Cooper 273*08ca345cSEnji Cooper static int 274*08ca345cSEnji Cooper protoent_fill_test_data(struct protoent_test_data *td) 275*08ca345cSEnji Cooper { 276*08ca345cSEnji Cooper struct protoent *pe; 277*08ca345cSEnji Cooper 278*08ca345cSEnji Cooper setprotoent(1); 279*08ca345cSEnji Cooper while ((pe = getprotoent()) != NULL) { 280*08ca345cSEnji Cooper if (protoent_test_correctness(pe, NULL) == 0) 281*08ca345cSEnji Cooper TEST_DATA_APPEND(protoent, td, pe); 282*08ca345cSEnji Cooper else 283*08ca345cSEnji Cooper return (-1); 284*08ca345cSEnji Cooper } 285*08ca345cSEnji Cooper endprotoent(); 286*08ca345cSEnji Cooper 287*08ca345cSEnji Cooper return (0); 288*08ca345cSEnji Cooper } 289*08ca345cSEnji Cooper 290*08ca345cSEnji Cooper static int 291*08ca345cSEnji Cooper protoent_test_correctness(struct protoent *pe, void *mdata) 292*08ca345cSEnji Cooper { 293*08ca345cSEnji Cooper printf("testing correctness with the following data:\n"); 294*08ca345cSEnji Cooper dump_protoent(pe); 295*08ca345cSEnji Cooper 296*08ca345cSEnji Cooper if (pe == NULL) 297*08ca345cSEnji Cooper goto errfin; 298*08ca345cSEnji Cooper 299*08ca345cSEnji Cooper if (pe->p_name == NULL) 300*08ca345cSEnji Cooper goto errfin; 301*08ca345cSEnji Cooper 302*08ca345cSEnji Cooper if (pe->p_proto < 0) 303*08ca345cSEnji Cooper goto errfin; 304*08ca345cSEnji Cooper 305*08ca345cSEnji Cooper if (pe->p_aliases == NULL) 306*08ca345cSEnji Cooper goto errfin; 307*08ca345cSEnji Cooper 308*08ca345cSEnji Cooper printf("correct\n"); 309*08ca345cSEnji Cooper 310*08ca345cSEnji Cooper return (0); 311*08ca345cSEnji Cooper errfin: 312*08ca345cSEnji Cooper printf("incorrect\n"); 313*08ca345cSEnji Cooper 314*08ca345cSEnji Cooper return (-1); 315*08ca345cSEnji Cooper } 316*08ca345cSEnji Cooper 317*08ca345cSEnji Cooper /* protoent_check_ambiguity() is needed when one port+proto is associated with 318*08ca345cSEnji Cooper * more than one peice (these cases are usually marked as PROBLEM in 319*08ca345cSEnji Cooper * /etc/peices. This functions is needed also when one peice+proto is 320*08ca345cSEnji Cooper * associated with several ports. We have to check all the protoent structures 321*08ca345cSEnji Cooper * to make sure that pe really exists and correct */ 322*08ca345cSEnji Cooper static int 323*08ca345cSEnji Cooper protoent_check_ambiguity(struct protoent_test_data *td, struct protoent *pe) 324*08ca345cSEnji Cooper { 325*08ca345cSEnji Cooper 326*08ca345cSEnji Cooper return (TEST_DATA_FIND(protoent, td, pe, compare_protoent, 327*08ca345cSEnji Cooper NULL) != NULL ? 0 : -1); 328*08ca345cSEnji Cooper } 329*08ca345cSEnji Cooper 330*08ca345cSEnji Cooper static int 331*08ca345cSEnji Cooper protoent_test_getprotobyname(struct protoent *pe_model, void *mdata) 332*08ca345cSEnji Cooper { 333*08ca345cSEnji Cooper char **alias; 334*08ca345cSEnji Cooper struct protoent *pe; 335*08ca345cSEnji Cooper 336*08ca345cSEnji Cooper printf("testing getprotobyname() with the following data:\n"); 337*08ca345cSEnji Cooper dump_protoent(pe_model); 338*08ca345cSEnji Cooper 339*08ca345cSEnji Cooper pe = getprotobyname(pe_model->p_name); 340*08ca345cSEnji Cooper if (protoent_test_correctness(pe, NULL) != 0) 341*08ca345cSEnji Cooper goto errfin; 342*08ca345cSEnji Cooper 343*08ca345cSEnji Cooper if ((compare_protoent(pe, pe_model, NULL) != 0) && 344*08ca345cSEnji Cooper (protoent_check_ambiguity((struct protoent_test_data *)mdata, pe) 345*08ca345cSEnji Cooper !=0)) 346*08ca345cSEnji Cooper goto errfin; 347*08ca345cSEnji Cooper 348*08ca345cSEnji Cooper for (alias = pe_model->p_aliases; *alias; ++alias) { 349*08ca345cSEnji Cooper pe = getprotobyname(*alias); 350*08ca345cSEnji Cooper 351*08ca345cSEnji Cooper if (protoent_test_correctness(pe, NULL) != 0) 352*08ca345cSEnji Cooper goto errfin; 353*08ca345cSEnji Cooper 354*08ca345cSEnji Cooper if ((compare_protoent(pe, pe_model, NULL) != 0) && 355*08ca345cSEnji Cooper (protoent_check_ambiguity( 356*08ca345cSEnji Cooper (struct protoent_test_data *)mdata, pe) != 0)) 357*08ca345cSEnji Cooper goto errfin; 358*08ca345cSEnji Cooper } 359*08ca345cSEnji Cooper 360*08ca345cSEnji Cooper printf("ok\n"); 361*08ca345cSEnji Cooper return (0); 362*08ca345cSEnji Cooper 363*08ca345cSEnji Cooper errfin: 364*08ca345cSEnji Cooper printf("not ok\n"); 365*08ca345cSEnji Cooper 366*08ca345cSEnji Cooper return (-1); 367*08ca345cSEnji Cooper } 368*08ca345cSEnji Cooper 369*08ca345cSEnji Cooper static int 370*08ca345cSEnji Cooper protoent_test_getprotobynumber(struct protoent *pe_model, void *mdata) 371*08ca345cSEnji Cooper { 372*08ca345cSEnji Cooper struct protoent *pe; 373*08ca345cSEnji Cooper 374*08ca345cSEnji Cooper printf("testing getprotobyport() with the following data...\n"); 375*08ca345cSEnji Cooper dump_protoent(pe_model); 376*08ca345cSEnji Cooper 377*08ca345cSEnji Cooper pe = getprotobynumber(pe_model->p_proto); 378*08ca345cSEnji Cooper if ((protoent_test_correctness(pe, NULL) != 0) || 379*08ca345cSEnji Cooper ((compare_protoent(pe, pe_model, NULL) != 0) && 380*08ca345cSEnji Cooper (protoent_check_ambiguity((struct protoent_test_data *)mdata, pe) 381*08ca345cSEnji Cooper != 0))) { 382*08ca345cSEnji Cooper printf("not ok\n"); 383*08ca345cSEnji Cooper return (-1); 384*08ca345cSEnji Cooper } else { 385*08ca345cSEnji Cooper printf("ok\n"); 386*08ca345cSEnji Cooper return (0); 387*08ca345cSEnji Cooper } 388*08ca345cSEnji Cooper } 389*08ca345cSEnji Cooper 390*08ca345cSEnji Cooper static int 391*08ca345cSEnji Cooper protoent_test_getprotoent(struct protoent *pe, void *mdata) 392*08ca345cSEnji Cooper { 393*08ca345cSEnji Cooper /* Only correctness can be checked when doing 1-pass test for 394*08ca345cSEnji Cooper * getprotoent(). */ 395*08ca345cSEnji Cooper return (protoent_test_correctness(pe, NULL)); 396*08ca345cSEnji Cooper } 397*08ca345cSEnji Cooper 398*08ca345cSEnji Cooper int 399*08ca345cSEnji Cooper run_tests(const char *snapshot_file, enum test_methods method) 400*08ca345cSEnji Cooper { 401*08ca345cSEnji Cooper struct protoent_test_data td, td_snap, td_2pass; 402*08ca345cSEnji Cooper int rv; 403*08ca345cSEnji Cooper 404*08ca345cSEnji Cooper TEST_DATA_INIT(protoent, &td, clone_protoent, free_protoent); 405*08ca345cSEnji Cooper TEST_DATA_INIT(protoent, &td_snap, clone_protoent, free_protoent); 406*08ca345cSEnji Cooper if (snapshot_file != NULL) { 407*08ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 408*08ca345cSEnji Cooper if (errno == ENOENT) 409*08ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 410*08ca345cSEnji Cooper else { 411*08ca345cSEnji Cooper printf("can't access the file %s\n", 412*08ca345cSEnji Cooper snapshot_file); 413*08ca345cSEnji Cooper 414*08ca345cSEnji Cooper rv = -1; 415*08ca345cSEnji Cooper goto fin; 416*08ca345cSEnji Cooper } 417*08ca345cSEnji Cooper } else { 418*08ca345cSEnji Cooper if (method == TEST_BUILD_SNAPSHOT) { 419*08ca345cSEnji Cooper rv = 0; 420*08ca345cSEnji Cooper goto fin; 421*08ca345cSEnji Cooper } 422*08ca345cSEnji Cooper 423*08ca345cSEnji Cooper TEST_SNAPSHOT_FILE_READ(protoent, snapshot_file, 424*08ca345cSEnji Cooper &td_snap, protoent_read_snapshot_func); 425*08ca345cSEnji Cooper } 426*08ca345cSEnji Cooper } 427*08ca345cSEnji Cooper 428*08ca345cSEnji Cooper rv = protoent_fill_test_data(&td); 429*08ca345cSEnji Cooper if (rv == -1) 430*08ca345cSEnji Cooper return (-1); 431*08ca345cSEnji Cooper switch (method) { 432*08ca345cSEnji Cooper case TEST_GETPROTOBYNAME: 433*08ca345cSEnji Cooper if (snapshot_file == NULL) 434*08ca345cSEnji Cooper rv = DO_1PASS_TEST(protoent, &td, 435*08ca345cSEnji Cooper protoent_test_getprotobyname, (void *)&td); 436*08ca345cSEnji Cooper else 437*08ca345cSEnji Cooper rv = DO_1PASS_TEST(protoent, &td_snap, 438*08ca345cSEnji Cooper protoent_test_getprotobyname, (void *)&td_snap); 439*08ca345cSEnji Cooper break; 440*08ca345cSEnji Cooper case TEST_GETPROTOBYNUMBER: 441*08ca345cSEnji Cooper if (snapshot_file == NULL) 442*08ca345cSEnji Cooper rv = DO_1PASS_TEST(protoent, &td, 443*08ca345cSEnji Cooper protoent_test_getprotobynumber, (void *)&td); 444*08ca345cSEnji Cooper else 445*08ca345cSEnji Cooper rv = DO_1PASS_TEST(protoent, &td_snap, 446*08ca345cSEnji Cooper protoent_test_getprotobynumber, (void *)&td_snap); 447*08ca345cSEnji Cooper break; 448*08ca345cSEnji Cooper case TEST_GETPROTOENT: 449*08ca345cSEnji Cooper if (snapshot_file == NULL) 450*08ca345cSEnji Cooper rv = DO_1PASS_TEST(protoent, &td, 451*08ca345cSEnji Cooper protoent_test_getprotoent, (void *)&td); 452*08ca345cSEnji Cooper else 453*08ca345cSEnji Cooper rv = DO_2PASS_TEST(protoent, &td, &td_snap, 454*08ca345cSEnji Cooper compare_protoent, NULL); 455*08ca345cSEnji Cooper break; 456*08ca345cSEnji Cooper case TEST_GETPROTOENT_2PASS: 457*08ca345cSEnji Cooper TEST_DATA_INIT(protoent, &td_2pass, clone_protoent, 458*08ca345cSEnji Cooper free_protoent); 459*08ca345cSEnji Cooper rv = protoent_fill_test_data(&td_2pass); 460*08ca345cSEnji Cooper if (rv != -1) 461*08ca345cSEnji Cooper rv = DO_2PASS_TEST(protoent, &td, &td_2pass, 462*08ca345cSEnji Cooper compare_protoent, NULL); 463*08ca345cSEnji Cooper TEST_DATA_DESTROY(protoent, &td_2pass); 464*08ca345cSEnji Cooper break; 465*08ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 466*08ca345cSEnji Cooper if (snapshot_file != NULL) 467*08ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_WRITE(protoent, snapshot_file, 468*08ca345cSEnji Cooper &td, sdump_protoent); 469*08ca345cSEnji Cooper break; 470*08ca345cSEnji Cooper default: 471*08ca345cSEnji Cooper rv = 0; 472*08ca345cSEnji Cooper break; 473*08ca345cSEnji Cooper } 474*08ca345cSEnji Cooper 475*08ca345cSEnji Cooper fin: 476*08ca345cSEnji Cooper TEST_DATA_DESTROY(protoent, &td_snap); 477*08ca345cSEnji Cooper TEST_DATA_DESTROY(protoent, &td); 478*08ca345cSEnji Cooper 479*08ca345cSEnji Cooper return (rv); 480*08ca345cSEnji Cooper } 481*08ca345cSEnji Cooper 482*08ca345cSEnji Cooper #define SNAPSHOT_FILE "snapshot_proto" 483*08ca345cSEnji Cooper 484*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(build_snapshot); 485*08ca345cSEnji Cooper ATF_TC_BODY(build_snapshot, tc) 486*08ca345cSEnji Cooper { 487*08ca345cSEnji Cooper 488*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 489*08ca345cSEnji Cooper } 490*08ca345cSEnji Cooper 491*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getprotoent); 492*08ca345cSEnji Cooper ATF_TC_BODY(getprotoent, tc) 493*08ca345cSEnji Cooper { 494*08ca345cSEnji Cooper 495*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOENT) == 0); 496*08ca345cSEnji Cooper } 497*08ca345cSEnji Cooper 498*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getprotoent_with_snapshot); 499*08ca345cSEnji Cooper ATF_TC_BODY(getprotoent_with_snapshot, tc) 500*08ca345cSEnji Cooper { 501*08ca345cSEnji Cooper 502*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 503*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPROTOENT) == 0); 504*08ca345cSEnji Cooper } 505*08ca345cSEnji Cooper 506*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getprotoent_with_two_pass); 507*08ca345cSEnji Cooper ATF_TC_BODY(getprotoent_with_two_pass, tc) 508*08ca345cSEnji Cooper { 509*08ca345cSEnji Cooper 510*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOENT_2PASS) == 0); 511*08ca345cSEnji Cooper } 512*08ca345cSEnji Cooper 513*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getprotobyname); 514*08ca345cSEnji Cooper ATF_TC_BODY(getprotobyname, tc) 515*08ca345cSEnji Cooper { 516*08ca345cSEnji Cooper 517*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOBYNAME) == 0); 518*08ca345cSEnji Cooper } 519*08ca345cSEnji Cooper 520*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getprotobyname_with_snapshot); 521*08ca345cSEnji Cooper ATF_TC_BODY(getprotobyname_with_snapshot, tc) 522*08ca345cSEnji Cooper { 523*08ca345cSEnji Cooper 524*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 525*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPROTOBYNAME) == 0); 526*08ca345cSEnji Cooper } 527*08ca345cSEnji Cooper 528*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getprotobynumber); 529*08ca345cSEnji Cooper ATF_TC_BODY(getprotobynumber, tc) 530*08ca345cSEnji Cooper { 531*08ca345cSEnji Cooper 532*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOBYNUMBER) == 0); 533*08ca345cSEnji Cooper } 534*08ca345cSEnji Cooper 535*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(getprotobynumber_with_snapshot); 536*08ca345cSEnji Cooper ATF_TC_BODY(getprotobynumber_with_snapshot, tc) 537*08ca345cSEnji Cooper { 538*08ca345cSEnji Cooper 539*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); 540*08ca345cSEnji Cooper ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPROTOBYNUMBER) == 0); 541*08ca345cSEnji Cooper } 542*08ca345cSEnji Cooper 543*08ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 544*08ca345cSEnji Cooper { 545*08ca345cSEnji Cooper 546*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, build_snapshot); 547*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getprotoent); 548*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getprotoent_with_snapshot); 549*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getprotoent_with_two_pass); 550*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getprotobyname); 551*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getprotobyname_with_snapshot); 552*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getprotobynumber); 553*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, getprotobynumber_with_snapshot); 554*08ca345cSEnji Cooper 555*08ca345cSEnji Cooper return (atf_no_error()); 556*08ca345cSEnji Cooper } 557