source: trunk/lib/rmdirhier.cc @ 1090

Last change on this file since 1090 was 1090, checked in by Peter Johansson, 13 years ago

update copyrights

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 2.9 KB
Line 
1// $Id: rmdirhier.cc 1090 2010-06-12 17:27:00Z peter $
2
3/*
4  Copyright (C) 2006 Jari Häkkinen
5  Copyright (C) 2007, 2008, 2009 Jari Häkkinen, Peter Johansson
6  Copyright (C) 2010 Peter Johansson
7
8  This file is part of svndigest, http://dev.thep.lu.se/svndigest
9
10  svndigest is free software; you can redistribute it and/or modify it
11  under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 3 of the License, or
13  (at your option) any later version.
14
15  svndigest is distributed in the hope that it will be useful, but
16  WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
22*/
23
24#include "rmdirhier.h"
25#include "utility.h"
26
27#include <cstring>
28#include <dirent.h>
29#include <cerrno>
30#include <fcntl.h>
31#include <iostream>
32#include <sys/stat.h>
33#include <unistd.h>
34
35
36namespace theplu {
37namespace svndigest {
38
39  void rmdirhier(const std::string& path)
40  {
41    int fd=open(".",O_RDONLY);  // remember "original" cwd
42    void rmdirhier__(const std::string&);
43
44    try {
45      rmdirhier__(path);
46    }
47    catch(const BadDirectory& x) {
48      std::cerr << "svndigest: " << x.what() << "\n" 
49                << strerror(errno) << std::endl;
50    }
51    catch(const DirectoryOpenError& x) {
52      std::cerr << "svndigest: cannot open directory " << x.what() << "\n" 
53                << strerror(errno) << "\n";
54    }
55    catch(const FileDeleteError& x) {
56      std::cerr << "svndigest: cannot delete file " << x.what() << "\n"
57                << strerror(errno) << "\n";
58    }
59    catch(const DirectoryDeleteError& x) {
60      std::cerr << "svndigest: cannot delete directory " << x.what() << "\n"
61                << strerror(errno) << "\n";
62    }
63
64    fchdir(fd); // return to "original" cwd
65  }
66
67
68  void rmdirhier__(const std::string& dir)
69  {
70    struct stat buf;
71    // using lstat because links should not be treated as dirs
72    lstat(dir.c_str(),&buf);
73    // check if dir - if not delete the node
74    if (!(buf.st_mode & S_IFDIR)) {
75      // Make sure file is removable before removing it
76      chmod(dir.c_str(),S_IWRITE);
77      if (unlink(dir.c_str()))
78        throw FileDeleteError(concatenate_path(pwd(),dir));
79      return;
80    }
81    if (::chdir(dir.c_str()))
82      throw BadDirectory(concatenate_path(pwd(),dir));
83
84   // Delete any remaining directory entries
85    DIR* dp;
86    struct dirent *entry;
87    if (!(dp=opendir(".")))
88      throw DirectoryOpenError(concatenate_path(pwd(),dir));
89    while ((entry=readdir(dp)) != NULL) {
90      if ((std::string(entry->d_name) == ".") ||
91          (std::string(entry->d_name) == ".."))
92        continue;
93      rmdirhier__(entry->d_name);
94    }
95    closedir(dp);
96
97    // Remove the directory from its parent
98    chdir("..");
99    if (rmdir(dir.c_str()))
100      throw DirectoryDeleteError(concatenate_path(pwd(),dir));
101  }
102
103}} // of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.