-#ifndef _WIN32
-#include <unistd.h>
-#include <sys/stat.h>
-#endif
-#include <msp/fs/dir.h>
-#include <msp/fs/stat.h>
-#include <msp/fs/utils.h>
-#include <msp/io/file.h>
-#include <msp/io/print.h>
-#include "builder.h"
-#include "copy.h"
-#include "installedfile.h"
-
-using namespace std;
-using namespace Msp;
-
-Target *Copy::create_target(const vector<Target *> &sources, const string &arg)
-{
- FileTarget &file_tgt = dynamic_cast<FileTarget &>(*sources.front());
- InstalledFile *inst = new InstalledFile(builder, *file_tgt.get_package(), file_tgt, arg);
- inst->set_tool(*this);
- return inst;
-}
-
-Task *Copy::run(const Target &target) const
-{
- const InstalledFile &install = dynamic_cast<const InstalledFile &>(target);
- Worker *worker = new Worker(install);
- InternalTask *task = new InternalTask(worker);
- task->add_file(install.get_path());
- task->set_unlink();
- return task;
-}
-
-
-void Copy::Worker::main()
-{
- const FileTarget &source = target.get_source();
- const FS::Path &src_path = source.get_path();
- const FS::Path &dst_path = target.get_path();
-
- try
- {
- IO::File in(src_path.str());
- IO::File out(dst_path.str(), IO::M_WRITE);
-
- // Actual transfer loop
- char buf[16384];
- while(!in.eof())
- {
- unsigned len = in.read(buf, sizeof(buf));
- out.write(buf, len);
- }
- }
- catch(const exception &e)
- {
- IO::print(IO::cerr, "%s\n", e.what());
- status = Task::ERROR;
- return;
- }
-
-#ifndef _WIN32
- // Preserve file permissions
- struct stat st;
- if(stat(src_path.str().c_str(), &st)==0)
- chmod(dst_path.str().c_str(), st.st_mode&0777);
-
- const FS::Path &link = target.get_symlink();
- if(!link.empty())
- {
- FS::Path relpath = FS::relative(dst_path, FS::dirname(link));
- if(FS::exists(link))
- FS::unlink(link);
- symlink(relpath.str().c_str(), link.str().c_str());
- }
-#endif
-
- status = Task::SUCCESS;
-}