1327Sjkh/*-
2327Sjkh * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org>
3327Sjkh * All rights reserved.
4327Sjkh *
5327Sjkh * Redistribution and use in source and binary forms, with or without
6327Sjkh * modification, are permitted provided that the following conditions
7327Sjkh * are met:
8327Sjkh * 1. Redistributions of source code must retain the above copyright
9327Sjkh *    notice, this list of conditions and the following disclaimer.
10327Sjkh * 2. Redistributions in binary form must reproduce the above copyright
11327Sjkh *    notice, this list of conditions and the following disclaimer in the
1293520Sobrien *    documentation and/or other materials provided with the distribution.
1393520Sobrien *
1493520Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1530221Scharnier * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16327Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17327Sjkh * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18327Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1995161Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20327Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21327Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22327Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23327Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2426473Sjkh * SUCH DAMAGE.
254996Sjkh *
26327Sjkh */
2741866Sjkh
28327Sjkh#include <sys/cdefs.h>
2941866Sjkh__FBSDID("$FreeBSD: stable/11/lib/libc/tests/nss/getusershell_test.c 319299 2017-05-31 08:32:05Z ngie $");
30327Sjkh
31327Sjkh#include <assert.h>
32445Sjkh#include <errno.h>
334996Sjkh#include <stdio.h>
347713Sjkh#include <stdlib.h>
3567454Ssobomax#include <string.h>
3684670Ssobomax#include <unistd.h>
3726473Sjkh
3871095Ssobomax#include <atf-c.h>
3971095Ssobomax
4095161Sobrien#include "testutil.h"
41327Sjkh
4230221Scharnierenum test_methods {
4330221Scharnier	TEST_GETUSERSHELL,
44327Sjkh	TEST_BUILD_SNAPSHOT
45327Sjkh};
46327Sjkh
47327Sjkhstruct usershell {
4884670Ssobomax	char *path;
49327Sjkh};
50327Sjkh
5124428SimpDECLARE_TEST_DATA(usershell)
52327SjkhDECLARE_TEST_FILE_SNAPSHOT(usershell)
53327SjkhDECLARE_2PASS_TEST(usershell)
54327Sjkh
55327Sjkhstatic void clone_usershell(struct usershell *, struct usershell const *);
56327Sjkhstatic int compare_usershell(struct usershell *, struct usershell *, void *);
571337Sjkhstatic void free_usershell(struct usershell *);
581337Sjkh
591337Sjkhstatic void sdump_usershell(struct usershell *, char *, size_t);
601337Sjkhstatic void dump_usershell(struct usershell *);
611337Sjkh
621337SjkhIMPLEMENT_TEST_DATA(usershell)
631337SjkhIMPLEMENT_TEST_FILE_SNAPSHOT(usershell)
641337SjkhIMPLEMENT_2PASS_TEST(usershell)
657986Sjkh
6671095Ssobomaxstatic void
677986Sjkhclone_usershell(struct usershell *dest, struct usershell const *src)
687986Sjkh{
69327Sjkh	assert(dest != NULL);
70327Sjkh	assert(src != NULL);
71327Sjkh
72327Sjkh	if (src->path != NULL) {
7326473Sjkh		dest->path = strdup(src->path);
7426473Sjkh		assert(dest->path != NULL);
7526473Sjkh	}
7626473Sjkh}
77327Sjkh
78327Sjkhstatic int
79327Sjkhcompare_usershell(struct usershell *us1, struct usershell *us2,
80327Sjkh    void *mdata __unused)
81327Sjkh{
82327Sjkh	int rv;
83327Sjkh
84327Sjkh	assert(us1 != NULL);
85327Sjkh	assert(us2 != NULL);
86327Sjkh
87327Sjkh	dump_usershell(us1);
88327Sjkh	dump_usershell(us2);
89327Sjkh
90327Sjkh	if (us1 == us2)
91327Sjkh		return (0);
92327Sjkh
9341866Sjkh	rv = strcmp(us1->path, us2->path);
9441866Sjkh	if (rv != 0) {
9541866Sjkh		printf("following structures are not equal:\n");
9641866Sjkh		dump_usershell(us1);
97327Sjkh		dump_usershell(us2);
98327Sjkh	}
99327Sjkh
100327Sjkh	return (rv);
10141866Sjkh}
10241866Sjkh
10341866Sjkhstatic void
10441866Sjkhfree_usershell(struct usershell *us)
105327Sjkh{
106327Sjkh	free(us->path);
107327Sjkh}
108327Sjkh
109383Sjkhstatic void
11085019Ssobomaxsdump_usershell(struct usershell *us, char *buffer, size_t buflen)
111383Sjkh{
112383Sjkh	snprintf(buffer, buflen, "%s", us->path);
113445Sjkh}
114445Sjkh
115445Sjkhstatic void
116445Sjkhdump_usershell(struct usershell *us)
117327Sjkh{
11871095Ssobomax	if (us != NULL) {
1191520Salm		char buffer[2048];
1201520Salm		sdump_usershell(us, buffer, sizeof(buffer));
1214996Sjkh		printf("%s\n", buffer);
1224996Sjkh	} else
1234996Sjkh		printf("(null)\n");
1244996Sjkh}
1254996Sjkh
1264996Sjkhstatic int
1274996Sjkhusershell_read_snapshot_func(struct usershell *us, char *line)
1284996Sjkh{
1297713Sjkh
1307713Sjkh	us->path = strdup(line);
1317713Sjkh	ATF_REQUIRE(us->path != NULL);
1327713Sjkh
13367454Ssobomax	return (0);
13467454Ssobomax}
13567454Ssobomax
13667454Ssobomaxstatic int
13771373Ssobomaxrun_tests(const char *snapshot_file, enum test_methods method)
13895161Sobrien{
13995161Sobrien	struct usershell_test_data td, td_snap;
14071373Ssobomax	struct usershell ushell;
14171373Ssobomax	int rv;
14295161Sobrien
14395161Sobrien	rv = 0;
14495161Sobrien
14595161Sobrien	TEST_DATA_INIT(usershell, &td, clone_usershell, free_usershell);
14684670Ssobomax	TEST_DATA_INIT(usershell, &td_snap, clone_usershell, free_usershell);
14785470Ssobomax
14884670Ssobomax	setusershell();
14984670Ssobomax	while ((ushell.path = getusershell()) != NULL) {
15084670Ssobomax		printf("usershell found:\n");
15184670Ssobomax		dump_usershell(&ushell);
15284670Ssobomax		TEST_DATA_APPEND(usershell, &td, &ushell);
15384670Ssobomax	}
15484670Ssobomax	endusershell();
15584670Ssobomax
15684670Ssobomax	if (snapshot_file != NULL) {
15784670Ssobomax		if (access(snapshot_file, W_OK | R_OK) != 0) {
15884670Ssobomax			if (errno == ENOENT)
15984670Ssobomax				method = TEST_BUILD_SNAPSHOT;
16084670Ssobomax			else {
16184670Ssobomax				printf("can't access the snapshot file %s\n",
162327Sjkh				    snapshot_file);
163327Sjkh
16430221Scharnier				rv = -1;
165327Sjkh				goto fin;
166327Sjkh			}
167327Sjkh		} else {
1688857Srgrimes			rv = TEST_SNAPSHOT_FILE_READ(usershell, snapshot_file,
169327Sjkh				&td_snap, usershell_read_snapshot_func);
170327Sjkh			if (rv != 0) {
171327Sjkh				printf("error reading snapshot file\n");
172327Sjkh				goto fin;
173327Sjkh			}
174327Sjkh		}
175327Sjkh	}
17684670Ssobomax
17730221Scharnier	switch (method) {
178327Sjkh	case TEST_GETUSERSHELL:
17984670Ssobomax		rv = DO_2PASS_TEST(usershell, &td, &td_snap,
18084670Ssobomax			compare_usershell, NULL);
18130221Scharnier		break;
18284670Ssobomax	case TEST_BUILD_SNAPSHOT:
18384670Ssobomax		if (snapshot_file != NULL) {
18484670Ssobomax			rv = TEST_SNAPSHOT_FILE_WRITE(usershell, snapshot_file,
185327Sjkh			    &td, sdump_usershell);
186327Sjkh		}
18730221Scharnier		break;
188327Sjkh	default:
189327Sjkh		rv = 0;
190327Sjkh		break;
191327Sjkh	}
192327Sjkh
193327Sjkhfin:
19430221Scharnier	TEST_DATA_DESTROY(usershell, &td_snap);
19530221Scharnier	TEST_DATA_DESTROY(usershell, &td);
196327Sjkh
19784670Ssobomax	return (rv);
19871373Ssobomax}
19941866Sjkh
20041866Sjkh#define	SNAPSHOT_FILE	"snapshot_usershell"
20167454Ssobomax
20284670SsobomaxATF_TC_WITHOUT_HEAD(getusershell_with_snapshot);
20384670SsobomaxATF_TC_BODY(getusershell_with_snapshot, tc)
204327Sjkh{
205327Sjkh
206	ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0);
207}
208
209ATF_TC_WITHOUT_HEAD(getusershell_with_two_pass);
210ATF_TC_BODY(getusershell_with_two_pass, tc)
211{
212
213	ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0);
214	ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETUSERSHELL) == 0);
215}
216
217ATF_TP_ADD_TCS(tp)
218{
219
220	ATF_TP_ADD_TC(tp, getusershell_with_snapshot);
221	ATF_TP_ADD_TC(tp, getusershell_with_two_pass);
222
223	return (atf_no_error());
224}
225