dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libadm / common / ckpath.c
blobb005c754a6bd757a693f2e6bc83a8d99c98a6b7f
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
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.
34 /*LINTLIBRARY*/
36 #include <stdio.h>
37 #include <ctype.h>
38 #include <string.h>
39 #include <limits.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include "valtools.h"
43 #include <stdlib.h>
44 #include <fcntl.h>
45 #include <unistd.h>
46 #include "libadm.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"
71 #define H_BLK E_BLK
72 #define H_CHR E_CHR
73 #define H_DIR E_DIR
74 #define H_REG E_REG
75 #define H_NONZERO E_NONZERO
77 #define MSGSIZ 1024
78 #define STDHELP \
79 "A pathname is a filename, optionally preceded by parent directories."
81 static char *errstr;
82 static char *badset = "*?[]{}()<> \t'`\"\\|^";
84 static void
85 addhlp(char *msg, char *text)
87 static int count;
89 if (text == NULL) {
90 count = 0;
91 return;
93 if (!count++)
94 (void) strcat(msg, " The pathname you enter:");
95 (void) strcat(msg, "\\n\\t-\\ ");
96 (void) strcat(msg, text);
99 static char *
100 sethlp(int pflags)
102 char *msg;
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);
118 if (pflags & P_READ)
119 addhlp(msg, H_READ);
120 if (pflags & P_WRITE)
121 addhlp(msg, H_WRITE);
122 if (pflags & P_EXEC)
123 addhlp(msg, H_EXEC);
124 if (pflags & P_CREAT)
125 addhlp(msg, H_CREAT);
127 if (pflags & P_BLK)
128 addhlp(msg, H_BLK);
129 else if (pflags & P_CHR)
130 addhlp(msg, H_CHR);
131 else if (pflags & P_DIR)
132 addhlp(msg, H_DIR);
133 else if (pflags & P_REG)
134 addhlp(msg, H_REG);
136 if (pflags & P_NONZERO)
137 addhlp(msg, H_NONZERO);
139 return (msg);
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))) {
152 return (1);
154 return (0);
158 ckpath_val(char *path, int pflags)
160 struct stat64 status;
161 int fd;
162 char *pt;
164 if ((pflags & P_RELATIVE) && (*path == '/')) {
165 errstr = E_RELATIVE;
166 return (1);
168 if ((pflags & P_ABSOLUTE) && (*path != '/')) {
169 errstr = E_ABSOLUTE;
170 return (1);
172 if (stat64(path, &status)) {
173 if (pflags & P_EXIST) {
174 errstr = E_EXIST;
175 return (1);
177 for (pt = path; *pt; pt++) {
178 if (!isprint((unsigned char)*pt) ||
179 strchr(badset, *pt)) {
180 errstr = E_SYNTAX;
181 return (1);
184 if (pflags & P_CREAT) {
185 if (pflags & P_DIR) {
186 if ((mkdir(path, 0755)) != 0) {
187 errstr = E_CREAT;
188 return (1);
190 } else {
191 if ((fd = creat(path, 0644)) < 0) {
192 errstr = E_CREAT;
193 return (1);
195 (void) close(fd);
198 return (0);
199 } else if (pflags & P_NEXIST) {
200 errstr = E_NEXIST;
201 return (1);
203 if ((status.st_mode & S_IFMT) == S_IFREG) {
204 /* check non zero status */
205 if ((pflags & P_NONZERO) && (status.st_size < 1)) {
206 errstr = E_NONZERO;
207 return (1);
210 if ((pflags & P_CHR) && ((status.st_mode & S_IFMT) != S_IFCHR)) {
211 errstr = E_CHR;
212 return (1);
214 if ((pflags & P_BLK) && ((status.st_mode & S_IFMT) != S_IFBLK)) {
215 errstr = E_BLK;
216 return (1);
218 if ((pflags & P_DIR) && ((status.st_mode & S_IFMT) != S_IFDIR)) {
219 errstr = E_DIR;
220 return (1);
222 if ((pflags & P_REG) && ((status.st_mode & S_IFMT) != S_IFREG)) {
223 errstr = E_REG;
224 return (1);
226 if ((pflags & P_READ) && !(status.st_mode & S_IREAD)) {
227 errstr = E_READ;
228 return (1);
230 if ((pflags & P_WRITE) && !(status.st_mode & S_IWRITE)) {
231 errstr = E_WRITE;
232 return (1);
234 if ((pflags & P_EXEC) && !(status.st_mode & S_IEXEC)) {
235 errstr = E_EXEC;
236 return (1);
238 return (0);
241 void
242 ckpath_err(int pflags, char *error, char *input)
244 char buffer[2048];
245 char *defhlp;
247 if (input) {
248 if (ckpath_val(input, pflags)) {
249 (void) snprintf(buffer, sizeof (buffer),
250 "Pathname %s.", errstr);
251 puterror(stdout, buffer, error);
252 return;
255 defhlp = sethlp(pflags);
256 puterror(stdout, defhlp, error);
257 free(defhlp);
260 void
261 ckpath_hlp(int pflags, char *help)
263 char *defhlp;
265 defhlp = sethlp(pflags);
266 puthelp(stdout, defhlp, help);
267 free(defhlp);
271 ckpath(char *pathval, int pflags, char *defstr, char *error, char *help,
272 char *prompt)
274 char *defhlp,
275 input[MAX_INPUT],
276 buffer[256];
278 if ((pathval == NULL) || ckpath_stx(pflags))
279 return (2); /* usage error */
281 if (!prompt) {
282 if (pflags & P_ABSOLUTE)
283 prompt = "Enter an absolute pathname";
284 else if (pflags & P_RELATIVE)
285 prompt = "Enter a relative pathname";
286 else
287 prompt = "Enter a pathname";
289 defhlp = sethlp(pflags);
291 start:
292 putprmpt(stderr, prompt, NULL, defstr);
293 if (getinput(input)) {
294 free(defhlp);
295 return (1);
298 if (strlen(input) == 0) {
299 if (defstr) {
300 (void) strcpy(pathval, defstr);
301 free(defhlp);
302 return (0);
304 puterror(stderr, NULL, "Input is required.");
305 goto start;
307 if (strcmp(input, "?") == 0) {
308 puthelp(stderr, defhlp, help);
309 goto start;
311 if (ckquit && (strcmp(input, "q") == 0)) {
312 free(defhlp);
313 return (3);
316 if (ckpath_val(input, pflags)) {
317 (void) snprintf(buffer, sizeof (buffer),
318 "Pathname %s.", errstr);
319 puterror(stderr, buffer, error);
320 goto start;
322 (void) strcpy(pathval, input);
323 free(defhlp);
324 return (0);