/* * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU General Public License along * with this program; if not, write the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston MA 02111-1307, USA. * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ */ /************************************************************** * * OS Testing - Silicon Graphics, Inc. * * FUNCTION NAME : parse_open_flags * openflags2symbols * * FUNCTION TITLE : converts open flag symbols into bitmask * converts open flag bitmask into symbols * * SYNOPSIS: * int parse_open_flags(symbols, badname) * char *symbols; * char **badname; * * char *openflags2symbols(openflags, sep, mode) * int openflags; * char *sep; * int mode; * * AUTHOR : Richard Logan * * CO-PILOT(s) : Dean Roehrich * * INITIAL RELEASE : UNICOS 8.0 * * DESIGN DESCRIPTION * The parse_open_flags function can be used to convert * a list of comma separated open(2) flag symbols (i.e. O_TRUNC) * into the bitmask that can be used by open(2). * If a symbol is unknown and <badname> is not NULL, <badname> * will updated to point that symbol in <string>. * Parse_open_flags will return -1 on this error. * Otherwise parse_open_flags will return the open flag bitmask. * If parse_open_flags returns, <string> will left unchanged. * * The openflags2symbols function attempts to convert open flag * bits into human readable symbols (i.e. O_TRUNC). If there * are more than one symbol, the <sep> string will be placed as * a separator between symbols. Commonly used separators would * be a comma "," or pipe "|". If <mode> is one and not all * <openflags> bits can be converted to symbols, the "UNKNOWN" * symbol will be added to return string. * Openflags2symbols will return the indentified symbols. * If no symbols are recognized the return value will be a empty * string or the "UNKNOWN" symbol. * * SPECIAL REQUIREMENTS * None. * * UPDATE HISTORY * This should contain the description, author, and date of any * "interesting" modifications (i.e. info should helpful in * maintaining/enhancing this module). * username description * ---------------------------------------------------------------- * rrl This code was first created during the beginning * of the SFS testing days. I think that was in 1993. * This code was updated in 05/96. * (05/96) openflags2symbols was written. * * BUGS/LIMITATIONS * Currently (05/96) all known symbols are coded into openflags2symbols. * If new open flags are added this code will have to updated * to know about them or they will not be recognized. * **************************************************************/ #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/param.h> #include <string.h> /* strcat */ #include "open_flags.h" #define UNKNOWN_SYMBOL "UNKNOWN" static char Open_symbols[512]; /* space for openflags2symbols return value */ struct open_flag_t { const char *symbol; int flag; }; static struct open_flag_t Open_flags[] = { { "O_RDONLY", O_RDONLY }, { "O_WRONLY", O_WRONLY }, { "O_RDWR", O_RDWR }, { "O_SYNC", O_SYNC }, { "O_CREAT", O_CREAT }, { "O_TRUNC", O_TRUNC }, { "O_EXCL", O_EXCL }, { "O_APPEND", O_APPEND }, { "O_NONBLOCK", O_NONBLOCK }, #if O_NOCTTY { "O_NOCTTY", O_NOCTTY }, #endif #if O_DSYNC { "O_DSYNC", O_DSYNC }, #endif #if O_RSYNC { "O_RSYNC", O_RSYNC }, #endif #if O_ASYNC { "O_ASYNC", O_ASYNC }, #endif #if O_PTYIGN { "O_PTYIGN", O_PTYIGN }, #endif #if O_NDELAY { "O_NDELAY", O_NDELAY }, #endif #if O_RAW { "O_RAW", O_RAW }, #endif #ifdef O_SSD { "O_SSD", O_SSD }, #endif #if O_BIG { "O_BIG", O_BIG }, #endif #if O_PLACE { "O_PLACE", O_PLACE }, #endif #if O_RESTART { "O_RESTART", O_RESTART }, #endif #if O_SFSXOP { "O_SFSXOP", O_SFSXOP }, #endif #if O_SFS_DEFER_TM { "O_SFS_DEFER_TM", O_SFS_DEFER_TM }, #endif #if O_WELLFORMED { "O_WELLFORMED", O_WELLFORMED }, #endif #if O_LDRAW { "O_LDRAW", O_LDRAW }, #endif #if O_T3D { "O_T3D", O_T3D }, #endif /* O_T3D */ #if O_PARALLEL { "O_PARALLEL", O_PARALLEL }, { "O_FSA", O_PARALLEL|O_WELLFORMED|O_RAW }, /* short cut */ #endif /* O_PARALLEL */ #ifdef O_LARGEFILE { "O_LARGEFILE", O_LARGEFILE }, #endif #ifdef O_DIRECT { "O_DIRECT", O_DIRECT }, #endif #ifdef O_PRIV { "O_PRIV", O_PRIV }, #endif }; int parse_open_flags(char *string, char **badname) { int bits = 0; char *name; char *cc; char savecc; int found; int ind; name=string; cc=name; while ( 1 ) { for(; ((*cc != ',') && (*cc != '\0')); cc++); savecc = *cc; *cc = '\0'; found = 0; for(ind=0; ind < sizeof(Open_flags)/sizeof(struct open_flag_t); ind++) { if ( strcmp(name, Open_flags[ind].symbol) == 0 ) { bits |= Open_flags[ind].flag; found=1; break; } } *cc = savecc; /* restore string */ if ( found == 0 ) { /* invalid name */ if ( badname != NULL ) *badname = name; return -1; } if ( savecc == '\0' ) break; name = ++cc; } /* end while */ return bits; } /* end of parse_open_flags */ char * openflags2symbols(int openflags, char *sep, int mode) { int ind; int size; int bits = openflags; int havesome=0; Open_symbols[0]='\0'; size=sizeof(Open_flags)/sizeof(struct open_flag_t); /* * Deal with special case of O_RDONLY. If O_WRONLY nor O_RDWR * bits are not set, assume O_RDONLY. */ if ( (bits & (O_WRONLY | O_RDWR)) == 0 ) { strcat(Open_symbols, "O_RDONLY"); havesome=1; } /* * Loop through all but O_RDONLY elments of Open_flags */ for(ind=1; ind < size; ind++) { if ( (bits & Open_flags[ind].flag) == Open_flags[ind].flag ) { if ( havesome ) strcat(Open_symbols, sep); strcat(Open_symbols, Open_flags[ind].symbol); havesome++; /* remove flag bits from bits */ bits = bits & (~Open_flags[ind].flag); } } /* * If not all bits were identified and mode was equal to 1, * added UNKNOWN_SYMBOL to return string */ if ( bits && mode == 1 ) { /* not all bits were identified */ if ( havesome ) strcat(Open_symbols, sep); strcat(Open_symbols, UNKNOWN_SYMBOL); } return Open_symbols; } /* end of openflags2symbols */ #ifdef UNIT_TEST /* * The following code provides a UNIT test main for * parse_open_flags and openflags2symbols functions. */ int main(argc, argv) int argc; char **argv; { int bits; int ret; char *err; if (argc == 1 ) { printf("Usage: %s openflagsbits\n\t%s symbols\n", argv[0], argv[0]); exit(1); } if ( sscanf(argv[1], "%i", &bits) == 1 ) { printf("openflags2symbols(%#o, \",\", 1) returned %s\n", bits, openflags2symbols(bits, ",", 1)); } else { ret=parse_open_flags(argv[1], &err); if ( ret == -1 ) printf("parse_open_flags(%s, &err) returned -1, err = %s\n", argv[0], err); else printf("parse_open_flags(%s, &err) returned %#o\n", argv[0], ret); } exit(0); } #endif /* end of UNIT_TEST */