commit 3dec5a086c264100bc9c41b1865d229d626d2006 Author: Karchnu Date: Sun Nov 29 01:14:51 2020 +0100 Initial commit. ofind provides partial file info, cbor. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b3858a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +old/ +bin/ +lib/ +shard.lock diff --git a/shard.yml b/shard.yml new file mode 100644 index 0000000..009356f --- /dev/null +++ b/shard.yml @@ -0,0 +1,24 @@ +name: osh +version: 0.1.0 + +# authors: +# - name + +description: | + Oriented-object shell (and associated tools). + +dependencies: + baguette-crystal-base: + git: https://git.baguette.netlib.re/Baguette/baguette-crystal-base + branch: master + cbor: + git: https://git.baguette.netlib.re/Baguette/crystal-cbor + branch: master + +targets: + osh: + main: src/osh/main.cr + ofind: + main: src/ofind/main.cr + +license: ISC diff --git a/src/ofind/main.cr b/src/ofind/main.cr new file mode 100644 index 0000000..3f73ff2 --- /dev/null +++ b/src/ofind/main.cr @@ -0,0 +1,96 @@ +require "option_parser" +require "cbor" + +class Representation + include CBOR::Serializable + + class Permissions + include CBOR::Serializable + property owner : String? = nil + property group : String? = nil + property other : String? = nil + + def initialize + end + end + + property name : String + property exists : Bool + property base_name : String? = nil + property size : UInt64? = nil + property owner : UInt32? = nil + property group : UInt32? = nil + property last_modification : Time? = nil + property type : String? = nil # directory, file, symlink, socket, … + property permissions : Permissions? = nil + + def initialize(@name) + @exists = File.exists?(@name) + return unless @exists + + infos = File.info(@name) + @owner = infos.owner_id.to_u32 + @group = infos.group_id.to_u32 + + @last_modification = infos.modification_time + @size = infos.size + @type = infos.type.to_s + @permissions = Permissions.new.tap do |perms| + perms.owner = String.build do |str| + str << (infos.permissions.owner_read? ? 'r' : '-') + str << (infos.permissions.owner_write? ? 'w' : '-') + str << (infos.permissions.owner_execute? ? 'x' : '-') + end + + perms.group = String.build do |str| + str << (infos.permissions.group_read? ? 'r' : '-') + str << (infos.permissions.group_write? ? 'w' : '-') + str << (infos.permissions.group_execute? ? 'x' : '-') + end + + perms.other = String.build do |str| + str << (infos.permissions.other_read? ? 'r' : '-') + str << (infos.permissions.other_write? ? 'w' : '-') + str << (infos.permissions.other_execute? ? 'x' : '-') + end + end + end +end + +class FindApplication + property to_search = Array(String).new + + def initialize + end + + def run + OptionParser.parse do |parser| + parser.banner = "usage: find [options] " + + parser.on "-h", "--help", "Displays this help and exits." do + puts parser + exit 0 + end + end + + @to_search = ARGV + + loop do + cur = @to_search.shift? + break unless cur + + representation = Representation.new (cur) + + if representation.type == "Directory" + Dir.each_child(cur) do |c| + @to_search << "#{cur}/#{c}" + end + end + + STDOUT.write representation.to_cbor + STDOUT.flush + end + end +end + +FindApplication.new.run