GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/mg/dir.c Lines: 0 78 0.0 %
Date: 2017-11-13 Branches: 0 54 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: dir.c,v 1.30 2017/05/30 07:05:22 florian Exp $	*/
2
3
/* This file is in the public domain. */
4
5
/*
6
 * Name:	MG 2a
7
 *		Directory management functions
8
 * Created:	Ron Flax (ron@vsedev.vse.com)
9
 *		Modified for MG 2a by Mic Kaczmarczik 03-Aug-1987
10
 */
11
12
#include <sys/queue.h>
13
#include <sys/stat.h>
14
#include <signal.h>
15
#include <stdio.h>
16
#include <string.h>
17
#include <unistd.h>
18
19
#include "def.h"
20
21
static char	 mgcwd[NFILEN];
22
23
/*
24
 * Initialize anything the directory management routines need.
25
 */
26
void
27
dirinit(void)
28
{
29
	mgcwd[0] = '\0';
30
	if (getcwd(mgcwd, sizeof(mgcwd)) == NULL)
31
		ewprintf("Can't get current directory!");
32
	if (mgcwd[0] != '\0' && !(mgcwd[0] == '/' && mgcwd[1] == '\0'))
33
		(void)strlcat(mgcwd, "/", sizeof(mgcwd));
34
}
35
36
/*
37
 * Change current working directory.
38
 */
39
/* ARGSUSED */
40
int
41
changedir(int f, int n)
42
{
43
	char	bufc[NFILEN], *bufp;
44
45
	(void)strlcpy(bufc, mgcwd, sizeof(bufc));
46
	if ((bufp = eread("Change default directory: ", bufc, NFILEN,
47
	    EFDEF | EFNEW | EFCR | EFFILE)) == NULL)
48
		return (ABORT);
49
	else if (bufp[0] == '\0')
50
		return (FALSE);
51
	/* Append trailing slash */
52
	if (chdir(bufc) == -1) {
53
		dobeep();
54
		ewprintf("Can't change dir to %s", bufc);
55
		return (FALSE);
56
	}
57
	if ((bufp = getcwd(mgcwd, sizeof(mgcwd))) == NULL) {
58
		if (bufc[0] == '/')
59
			(void)strlcpy(mgcwd, bufc, sizeof(mgcwd));
60
		else
61
			(void)strlcat(mgcwd, bufc, sizeof(mgcwd));
62
	}
63
	if (mgcwd[strlen(mgcwd) - 1] != '/')
64
		(void)strlcat(mgcwd, "/", sizeof(mgcwd));
65
	ewprintf("Current directory is now %s", mgcwd);
66
	return (TRUE);
67
}
68
69
/*
70
 * Show current directory.
71
 */
72
/* ARGSUSED */
73
int
74
showcwdir(int f, int n)
75
{
76
	ewprintf("Current directory: %s", mgcwd);
77
	return (TRUE);
78
}
79
80
int
81
getcwdir(char *buf, size_t len)
82
{
83
	if (strlcpy(buf, mgcwd, len) >= len)
84
		return (FALSE);
85
86
	return (TRUE);
87
}
88
89
/* Create the directory and it's parents. */
90
/* ARGSUSED */
91
int
92
makedir(int f, int n)
93
{
94
	return (ask_makedir());
95
}
96
97
int
98
ask_makedir(void)
99
{
100
101
	char		 bufc[NFILEN];
102
	char		*path;
103
104
	if (getbufcwd(bufc, sizeof(bufc)) != TRUE)
105
		return (ABORT);
106
	if ((path = eread("Make directory: ", bufc, NFILEN,
107
	    EFDEF | EFNEW | EFCR | EFFILE)) == NULL)
108
		return (ABORT);
109
	else if (path[0] == '\0')
110
		return (FALSE);
111
112
	return (do_makedir(path));
113
}
114
115
int
116
do_makedir(char *path)
117
{
118
	struct stat	 sb;
119
	int		 finished, ishere;
120
	mode_t		 dir_mode, f_mode, oumask;
121
	char		*slash;
122
123
	if ((path = adjustname(path, TRUE)) == NULL)
124
		return (FALSE);
125
126
	/* Remove trailing slashes */
127
	slash = strrchr(path, '\0');
128
	while (--slash > path && *slash == '/')
129
		*slash = '\0';
130
131
	slash = path;
132
133
	oumask = umask(0);
134
	f_mode = 0777 & ~oumask;
135
	dir_mode = f_mode | S_IWUSR | S_IXUSR;
136
137
	for (;;) {
138
		slash += strspn(slash, "/");
139
		slash += strcspn(slash, "/");
140
141
		finished = (*slash == '\0');
142
		*slash = '\0';
143
144
		ishere = !stat(path, &sb);
145
		if (finished && ishere) {
146
			dobeep();
147
			ewprintf("Cannot create directory %s: file exists",
148
			     path);
149
			return(FALSE);
150
		} else if (!finished && ishere && S_ISDIR(sb.st_mode)) {
151
			*slash = '/';
152
			continue;
153
		}
154
155
		if (mkdir(path, finished ? f_mode : dir_mode) == 0) {
156
			if (f_mode > 0777 && chmod(path, f_mode) < 0) {
157
				umask(oumask);
158
				return (ABORT);
159
			}
160
		} else {
161
			if (!ishere || !S_ISDIR(sb.st_mode)) {
162
				if (!ishere) {
163
					dobeep();
164
					ewprintf("Creating directory: "
165
					    "permission denied, %s", path);
166
				} else
167
					eerase();
168
169
				umask(oumask);
170
				return (FALSE);
171
			}
172
		}
173
174
		if (finished)
175
			break;
176
177
		*slash = '/';
178
	}
179
180
	eerase();
181
	umask(oumask);
182
	return (TRUE);
183
}