Index: trunk/docs/Changelog
===================================================================
--- trunk/docs/Changelog	(revision 93)
+++ trunk/docs/Changelog	(revision 94)
@@ -1,4 +1,5 @@
 2.3.3:
-	* fix bug with leading slashes in liked path of symlinks within
+	* refactor sh_kern.c, sh_suidchk.c
+	* fix bug with leading slashes in linked path of symlinks within
 	  the root directory
 	* sh_kern.c: check PCI ROM (Linux), refactor code
Index: trunk/src/sh_files.c
===================================================================
--- trunk/src/sh_files.c	(revision 93)
+++ trunk/src/sh_files.c	(revision 94)
@@ -352,6 +352,8 @@
 	      tmp = NULL;
 	    }
-	  SH_FREE(file);
-	  SH_FREE(dir);
+	  if (file)
+	    SH_FREE(file);
+	  if (dir)
+	    SH_FREE(dir);
 
 	  ptr->checked = S_TRUE;
Index: trunk/src/sh_suidchk.c
===================================================================
--- trunk/src/sh_suidchk.c	(revision 93)
+++ trunk/src/sh_suidchk.c	(revision 94)
@@ -30,7 +30,5 @@
 #include <errno.h>
 #include <limits.h>
-#ifdef HAVE_LIBGEN_H
-#include <libgen.h>
-#endif
+
 #ifdef HAVE_SCHED_H
 #include <sched.h>
@@ -38,8 +36,4 @@
 
 #ifdef SH_USE_SUIDCHK
-
-#ifndef HAVE_BASENAME
-#define basename(a) ((NULL == strrchr(a, '/')) ? (a) : (strrchr(a, '/')))
-#endif
 
 #undef  FIL__
@@ -353,8 +347,9 @@
 }
 
-static int do_truncate (char * path)
-{
-  int         caperr;
-  int result;
+static int do_truncate (const char * path_in)
+{
+  int    caperr;
+  int    result;
+  char * path;
 
   if (0 != chdir("/"))
@@ -372,5 +367,7 @@
     }
 
+  path   = sh_util_strdup  (path_in);
   result = do_truncate_int (path, 0);
+  SH_FREE(path);
 
   if (0 != (caperr = sl_drop_cap_qdel()))
@@ -390,37 +387,453 @@
 }
 
+static void sh_q_delete(const char * fullpath)
+{
+  int    status;
+  char * msg;
+  char * tmp;
+
+  if (do_truncate (fullpath) == -1)
+    {
+      status = errno;
+      msg    = SH_ALLOC(SH_BUFSIZE);
+      tmp    = sh_util_safe_name(fullpath);
+
+      (void) sl_snprintf(msg, SH_BUFSIZE, 
+			 _("Problem quarantining file.  File NOT quarantined.  errno = %ld"), 
+			 status);
+      sh_error_handle (ShSuidchkSeverity,
+		       FIL__, __LINE__, 
+		       status,
+		       MSG_SUID_QREPORT, msg,
+		       tmp );
+      SH_FREE(tmp);
+      SH_FREE(msg);
+    }
+  else
+    {
+      tmp    = sh_util_safe_name(fullpath);
+      sh_error_handle (ShSuidchkSeverity,
+		       FIL__, __LINE__, 0,
+		       MSG_SUID_QREPORT,
+		       _("Quarantine method applied"),
+		       tmp );
+      SH_FREE(tmp);
+    }
+  return;
+}
+
+static void sh_q_move(const char * fullpath, file_type * theFile, 
+		      const char * timestrc, const char * timestra, 
+		      const char * timestrm)
+{
+  int           status;
+  int           readFile  = -1;
+  int           writeFile = -1;;
+  struct stat   fileInfo;
+  ssize_t       count;
+  char        * msg;
+  char        * tmp;
+  char        * basetmp;
+  char        * filetmp;
+  char          buffer[1024];
+  char        * dir = SH_ALLOC(PATH_MAX+1);
+  mode_t        umask_old;
+  FILE *        filePtr = NULL;
+
+  (void) sl_strlcpy (dir, DEFAULT_QDIR, PATH_MAX+1);
+
+  if (retry_stat (FIL__, __LINE__, dir, &fileInfo) != 0)
+    {
+      /* Quarantine directory does not exist,
+       */
+      status = errno;
+      msg    = SH_ALLOC(SH_BUFSIZE);
+      tmp    = sh_util_safe_name(fullpath);
+
+      (void) sl_snprintf(msg, SH_BUFSIZE, 
+			 _("Problem quarantining file.  File NOT quarantined.  errno = %ld (stat)"), 
+			 status);
+      sh_error_handle (ShSuidchkSeverity,
+		       FIL__, __LINE__, 
+		       status,
+		       MSG_SUID_QREPORT, msg,
+		       tmp );
+      SH_FREE(tmp);
+      SH_FREE(msg);
+    }
+  else
+    {
+      if (retry_lstat (FIL__, __LINE__, 
+		       fullpath, &fileInfo) == -1)
+	{
+	  status = errno;
+	  msg    = SH_ALLOC(SH_BUFSIZE);
+	  tmp    = sh_util_safe_name(fullpath);
+
+	  (void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld(stat)"), status);
+	  sh_error_handle (ShSuidchkSeverity,
+			   FIL__, __LINE__, 
+			   status,
+			   MSG_SUID_QREPORT,
+			   msg, tmp );
+	  SH_FREE(tmp);
+	  SH_FREE(msg);
+	}
+      else
+	{
+	  basetmp = sh_util_strdup(fullpath);
+	  filetmp = SH_ALLOC(PATH_MAX+1);
+	  tmp     = sh_util_basename(basetmp);
+
+	  (void) sl_snprintf(filetmp, PATH_MAX+1, "%s/%s", 
+			     DEFAULT_QDIR, tmp);
+	  SH_FREE(tmp);
+	  SH_FREE(basetmp);
+	  
+	  readFile  = open (fullpath, O_RDONLY);
+	  if (readFile != -1)
+	    writeFile = open (filetmp, O_WRONLY|O_CREAT);
+	  
+	  if ((readFile == -1) || (writeFile == -1))
+	    {
+	      status = errno;
+	      msg    = SH_ALLOC(SH_BUFSIZE);
+	      tmp    = sh_util_safe_name(fullpath);
+
+	      (void) sl_snprintf(msg, SH_BUFSIZE, _("Problem quarantining file.  File NOT quarantined.  errno = %ld (open)"), status);
+	      sh_error_handle (ShSuidchkSeverity,
+			       FIL__, __LINE__, status,
+			       MSG_SUID_QREPORT,
+			       msg, tmp );
+	      SH_FREE(tmp);
+	      SH_FREE(msg);
+	    }
+	  else
+	    { 
+	      /* sizeof(buffer) is 1024 
+	       */
+	      while ((count = (int) read (readFile, buffer, sizeof (buffer))) > 0)
+		{
+		  if ((int) write (writeFile, buffer, (size_t) count) != count)
+		    {
+		      status = errno;
+		      msg    = SH_ALLOC(SH_BUFSIZE);
+		      tmp    = sh_util_safe_name(fullpath);
+
+		      (void) sl_snprintf(msg, SH_BUFSIZE, 
+					 _("I/O error.  errno = %ld (write)"), status);
+		      sh_error_handle (ShSuidchkSeverity,
+				       FIL__,
+				       __LINE__,
+				       status,
+				       MSG_SUID_QREPORT,
+				       msg, tmp );
+		      SH_FREE(tmp);
+		      SH_FREE(msg);
+		    }
+		}
+	    }
+
+	  (void) close (readFile);
+	  (void) fchmod(writeFile, S_IRUSR | S_IWUSR | S_IXUSR);
+	  (void) close (writeFile);
+
+	  if (do_truncate (fullpath) == -1)
+	    {
+	      status = errno;
+	      msg    = SH_ALLOC(SH_BUFSIZE);
+	      tmp    = sh_util_safe_name(fullpath);
+
+	      (void) sl_snprintf(msg, SH_BUFSIZE, 
+				 _("Problem quarantining file.  File NOT quarantined.  errno = %ld"), 
+				 status);
+	      sh_error_handle (ShSuidchkSeverity,
+			       FIL__, __LINE__, status,
+			       MSG_SUID_QREPORT,
+			       msg, tmp );
+	      SH_FREE(tmp);
+	      SH_FREE(msg);
+	    }
+	  else
+	    {
+	      tmp = sh_util_basename(fullpath);
+
+	      (void) sl_snprintf(filetmp, PATH_MAX+1, "%s/%s.info", 
+				 DEFAULT_QDIR, 
+				 tmp);
+
+	      SH_FREE(tmp);
+	      /*
+	       * avoid chmod by setting umask
+	       */
+	      umask_old = umask (0077);
+	      filePtr   = fopen (filetmp, "w+");
+
+	      /*@-usedef@*/
+	      if (filePtr)
+		{
+		  fprintf(filePtr, 
+			  _("File Info:\n filename=%s\n size=%lu\n owner=%s(%d)\n group=%s(%d)\n ctime=%s\n atime=%s\n mtime=%s\n"), 
+			  fullpath, 
+			  (unsigned long) theFile->size, 
+			  theFile->c_owner, (int) theFile->owner, 
+			  theFile->c_group, (int) theFile->group, 
+			  timestrc, timestra, timestrm);
+		  (void) fclose (filePtr);
+		}
+	      /*@+usedef@*/
+	      umask (umask_old);
+	      
+	      tmp    = sh_util_safe_name(fullpath);
+	      sh_error_handle (ShSuidchkSeverity,
+			       FIL__,__LINE__,
+			       0, MSG_SUID_QREPORT,
+			       _("Quarantine method applied"),
+			       tmp );
+	      SH_FREE(tmp);
+	    }
+	  SH_FREE(filetmp);
+	}
+    }
+  SH_FREE(dir);
+  return;
+}
+
+static void sh_q_changeperm(const char * fullpath)
+{
+  int             caperr;
+  int             status;
+  char          * msg;
+  char          * tmp;
+  struct stat     fileInfo;
+  struct stat     fileInfo_F;
+  int             cperm_status = 0;
+  int             file_d       = -1;
+
+  if (retry_lstat(FIL__, __LINE__, fullpath, &fileInfo) == -1)
+    {
+      status = errno;
+      msg    = SH_ALLOC(SH_BUFSIZE);
+      tmp    = sh_util_safe_name(fullpath);
+
+      (void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld"), status);
+      sh_error_handle (ShSuidchkSeverity,
+		       FIL__, __LINE__, 
+		       status,
+		       MSG_SUID_QREPORT, msg,
+		       tmp );
+      SH_FREE(tmp);
+      SH_FREE(msg);
+      cperm_status = -1;
+    }
+  
+  if (cperm_status == 0)
+    {
+      if (0 != (caperr = sl_get_cap_qdel()))
+	{
+	  sh_error_handle((-1), FIL__, __LINE__, 
+			  caperr, MSG_E_SUBGEN,
+			  sh_error_message (caperr), 
+			  _("sl_get_cap_qdel"));
+	  cperm_status = -1;
+	}
+    }
+  
+  if (cperm_status == 0)
+    {
+      file_d = aud_open (FIL__, __LINE__, SL_YESPRIV,
+			 fullpath, O_RDONLY, 0);
+      if (-1 == file_d)
+	{
+	  status = errno;
+	  msg    = SH_ALLOC(SH_BUFSIZE);
+	  tmp    = sh_util_safe_name(fullpath);
+
+	  (void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld"), status);
+	  sh_error_handle (ShSuidchkSeverity,
+			   FIL__, __LINE__, 
+			   status,
+			   MSG_SUID_QREPORT, msg,
+			   tmp );
+	  SH_FREE(tmp);
+	  SH_FREE(msg);
+	  cperm_status = -1;
+	}
+    }
+  
+  if (cperm_status == 0)
+    {
+      if (retry_fstat(FIL__, __LINE__, file_d, &fileInfo_F) == -1)
+	{
+	  status = errno;
+	  msg    = SH_ALLOC(SH_BUFSIZE);
+	  tmp    = sh_util_safe_name(fullpath);
+
+	  (void) sl_snprintf(msg, SH_BUFSIZE, 
+			     _("I/O error.  errno = %ld"), status);
+	  sh_error_handle (ShSuidchkSeverity,
+			   FIL__, __LINE__, 
+			   status,
+			   MSG_SUID_QREPORT, msg,
+			   tmp );
+	  SH_FREE(tmp);
+	  SH_FREE(msg);
+	  cperm_status = -1;
+	}
+    }
+  
+  if (cperm_status == 0)
+    {
+      if (fileInfo_F.st_ino  != fileInfo.st_ino ||
+	  fileInfo_F.st_dev  != fileInfo.st_dev ||
+	  fileInfo_F.st_mode != fileInfo.st_mode)
+	{
+	  status = errno;
+	  msg    = SH_ALLOC(SH_BUFSIZE);
+	  tmp    = sh_util_safe_name(fullpath);
+
+	  (void) sl_snprintf(msg, SH_BUFSIZE, 
+			     _("Race detected.  errno = %ld"), status);
+	  sh_error_handle (ShSuidchkSeverity,
+			   FIL__, __LINE__, 
+			   status,
+			   MSG_SUID_QREPORT, msg,
+			   tmp );
+	  SH_FREE(tmp);
+	  SH_FREE(msg);
+	  cperm_status = -1;
+	}
+    }
+  
+  if ((fileInfo.st_mode & S_ISUID) > 0)
+    fileInfo.st_mode -= S_ISUID;
+  if ((fileInfo.st_mode & S_ISGID) > 0)
+    fileInfo.st_mode -= S_ISGID;
+  
+  if (cperm_status == 0)
+    {
+      if (fchmod(file_d, fileInfo.st_mode) == -1)
+	{
+	  status = errno;
+	  msg    = SH_ALLOC(SH_BUFSIZE);
+	  tmp    = sh_util_safe_name(fullpath);
+
+	  (void) sl_snprintf(msg, SH_BUFSIZE, 
+			     _("Problem quarantining file.  File NOT quarantined.  errno = %ld"), 
+			     status);
+	  sh_error_handle (ShSuidchkSeverity,
+			   FIL__, __LINE__, 
+			   status,
+			   MSG_SUID_QREPORT,
+			   msg, tmp );
+	  SH_FREE(tmp);
+	  SH_FREE(msg);
+	}
+      else
+	{
+	  tmp    = sh_util_safe_name(fullpath);
+	  sh_error_handle (ShSuidchkSeverity,
+			   FIL__, __LINE__, 
+			   0,
+			   MSG_SUID_QREPORT,
+			   _("Quarantine method applied"),
+			   tmp );
+	  SH_FREE(tmp);
+	}
+    }
+  
+  if (0 != (caperr = sl_drop_cap_qdel()))
+    {
+      sh_error_handle((-1), FIL__, __LINE__, 
+		      caperr, MSG_E_SUBGEN,
+		      sh_error_message (caperr), 
+		      _("sl_drop_cap_qdel"));
+    }
+  
+  if (file_d != -1)
+    {
+      do {
+	status = close (file_d);
+      } while (status == -1 && errno == EINTR);
+      
+      if (-1 == status)
+	{
+	  status = errno;
+	  msg    = SH_ALLOC(SH_BUFSIZE);
+	  tmp    = sh_util_safe_name(fullpath);
+
+	  (void) sl_snprintf(msg, SH_BUFSIZE, 
+			     _("I/O error.  errno = %ld"), status);
+	  sh_error_handle (ShSuidchkSeverity,
+			   FIL__, __LINE__, 
+			   status,
+			   MSG_SUID_QREPORT, msg,
+			   tmp );
+	  SH_FREE(tmp);
+	  SH_FREE(msg);
+	  cperm_status = -1;
+	}
+    }
+  return;
+}
+
+static void report_file (const char * tmpcat, file_type * theFile, 
+			 char * timestrc, char * timestra, char * timestrm)
+{
+  char * msg = SH_ALLOC(SH_BUFSIZE);
+  char * tmp = sh_util_safe_name(tmpcat);
+
+  msg[0] = '\0';
+  /*@-usedef@*/
+  (void) sl_strlcpy (timestrc, 
+		     sh_unix_gmttime (theFile->ctime), 
+		     32);
+  (void) sl_strlcpy (timestra, 
+		     sh_unix_gmttime (theFile->atime), 
+		     32);
+  (void) sl_strlcpy (timestrm, 
+		     sh_unix_gmttime (theFile->mtime), 
+		     32);
+#ifdef SH_USE_XML
+  (void) sl_snprintf(msg, SH_BUFSIZE, _("owner_new=\"%s\" iowner_new=\"%ld\" group_new=\"%s\" igroup_new=\"%ld\" size_new=\"%lu\" ctime_new=\"%s\" atime_new=\"%s\" mtime_new=\"%s\""), 
+		     theFile->c_owner, theFile->owner, 
+		     theFile->c_group, theFile->group, 
+		     (unsigned long) theFile->size, 
+		     timestrc, timestra, timestrm);
+#else
+  (void) sl_snprintf(msg, SH_BUFSIZE, _("owner_new=<%s>, iowner_new=<%ld>, group_new=<%s>, igroup_new=<%ld>, filesize=<%lu>, ctime=<%s>, atime=<%s>, mtime=<%s>"), 
+		     theFile->c_owner, theFile->owner, 
+		     theFile->c_group, theFile->group, 
+		     (unsigned long) theFile->size, 
+		     timestrc, timestra, timestrm);
+#endif
+  /*@+usedef@*/
+  
+  sh_error_handle (ShSuidchkSeverity, FIL__, __LINE__, 
+		   0, MSG_SUID_POLICY,
+		   _("suid/sgid file not in database"),
+		   tmp, msg );
+  SH_FREE(tmp);
+  SH_FREE(msg);
+  return;
+}
+
 static
 int sh_suidchk_check_internal (char * iname)
 {
-  int             caperr;
   DIR *           thisDir = NULL;
-  FILE *          filePtr = NULL;
   struct dirent * thisEntry;
   char          * tmpcat;
   char          * tmp;
-  char          * msg;
-  char          * dir;
-  char          * filetmp;
-  char          * basetmp;
   char            timestrc[32];
   char            timestra[32];
   char            timestrm[32];
-  char            buffer[1024];
   struct stat     buf;
   int             status;
-  int             count;
-  int             readFile = -1;
-  int             writeFile = -1;
   char          * fs;
   long            sl_status = SL_ENONE;
-  struct stat     fileInfo;
-  struct stat     fileInfo_F;
-  int             file_d;
-
   file_type       theFile;
   char            fileHash[2*(KEY_LEN + 1)];
 
-  mode_t          umask_old;
-  int             cperm_status;
 
   SL_ENTER(_("sh_suidchk_check_internal"));
@@ -449,4 +862,6 @@
     }
 
+  /* Loop over directory entries
+   */
   do {
 
@@ -455,5 +870,4 @@
     }
 
-
     thisEntry = readdir (thisDir);
 
@@ -470,5 +884,7 @@
 
       if ((sl_strlen(tmpcat) != sl_strlen(iname)) || (tmpcat[0] == '\0'))
-	sl_status = SL_ETRUNC;
+	{
+	  sl_status = SL_ETRUNC;
+	}
       else
 	{
@@ -476,6 +892,8 @@
 	    sl_status = sl_strlcat(tmpcat, "/",                 PATH_MAX);
 	}
+
       if (! SL_ISERROR(sl_status))
 	sl_status = sl_strlcat(tmpcat, thisEntry->d_name,   PATH_MAX);
+
       if (SL_ISERROR(sl_status))
 	{
@@ -554,5 +972,5 @@
 		    )
 		   )
-	    { /* way too long routine */
+	    {
 	      
 	      (void) sl_strlcpy (theFile.fullpath, tmpcat, PATH_MAX);
@@ -584,13 +1002,12 @@
 			{
 			  sh_error_handle ((-1), FIL__, __LINE__, 
-					   0, MSG_SUID_FOUND,
-					   tmp );
+					   0, MSG_SUID_FOUND, tmp );
 			}
 		      else
 			{
 			  sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
-					   0, MSG_SUID_FOUND,
-					   tmp );
+					   0, MSG_SUID_FOUND, tmp );
 			}
+
 		      if (0 == sh_hash_compdata (SH_LEVEL_READONLY, 
 						 &theFile, fileHash,
@@ -606,46 +1023,13 @@
 		      sh_hash_pushdata (&theFile, fileHash);
 		      sh_error_handle ((-1), FIL__, __LINE__, 
-				       0, MSG_SUID_FOUND,
-				       tmp );
+				       0, MSG_SUID_FOUND, tmp );
 		    }
 		  else if (sh.flag.checkSum == SH_CHECK_CHECK )
 		    {
 		      sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, 
-				       0, MSG_SUID_FOUND,
-				       tmp );
+				       0, MSG_SUID_FOUND, tmp );
 		      if (-1 == sh_hash_have_it (tmpcat))
 			{
-			  msg = SH_ALLOC(SH_BUFSIZE);
-			  msg[0] = '\0';
-			  /*@-usedef@*/
-			  (void) sl_strlcpy (timestrc, 
-					     sh_unix_gmttime (theFile.ctime), 
-					     32);
-			  (void) sl_strlcpy (timestra, 
-					     sh_unix_gmttime (theFile.atime), 
-					     32);
-			  (void) sl_strlcpy (timestrm, 
-					     sh_unix_gmttime (theFile.mtime), 
-					     32);
-#ifdef SH_USE_XML
-			  (void) sl_snprintf(msg, SH_BUFSIZE, _("owner_new=\"%s\" iowner_new=\"%ld\" group_new=\"%s\" igroup_new=\"%ld\" size_new=\"%lu\" ctime_new=\"%s\" atime_new=\"%s\" mtime_new=\"%s\""), 
-				      theFile.c_owner, theFile.owner, 
-				      theFile.c_group, theFile.group, 
-				      (unsigned long) theFile.size, 
-				      timestrc, timestra, timestrm);
-#else
-			  (void) sl_snprintf(msg, SH_BUFSIZE, _("owner_new=<%s>, iowner_new=<%ld>, group_new=<%s>, igroup_new=<%ld>, filesize=<%lu>, ctime=<%s>, atime=<%s>, mtime=<%s>"), 
-				      theFile.c_owner, theFile.owner, 
-				      theFile.c_group, theFile.group, 
-				      (unsigned long) theFile.size, 
-				      timestrc, timestra, timestrm);
-#endif
-			  /*@+usedef@*/
-
-			  sh_error_handle (ShSuidchkSeverity, FIL__, __LINE__, 
-					   0, MSG_SUID_POLICY,
-					   _("suid/sgid file not in database"),
-					   tmp, msg );
-			  SH_FREE(msg);
+			  report_file(tmpcat, &theFile, timestrc, timestra, timestrm);
 
 			  /* Quarantine file according to configured method
@@ -656,298 +1040,16 @@
 				{
 				  case SH_Q_DELETE:
-				    /* if (unlink (theFile.fullpath) == -1) */
-				    if (do_truncate (theFile.fullpath) == -1)
-				      {
-					status = errno;
-					msg = SH_ALLOC(SH_BUFSIZE);
-					(void) sl_snprintf(msg, SH_BUFSIZE, _("Problem quarantining file.  File NOT quarantined.  errno = %ld"), status);
-					sh_error_handle (ShSuidchkSeverity,
-							 FIL__, __LINE__, 
-							 status,
-							 MSG_SUID_QREPORT, msg,
-							 tmp );
-					SH_FREE(msg);
-				      }
-				    else
-				      {
-				        sh_error_handle (ShSuidchkSeverity,
-							 FIL__, __LINE__, 0,
-							 MSG_SUID_QREPORT,
-							 _("Quarantine method applied"),
-							 tmp );
-				      }
+				    sh_q_delete(theFile.fullpath);
 				    break;
 				  case SH_Q_CHANGEPERM:
-				    cperm_status = 0;
-				    file_d = -1;
-				    if (retry_lstat(FIL__, __LINE__, tmpcat, &fileInfo) == -1)
-				      {
-					status = errno;
-					msg = SH_ALLOC(SH_BUFSIZE);
-					(void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld"), status);
-					sh_error_handle (ShSuidchkSeverity,
-							 FIL__, __LINE__, 
-							 status,
-							 MSG_SUID_QREPORT, msg,
-							 tmp );
-					SH_FREE(msg);
-					cperm_status = -1;
-				      }
-
-				    if (cperm_status == 0)
-				      {
-					if (0 != (caperr = sl_get_cap_qdel()))
-					  {
-					    sh_error_handle((-1), FIL__, __LINE__, 
-							    caperr, MSG_E_SUBGEN,
-							    sh_error_message (caperr), 
-							    _("sl_get_cap_qdel"));
-					    cperm_status = -1;
-					  }
-				      }
-
-				    if (cperm_status == 0)
-				      {
-					file_d = aud_open (FIL__, __LINE__, SL_YESPRIV,
-							   tmpcat, O_RDONLY, 0);
-					if (-1 == file_d)
-					  {
-					    status = errno;
-					    msg = SH_ALLOC(SH_BUFSIZE);
-					    (void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld"), status);
-					    sh_error_handle (ShSuidchkSeverity,
-							     FIL__, __LINE__, 
-							     status,
-							     MSG_SUID_QREPORT, msg,
-							     tmp );
-					    SH_FREE(msg);
-					    cperm_status = -1;
-					  }
-				      }
-
-				    if (cperm_status == 0)
-				      {
-					if (retry_fstat(FIL__, __LINE__, file_d, &fileInfo_F) == -1)
-					  {
-					    status = errno;
-					    msg = SH_ALLOC(SH_BUFSIZE);
-					    (void) sl_snprintf(msg, SH_BUFSIZE, 
-							       _("I/O error.  errno = %ld"), status);
-					    sh_error_handle (ShSuidchkSeverity,
-							     FIL__, __LINE__, 
-							     status,
-							     MSG_SUID_QREPORT, msg,
-							     tmp );
-					    SH_FREE(msg);
-					    cperm_status = -1;
-					  }
-				      }
-
-				    if (cperm_status == 0)
-				      {
-					if (fileInfo_F.st_ino  != fileInfo.st_ino ||
-					    fileInfo_F.st_dev  != fileInfo.st_dev ||
-					    fileInfo_F.st_mode != fileInfo.st_mode)
-					  {
-					    status = errno;
-					    msg = SH_ALLOC(SH_BUFSIZE);
-					    (void) sl_snprintf(msg, SH_BUFSIZE, 
-							       _("Race detected.  errno = %ld"), status);
-					    sh_error_handle (ShSuidchkSeverity,
-							     FIL__, __LINE__, 
-							     status,
-							     MSG_SUID_QREPORT, msg,
-							     tmp );
-					    SH_FREE(msg);
-					    cperm_status = -1;
-					  }
-				      }
-
-				    if ((fileInfo.st_mode & S_ISUID) > 0)
-				      fileInfo.st_mode -= S_ISUID;
-				    if ((fileInfo.st_mode & S_ISGID) > 0)
-				      fileInfo.st_mode -= S_ISGID;
-
-				    if (cperm_status == 0)
-				      {
-					if (fchmod(file_d, fileInfo.st_mode) == -1)
-					  {
-					    status = errno;
-					    msg = SH_ALLOC(SH_BUFSIZE);
-					    (void) sl_snprintf(msg, SH_BUFSIZE, _("Problem quarantining file.  File NOT quarantined.  errno = %ld"), status);
-					    sh_error_handle (ShSuidchkSeverity,
-							     FIL__, __LINE__, 
-							     status,
-							     MSG_SUID_QREPORT,
-							     msg, tmp );
-					    SH_FREE(msg);
-					  }
-					else
-					  {
-					    sh_error_handle (ShSuidchkSeverity,
-							     FIL__, __LINE__, 
-							     0,
-							     MSG_SUID_QREPORT,
-							     _("Quarantine method applied"),
-							     tmp );
-					  }
-				      }
-
-				    if (0 != (caperr = sl_drop_cap_qdel()))
-				      {
-					sh_error_handle((-1), FIL__, __LINE__, 
-							caperr, MSG_E_SUBGEN,
-							sh_error_message (caperr), 
-							_("sl_drop_cap_qdel"));
-				      }
-
-				    if (file_d != -1)
-				      {
-					do {
-					  status = close (file_d);
-					} while (status == -1 && errno == EINTR);
-
-					if (-1 == status)
-					  {
-					    status = errno;
-					    msg = SH_ALLOC(SH_BUFSIZE);
-					    (void) sl_snprintf(msg, SH_BUFSIZE, 
-							       _("I/O error.  errno = %ld"), status);
-					    sh_error_handle (ShSuidchkSeverity,
-							     FIL__, __LINE__, 
-							     status,
-							     MSG_SUID_QREPORT, msg,
-							     tmp );
-					    SH_FREE(msg);
-					    cperm_status = -1;
-					  }
-				      }
+				    sh_q_changeperm(theFile.fullpath);
 				    break;
 				  case SH_Q_MOVE:
-				    dir = SH_ALLOC(PATH_MAX+1);
-				    (void) sl_strlcpy (dir, DEFAULT_QDIR, PATH_MAX+1);
-				    if (retry_stat (FIL__, __LINE__, dir, &fileInfo) != 0)
-				      {
-					status = errno;
-					msg = SH_ALLOC(SH_BUFSIZE);
-					(void) sl_snprintf(msg, SH_BUFSIZE, _("Problem quarantining file.  File NOT quarantined.  errno = %ld (stat)"), status);
-					sh_error_handle (ShSuidchkSeverity,
-							 FIL__, __LINE__, 
-							 status,
-							 MSG_SUID_QREPORT, msg,
-							 tmp );
-					SH_FREE(msg);
-				      }
-				    else
-				      {
-					if (retry_lstat (FIL__, __LINE__, 
-							theFile.fullpath, &fileInfo) == -1)
-					  {
-					    status = errno;
-					    msg = SH_ALLOC(SH_BUFSIZE);
-					    (void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld(stat)"), status);
-					    sh_error_handle (ShSuidchkSeverity,
-							     FIL__, __LINE__, 
-							     status,
-							     MSG_SUID_QREPORT,
-							     msg, tmp );
-					    SH_FREE(msg);
-					  }
-					else
-					  {
-					    basetmp = sh_util_strdup(theFile.fullpath);
-					    filetmp = SH_ALLOC(PATH_MAX+1);
-					    (void) sl_snprintf(filetmp, PATH_MAX+1, "%s/%s", 
-							DEFAULT_QDIR, basename(basetmp));
-					    SH_FREE(basetmp);
-					    
-					    readFile  = open (theFile.fullpath, O_RDONLY);
-					    if (readFile != -1)
-					      writeFile = open (filetmp, O_WRONLY|O_CREAT);
-
-					    if ((readFile == -1) || (writeFile == -1))
-					      {
-						status = errno;
-						msg = SH_ALLOC(SH_BUFSIZE);
-						(void) sl_snprintf(msg, SH_BUFSIZE, _("Problem quarantining file.  File NOT quarantined.  errno = %ld (open)"), status);
-						sh_error_handle (ShSuidchkSeverity,
-								 FIL__, __LINE__, status,
-								 MSG_SUID_QREPORT,
-								 msg, tmp );
-						SH_FREE(msg);
-					      }
-					    else
-					      { 
-						/* sizeof(buffer) is 1024 */
-						while ((count = (int) read (readFile, buffer, sizeof (buffer))) > 0)
-						  if ((int) write (writeFile, buffer, (size_t) count) != count)
-						    {
-						      status = errno;
-						      msg = SH_ALLOC(SH_BUFSIZE);
-					    	      (void) sl_snprintf(msg, SH_BUFSIZE, _("I/O error.  errno = %ld (write)"), status);
-						      sh_error_handle (ShSuidchkSeverity,
-								       FIL__,
-								       __LINE__,
-								       status,
-								       MSG_SUID_QREPORT,
-								       msg, tmp );
-						      SH_FREE(msg);
-						    }
-					      }
-					    (void) close (readFile);
-					    (void) fchmod(writeFile, S_IRUSR | S_IWUSR | S_IXUSR);
-					    (void) close (writeFile);
-					    /* if (unlink (theFile.fullpath) == -1) */
-					    if (do_truncate (theFile.fullpath) == -1)
-					      {
-						status = errno;
-						msg = SH_ALLOC(SH_BUFSIZE);
-						(void) sl_snprintf(msg, SH_BUFSIZE, _("Problem quarantining file.  File NOT quarantined.  errno = %ld"), status);
-						sh_error_handle (ShSuidchkSeverity,
-								 FIL__, __LINE__, status,
-								 MSG_SUID_QREPORT,
-								 msg, tmp );
-						SH_FREE(msg);
-					      }
-					    else
-					      {
-						(void) sl_snprintf(filetmp, PATH_MAX+1, "%s/%s.info", 
-								   DEFAULT_QDIR, 
-								   basename(theFile.fullpath));
-						/*
-						 * avoid chmod by setting umask
-						 */
-						umask_old = umask (0077);
-						filePtr = fopen (filetmp, "w+");
-						/*@-usedef@*/
-						if (filePtr)
-						  {
-						    fprintf(filePtr, _("File Info:\n filename=%s\n size=%lu\n owner=%s(%d)\n group=%s(%d)\n ctime=%s\n atime=%s\n mtime=%s\n"), 
-							    theFile.fullpath, 
-							    (unsigned long) theFile.size, 
-							    theFile.c_owner, (int) theFile.owner, 
-							    theFile.c_group, (int) theFile.group, 
-							    timestrc, timestra, timestrm);
-						    (void) fclose (filePtr);
-						  }
-						/*@+usedef@*/
-						umask (umask_old);
-					
-						sh_error_handle (ShSuidchkSeverity,
-							 	 FIL__,__LINE__,
-								 0, MSG_SUID_QREPORT,
-								 _("Quarantine method applied"),
-								 tmp );
-					      }
-					    SH_FREE(filetmp);
-					  }
-				      }
-				    SH_FREE(dir);
+				    sh_q_move(theFile.fullpath, &theFile, timestrc, timestra, timestrm);
 				    break;
 				  default:
 				    sh_error_handle (ShSuidchkSeverity, FIL__,
 						     __LINE__, 0, MSG_SUID_QREPORT,
-						     _("Bad quarantine method"),
-						     tmp);
+						     _("Bad quarantine method"), tmp);
 				    break;
 				}
@@ -975,6 +1077,5 @@
 	      if (theFile.attr_string)
 		SH_FREE(theFile.attr_string);
-
-	    } /* end of way too long routine */
+	    }
 	}
       SH_FREE(tmpcat);
@@ -990,5 +1091,4 @@
 		             _("Failed to release time slice"),
 			     _("sh_suidchk_check_internal") );
-	    
 	  }
       }
