// MIT/X Consortium License
//
// © 2011 Connor Lane Smith <cls@lubutu.com>
// © 2011-2016 Dimitris Papastamos <sin@2f30.org>
// © 2014-2016 Laslo Hunhold <dev@frign.de>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Authors/contributors include:
//
// © 2011 Kamil Cholewiński <harry666t@gmail.com>
// © 2011 Rob Pilling <robpilling@gmail.com>
// © 2011 Hiltjo Posthuma <hiltjo@codemadness.org>
// © 2011 pancake <pancake@youterm.com>
// © 2011 Random832 <random832@fastmail.us>
// © 2012 William Haddon <william@haddonthethird.net>
// © 2012 Kurt H. Maier <khm@sciops.net>
// © 2012 Christoph Lohmann <20h@r-36.net>
// © 2012 David Galos <galosd83@students.rowan.edu>
// © 2012 Robert Ransom <rransom.8774@gmail.com>
// © 2013 Jakob Kramer <jakob.kramer@gmx.de>
// © 2013 Anselm R Garbe <anselm@garbe.us>
// © 2013 Truls Becken <truls.becken@gmail.com>
// © 2013 dsp <dsp@2f30.org>
// © 2013 Markus Teich <markus.teich@stusta.mhn.de>
// © 2013 Jesse Ogle <jesse.p.ogle@gmail.com>
// © 2013 Lorenzo Cogotti <miciamail@hotmail.it>
// © 2013 Federico G. Benavento <benavento@gmail.com>
// © 2013 Roberto E. Vargas Caballero <k0ga@shike2.com>
// © 2013 Christian Hesse <mail@eworm.de>
// © 2013 Markus Wichmann <nullplan@gmx.net>
// © 2014 Silvan Jegen <s.jegen@gmail.com>
// © 2014 Daniel Bainton <dpb@driftaway.org>
// © 2014 Tuukka Kataja <stuge@xor.fi>
// © 2014 Jeffrey Picard <jeff@jeffreypicard.com>
// © 2014 Evan Gates <evan.gates@gmail.com>
// © 2014 Michael Forney <mforney@mforney.org>
// © 2014 Ari Malinen <ari.malinen@gmail.com>
// © 2014 Brandon Mulcahy <brandon@jangler.info>
// © 2014 Adria Garriga <rhaps0dy@installgentoo.com>
// © 2014-2015 Greg Reagle <greg.reagle@umbc.edu>
// © 2015 Tai Chi Minh Ralph Eastwood <tcmreastwood@gmail.com>
// © 2015 Quentin Rameau <quinq@quinq.eu.org>
// © 2015 Dionysis Grigoropoulos <info@erethon.com>
// © 2015 Wolfgang Corcoran-Mathe <wcm@sigwinch.xyz>
// © 2016 Mattias Andrée <maandree@kth.se>
// © 2016 Eivind Uggedal <eivind@uggedal.com>

#include "config.h"

#include <sys/stat.h>
#if HAVE_ERR
# include <err.h>
#endif
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#include "io.h"

bool
mkdirp(const char *path)
{
	mode_t mask = umask(0);
	umask(mask);
	mode_t mode = 0777 & ~mask;
	mode_t pmode = 0777 & (~mask | 0300);

	char tmp[PATH_MAX], *p;
	struct stat st;

	if (stat(path, &st) == 0) {
		if (S_ISDIR(st.st_mode))
			return true;
		errno = ENOTDIR;
		return false;
	}

	if (strlcpy(tmp, path, sizeof(tmp)) >= sizeof(tmp))
		errx(1, "strlcpy: input string too long");
	for (p = tmp + (tmp[0] == '/'); *p; p++) {
		if (*p != '/')
			continue;
		*p = '\0';
		if (mkdir(tmp, pmode) < 0 && errno != EEXIST) {
			return false;
		}
		*p = '/';
	}
	if (mkdir(tmp, mode) < 0 && errno != EEXIST) {
		return false;
	}
	return true;
}
