From d9b83dfada7e407c2b7c4b692dbcc22438d6edc0 Mon Sep 17 00:00:00 2001
From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137>
Date: Wed, 14 Apr 2004 13:27:20 +0000
Subject: [PATCH] Added exit values 5/6 for missing/unreadable config file

git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@1672 4ea69e1a-61f1-4043-bf83-b5c94c648137
---
 sm5/CHANGELOG   |  4 +++-
 sm5/smartd.8.in | 12 +++++++++---
 sm5/smartd.c    | 41 ++++++++++++++++++++++++++---------------
 sm5/smartd.cpp  | 41 ++++++++++++++++++++++++++---------------
 sm5/utility.h   |  6 ++++--
 5 files changed, 68 insertions(+), 36 deletions(-)

diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG
index 4d1ecb425..566c25f34 100644
--- a/sm5/CHANGELOG
+++ b/sm5/CHANGELOG
@@ -1,6 +1,6 @@
 CHANGELOG for smartmontools
 
-$Id: CHANGELOG,v 1.396 2004/04/09 00:42:53 ballen4705 Exp $
+$Id: CHANGELOG,v 1.397 2004/04/14 13:27:19 chrfranke Exp $
 
 The most recent version of this file is:
 http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/CHANGELOG?sortby=date&view=markup
@@ -27,6 +27,8 @@ NOTES FOR FUTURE RELEASES: see TODO file.
 
 <ADDITIONS TO THE CHANGE LOG SHOULD BE ADDED JUST BELOW HERE, PLEASE>
 
+  [CF] smartd: Added exit values 5/6 for missing/unreadable config file.
+
   [BA] smartd: now monitor the Current Pending Sector count (Attribute 197)
        and the Offline Pending Sector Count (Attribute 198).  Log a
        warning (and send an email, if so configured) if the raw count
diff --git a/sm5/smartd.8.in b/sm5/smartd.8.in
index 628dbc59d..42fd9f534 100644
--- a/sm5/smartd.8.in
+++ b/sm5/smartd.8.in
@@ -1,7 +1,7 @@
 .ig
 Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net>
  
-$Id: smartd.8.in,v 1.60 2004/04/11 17:13:39 chrfranke Exp $
+$Id: smartd.8.in,v 1.61 2004/04/14 13:27:19 chrfranke Exp $
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -1529,7 +1529,7 @@ Daemon startup successful, or \fBsmartd\fP was killed by a SIGTERM (or in debug
 Commandline did not parse.
 .TP
 .B 2:
-There was a problem opening or parsing \fB/etc/smartd.conf\fP.
+There was a syntax error in the config file.
 .TP
 .B 3:
 Forking the daemon failed.
@@ -1537,6 +1537,12 @@ Forking the daemon failed.
 .B 4:
 Couldn\'t create PID file.
 .TP
+.B 5:
+Config file does not exist (only returned in conjunction with the \'-c\' option).
+.TP
+.B 6:
+Config file exists, but cannot be read.
+.TP
 .B 8:
 \fBsmartd\fP
 ran out of memory during startup.
@@ -1647,4 +1653,4 @@ smartmontools home page at \fBhttp://smartmontools.sourceforge.net/\fP .
 
 .SH
 CVS ID OF THIS PAGE:
-$Id: smartd.8.in,v 1.60 2004/04/11 17:13:39 chrfranke Exp $
+$Id: smartd.8.in,v 1.61 2004/04/14 13:27:19 chrfranke Exp $
diff --git a/sm5/smartd.c b/sm5/smartd.c
index 96098d07a..51fb8ef63 100644
--- a/sm5/smartd.c
+++ b/sm5/smartd.c
@@ -98,7 +98,7 @@ int getdomainname(char *, int); /* no declaration in header files! */
 extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid, 
                   *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid;
 
-static const char *filenameandversion="$Id: smartd.c,v 1.315 2004/04/12 17:42:19 chrfranke Exp $";
+static const char *filenameandversion="$Id: smartd.c,v 1.316 2004/04/14 13:27:20 chrfranke Exp $";
 #ifdef NEED_SOLARIS_ATA_CODE
 extern const char *os_solaris_ata_s_cvsid;
 #endif
@@ -109,7 +109,7 @@ extern const char *syslog_win32_c_cvsid;
 extern const char *int64_vc6_c_cvsid;
 #endif
 #endif
-const char *smartd_c_cvsid="$Id: smartd.c,v 1.315 2004/04/12 17:42:19 chrfranke Exp $" 
+const char *smartd_c_cvsid="$Id: smartd.c,v 1.316 2004/04/14 13:27:20 chrfranke Exp $" 
 ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID
 KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID
 #ifdef SYSLOG_H_CVSID
@@ -3028,8 +3028,9 @@ void cleanup(FILE **fpp){
 // Parses a configuration file.  Return values are:
 //  N=>0: found N entries
 // -1:    syntax error in config file
-// -2:    could not open config file
-// 
+// -2:    config file does not exist
+// -3:    config file exists but cannot be read
+//
 // In the case where the return value is 0, there are three
 // possiblities:
 // Empty configuration file ==> cfgentries==NULL
@@ -3046,9 +3047,10 @@ int ParseConfigFile(){
     fp=fopen(configfile,"r");
     if (fp==NULL && (errno!=ENOENT || configfile_alt)) {
       // file exists but we can't read it or it should exist due to '-c' option
+      int ret = (errno!=ENOENT ? -3 : -2);
       PrintOut(LOG_CRIT,"%s: Unable to open configuration file %s\n",
                strerror(errno),configfile);
-      return -2;
+      return ret;
     }
   }
   else // read from stdin ('-c -' option)
@@ -3496,9 +3498,10 @@ void CanNotRegister(char *name, char *type, int line, int scandirective){
   return;
 }
 
-// returns -1 if config file had syntax errors, else number of entries
-// which may be zero or positive.  If we found no configuration file,
-// or it contained SCANDIRECTIVE, then *scanning is set to 1, else 0.
+// Returns negative value (see ParseConfigFile()) if config file
+// had errors, else number of entries which may be zero or positive. 
+// If we found no configuration file, or it contained SCANDIRECTIVE,
+// then *scanning is set to 1, else 0.
 int ReadOrMakeConfigEntries(int *scanning){
   int entries;
   
@@ -3512,7 +3515,7 @@ int ReadOrMakeConfigEntries(int *scanning){
     RmAllConfigEntries();
     if (entries == -1)
       PrintOut(LOG_CRIT, "Configuration file %s has fatal syntax errors.\n", configfile);
-    return -1;
+    return entries;
   }
 
   // did we find entries or scan?
@@ -3705,7 +3708,7 @@ int main(int argc, char **argv){
       int isok=debugmode?isterm || isquit:isterm;
       
       PrintOut(isok?LOG_INFO:LOG_CRIT, "smartd received signal %d: %s\n",
-	       caughtsigEXIT, strsignal(caughtsigEXIT));
+               caughtsigEXIT, strsignal(caughtsigEXIT));
       
       EXIT(isok?0:EXIT_SIGNAL);
     }
@@ -3724,12 +3727,20 @@ int main(int argc, char **argv){
       // clears cfgentries, (re)reads config file, makes >=0 entries
       entries=ReadOrMakeConfigEntries(&scanning);
 
-      // checks devices, then moves onto ata/scsi list or deallocates.
-      if (entries>=0 || quit==4)
+      if (entries>=0) {
+        // checks devices, then moves onto ata/scsi list or deallocates.
         RegisterDevices(scanning);
-      
-      if (entries<0 && quit==4)
-        EXIT(EXIT_BADCONF);
+      }
+      else if (quit==2 || ((quit==0 || quit==1) && !firstpass)) {
+        // user has asked to continue on error in configuration file
+        if (!firstpass)
+          PrintOut(LOG_INFO,"Reusing previous configuration\n");
+      }
+      else {
+        // exit with configuration file error status
+        int status = (entries==-3 ? EXIT_READCONF : entries==-2 ? EXIT_NOCONF : EXIT_BADCONF);
+        EXIT(status);
+      }
 
       // Log number of devices we are monitoring...
       if (numdevata+numdevscsi || quit==2 || (quit==1 && !firstpass))
diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp
index cc38fd0ca..97b62d4fc 100644
--- a/sm5/smartd.cpp
+++ b/sm5/smartd.cpp
@@ -98,7 +98,7 @@ int getdomainname(char *, int); /* no declaration in header files! */
 extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid, 
                   *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid;
 
-static const char *filenameandversion="$Id: smartd.cpp,v 1.315 2004/04/12 17:42:19 chrfranke Exp $";
+static const char *filenameandversion="$Id: smartd.cpp,v 1.316 2004/04/14 13:27:20 chrfranke Exp $";
 #ifdef NEED_SOLARIS_ATA_CODE
 extern const char *os_solaris_ata_s_cvsid;
 #endif
@@ -109,7 +109,7 @@ extern const char *syslog_win32_c_cvsid;
 extern const char *int64_vc6_c_cvsid;
 #endif
 #endif
-const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.315 2004/04/12 17:42:19 chrfranke Exp $" 
+const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.316 2004/04/14 13:27:20 chrfranke Exp $" 
 ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID
 KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID
 #ifdef SYSLOG_H_CVSID
@@ -3028,8 +3028,9 @@ void cleanup(FILE **fpp){
 // Parses a configuration file.  Return values are:
 //  N=>0: found N entries
 // -1:    syntax error in config file
-// -2:    could not open config file
-// 
+// -2:    config file does not exist
+// -3:    config file exists but cannot be read
+//
 // In the case where the return value is 0, there are three
 // possiblities:
 // Empty configuration file ==> cfgentries==NULL
@@ -3046,9 +3047,10 @@ int ParseConfigFile(){
     fp=fopen(configfile,"r");
     if (fp==NULL && (errno!=ENOENT || configfile_alt)) {
       // file exists but we can't read it or it should exist due to '-c' option
+      int ret = (errno!=ENOENT ? -3 : -2);
       PrintOut(LOG_CRIT,"%s: Unable to open configuration file %s\n",
                strerror(errno),configfile);
-      return -2;
+      return ret;
     }
   }
   else // read from stdin ('-c -' option)
@@ -3496,9 +3498,10 @@ void CanNotRegister(char *name, char *type, int line, int scandirective){
   return;
 }
 
-// returns -1 if config file had syntax errors, else number of entries
-// which may be zero or positive.  If we found no configuration file,
-// or it contained SCANDIRECTIVE, then *scanning is set to 1, else 0.
+// Returns negative value (see ParseConfigFile()) if config file
+// had errors, else number of entries which may be zero or positive. 
+// If we found no configuration file, or it contained SCANDIRECTIVE,
+// then *scanning is set to 1, else 0.
 int ReadOrMakeConfigEntries(int *scanning){
   int entries;
   
@@ -3512,7 +3515,7 @@ int ReadOrMakeConfigEntries(int *scanning){
     RmAllConfigEntries();
     if (entries == -1)
       PrintOut(LOG_CRIT, "Configuration file %s has fatal syntax errors.\n", configfile);
-    return -1;
+    return entries;
   }
 
   // did we find entries or scan?
@@ -3705,7 +3708,7 @@ int main(int argc, char **argv){
       int isok=debugmode?isterm || isquit:isterm;
       
       PrintOut(isok?LOG_INFO:LOG_CRIT, "smartd received signal %d: %s\n",
-	       caughtsigEXIT, strsignal(caughtsigEXIT));
+               caughtsigEXIT, strsignal(caughtsigEXIT));
       
       EXIT(isok?0:EXIT_SIGNAL);
     }
@@ -3724,12 +3727,20 @@ int main(int argc, char **argv){
       // clears cfgentries, (re)reads config file, makes >=0 entries
       entries=ReadOrMakeConfigEntries(&scanning);
 
-      // checks devices, then moves onto ata/scsi list or deallocates.
-      if (entries>=0 || quit==4)
+      if (entries>=0) {
+        // checks devices, then moves onto ata/scsi list or deallocates.
         RegisterDevices(scanning);
-      
-      if (entries<0 && quit==4)
-        EXIT(EXIT_BADCONF);
+      }
+      else if (quit==2 || ((quit==0 || quit==1) && !firstpass)) {
+        // user has asked to continue on error in configuration file
+        if (!firstpass)
+          PrintOut(LOG_INFO,"Reusing previous configuration\n");
+      }
+      else {
+        // exit with configuration file error status
+        int status = (entries==-3 ? EXIT_READCONF : entries==-2 ? EXIT_NOCONF : EXIT_BADCONF);
+        EXIT(status);
+      }
 
       // Log number of devices we are monitoring...
       if (numdevata+numdevscsi || quit==2 || (quit==1 && !firstpass))
diff --git a/sm5/utility.h b/sm5/utility.h
index 96daf2422..4dc654ac1 100644
--- a/sm5/utility.h
+++ b/sm5/utility.h
@@ -25,7 +25,7 @@
 #ifndef UTILITY_H_
 #define UTILITY_H_
 
-#define UTILITY_H_CVSID "$Id: utility.h,v 1.32 2004/03/29 00:26:03 ballen4705 Exp $\n"
+#define UTILITY_H_CVSID "$Id: utility.h,v 1.33 2004/04/14 13:27:20 chrfranke Exp $\n"
 
 #include <time.h>
 #include <sys/types.h> // for regex.h (according to POSIX)
@@ -138,9 +138,11 @@ void MsecToText(unsigned int msec, char *txt);
 
 // Exit codes
 #define EXIT_BADCMD    1   // command line did not parse
-#define EXIT_BADCONF   2   // problem reading/parsing config file
+#define EXIT_BADCONF   2   // syntax error in config file
 #define EXIT_STARTUP   3   // problem forking daemon
 #define EXIT_PID       4   // problem creating pid file
+#define EXIT_NOCONF    5   // config file does not exist
+#define EXIT_READCONF  6   // config file exists but cannot be read
 
 #define EXIT_NOMEM     8   // out of memory
 #define EXIT_BADCODE   10  // internal error - should NEVER happen
-- 
GitLab