Created
August 20, 2013 22:26
-
-
Save archaelus/6288153 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Eshell V5.5.5 (abort with ^G) | |
([email protected])1> ssae:rebuild_module("../racer.zip", "ebin/ssae.beam", "ebin/evil/ssae.beam"). | |
ok | |
([email protected])2> code:load_abs("ebin/evil/ssae"). | |
{module,ssae} | |
([email protected])3> nl(ssae). | |
abcast | |
([email protected])4> beam_lib:chunks("ebin/evil/ssae.beam", ["SSAE"]). | |
{ok,{ssae,[{"SSAE", | |
<<80,75,3,4,10,0,0,0,0,0,66,181,59,55,0,0,0,0,0,0,0,0,...>>}]}} | |
([email protected])5> nl(ssae). | |
abcast | |
([email protected])6> code:which(ssae). | |
"/path_to/ssae/ebin/ssae.beam" | |
([email protected])7> ssae:rebuild_module("../racer.zip", "ebin/ssae.beam", "ebin/evil/ssae.beam"). | |
ok | |
([email protected])8> code:load_abs("ebin/evil/ssae"). | |
{error,not_purged} | |
=ERROR REPORT==== 28-Sep-2007::00:11:55 === | |
Loading of /path_to/ssae/ebin/evil/ssae.beam failed: not_purged | |
=ERROR REPORT==== 28-Sep-2007::00:11:55 === | |
Module ssae must be purged before loading | |
([email protected])9> code:purge(ssae). | |
false | |
([email protected])10> code:load_abs("ebin/evil/ssae"). | |
{module,ssae} | |
([email protected])11> code:which(ssae). | |
"/path_to/ssae/ebin/evil/ssae.beam" | |
([email protected])12> ssae:zip_file_names(). | |
["racer/", | |
"racer/.git/", | |
"racer/.git/COMMIT_EDITMSG~", | |
"racer/.git/HEAD", | |
"racer/.git/config", | |
"racer/.git/description", | |
"racer/.git/hooks/", | |
"racer/.git/hooks/applypatch-msg", | |
"racer/.git/hooks/commit-msg", | |
"racer/.git/hooks/post-commit", | |
"racer/.git/hooks/post-receive", | |
"racer/.git/hooks/post-update", | |
"racer/.git/hooks/pre-applypatch", | |
"racer/.git/hooks/pre-commit", | |
"racer/.git/hooks/pre-rebase", | |
"racer/.git/hooks/update", | |
"racer/.git/index", | |
"racer/.git/info/", | |
"racer/.git/info/exclude", | |
"racer/.git/logs/", | |
"racer/.git/logs/HEAD", | |
"racer/.git/logs/refs/", | |
"racer/.git/logs/refs/heads/", | |
"racer/.git/logs/refs/heads/master", | |
"racer/.git/objects/", | |
"racer/.git/objects/1a/", | |
"racer/.git/objects/1a/c1ff5971dbf3eb947c5090f35ff399c81910d3", | |
"racer/.git/objects/20/", | |
[...]|...] | |
([email protected])13> ssae:use(). | |
error_handler | |
([email protected])14> re:module_info(). | |
[{exports,[{parse,1}, | |
{match,2}, | |
{first_match,2}, | |
{smatch,2}, | |
{first_smatch,2}, | |
{matches,2}, | |
{sub,3}, | |
{gsub,3}, | |
{split,2}, | |
{tt,2}, | |
{loadf,1}, | |
{module_info,0}, | |
{module_info,1}]}, | |
{imports,[]}, | |
{attributes,[{vsn,[77891265686719082290801561385576450333]}]}, | |
{compile,[{options,[{cwd,"/path_to/racer"}, | |
{outdir,"/path_to/racer/ebin"}, | |
{i,"/Library/DarwinPorts/lib/erlang/lib/stdlib-1.14.5/include"}, | |
{i,"/path_to/racer/../eunit/include"}, | |
{i,"/path_to/racer/include"}, | |
debug_info]}, | |
{version,"4.4.5"}, | |
{time,{2007,9,25,1,40,13}}, | |
{source,"/path_to/racer/src/re.erl"}]}] | |
([email protected])15> code:which(re). | |
"ssae://racer/ebin/re.beam" | |
([email protected])16> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% @copyright Geoff Cant | |
%% @author Geoff Cant <[email protected]> | |
%% @version {@vsn}, {@date} {@time} | |
%% @doc Silly standalone erlang. | |
%% | |
%% Created because people keep whining that standalone erlang is long dead. | |
%% | |
%% Use: 1) Create a zip file full of erlang code you want to use (precompiled). (e.g. zip -r code.zip /path/to/code) | |
%% 2) code:ensure_loaded(ssae). | |
%% 3) ssae:rebuild_module("code.zip", code:which(ssae), "evil/ssae.ebin"). | |
%% 4) code:load_abs("evil/ssae"). | |
%% 5) ssae:use(). | |
%% 6) You can now call module you put in code.zip. | |
%% 7) You encounter a bug, ssae eats all your ram, your machine dies in swapdeath. | |
%% | |
%% @end | |
-module(ssae). | |
-export([undefined_function/3, undefined_lambda/3]). | |
-compile(export_all). | |
use() -> | |
process_flag(error_handler, ?MODULE). | |
undefined_function(Module, Func, Args) -> | |
%% Try the code server first. SSAE is a really expensive loader | |
%% and relies on stuff that SSAE itself can't load.(it used up all | |
%% my ram and died a painful swapdeath.) | |
case code:ensure_loaded(Module) of | |
{module, Module} -> | |
error_handler:undefined_function(Module, Func, Args); | |
_Error -> | |
case ensure_loaded(Module) of | |
{module, Module} -> apply(Module, Func, Args); | |
_Else -> crash(Module, Func, Args) | |
end | |
end. | |
undefined_lambda(Module, Fun, Args) -> | |
%% Try the code server first. SSAE is a really expensive loader | |
%% and relies on stuff that SSAE itself can't load.(it used up all | |
%% my ram and died a painful swapdeath.) | |
case code:ensure_loaded(Module) of | |
{module, Module} -> | |
%% There is no need (and no way) to test if the fun is present. | |
%% apply/2 will not call us again if the fun is missing. | |
error_handler:undefined_lambda(Module, Fun, Args); | |
_Error -> | |
case ensure_loaded(Module) of | |
{module, Module} -> apply(Fun, Args); | |
_Else -> crash(Module, Fun, Args) | |
end | |
end. | |
ensure_loaded(Mod) -> | |
try {Name, Path, Bin} = find_module(Mod), | |
code:load_binary(Name, "ssae://" ++ Path, Bin) | |
catch | |
throw:Error -> | |
{error, Error} | |
end. | |
find_module(Name) when is_atom(Name) -> | |
Zip = zip(), | |
case lists:keysearch(Name, 1, beam_files(zip_file_names(Zip))) of | |
{value, {Name, Path}} -> | |
find_module(Name, Path, file(Path, Zip), Zip); | |
false -> throw({ssae_nosuch_file, Name}) | |
end. | |
find_module(Name, Path, Bin, Zip) when is_binary(Zip) -> | |
Info = beam_lib:info(Bin), | |
case lists:keysearch(module, 1, Info) of | |
{value, {module, Name}} -> | |
{Name, Path, Bin}; | |
{value, {module, Else}} -> | |
throw({ssae_wrong_module, "ssae://" ++ Path, Else}); | |
Else -> throw({ssae_module_info, Else}) | |
end. | |
file(Path) -> file(Path, zip()). | |
file(Path, Zip) -> | |
case zip:extract(Zip, [memory, {file_list, [Path]}]) of | |
{ok, [{Path, Bin}]} -> Bin; | |
Else -> throw({ssae_zip_err, Else}) | |
end. | |
zip_file_names() -> zip_file_names(zip()). | |
zip_file_names(Bin) -> | |
{ok, Contents} = zip:list_dir(Bin), | |
[Name || {zip_file, Name, _info, _, _sz_uncomp, _sz} <- Contents]. | |
beam_files() -> beam_files(zip_file_names()). | |
beam_files(NameList) -> | |
Xtn = code:objfile_extension(), | |
Files = lists:filter(fun (N) -> | |
0 =/= string:str(N,Xtn) end, | |
NameList), | |
[{list_to_atom(filename:basename(N, Xtn)), N} || N <- Files]. | |
zip() -> | |
File = code:which(?MODULE), | |
{ok, {_, [{"SSAE", Bin}]}} = beam_lib:chunks(File, ["SSAE"]), | |
Bin. | |
crash(Fun, Args) -> | |
crash({Fun,Args}). | |
crash(M, F, A) -> | |
crash({M,F,A}). | |
crash(MFA) -> | |
try erlang:error(undef) | |
catch | |
error:undef -> | |
erlang:raise(error, undef, [MFA|tl(erlang:get_stacktrace())]) | |
end. | |
rebuild_module(Zip, Beam, OutputFile) -> | |
{ok, Bin} = add_zip_to_beam(Zip, Beam), | |
file:write_file(OutputFile, Bin). | |
add_zip_to_beam(Zip, Beam) when is_list(Zip) -> | |
{ok, Bin} = file:read_file(Zip), | |
add_zip_to_beam(Bin, Beam); | |
add_zip_to_beam(Zip, Beam) when is_binary(Zip), is_list(Beam) -> | |
{ok, _, Chunks} = beam_lib:all_chunks(Beam), | |
add_zip_to_beam_chunks(Zip, Chunks). | |
add_zip_to_beam_chunks(Zip, Chunks) -> | |
beam_lib:build_module([{"SSAE", Zip} | Chunks]). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment