summaryrefslogtreecommitdiff
path: root/confget_common.c
blob: 0ec58a10cdd9989617439a5c00f66cbcd4caa7cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*-
 * SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <err.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "confget.h"
#include "confget_common.h"
#include "readaline.h"

/* Is conffile pointing to stdin? */
static bool	 is_stdin;

/***
 * Function:
 *	common_openfile		- open any type of file for reading
 * Inputs:
 *	None.
 * Returns:
 *	0 on success, -1 on error.
 * Modifies:
 *	Stores the opened file into conffile.
 */
void
common_openfile(void)
{
	if (filename == NULL)
		errx(1, "No configuration file name specified");
	if (strcmp(filename, "-") == 0) {
		conffile = stdin;
		is_stdin = true;
		return;
	}

	FILE * const ifp = fopen(filename, "r");
	if (ifp == NULL)
		err(1, "Opening the input file %s", filename);
	conffile = ifp;
	is_stdin = false;
}

/***
 * Function:
 *	common_openfile_null	- do not open any file for methods that do not
 *				  take their input from files
 * Inputs:
 *	None.
 * Returns:
 *	Nothing.
 * Modifies:
 *	Stores a null value into conffile.
 */
void
common_openfile_null(void)
{
	conffile = NULL;
	is_stdin = false;
}

/***
 * Function:
 *	common_closefile	- close a scanned file
 * Inputs:
 *	None.
 * Returns:
 *	Nothing; exits on error.
 * Modifies:
 *	Closes the file pointed to by fp.
 */
void
common_closefile(void)
{
	if (conffile == NULL)
		return;
	if (!is_stdin)
		if (fclose(conffile) == EOF)
			err(1, "Could not close the config file");
	conffile = NULL;
}

/***
 * Function:
 *	confgetline		- read a line from a file
 * Inputs:
 *	fp			- the file to read from
 *	line			- a pointer to a location to store the line
 *	n			- the location to store the line length
 * Returns:
 *	The line pointer on success, NULL on error or EOF.
 * Modifies:
 *	Reallocates a buffer at *line to as much as needed.
 */
char *
confgetline(FILE * const fp, char ** const line, size_t * const len)
{
#if defined(HAVE_GETLINE)
	ssize_t r = getline(line, len, fp);
	if (r == -1)
		return (NULL);
	while (r > 0 && ((*line)[r - 1] == '\r' || (*line)[r - 1] == '\n'))
		(*line)[--r] = '\0';
	return (*line);
#elif defined(HAVE_FGETLN)
	size_t n;
	char * const p = fgetln(fp, &n);
	if (p == NULL)
		return (NULL);
	while (n > 0 && (p[n - 1] == '\r' || p[n - 1] == '\n'))
		n--;
	char *q;
	if (*line == NULL || *len < n + 1) {
		q = realloc(*line, n + 1);
		if (q == NULL)
			return (NULL);
		*line = q;
		*len = n + 1;
	} else {
		q = *line;
	}
	memcpy(q, p, n);
	q[n] = '\0';
	return (q);
#elif !defined(CONFGET_MAKEDEP)
#error Neither HAVE_GETLINE nor HAVE_FGETLN defined!
#endif
}