GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/gen/getusershell.c Lines: 0 44 0.0 %
Date: 2017-11-13 Branches: 0 27 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: getusershell.c,v 1.17 2015/12/08 16:28:26 tedu Exp $ */
2
/*
3
 * Copyright (c) 1985, 1993
4
 *	The Regents of the University of California.  All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the University nor the names of its contributors
15
 *    may be used to endorse or promote products derived from this software
16
 *    without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 */
30
31
#include <ctype.h>
32
#include <limits.h>
33
#include <paths.h>
34
#include <stdint.h>
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
#include <unistd.h>
39
40
/*
41
 * Local shells should NOT be added here.  They should be added in
42
 * /etc/shells.
43
 */
44
45
static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, _PATH_KSHELL, NULL };
46
static char **curshell, **shells;
47
static char **initshells(void);
48
49
/*
50
 * Get a list of shells from _PATH_SHELLS, if it exists.
51
 */
52
char *
53
getusershell(void)
54
{
55
	char *ret;
56
57
	if (curshell == NULL)
58
		curshell = initshells();
59
	ret = *curshell;
60
	if (ret != NULL)
61
		curshell++;
62
	return (ret);
63
}
64
65
void
66
endusershell(void)
67
{
68
	char **s;
69
70
	if ((s = shells))
71
		while (*s)
72
			free(*s++);
73
	free(shells);
74
	shells = NULL;
75
76
	curshell = NULL;
77
}
78
79
void
80
setusershell(void)
81
{
82
83
	curshell = initshells();
84
}
85
86
static char **
87
initshells(void)
88
{
89
	size_t nshells, nalloc, linesize;
90
	char *line;
91
	FILE *fp;
92
93
	free(shells);
94
	shells = NULL;
95
96
	if ((fp = fopen(_PATH_SHELLS, "re")) == NULL)
97
		return (okshells);
98
99
	line = NULL;
100
	nalloc = 10; // just an initial guess
101
	nshells = 0;
102
	shells = reallocarray(NULL, nalloc, sizeof (char *));
103
	if (shells == NULL)
104
		goto fail;
105
	linesize = 0;
106
	while (getline(&line, &linesize, fp) != -1) {
107
		if (*line != '/')
108
			continue;
109
		line[strcspn(line, "#\n")] = '\0';
110
		if (!(shells[nshells] = strdup(line)))
111
			goto fail;
112
113
		if (nshells + 1 == nalloc) {
114
			char **new = reallocarray(shells, nalloc * 2, sizeof(char *));
115
			if (!new)
116
				goto fail;
117
			shells = new;
118
			nalloc *= 2;
119
		}
120
		nshells++;
121
	}
122
	free(line);
123
	shells[nshells] = NULL;
124
	(void)fclose(fp);
125
	return (shells);
126
127
fail:
128
	free(line);
129
	while (nshells)
130
		free(shells[nshells--]);
131
	free(shells);
132
	shells = NULL;
133
	(void)fclose(fp);
134
	return (okshells);
135
}