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
|
/*
* Copyright 2009 Oracle. All rights reserved.
* Copyright 2017 Red Hat, Inc. All rights reserved.
*
* This file is part of nfs-utils.
*
* nfs-utils is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* nfs-utils is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with nfs-utils. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/stat.h>
#include <string.h>
#include <libgen.h>
#include <stdio.h>
#include <errno.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#include "xlog.h"
#include "misc.h"
/*
* Returns a dynamically allocated, '\0'-terminated buffer
* containing an appropriate pathname, or NULL if an error
* occurs. Caller must free the returned result with free(3).
*/
__attribute__((__malloc__))
char *
generic_make_pathname(const char *base, const char *leaf)
{
size_t size;
char *path;
int len;
size = strlen(base) + strlen(leaf) + 2;
if (size > PATH_MAX)
return NULL;
path = malloc(size);
if (path == NULL)
return NULL;
len = snprintf(path, size, "%s/%s", base, leaf);
if ((len < 0) || ((size_t)len >= size)) {
free(path);
return NULL;
}
return path;
}
/**
* generic_setup_basedir - set up basedir
* @progname: C string containing name of program, for error messages
* @parentdir: C string containing pathname to on-disk state, or NULL
* @base: character buffer to contain the basedir that is set up
* @baselen: size of @base in bytes
*
* This runs before logging is set up, so error messages are directed
* to stderr.
*
* Returns true and sets up our basedir, if @parentdir was valid
* and usable; otherwise false is returned.
*/
_Bool
generic_setup_basedir(const char *progname, const char *parentdir, char *base,
const size_t baselen)
{
static char buf[PATH_MAX];
struct stat st;
char *path;
/* First: test length of name and whether it exists */
if ((strlen(parentdir) >= baselen) || (strlen(parentdir) >= PATH_MAX)) {
(void)fprintf(stderr, "%s: Directory name too long: %s",
progname, parentdir);
return false;
}
if (lstat(parentdir, &st) == -1) {
(void)fprintf(stderr, "%s: Failed to stat %s: %s",
progname, parentdir, strerror(errno));
return false;
}
/* Ensure we have a clean directory pathname */
strncpy(buf, parentdir, sizeof(buf)-1);
path = dirname(buf);
if (*path == '.') {
(void)fprintf(stderr, "%s: Unusable directory %s",
progname, parentdir);
return false;
}
xlog(D_CALL, "Using %s as the state directory", parentdir);
strcpy(base, parentdir);
return true;
}
|