4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright (c) 1996-1998, 2001 by Sun Microsystems, Inc.
28 * All rights reserved.
31 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
40 #include <sys/types.h>
48 #define E_SYNTAX "does not meet suggested filename syntax standard"
49 #define E_READ "is not readable"
50 #define E_WRITE "is not writable"
51 #define E_EXEC "is not executable"
52 #define E_CREAT "cannot be created"
53 #define E_ABSOLUTE "must begin with a slash (/)"
54 #define E_RELATIVE "must not begin with a slash (/)"
55 #define E_EXIST "does not exist"
56 #define E_NEXIST "must not already exist"
57 #define E_BLK "must specify a block special device"
58 #define E_CHR "must specify a character special device"
59 #define E_DIR "must specify a directory"
60 #define E_REG "must be a regular file"
61 #define E_NONZERO "must be a file of non-zero length"
63 #define H_READ "must be readable"
64 #define H_WRITE "must be writable"
65 #define H_EXEC "must be executable"
66 #define H_CREAT "will be created if it does not exist"
67 #define H_ABSOLUTE E_ABSOLUTE
68 #define H_RELATIVE E_RELATIVE
69 #define H_EXIST "must already exist"
70 #define H_NEXIST "must not already exist"
75 #define H_NONZERO E_NONZERO
79 "A pathname is a filename, optionally preceded by parent directories."
82 static char *badset
= "*?[]{}()<> \t'`\"\\|^";
85 addhlp(char *msg
, char *text
)
94 (void) strcat(msg
, " The pathname you enter:");
95 (void) strcat(msg
, "\\n\\t-\\ ");
96 (void) strcat(msg
, text
);
104 msg
= calloc(MSGSIZ
, sizeof (char));
105 addhlp(msg
, NULL
); /* initialize count */
106 (void) strcpy(msg
, STDHELP
);
108 if (pflags
& P_EXIST
)
109 addhlp(msg
, H_EXIST
);
110 else if (pflags
& P_NEXIST
)
111 addhlp(msg
, H_NEXIST
);
113 if (pflags
& P_ABSOLUTE
)
114 addhlp(msg
, H_ABSOLUTE
);
115 else if (pflags
& P_RELATIVE
)
116 addhlp(msg
, H_RELATIVE
);
120 if (pflags
& P_WRITE
)
121 addhlp(msg
, H_WRITE
);
124 if (pflags
& P_CREAT
)
125 addhlp(msg
, H_CREAT
);
129 else if (pflags
& P_CHR
)
131 else if (pflags
& P_DIR
)
133 else if (pflags
& P_REG
)
136 if (pflags
& P_NONZERO
)
137 addhlp(msg
, H_NONZERO
);
143 ckpath_stx(int pflags
)
145 if (((pflags
& P_ABSOLUTE
) && (pflags
& P_RELATIVE
)) ||
146 ((pflags
& P_NEXIST
) && (pflags
&
147 (P_EXIST
|P_NONZERO
|P_READ
|P_WRITE
|P_EXEC
))) ||
148 ((pflags
& P_CREAT
) && (pflags
& (P_EXIST
|P_NEXIST
|P_BLK
|P_CHR
))) ||
149 ((pflags
& P_BLK
) && (pflags
& (P_CHR
|P_REG
|P_DIR
|P_NONZERO
))) ||
150 ((pflags
& P_CHR
) && (pflags
& (P_REG
|P_DIR
|P_NONZERO
))) ||
151 ((pflags
& P_DIR
) && (pflags
& P_REG
))) {
158 ckpath_val(char *path
, int pflags
)
160 struct stat64 status
;
164 if ((pflags
& P_RELATIVE
) && (*path
== '/')) {
168 if ((pflags
& P_ABSOLUTE
) && (*path
!= '/')) {
172 if (stat64(path
, &status
)) {
173 if (pflags
& P_EXIST
) {
177 for (pt
= path
; *pt
; pt
++) {
178 if (!isprint((unsigned char)*pt
) ||
179 strchr(badset
, *pt
)) {
184 if (pflags
& P_CREAT
) {
185 if (pflags
& P_DIR
) {
186 if ((mkdir(path
, 0755)) != 0) {
191 if ((fd
= creat(path
, 0644)) < 0) {
199 } else if (pflags
& P_NEXIST
) {
203 if ((status
.st_mode
& S_IFMT
) == S_IFREG
) {
204 /* check non zero status */
205 if ((pflags
& P_NONZERO
) && (status
.st_size
< 1)) {
210 if ((pflags
& P_CHR
) && ((status
.st_mode
& S_IFMT
) != S_IFCHR
)) {
214 if ((pflags
& P_BLK
) && ((status
.st_mode
& S_IFMT
) != S_IFBLK
)) {
218 if ((pflags
& P_DIR
) && ((status
.st_mode
& S_IFMT
) != S_IFDIR
)) {
222 if ((pflags
& P_REG
) && ((status
.st_mode
& S_IFMT
) != S_IFREG
)) {
226 if ((pflags
& P_READ
) && !(status
.st_mode
& S_IREAD
)) {
230 if ((pflags
& P_WRITE
) && !(status
.st_mode
& S_IWRITE
)) {
234 if ((pflags
& P_EXEC
) && !(status
.st_mode
& S_IEXEC
)) {
242 ckpath_err(int pflags
, char *error
, char *input
)
248 if (ckpath_val(input
, pflags
)) {
249 (void) snprintf(buffer
, sizeof (buffer
),
250 "Pathname %s.", errstr
);
251 puterror(stdout
, buffer
, error
);
255 defhlp
= sethlp(pflags
);
256 puterror(stdout
, defhlp
, error
);
261 ckpath_hlp(int pflags
, char *help
)
265 defhlp
= sethlp(pflags
);
266 puthelp(stdout
, defhlp
, help
);
271 ckpath(char *pathval
, int pflags
, char *defstr
, char *error
, char *help
,
278 if ((pathval
== NULL
) || ckpath_stx(pflags
))
279 return (2); /* usage error */
282 if (pflags
& P_ABSOLUTE
)
283 prompt
= "Enter an absolute pathname";
284 else if (pflags
& P_RELATIVE
)
285 prompt
= "Enter a relative pathname";
287 prompt
= "Enter a pathname";
289 defhlp
= sethlp(pflags
);
292 putprmpt(stderr
, prompt
, NULL
, defstr
);
293 if (getinput(input
)) {
298 if (strlen(input
) == 0) {
300 (void) strcpy(pathval
, defstr
);
304 puterror(stderr
, NULL
, "Input is required.");
307 if (strcmp(input
, "?") == 0) {
308 puthelp(stderr
, defhlp
, help
);
311 if (ckquit
&& (strcmp(input
, "q") == 0)) {
316 if (ckpath_val(input
, pflags
)) {
317 (void) snprintf(buffer
, sizeof (buffer
),
318 "Pathname %s.", errstr
);
319 puterror(stderr
, buffer
, error
);
322 (void) strcpy(pathval
, input
);