• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.  Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  *
23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24  * Mountain View, CA  94043, or:
25  *
26  * http://www.sgi.com
27  *
28  * For further information regarding this notice, see:
29  *
30  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31  */
32 /**************************************************************
33  *
34  *    OS Testing - Silicon Graphics, Inc.
35  *
36  *    FUNCTION NAME     : parse_open_flags
37  *			  openflags2symbols
38  *
39  *    FUNCTION TITLE    : converts open flag symbols into bitmask
40  *			  converts open flag bitmask into symbols
41  *
42  *    SYNOPSIS:
43  *      int parse_open_flags(symbols, badname)
44  *	char *symbols;
45  *	char **badname;
46  *
47  *      char *openflags2symbols(openflags, sep, mode)
48  *	int openflags;
49  *	char *sep;
50  *	int mode;
51  *
52  *    AUTHOR            : Richard Logan
53  *
54  *    CO-PILOT(s)       : Dean Roehrich
55  *
56  *    INITIAL RELEASE   : UNICOS 8.0
57  *
58  *    DESIGN DESCRIPTION
59  *	The parse_open_flags function can be used to convert
60  *	a list of comma separated open(2) flag symbols (i.e. O_TRUNC)
61  *	into the bitmask that can be used by open(2).
62  *	If a symbol is unknown and <badname> is not NULL, <badname>
63  *	will updated to point that symbol in <string>.
64  *	Parse_open_flags will return -1 on this error.
65  *      Otherwise parse_open_flags will return the open flag bitmask.
66  *	If parse_open_flags returns, <string> will left unchanged.
67  *
68  * 	The openflags2symbols function attempts to convert open flag
69  *	bits into human readable  symbols (i.e. O_TRUNC).  If there
70  *	are more than one symbol, the <sep> string will be placed as
71  *	a separator between symbols.  Commonly used separators would
72  *	be a comma "," or pipe "|".  If <mode> is one and not all
73  *	<openflags> bits can be converted to symbols, the "UNKNOWN"
74  *	symbol will be added to return string.
75  * 	Openflags2symbols will return the indentified symbols.
76  * 	If no symbols are recognized the return value will be a empty
77  * 	string or the "UNKNOWN" symbol.
78  *
79  *    SPECIAL REQUIREMENTS
80  *	None.
81  *
82  *    UPDATE HISTORY
83  *      This should contain the description, author, and date of any
84  *      "interesting" modifications (i.e. info should helpful in
85  *      maintaining/enhancing this module).
86  *      username     description
87  *      ----------------------------------------------------------------
88  *	rrl    This code was first created during the beginning
89  *		of the SFS testing days.  I think that was in 1993.
90  *	       This code was updated in 05/96.
91  *		(05/96)  openflags2symbols was written.
92  *
93  *    BUGS/LIMITATIONS
94  * 	Currently (05/96) all known symbols are coded into openflags2symbols.
95  * 	If new open flags are added this code will have to updated
96  * 	to know about them or they will not be recognized.
97  *
98  **************************************************************/
99 
100 #include <stdio.h>
101 #include <unistd.h>
102 #include <fcntl.h>
103 #include <sys/param.h>
104 #include <string.h>		/* strcat */
105 #include "open_flags.h"
106 
107 #define UNKNOWN_SYMBOL	"UNKNOWN"
108 
109 static char Open_symbols[512];	/* space for openflags2symbols return value */
110 
111 struct open_flag_t {
112 	char *symbol;
113 	int flag;
114 };
115 
116 static struct open_flag_t Open_flags[] = {
117 	{"O_RDONLY", O_RDONLY},
118 	{"O_WRONLY", O_WRONLY},
119 	{"O_RDWR", O_RDWR},
120 	{"O_SYNC", O_SYNC},
121 	{"O_CREAT", O_CREAT},
122 	{"O_TRUNC", O_TRUNC},
123 	{"O_EXCL", O_EXCL},
124 	{"O_APPEND", O_APPEND},
125 	{"O_NONBLOCK", O_NONBLOCK},
126 #if O_NOCTTY
127 	{"O_NOCTTY", O_NOCTTY},
128 #endif
129 #if O_DSYNC
130 	{"O_DSYNC", O_DSYNC},
131 #endif
132 #if O_RSYNC
133 	{"O_RSYNC", O_RSYNC},
134 #endif
135 #if O_ASYNC
136 	{"O_ASYNC", O_ASYNC},
137 #endif
138 #if O_PTYIGN
139 	{"O_PTYIGN", O_PTYIGN},
140 #endif
141 #if O_NDELAY
142 	{"O_NDELAY", O_NDELAY},
143 #endif
144 #if O_RAW
145 	{"O_RAW", O_RAW},
146 #endif
147 #ifdef O_SSD
148 	{"O_SSD", O_SSD},
149 #endif
150 #if O_BIG
151 	{"O_BIG", O_BIG},
152 #endif
153 #if O_PLACE
154 	{"O_PLACE", O_PLACE},
155 #endif
156 #if O_RESTART
157 	{"O_RESTART", O_RESTART},
158 #endif
159 #if O_SFSXOP
160 	{"O_SFSXOP", O_SFSXOP},
161 #endif
162 #if O_SFS_DEFER_TM
163 	{"O_SFS_DEFER_TM", O_SFS_DEFER_TM},
164 #endif
165 #if O_WELLFORMED
166 	{"O_WELLFORMED", O_WELLFORMED},
167 #endif
168 #if O_LDRAW
169 	{"O_LDRAW", O_LDRAW},
170 #endif
171 #if O_T3D
172 	{"O_T3D", O_T3D},
173 #endif /* O_T3D */
174 #if O_PARALLEL
175 	{"O_PARALLEL", O_PARALLEL},
176 	{"O_FSA", O_PARALLEL | O_WELLFORMED | O_RAW},	/* short cut */
177 #endif /* O_PARALLEL */
178 #ifdef O_LARGEFILE
179 	{"O_LARGEFILE", O_LARGEFILE},
180 #endif
181 #ifdef O_DIRECT
182 	{"O_DIRECT", O_DIRECT},
183 #endif
184 #ifdef O_PRIV
185 	{"O_PRIV", O_PRIV},
186 #endif
187 
188 };
189 
parse_open_flags(char * string,char ** badname)190 int parse_open_flags(char *string, char **badname)
191 {
192 	int bits = 0;
193 	char *name;
194 	char *cc;
195 	char savecc;
196 	int found;
197 	unsigned int ind;
198 
199 	name = string;
200 	cc = name;
201 
202 	while (1) {
203 
204 		for (; ((*cc != ',') && (*cc != '\0')); cc++) ;
205 		savecc = *cc;
206 		*cc = '\0';
207 
208 		found = 0;
209 
210 		for (ind = 0;
211 		     ind < sizeof(Open_flags) / sizeof(struct open_flag_t);
212 		     ind++) {
213 			if (strcmp(name, Open_flags[ind].symbol) == 0) {
214 				bits |= Open_flags[ind].flag;
215 				found = 1;
216 				break;
217 			}
218 		}
219 
220 		*cc = savecc;	/* restore string */
221 
222 		if (found == 0) {	/* invalid name */
223 			if (badname != NULL)
224 				*badname = name;
225 			return -1;
226 		}
227 
228 		if (savecc == '\0')
229 			break;
230 
231 		name = ++cc;
232 
233 	}			/* end while */
234 
235 	return bits;
236 
237 }				/* end of parse_open_flags */
238 
openflags2symbols(int openflags,char * sep,int mode)239 char *openflags2symbols(int openflags, char *sep, int mode)
240 {
241 	int ind;
242 	int size;
243 	int bits = openflags;
244 	int havesome = 0;
245 
246 	Open_symbols[0] = '\0';
247 
248 	size = sizeof(Open_flags) / sizeof(struct open_flag_t);
249 
250 	/*
251 	 * Deal with special case of O_RDONLY.  If O_WRONLY nor O_RDWR
252 	 * bits are not set, assume O_RDONLY.
253 	 */
254 
255 	if ((bits & (O_WRONLY | O_RDWR)) == 0) {
256 		strcat(Open_symbols, "O_RDONLY");
257 		havesome = 1;
258 	}
259 
260 	/*
261 	 *  Loop through all but O_RDONLY elments of Open_flags
262 	 */
263 	for (ind = 1; ind < size; ind++) {
264 
265 		if ((bits & Open_flags[ind].flag) == Open_flags[ind].flag) {
266 			if (havesome)
267 				strcat(Open_symbols, sep);
268 
269 			strcat(Open_symbols, Open_flags[ind].symbol);
270 			havesome++;
271 
272 			/* remove flag bits from bits */
273 			bits = bits & (~Open_flags[ind].flag);
274 		}
275 	}
276 
277 	/*
278 	 * If not all bits were identified and mode was equal to 1,
279 	 * added UNKNOWN_SYMBOL to return string
280 	 */
281 	if (bits && mode == 1) {	/* not all bits were identified */
282 		if (havesome)
283 			strcat(Open_symbols, sep);
284 		strcat(Open_symbols, UNKNOWN_SYMBOL);
285 	}
286 
287 	return Open_symbols;
288 
289 }				/* end of openflags2symbols */
290 
291 #ifdef UNIT_TEST
292 
293 /*
294  * The following code provides a UNIT test main for
295  * parse_open_flags and openflags2symbols functions.
296  */
297 
main(argc,argv)298 int main(argc, argv)
299 int argc;
300 char **argv;
301 {
302 	int bits;
303 	int ret;
304 	char *err;
305 
306 	if (argc == 1) {
307 		printf("Usage: %s openflagsbits\n\t%s symbols\n", argv[0],
308 		       argv[0]);
309 		exit(1);
310 	}
311 
312 	if (sscanf(argv[1], "%i", &bits) == 1) {
313 		printf("openflags2symbols(%#o, \",\", 1) returned %s\n",
314 		       bits, openflags2symbols(bits, ",", 1));
315 
316 	} else {
317 		ret = parse_open_flags(argv[1], &err);
318 		if (ret == -1)
319 			printf
320 			    ("parse_open_flags(%s, &err) returned -1, err = %s\n",
321 			     argv[0], err);
322 		else
323 			printf("parse_open_flags(%s, &err) returned %#o\n",
324 			       argv[0], ret);
325 	}
326 
327 	exit(0);
328 }
329 
330 #endif /* end of UNIT_TEST */
331