Listing 4 Illustrates exception classes

// ddir2.cpp
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <dir.h>
#include <iostream.h>
#include <fstream.h>
#include <strstream.h>

// Exception classes
class Dir_err
{};
class Bad_dir : public Dir_err
{};
class Dir_open_err : public Dir_err
{};
class File_de_err : public Dir_err
{};
class Dir_del_err : public Dir_err
{};

// Put response file in root directory
char response_file[L_tmpnam+1] = "\\";
// (Change this to "/" for UNIX)

main(int argc, char **argv)
{
   char *old_path = getcwd(NULL,MAXDIR);
   void rd(char *);

   // Initialize response file for DOS "del" command
   tmpnam(response_file+1);
   ofstream(response_file) << "Y\n";

   // Delete the directories
   while (--argc)
   {
      try
      {
         rd(*++argv);
      }

      // Catch exceptions
      catch(Bad_dir)
      {
         cerr << "Invalid directory\n";
      }

      catch(Dir_open_err)
      {
         cerr << "Error opening directory\n";
      }
      catch(File_del_err)
      {
         cerr << "Error deleting file\n";
      }
      catch(Dir_del_err)
      {
         cerr << "Error deleting directory\n";
      }
      catch(Dir_err)
      {
         cerr << "Directory error\n";
      }
   }

   // Clean-up
   remove(response_file);
   chdir(old_path);
   return 0;
}

void rd(char* dir)
{
   // Log onto the directory that is to be deleted
   cout << strlwr(dir) << endl;
   if (chdir(dir))
      throw Bad_dir();

   // Delete all normal files via OS shell
   const size_t SH_CMD_LEN = 14;
   char sh_cmd[L_tmpnam+SH_CMD_LEN+1];
   ostrstream(sh_cmd,sizeof sh_cmd) << "del *.* <"
                               << response_file
                               << " >nul"
                               << ends;
   system(sh_cmd);

   // Delete any remaining directory entries
   DIR *dirp;
   struct dirent *entry;
   if ((dirp = opendir(".")) == NULL)
      throw Dir_open_err();
   while ((entry = readdir(dirp)) != NULL)
   {
      struct stat finfo;

      if (entry->d_name[0] == '.')
         continue;
      stat(entry->d_name,&finfo);
      if (finfo.st_mode & S_IFDIR)
         rd(entry->d_name);      // Subdirectory
      else
      {
         // Enable delete of file, then do it
         chmod(entry->d_name,S_IWRITE);
         if (unlink(entry->d_name))
            throw File_del_err();
      }
   }
   closedir(dirp);

   // Remove the directory from its parent
   chdir("..");
   if (rmdir(dir))
      throw Dir_del_err();
}

// End of File