diff --git a/include/struc.hpp b/include/struc.hpp index e6b4ff2..f58589c 100644 --- a/include/struc.hpp +++ b/include/struc.hpp @@ -231,6 +231,9 @@ public: condlist* last_cond() { return cls[cls.size()-1]; } + void insert(uint32_t i, condlist* val); + void insert(uint32_t i, list const& lst); + size_t size() { return cls.size(); } condlist* operator[](uint32_t i) { return cls[i]; } diff --git a/src/debashify.cpp b/src/debashify.cpp index 6d86ff4..eea8c69 100644 --- a/src/debashify.cpp +++ b/src/debashify.cpp @@ -2,6 +2,8 @@ #include "recursive.hpp" #include "util.hpp" +#include "parse.hpp" +#include "struc_helper.hpp" bool debashify_replace_bashtest(cmd* in) { @@ -11,6 +13,8 @@ bool debashify_replace_bashtest(cmd* in) return false; } +// replace &>, &>> and >&: +// add 2>&1 as redirect bool debashify_replace_combined_redirects(block* in) { bool has_replaced=false; @@ -40,10 +44,125 @@ bool debashify_replace_combined_redirects(block* in) return has_replaced; } -bool r_debashify(_obj* o) +// replace <<< and +// <<< : TODO +bool debashify_replace_extended_redirects(pipeline* in) +{ + return false; +} + +// replace <() and >() +/* + <() replacer: +REPLACE: CMD <(PSUB) +TO: + fifoN=${TMPDIR-/tmp}/lxshfifo_$(__lxsh_random 10) + mkfifo "$fifoN" + ( {PSUB;} > "$fifoN" ; rm "$fifoN") & + CMD "$fifoN" + +REPLACE CMD >(PSUB) +TO: + fifoN=${TMPDIR-/tmp}/lxshfifo_$(__lxsh_random 10) + mkfifo "$fifoN" + ( {PSUB;} < "$fifoN" ; rm "$fifoN") & + jobN + CMD "$fifoN" + wait "$jobN" +*/ +bool debashify_replace_procsub(list* lst) +{ + bool has_replaced=false; + for(uint32_t li=0; licls.size(); li++) + { + std::vector> affected_args; + // iterate all applicable args of the cl + for(auto plit: lst->cls[li]->pls) + { + for(auto cmit: plit->cmds) + { + if(cmit->type == _obj::block_cmd) + { + cmd* t = dynamic_cast(cmit); + if(t->args != nullptr) + { + for(auto ait: t->args->args) + { + if(ait->sa[0]->type == _obj::subarg_procsub) + { + procsub_subarg* st = dynamic_cast(ait->sa[0]); + affected_args.push_back( std::make_pair(ait, st->is_output) ); + } + } + } + } + } + } + // perform the replace + if(affected_args.size()>0) + { + has_replaced=true; + list* lst_insert = new list; + std::vector mkfifoargs = {"mkfifo"}; + for(uint32_t i=0; iadd( make_condlist( strf("__lxshfifo%u=${TMPDIR-/tmp}/lxshfifo_$(__lxsh_random 10)", i) ) ); + mkfifoargs.push_back( strf("\"$__lxshfifo%u\"", i) ); + } + // mkfifo "$fifoN" + lst_insert->add( new condlist(make_cmd(mkfifoargs)) ); + for(uint32_t i=0; i "$fifoN" ; rm "$fifoN") & + subshell* psub = new subshell(new list); + procsub_subarg* st = dynamic_cast(affected_args[i].first->sa[0]); + // {PSUB;} + brace* cbr = new brace(st->sbsh->lst); + // deindex list + st->sbsh->lst=nullptr; + // {PSUB;} > "$__lxshfifoN" + cbr->redirs.push_back( new redirect( affected_args[i].second ? "<" : ">", new arg(strf("\"$__lxshfifo%u\"", i)) ) ); + // ( {PSUB;} > "$__lxshfifoN" ) + psub->lst->add( new condlist(cbr) ); + // ( {PSUB;} > "$__lxshfifoN" ; rm "$__lxshfifoN" ) + psub->lst->add( make_condlist(strf("rm \"$__lxshfifo%u\"", i)) ); + // ( {PSUB;} > "$__lxshfifoN" ; rm "$__lxshfifoN" ) & + condlist* pscl = new condlist(psub); + pscl->parallel=true; + lst_insert->add( pscl ); + + // replace the arg + delete affected_args[i].first->sa[0]; + affected_args[i].first->sa[0] = new string_subarg(strf("\"$__lxshfifo%u\"", i)); + } + lst->insert(li, *lst_insert ); + li+= lst_insert->size(); + //cleanup + lst_insert->cls.resize(0); + delete lst_insert; + } + } + return has_replaced; +} + +function* create_random_func() +{ + std::string code="{ tr -cd '[:alnum:]' name="__lxsh_random"; + return fct; +} + +bool r_debashify(_obj* o, bool* need_random_func) { switch(o->type) { + case _obj::_list: { + list* t = dynamic_cast(o); + if(debashify_replace_procsub(t)) + *need_random_func = true; + } break; case _obj::block_subshell: { subshell* t = dynamic_cast(o); debashify_replace_combined_redirects(t); @@ -88,6 +207,12 @@ bool r_debashify(_obj* o) void debashify(shmain* sh) { - sh->shebang = dirname(sh->shebang)+"/sh"; - recurse(r_debashify, sh); + bool need_random_func=false; + if(sh->shebang == "") + sh->shebang = "#!/bin/bash"; + else + sh->shebang = dirname(sh->shebang)+"/sh"; + recurse(r_debashify, sh, &need_random_func); + if(need_random_func) + sh->lst->insert(0, new condlist(create_random_func())); } diff --git a/src/struc_helper.cpp b/src/struc_helper.cpp index ee47c7d..b03c810 100644 --- a/src/struc_helper.cpp +++ b/src/struc_helper.cpp @@ -154,10 +154,24 @@ void condlist::add(pipeline* pl, bool or_op) pls.push_back(pl); } +void list::insert(uint32_t i, condlist* val) +{ + if(i<0) + cls.insert(cls.end(), val); + else + cls.insert(cls.begin()+i, val); +} +void list::insert(uint32_t i, list const& lst) +{ + if(i<0) + cls.insert(cls.end(), lst.cls.begin(), lst.cls.end()); + else + cls.insert(cls.begin()+i, lst.cls.begin(), lst.cls.end()); +} void shmain::concat(shmain* in) { - this->lst->cls.insert(this->lst->cls.end(), in->lst->cls.begin(), in->lst->cls.end()); + lst->insert(lst->size(), *in->lst); in->lst->cls.resize(0); if(this->shebang == "") this->shebang = in->shebang;