Technical notes on my code submission of 26 Sep 99 Kern Sibbald General: - I've tried to follow the indenting standards existing for apcupsd, but in reviewing my changes, I've noted several places where I have followed the standards that I have used for many years, being a bit lazy to correct them, I submit them as is, but if someone objects, I'll be glad to fix them. - I recommend that we discuss indenting standards. I find the current standard of something like 6 of 7 spaces for each level of indentation difficult to enter (it slows me down), difficult to read, and it allows a lot less code per line. I propose a standard that indents three spaces for each new indention level. This yields very readable code and preserves space. Comments? - I was displeased to discover two things about GNU software in making this submission: 1. diff has no option to ignore tabs on input when making comparisons. 2. make REQUIRES a tab in certain positions -- this "problem" was fixed 10 years ago in all other versions of make with which I have worked. - In order to produce a minimum diff for this submission, I was forced to remove all tabs from all .c and .h files. Unfortunately, due to the make restrictions, I was not able to remove them from the Makefile.in files. Consequently, for this submission, you will find that all lines in the Makefile.in files that I changed are tabbed. Changes to code: general - This first set of changes attempts to implement two new error termination routines error_abort() and error_exit(). Both are implemented as #defines taking a variable number of arguments. I used defines, because they pass the file and line number of the calling statement. Both ultimately use the subroutine error_out(), which is a new subroutine located in apcupsd.c. Note, for compilers such as the HP which apparently do not permit variable arguments in #defines, I recommend that the HP coder, simply make some HP defines as follows: #define error_abort error_out #define error_exit error_out Then use ifdefs to change the definition of error_out to eliminate the first three arguments keeping only the error varargs message passed to it. - I then cleaned up a number of files (mostly those called directly from apcupsd.c) to use the new routines. There are still MANY other places where these routines could be used. For example, apcserial.c takes great care to return SUCCESS or FAILURE, but in doing so, the reason for any failure is completely lost. Personally, I would prefer that apcserial.c immediately error if it cannot continue. However, before making any sweeping changes there, I would like to get the reactions of the other developers to this code. The same applies to other files. - Not implemented, but possible is to log the error messages rather than fprintf them depending on whether or not the system log file is open. I'll be glad to implement this idea depending on the reaction of the developers. - I modified all the routines called by terminate() to do nothing if they were not initialized. This means that terminate() or error_abort,... can be called from anywhere either before or after the program becomes a daeon and starts the networking ... Again, some future work needs to be done to use the log file rather than fprintf if apcupsd is running as a daemon, but with my changes, it should be centralized in one or two subroutines for the most part. - I moved the initialization of the myUPS structure to very early in the program. This permits proper checking of the state for early shutdowns. - I added a sentinel to the beginning of the shared memory structure. This permits distinguishing the old version and the new version when the memory structure changes. I also added a version number for ensuring that the programs such as apcaccess (and future .cgi programs) are using the proper structure definition. I also added the size of the structure, and the release number of apcupsd. This allows for full sanity checking. - I updated the .man file. There seems to be a lot more work to do here. Please give me your reactions. - I cleaned up the apcupsd.config file a bit (removed obsolete configuration statements) and added a bit more documentation. - I added code to detect that the installation is being done on a RedHat 5.2 or 6.0 system (all the hooks were already there -- thanks). I also added all the code necessary to do a correct make install on a RedHat system. Please note that this is not tested yet on RedHat 5.2, so I am sure there will need to be additional changes. In doing this, I moved the code (or the logic) of /sbin/powersc into the apcupsd script -- this makes it much more readable and eliminates the need for /sbin/powersc on RedHat systems. I recommend that the same be done in all other platforms and that we eliminate entirely /etc/powersc. In the mean time, I would like to see powersc moved to the distributions directory. That way it will not be installed on RedHat systems. - I like the new /usr/lib/apccontrol file. It is very nice. However, I am a bit surprised that we eliminated the CONTROL configuration statement. On RedHat systems, I would MUCH prefer to put this file in /etc/apcupsd and to be able to configure its location in /etc/apcupsd.conf. Eventhough /etc is getting a bit cluttered, most system administrators would prefer that the really critical system stuff (such as apcupsd) be located in etc. Can we resurrect the CONTROL code? Comments. - Instead of erroring when obsolete configuration statements are found, I made it print and error message and continue. This makes upgradding a bit more pleasant. - I removed the 10 second sleep in terminate() as in my opinion, it is very undesirable. I have not yet had the time to test all the termination cases, so there may be some subtile problems lurking in this change. I'll test all the various shutdown cases in the next few weeks. Final comments: - I would like to get some feedback about what I did. Good/bad/indifferent? - Now that I have a bit of experience in the code, I would like to undertake a more "serious" project while at the same time continuing some of the cleanup efforts that I have started. Some projects that I consider "serious" are: 1. Implement PowerChute event logging. 2. Implement some way through a user program to query and change the state of the UPS (e.g. Initiate UPS self test, Initiate UPS runtime calibration, Simulate power failure, test UPS alarm, ...) 3. Integrate the apcupscgi-1.0 code with apcupsd. 4. Implement .cgi programs that query and change the state of the UPS. 5. Implement a general .cgi interface in place of the old HTTP code. 6. Implement networking with APC PowerChute programs on other machines (probably a .cgi program to keep the footprint of apcupsd small). Other projects already planned that I would like to continue with little by little: - Implementation of error_abort() throughout the code where appropriate. - Implementation of consistent logging as discussed in recent emails. - Adding additional documentation. - Making a source and binary .rpm release for RedHat. I would like to hear your comments on these and particularily what the rest of you consider the priority of items 1 - 6.