15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2010 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/create_dir_work_item.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/logging_installer.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateDirWorkItem::~CreateDirWorkItem() {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CreateDirWorkItem::CreateDirWorkItem(const base::FilePath& path)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : path_(path),
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rollback_needed_(false) {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateDirWorkItem::GetTopDirToCreate() {
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (base::PathExists(path_)) {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    top_path_ = base::FilePath();
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath parent_dir(path_);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    top_path_ = parent_dir;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parent_dir = parent_dir.DirName();
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } while ((parent_dir != top_path_) && !base::PathExists(parent_dir));
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateDirWorkItem::Do() {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "creating directory " << path_.value();
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetTopDirToCreate();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (top_path_.empty())
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "top directory that needs to be created: " << top_path_.value();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = file_util::CreateDirectory(path_);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "directory creation result: " << result;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rollback_needed_ = true;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateDirWorkItem::Rollback() {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!rollback_needed_)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete all the directories we created to rollback.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note we can not recusively delete top_path_ since we don't want to
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delete non-empty directory. (We may have created a shared directory).
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Instead we walk through path_ to top_path_ and delete directories
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // along the way.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path_to_delete(path_);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (1) {
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (base::PathExists(path_to_delete)) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!RemoveDirectory(path_to_delete.value().c_str()))
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (path_to_delete == top_path_)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path_to_delete = path_to_delete.DirName();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70