summaryrefslogtreecommitdiff
path: root/src/tet3/dtet2lib/madir.c
blob: ef33b040d4d93b1b61607b52a7f7a40f2c4982f8 (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
132
/*
 *      SCCS:  @(#)madir.c	1.9 (96/11/04) 
 *
 *	UniSoft Ltd., London, England
 *
 * (C) Copyright 1992 X/Open Company Limited
 *
 * All rights reserved.  No part of this source code may be reproduced,
 * stored in a retrieval system, or transmitted, in any form or by any
 * means, electronic, mechanical, photocopying, recording or otherwise,
 * except as stated in the end-user licence agreement, without the prior
 * permission of the copyright owners.
 *
 * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
 * the UK and other countries.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/************************************************************************

SCCS:   	@(#)madir.c	1.9 96/11/04 TETware release 3.3
NAME:		madir.c
PRODUCT:	TETware
AUTHOR:		Andrew Dingwall, UniSoft Ltd.
DATE CREATED:	June 1992

DESCRIPTION:
	recursive directory creation function

MODIFICATIONS:

************************************************************************/

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "dtmac.h"
#include "error.h"
#include "dtetlib.h"

/* mode for created directories */
#define MODEANY		((mode_t) (S_IRWXU | S_IRWXG | S_IRWXO))

/* static function declarations */
static int mkad2 PROTOLIST((char *));


/*
**	tet_mkalldirs() - make directories as necessary in a directory path
**
**	return 0 if successful, -1 otherwise
*/

int tet_mkalldirs(path)
char *path;
{
	register int rc;
	struct STAT_ST stbuf;
	char buf[MAXPATH + 1];

	if (STAT(path, &stbuf) < 0) {
		if (errno == ENOENT) {
			(void) sprintf(buf, "%.*s", (int)sizeof buf - 1, path);
			rc = mkad2(buf);
		}
		else {
			error(errno, "can't stat", path);
			rc = -1;
		}
	}
	else
		rc = 0;

	return(rc);
}

/*
**	mkad2() - make directories as necessary when the last component in the
**	path is known not to exist
**
**	return 0 if successful, -1 otherwise
*/

static int mkad2(path)
char *path;
{
	register char *p;
	register int rc;
	struct STAT_ST stbuf;
	int errsave;

	ASSERT(*path);

	/* find the last / character (if any) */
	for (p = path + strlen(path) - 1; p >= path; p--)
		if (isdirsep(*p))
			break;

	/* if found:
		replace it with a \0 
		if the parent directory does not exist, create that as well
		restore the / */
	if (p > path) {
		*p = '\0';
		if (STAT(path, &stbuf) < 0)
			rc = mkad2(path);
		else if (!S_ISDIR(stbuf.st_mode)) {
			error(ENOTDIR, path, (char *) 0);
			rc = -1;
		}
		else
			rc = 0;
		*p = '/';
		if (rc < 0)
			return(rc);
	}

	/* finally, create the directory on this level */
	if ((rc = tet_mkdir(path, MODEANY)) < 0) {
		errsave = errno;
		error(errno, "can't make directory", path);
		errno = errsave;
	}

	return(rc);
}