source: trunk/bin/rmdirhier.cc @ 58

Last change on this file since 58 was 55, checked in by Jari Häkkinen, 16 years ago

Fixed bug that made file names starting with a '.' to be invisible in delete.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 1.8 KB
Line 
1// $Id: rmdirhier.cc 55 2006-01-15 01:34:04Z jari $
2
3#include "rmdirhier.h"
4
5#include <dirent.h>
6#include <fcntl.h>
7#include <iostream>
8#include <sys/stat.h>
9#include <unistd.h>
10
11
12namespace theplu {
13namespace svnstat {
14
15  void rmdirhier(const std::string& path)
16  {
17    int fd=open(".",O_RDONLY);  // remember "original" cwd
18    void rmdirhier__(const std::string&);
19
20    try {
21      rmdirhier__(path);
22    }
23    catch(const BadDirectory& x) {
24      std::cerr << "Invalid directory: " << x.what() << std::endl;
25    }
26    catch(const DirectoryOpenError& x) {
27      std::cerr << "Error opening directory: " << x.what() << std::endl;
28    }
29    catch(const FileDeleteError& x) {
30      std::cerr << "Error deleting file: " << x.what() << std::endl;
31    }
32    catch(const DirectoryDeleteError& x) {
33      std::cerr << "Error deleting directory: " << x.what() << std::endl;
34    }
35    catch(const DirectoryError& x) {
36      std::cerr << "Directory error:" << x.what() << std::endl;
37    }
38
39    fchdir(fd); // return to "original" cwd
40  }
41
42
43  void rmdirhier__(const std::string& dir)
44  {
45    if (chdir(dir.c_str()))
46      throw BadDirectory(dir);
47
48   // Delete any remaining directory entries
49    DIR* dp;
50    struct dirent *entry;
51    if (!(dp=opendir(".")))
52      throw DirectoryOpenError(dir);
53    while ((entry=readdir(dp)) != NULL) {
54      struct stat buf;
55      if ((std::string(entry->d_name) == ".") ||
56          (std::string(entry->d_name) == ".."))
57        continue;
58      stat(entry->d_name,&buf);
59      if (buf.st_mode & S_IFDIR)
60        rmdirhier__(entry->d_name);      // sub-directory
61      else {
62        // Make sure file is removable before removing it
63        chmod(entry->d_name,S_IWRITE);
64        if (unlink(entry->d_name))
65          throw FileDeleteError(entry->d_name);
66      }
67    }
68    closedir(dp);
69
70    // Remove the directory from its parent
71    chdir("..");
72    if (rmdir(dir.c_str()))
73      throw DirectoryDeleteError(dir);
74  }
75
76}} // of namespace svnstat and namespace theplu
Note: See TracBrowser for help on using the repository browser.