/* * 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 . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #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; }