1*6d38604fSBaptiste Daroussin /* $Id: compat_mkdtemp.c,v 1.4 2021/09/19 15:02:55 schwarze Exp $ */
261d06d6bSBaptiste Daroussin /*
3*6d38604fSBaptiste Daroussin * Copyright (c) 2015, 2021 Ingo Schwarze <schwarze@openbsd.org>
461d06d6bSBaptiste Daroussin *
561d06d6bSBaptiste Daroussin * Permission to use, copy, modify, and distribute this software for any
661d06d6bSBaptiste Daroussin * purpose with or without fee is hereby granted, provided that the above
761d06d6bSBaptiste Daroussin * copyright notice and this permission notice appear in all copies.
861d06d6bSBaptiste Daroussin *
961d06d6bSBaptiste Daroussin * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1061d06d6bSBaptiste Daroussin * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1161d06d6bSBaptiste Daroussin * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1261d06d6bSBaptiste Daroussin * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1361d06d6bSBaptiste Daroussin * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1461d06d6bSBaptiste Daroussin * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1561d06d6bSBaptiste Daroussin * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1661d06d6bSBaptiste Daroussin *
1761d06d6bSBaptiste Daroussin * The algorithm of this function is inspired by OpenBSD mkdtemp(3)
1861d06d6bSBaptiste Daroussin * by Theo de Raadt and Todd Miller, but the code differs.
1961d06d6bSBaptiste Daroussin */
20*6d38604fSBaptiste Daroussin #include "config.h"
2161d06d6bSBaptiste Daroussin
2261d06d6bSBaptiste Daroussin #include <sys/stat.h>
2361d06d6bSBaptiste Daroussin #include <errno.h>
2461d06d6bSBaptiste Daroussin #include <limits.h>
2561d06d6bSBaptiste Daroussin #include <stdlib.h>
2661d06d6bSBaptiste Daroussin #include <string.h>
2761d06d6bSBaptiste Daroussin
2861d06d6bSBaptiste Daroussin char *
mkdtemp(char * path)2961d06d6bSBaptiste Daroussin mkdtemp(char *path)
3061d06d6bSBaptiste Daroussin {
3161d06d6bSBaptiste Daroussin char *start, *cp;
3261d06d6bSBaptiste Daroussin unsigned int tries;
3361d06d6bSBaptiste Daroussin
3461d06d6bSBaptiste Daroussin start = strchr(path, '\0');
3561d06d6bSBaptiste Daroussin while (start > path && start[-1] == 'X')
3661d06d6bSBaptiste Daroussin start--;
3761d06d6bSBaptiste Daroussin
3861d06d6bSBaptiste Daroussin for (tries = INT_MAX; tries; tries--) {
39*6d38604fSBaptiste Daroussin if (mktemp(path) == NULL)
4061d06d6bSBaptiste Daroussin return NULL;
4161d06d6bSBaptiste Daroussin if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR) == 0)
4261d06d6bSBaptiste Daroussin return path;
4361d06d6bSBaptiste Daroussin for (cp = start; *cp != '\0'; cp++)
4461d06d6bSBaptiste Daroussin *cp = 'X';
45*6d38604fSBaptiste Daroussin if (errno != EEXIST)
46*6d38604fSBaptiste Daroussin return NULL;
4761d06d6bSBaptiste Daroussin }
4861d06d6bSBaptiste Daroussin errno = EEXIST;
4961d06d6bSBaptiste Daroussin return NULL;
5061d06d6bSBaptiste Daroussin }
51