1168754Sbushman/*- 2168754Sbushman * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org> 3251867Seadler * All rights reserved. 4168754Sbushman * 5168754Sbushman * Redistribution and use in source and binary forms, with or without 6168754Sbushman * modification, are permitted provided that the following conditions 7168754Sbushman * are met: 8168754Sbushman * 1. Redistributions of source code must retain the above copyright 9168754Sbushman * notice, this list of conditions and the following disclaimer. 10168754Sbushman * 2. Redistributions in binary form must reproduce the above copyright 11168754Sbushman * notice, this list of conditions and the following disclaimer in the 12168754Sbushman * documentation and/or other materials provided with the distribution. 13168754Sbushman * 14168754Sbushman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15168754Sbushman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16168754Sbushman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17168754Sbushman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18168754Sbushman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19168754Sbushman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20168754Sbushman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21168754Sbushman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22168754Sbushman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23168754Sbushman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24168754Sbushman * SUCH DAMAGE. 25168754Sbushman * 26168754Sbushman */ 27168754Sbushman 28168754Sbushman#include <sys/cdefs.h> 29168754Sbushman__FBSDID("$FreeBSD$"); 30168754Sbushman 31168754Sbushman#include <assert.h> 32168754Sbushman#include <errno.h> 33168754Sbushman#include <stdio.h> 34168754Sbushman#include <stdlib.h> 35168754Sbushman#include <string.h> 36168754Sbushman#include <unistd.h> 37168754Sbushman#include "testutil.h" 38168754Sbushman 39168754Sbushmanenum test_methods { 40168754Sbushman TEST_GETUSERSHELL, 41168754Sbushman TEST_BUILD_SNAPSHOT 42168754Sbushman}; 43168754Sbushman 44168754Sbushmanstruct usershell { 45168754Sbushman char *path; 46168754Sbushman}; 47168754Sbushman 48168754Sbushmanstatic int debug = 0; 49168754Sbushmanstatic enum test_methods method = TEST_GETUSERSHELL; 50168754Sbushman 51168754SbushmanDECLARE_TEST_DATA(usershell) 52168754SbushmanDECLARE_TEST_FILE_SNAPSHOT(usershell) 53168754SbushmanDECLARE_2PASS_TEST(usershell) 54168754Sbushman 55168754Sbushmanstatic void clone_usershell(struct usershell *, struct usershell const *); 56168754Sbushmanstatic int compare_usershell(struct usershell *, struct usershell *, void *); 57168754Sbushmanstatic void free_usershell(struct usershell *); 58168754Sbushman 59168754Sbushmanstatic void sdump_usershell(struct usershell *, char *, size_t); 60168754Sbushmanstatic void dump_usershell(struct usershell *); 61168754Sbushman 62168754Sbushmanstatic int usershell_read_snapshot_func(struct usershell *, char *); 63168754Sbushman 64168754Sbushmanstatic void usage(void) __attribute__((__noreturn__)); 65168754Sbushman 66168754SbushmanIMPLEMENT_TEST_DATA(usershell) 67168754SbushmanIMPLEMENT_TEST_FILE_SNAPSHOT(usershell) 68168754SbushmanIMPLEMENT_2PASS_TEST(usershell) 69168754Sbushman 70291759Sngiestatic void 71168754Sbushmanclone_usershell(struct usershell *dest, struct usershell const *src) 72168754Sbushman{ 73168754Sbushman assert(dest != NULL); 74168754Sbushman assert(src != NULL); 75291759Sngie 76168754Sbushman if (src->path != NULL) { 77168754Sbushman dest->path = strdup(src->path); 78168754Sbushman assert(dest->path != NULL); 79168754Sbushman } 80168754Sbushman} 81168754Sbushman 82291759Sngiestatic int 83168754Sbushmancompare_usershell(struct usershell *us1, struct usershell *us2, void *mdata) 84168754Sbushman{ 85168754Sbushman int rv; 86291759Sngie 87168754Sbushman assert(us1 != NULL); 88168754Sbushman assert(us2 != NULL); 89291759Sngie 90168754Sbushman dump_usershell(us1); 91168754Sbushman dump_usershell(us2); 92291759Sngie 93168754Sbushman if (us1 == us2) 94168754Sbushman return (0); 95168754Sbushman 96168754Sbushman rv = strcmp(us1->path, us2->path); 97168754Sbushman if (rv != 0) { 98168754Sbushman printf("following structures are not equal:\n"); 99168754Sbushman dump_usershell(us1); 100168754Sbushman dump_usershell(us2); 101168754Sbushman } 102291759Sngie 103168754Sbushman return (rv); 104168754Sbushman} 105168754Sbushman 106291759Sngiestatic void 107168754Sbushmanfree_usershell(struct usershell *us) 108168754Sbushman{ 109168754Sbushman free(us->path); 110168754Sbushman} 111168754Sbushman 112291759Sngiestatic void 113168754Sbushmansdump_usershell(struct usershell *us, char *buffer, size_t buflen) 114168754Sbushman{ 115168754Sbushman snprintf(buffer, buflen, "%s", us->path); 116168754Sbushman} 117168754Sbushman 118168754Sbushmanstatic void 119168754Sbushmandump_usershell(struct usershell *us) 120168754Sbushman{ 121168754Sbushman if (us != NULL) { 122168754Sbushman char buffer[2048]; 123168754Sbushman sdump_usershell(us, buffer, sizeof(buffer)); 124168754Sbushman printf("%s\n", buffer); 125168754Sbushman } else 126168754Sbushman printf("(null)\n"); 127168754Sbushman} 128168754Sbushman 129291759Sngiestatic int 130168754Sbushmanusershell_read_snapshot_func(struct usershell *us, char *line) 131168754Sbushman{ 132168754Sbushman us->path = strdup(line); 133168754Sbushman assert(us->path != NULL); 134291759Sngie 135168754Sbushman return (0); 136168754Sbushman} 137168754Sbushman 138168754Sbushmanstatic void 139168754Sbushmanusage(void) 140168754Sbushman{ 141168754Sbushman (void)fprintf(stderr, 142168754Sbushman "Usage: %s [-d] -s <file>\n", 143168754Sbushman getprogname()); 144168754Sbushman exit(1); 145168754Sbushman} 146168754Sbushman 147168754Sbushmanint 148168754Sbushmanmain(int argc, char **argv) 149168754Sbushman{ 150168754Sbushman struct usershell_test_data td, td_snap; 151168754Sbushman struct usershell ushell; 152168754Sbushman char *snapshot_file; 153168754Sbushman int rv; 154168754Sbushman int c; 155291759Sngie 156168754Sbushman if (argc < 2) 157168754Sbushman usage(); 158168754Sbushman 159168754Sbushman rv = 0; 160168754Sbushman snapshot_file = NULL; 161168754Sbushman while ((c = getopt(argc, argv, "ds:")) != -1) { 162168754Sbushman switch (c) { 163168754Sbushman case 'd': 164168754Sbushman debug = 1; 165168754Sbushman break; 166168754Sbushman case 's': 167168754Sbushman snapshot_file = strdup(optarg); 168168754Sbushman break; 169168754Sbushman default: 170168754Sbushman usage(); 171168754Sbushman } 172168754Sbushman } 173291759Sngie 174168754Sbushman TEST_DATA_INIT(usershell, &td, clone_usershell, free_usershell); 175168754Sbushman TEST_DATA_INIT(usershell, &td_snap, clone_usershell, free_usershell); 176291759Sngie 177168754Sbushman setusershell(); 178168754Sbushman while ((ushell.path = getusershell()) != NULL) { 179168754Sbushman if (debug) { 180168754Sbushman printf("usershell found:\n"); 181168754Sbushman dump_usershell(&ushell); 182168754Sbushman } 183168754Sbushman TEST_DATA_APPEND(usershell, &td, &ushell); 184168754Sbushman } 185168754Sbushman endusershell(); 186291759Sngie 187291759Sngie 188168754Sbushman if (snapshot_file != NULL) { 189291759Sngie if (access(snapshot_file, W_OK | R_OK) != 0) { 190168754Sbushman if (errno == ENOENT) 191168754Sbushman method = TEST_BUILD_SNAPSHOT; 192168754Sbushman else { 193168754Sbushman if (debug) 194168754Sbushman printf("can't access the snapshot file %s\n", 195168754Sbushman snapshot_file); 196291759Sngie 197168754Sbushman rv = -1; 198168754Sbushman goto fin; 199168754Sbushman } 200168754Sbushman } else { 201168754Sbushman rv = TEST_SNAPSHOT_FILE_READ(usershell, snapshot_file, 202168754Sbushman &td_snap, usershell_read_snapshot_func); 203168754Sbushman if (rv != 0) { 204168754Sbushman if (debug) 205168754Sbushman printf("error reading snapshot file\n"); 206168754Sbushman goto fin; 207168754Sbushman } 208168754Sbushman } 209168754Sbushman } 210291759Sngie 211168754Sbushman switch (method) { 212168754Sbushman case TEST_GETUSERSHELL: 213168754Sbushman if (snapshot_file != NULL) { 214168754Sbushman rv = DO_2PASS_TEST(usershell, &td, &td_snap, 215168754Sbushman compare_usershell, NULL); 216168754Sbushman } 217168754Sbushman break; 218168754Sbushman case TEST_BUILD_SNAPSHOT: 219168754Sbushman if (snapshot_file != NULL) { 220291759Sngie rv = TEST_SNAPSHOT_FILE_WRITE(usershell, snapshot_file, &td, 221168754Sbushman sdump_usershell); 222168754Sbushman } 223168754Sbushman break; 224168754Sbushman default: 225168754Sbushman rv = 0; 226168754Sbushman break; 227168754Sbushman }; 228168754Sbushman 229168754Sbushmanfin: 230168754Sbushman TEST_DATA_DESTROY(usershell, &td_snap); 231168754Sbushman TEST_DATA_DESTROY(usershell, &td); 232168754Sbushman free(snapshot_file); 233168754Sbushman return (rv); 234168754Sbushman 235168754Sbushman} 236