1 /** 2 Copyright: Copyright (c) 2019, Joakim Brännström. All rights reserved. 3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 */ 6 module dsnapshot.cmdgroup.remote; 7 8 import logger = std.experimental.logger; 9 10 import dsnapshot.config; 11 import dsnapshot.types; 12 13 int cmdRemote(const Config.Remotecmd conf) nothrow { 14 import std.algorithm : map, filter; 15 import std.exception : collectException; 16 import std.file : dirEntries, SpanMode, exists, mkdirRecurse, rmdirRecurse, rename; 17 import std.path : baseName; 18 import std.stdio : writeln; 19 20 final switch (conf.cmd) { 21 case RemoteSubCmd.none: 22 break; 23 case RemoteSubCmd.lsDirs: 24 try { 25 foreach (p; dirEntries(conf.path, SpanMode.shallow).filter!(a => a.isDir) 26 .map!(a => a.name.baseName)) { 27 writeln(p); 28 } 29 } catch (Exception e) { 30 } 31 break; 32 case RemoteSubCmd.mkdirRecurse: 33 try { 34 if (!exists(conf.path)) 35 mkdirRecurse(conf.path); 36 } catch (Exception e) { 37 logger.warning(e.msg).collectException; 38 } 39 break; 40 case RemoteSubCmd.rmdirRecurse: 41 if (!exists(conf.path)) 42 return 0; 43 44 try { 45 // can fail because a directory is write protected. 46 rmdirRecurse(conf.path); 47 return 0; 48 } catch (Exception e) { 49 } 50 51 try { 52 foreach (const p; dirEntries(conf.path, SpanMode.depth).filter!(a => a.isDir)) { 53 import core.sys.posix.sys.stat; 54 import std.file : getAttributes, setAttributes; 55 56 const attrs = getAttributes(p); 57 setAttributes(p, attrs | S_IRWXU); 58 } 59 rmdirRecurse(conf.path); 60 } catch (Exception e) { 61 logger.warning(e.msg).collectException; 62 } 63 break; 64 case RemoteSubCmd.publishSnapshot: 65 if (!exists(conf.path)) { 66 logger.infof("Snapshot %s do not exist", conf.path).collectException; 67 return 1; 68 } 69 70 publishSnapshot(conf.path); 71 break; 72 } 73 return 0; 74 } 75 76 /// Publish a snapshot that has the status "in-progress". 77 int publishSnapshot(const string snapshot) nothrow { 78 import std.algorithm : map, filter; 79 import std.exception : collectException; 80 import std.file : dirEntries, SpanMode, exists, mkdirRecurse, rmdirRecurse, rename; 81 import std.path : baseName; 82 import std.stdio : writeln; 83 84 const dst = () { 85 if (snapshot.length < snapshotInProgressSuffix.length) 86 return null; 87 return snapshot[0 .. $ - snapshotInProgressSuffix.length]; 88 }(); 89 90 if (exists(dst)) { 91 logger.errorf("Destination %s already exist thus unable to publish snapshot %s", 92 dst, snapshot).collectException; 93 return 1; 94 } 95 96 try { 97 rename(snapshot, dst); 98 } catch (Exception e) { 99 logger.error(e.msg).collectException; 100 return 1; 101 } 102 103 return 0; 104 }