943N/A * Copyright (c) 1993, 1996, Oracle and/or its affiliates. All rights reserved. 824N/A * Permission is hereby granted, free of charge, to any person obtaining a 919N/A * copy of this software and associated documentation files (the "Software"), 919N/A * to deal in the Software without restriction, including without limitation 919N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense, 919N/A * and/or sell copies of the Software, and to permit persons to whom the 919N/A * Software is furnished to do so, subject to the following conditions: 919N/A * The above copyright notice and this permission notice (including the next 919N/A * paragraph) shall be included in all copies or substantial portions of the 919N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 919N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 919N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 919N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 919N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 919N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 919N/A * DEALINGS IN THE SOFTWARE. 824N/A/*************************************************************************** 824N/AImplementation Note: This implementation was done with some generality 824N/A in mind. If at some point it becomes necessary to add more 824N/A elaborate per class or per instance data, this should be 824N/A readily accommodated by this implementation. 824N/A It is assumed that the configuration database is relatively 824N/A small, say, fewer than 1000 entries. There's no hard limit, but 824N/A there's no optimization either. 824N/A The "package" mechanism is hokey. It was done to 824N/A address the concern that nobody wanted package names specified 824N/A on a per instance basis, but there needed to be some mechanism 824N/A that identified an instance as belonging to a package. 824N/A The previous implementation mentioned that it was not 824N/A MTsafe or MThot. The same applies to this implementation. 824N/A Error handling is very primitive. If a more sophisticated 824N/A means of reporting and acting upon error conditions can be 824N/A It would be nice if we could use alloca, but since this 824N/A is also an Xsun server library, we can't. 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/A OWconfig implementation private data structures... 824N/A***************************************************************************/ 824N/A * A class list is a child of the database. 824N/A * An instance list is a child of a class. 824N/A * An attribute list is a child of an instance. 824N/A * Store comments as a singly linked list... 824N/A/*** Max pathname length... ***/ 824N/A/*** Unit of allocation for input line buffer... ***/ 824N/A/*** Max length of statically allocated strings... ***/ 824N/A/*************************************************************************** 824N/A***************************************************************************/ 824N/A/*** If ever there are multiple databases, this could be moved into 824N/A/*************************************************************************** 824N/A**************************************************************************** 824N/AImplementation private functions... 824N/A**************************************************************************** 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AfreeNodeList: The generic node list destructor... 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AfreeClass: The class node destructor... 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AfreeInstance: The instance node destructor... 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AfreeAttr: The attribute node destructor... 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AhashValue: Generates the arithmetic sum of the bytes of the string 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AdupString: Given a non-null pointer to a string, allocates memory 824N/A sufficient to contain a copy of the string pointed to by 824N/A "str", copies the string to the newly allocated memory, and 824N/A returns a pointer to the new string. 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AsearchNodeList: Searches next-wise along a list, starting at the node 824N/A pointed to by "node", until either the end of the list is 824N/A found, or a node whose name matches the string pointed to by 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AsearchClass: Searches for the class node whose name matches the string 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AsearchInstance: Searches for the instance node identified by "name", 824N/A parented by the class node identified by "class". 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AsearchAttr: Searches for the attribute node identified by "attr", 824N/A parented by the instance node identified by "name", 824N/A which in turn is parented by the class node identified by "class". 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AcreateClass: Creates a new class node within the OWconfig database. 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AcreateInstance: Creates a new instance node parented by the class node 824N/A identified by "class". The instance node will be identified 824N/A by "name". If the class node does not already exist, it will 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AunlockOWconfig: Remove the read or write lock from an OWconfig file. 824N/A***************************************************************************/ 824N/A lockStruct.l_type = F_UNLCK; 824N/A lockStruct.l_whence = 0; 824N/A lockStruct.l_start = 0; 824N/A (void)fcntl(f, F_SETLK, &lockStruct); 824N/A/*************************************************************************** 824N/AreadLockOWconfig: Place a read lock on an OWconfig file. Should only 824N/A fail if the file is write locked. 824N/A***************************************************************************/ 824N/ADo not do any read locking. 824N/A lockStruct.l_type = F_RDLCK; 824N/A lockStruct.l_whence = 0; 824N/A lockStruct.l_start = 0; 824N/A result = fcntl(f, F_SETLK, &lockStruct); 824N/A return(OWCFG_LOCK1FAIL); 824N/A/*************************************************************************** 824N/AwriteLockOWconfig: Place a write lock on an OWconfig file. Will fail 824N/A if any other locks, read or write, are already on the file. 824N/A***************************************************************************/ 824N/ADo not do any write locking. 824N/A lockStruct.l_type = F_WRLCK; 824N/A lockStruct.l_whence = 0; 824N/A lockStruct.l_start = 0; 824N/A result = fcntl(f, F_SETLK, &lockStruct); 824N/A return(OWCFG_LOCK1FAIL); 824N/A/*************************************************************************** 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AinitDatabase: If a database already exists, free it, and set the 824N/A OWconfigDatabase structure to a known state. 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AreAllocMem: Because we don't really want to add another parameter to 824N/A OWconfigInit..., we implement a realloc routine that uses 824N/A the allocMem and freeMem routines specified by OWconfigInit. 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AreadLine: Read the file, line by line, until an "interesting" line 824N/A is encountered. Maintain a line number counter along the 824N/A way. When a line is found, fill "lineBuf" with the data. 824N/A It is the responsibility of the caller to free the dynamically 824N/ANote: Need to find proper way to use ctype functions... 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AreadPair: Starting at character position "charPos" in "lineBuf", 824N/A search for an expression of appx. the following syntax: 824N/A <alnum>{<whitespace>}<equal>{<whitespace>}\ 824N/A (<quote><anything goes, even \ stuff><quote>) | \ 824N/A If such an expression is found, "nameBuf" is filled with the 824N/A value to the left of the = and "valBuf" is filled with the 824N/A value to the right of the =. "charPos" will be updated to 824N/A point at the next candidate expression. 824N/A***************************************************************************/ 824N/A /*** Skip whitespace preceding name... ***/ 824N/A /*** Skip "=" and whitespace preceding open quote or string...***/ 824N/A /*** Fetch quote delimited string... ***/ 824N/A /*** Fetch white space terminated string... ***/ 824N/A /*** Skip past terminating character, if any. ***/ 824N/A/*************************************************************************** 824N/AreadOWconfig: Read the OWconfig database file named by "fileName". 824N/A The internal database is built and the file's last modified time 824N/A is returned in "timeStamp". If anything goes wrong, it is 824N/A the caller's responsibility to clean up the database. 824N/A***************************************************************************/ 824N/A /*** class=<value> ??? ***/ 824N/A /*** name=<value> ??? ***/ 824N/A /*** package=<value> ??? ***/ 824N/A /*** <attr>=<value> ??? ***/ 824N/A /*** BLAMMO (TM)... ***/ 824N/A }
/* while readPair... */ 824N/A }
/* while readLine... */ 824N/A/*************************************************************************** 824N/AwriteString: Writes to "fp" a quoted string specified by "str". Does 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/A***************************************************************************/ 824N/A /*** Need to do something about Copyright notices... ***/ 824N/A /*** Write database in something resembling 824N/A original source order... 824N/A /*** Start new package? ***/ 824N/A /*** Write database, class by class... ***/ 824N/A /*** Start new package? ***/ 824N/A/*************************************************************************** 824N/AwriteOWconfig: Writes the internal database, in OWconfig syntax, to 824N/A the file specified by fileName. As a precaution, the original 824N/A file is preserved, renamed as <filename>.BAK. 824N/ANote: I'm concerned that a more sophisticated locking mechanism might be 824N/Amore trouble prone than this one. 824N/A***************************************************************************/ 824N/A /*** Try write locking current OWconfig file... ***/ 824N/A/*************************************************************************** 824N/A**************************************************************************** 824N/A**************************************************************************** 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AThis function establishes the name of the package to associate with 824N/Adatabase resources created by subsequent calls to OWconfigSetAttribute or 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AThis function removes any resources from the database that were 824N/Aassociated with the named package. 824N/AReturn: OWCFG_OK or !OWCFG_OK. 824N/ANote: The data structure is not really optimal for searching by package, 824N/Abut performance isn't really critical here. 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/A"OWconfigSetInstance" is a convenient front end to "OWconfigSetAttribute". 824N/AIt takes a list of attributes and adds them to an instance of a class. 824N/AIf that class and/or instance does not already exist, they are or it is created.If that instance does exist, replacements, when necessary, occur on a per 824N/AReturn: OWCFG_OK or !OWCFG_OK(could occur during an out of memory condition). 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/A"OWconfigRemoveInstance" removes an instance of a class, identified by 824N/AReturn: OWCFG_OK or !OWCFG_OK 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/Ainstance of a class. If that class and/or instance does not already 824N/Aexist, they are or it is created. If the named attribute already exists 824N/Awithin the instance, it is replaced. 824N/AReturn: OWCFG_OK or !OWCFG_OK(could occur during with out of memory condition). 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/A"OWconfigGetClassNames" returns a list of the names of all the 824N/Ainstances of the named class. The end of the list is indicated by 824N/Aa NULL pointer. All users of this function may call "OWconfigFreeClassNames" 824N/Ato free the list and the strings it points to. 824N/AReturn: (char **) to list of class instance names or NULL if class did 824N/A***************************************************************************/ 824N/A /*** Count the number of instances in the class... ***/ 824N/A /*** If dupString fails, free previously allocated 824N/A strings and return NULL... 824N/A/*************************************************************************** 824N/A"OWconfigFreeClassNames" frees the list of class names returned by 824N/A"OWconfigGetClassNames". 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/A"OWconfigGetInstance" returns a list of attribute definitions belonging 824N/Ato the instance identified by "class" and "name". Use "OWconfigFreeInstance" 824N/Ato free the memory allocated to the information returned by 824N/A OWconfigAttributePtr or NULL (if instance doesn't exist). 824N/A***************************************************************************/ 824N/A /*** Count the number of attributes in the instance... ***/ 824N/A/*************************************************************************** 824N/A"OWconfigFreeInstance" frees the data returned by OWconfigGetInstance. 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/A"OWconfigGetAttribute" returns the string value of the requested attribute. 824N/AReturn: (char *) to value of attribute or NULL if attribute could not 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/A"OWconfigFreeAttribute" frees the string returned by OWconfigGetAttribute. 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AIf writefile was specified, the existing target file, if any, is write locked 824N/Ausing fcntl. If the lock succeeds, the new OWconfig file is written to the 824N/Asame directory, with a temporary name. The old file is removed and the new 824N/Afile is renamed to match the old file. 824N/AThe internal database is freed. 824N/AReturn: OWCFG_OK or !OWCFG_OK(could occur if write or write lock failed). 824N/ANote: When a file is written, all comments are lost from the 824N/Aoriginal file(s). When written, the OWconfig entries will be grouped by class. 824N/A***************************************************************************/ 824N/A/*************************************************************************** 824N/AOWconfigValidate: Verifies that the internal database is up to date 824N/A with respect to the database file indicated by the global "readFlags". 824N/A If it isn't, the files are re-read and a new internal database is 824N/A OWCFG_OK or !OWCFG_OK (if re-read fails). 824N/A***************************************************************************/ 824N/A /*** Setting databaseValid to zero causes initDatabase() 824N/A to NOT free existing database... 824N/A/*************************************************************************** 824N/A"OWconfigInit" will read the OWconfig files named by readfile1 and 824N/Athose read from readfile1. The replacement will occur on a per 824N/Aread locked using the fcntl facility. Immediately after the file 824N/Ais read, it is unlocked. 824N/AReturn: OWCFG_OK or !OWCFG_OK. Bogus filepaths can return !OWCFG_OK. 824N/A If readfile1 and readfile2 are both non-NULL, and the read of 824N/A readfile1 succeeds but the read of readfile2 fails, OWCFG_OK 824N/A will be returned. Lock test failures will return !OWCFG_OK. 824N/A***************************************************************************/ 824N/A /*** Check for specific corner cases... ***/ 824N/A /*** Read file 1, if specified... ***/ 824N/A /*** Read file 2, if specified... ***/