From 014909f79b1c3fb9206bbbc5cfde6f1f6ecece25 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Thu, 31 May 2018 16:46:44 +0900 Subject: [PATCH] wip --- zomp/lib/otpr/zx/0.1.0/include/zx_logger.hrl | 4 +- zomp/lib/otpr/zx/0.1.0/src/zx.erl | 143 +++---- zomp/lib/otpr/zx/0.1.0/src/zx_conn.erl | 4 +- zomp/lib/otpr/zx/0.1.0/src/zx_daemon.erl | 7 +- zomp/lib/otpr/zx/0.1.0/src/zx_key.erl | 64 ++- zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl | 125 +++--- zomp/lib/otpr/zx/0.1.0/src/zx_local.erl | 366 ++++++++---------- .../src/{zx_conf_sys.erl => zx_sys_conf.erl} | 4 +- 8 files changed, 332 insertions(+), 385 deletions(-) rename zomp/lib/otpr/zx/0.1.0/src/{zx_conf_sys.erl => zx_sys_conf.erl} (99%) diff --git a/zomp/lib/otpr/zx/0.1.0/include/zx_logger.hrl b/zomp/lib/otpr/zx/0.1.0/include/zx_logger.hrl index 763af58..df4ea57 100644 --- a/zomp/lib/otpr/zx/0.1.0/include/zx_logger.hrl +++ b/zomp/lib/otpr/zx/0.1.0/include/zx_logger.hrl @@ -31,4 +31,6 @@ log(Level, Format, Args) -> warning -> "[WARNING]"; error -> "[ERROR]" end, - io:format("~s ~p: " ++ Format ++ "~n", [Tag, self() | Args]). + Out = io_lib:format("~s ~p: " ++ Format ++ "~n", [Tag, self() | Args]), + UTF8 = unicode:characters_to_binary(Out), + io:format(UTF8). diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx.erl b/zomp/lib/otpr/zx/0.1.0/src/zx.erl index 27d1975..b824ce2 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx.erl @@ -30,7 +30,8 @@ key_id/0, key_name/0, key_data/0, user_id/0, user_name/0, contact_info/0, user_data/0, lower0_9/0, label/0, - package_meta/0]). + package_meta/0, + outcome/0]). -include("zx_logger.hrl"). @@ -65,6 +66,11 @@ deps := [package_id()], type := app | lib}. +-type outcome() :: ok + | {error, Reason :: atom()} + | {error, Code :: non_neg_integer()} + | {error, Info :: string(), Code :: non_neg_integer()}. + %%% Command Dispatch @@ -89,114 +95,103 @@ do(["runlocal" | ArgV]) -> run_local(ArgV); do(["init", "app", PackageString]) -> ok = compatibility_check([unix]), - ok = zx_local:initialize(app, PackageString), - halt(0); + done(zx_local:initialize(app, PackageString)); do(["init", "lib", PackageString]) -> ok = compatibility_check([unix]), - ok = zx_local:initialize(lib, PackageString), - halt(0); + done(zx_local:initialize(lib, PackageString)); do(["install", PackageFile]) -> - ok = zx_local:assimilate(PackageFile), - halt(0); + done(zx_local:assimilate(PackageFile)); do(["set", "dep", PackageString]) -> - ok = zx_local:set_dep(PackageString), - halt(0); + done(zx_local:set_dep(PackageString)); do(["set", "version", VersionString]) -> ok = compatibility_check([unix]), - ok = zx_local:set_version(VersionString), - halt(0); + done(zx_local:set_version(VersionString)); do(["verup", Level]) -> ok = compatibility_check([unix]), - ok = zx_local:verup(Level), - halt(0); + done(zx_local:verup(Level)); do(["list", "realms"]) -> - ok = zx_local:list_realms(), - halt(0); + done(zx_local:list_realms()); do(["list", "packages", Realm]) -> ok = start(), - ok = zx_local:list_packages(Realm), - halt(0); + done(zx_local:list_packages(Realm)); do(["list", "versions", PackageName]) -> ok = start(), - ok = zx_local:list_versions(PackageName), - halt(0); + done(zx_local:list_versions(PackageName)); do(["add", "realm", RealmFile]) -> - ok = zx_local:add_realm(RealmFile), - halt(0); + done(zx_local:add_realm(RealmFile)); do(["drop", "dep", PackageString]) -> PackageID = zx_lib:package_id(PackageString), - ok = zx_local:drop_dep(PackageID), - halt(0); + done(zx_local:drop_dep(PackageID)); do(["package"]) -> {ok, TargetDir} = file:get_cwd(), zx_local:package(TargetDir); do(["package", TargetDir]) -> case filelib:is_dir(TargetDir) of - true -> - ok = zx_local:package(TargetDir), - halt(0); - false -> - ok = log(error, "Target directory ~tp does not exist!", [TargetDir]), - halt(22) + true -> done(zx_local:package(TargetDir)); + false -> done({error, "Target directory does not exist", 22}) end; do(["dialyze"]) -> - ok = zx_local:dialyze(), - halt(0); + done(zx_local:dialyze()); do(["create", "user", Realm, Name]) -> - ok = zx_local:create_user(Realm, Name), - halt(0); + done(zx_local:create_user(Realm, Name)); do(["create", "keypair"]) -> - ok = zx_local:grow_a_pair(), - halt(0); + done(zx_local:grow_a_pair()); do(["drop", "key", Realm, KeyName]) -> - ok = zx_local:drop_key({Realm, KeyName}), - halt(0); + done(zx_local:drop_key({Realm, KeyName})); do(["create", "plt"]) -> - ok = zx_local:create_plt(), - halt(0); + done(zx_local:create_plt()); do(["create", "realm"]) -> - ok = zx_local:create_realm(), - halt(0); + done(zx_local:create_realm()); do(["create", "realmfile", Realm]) -> - ok = zx_local:create_realmfile(Realm, "."), - halt(0); + done(zx_local:create_realmfile(Realm, ".")); do(["takeover", Realm]) -> - ok = zx_local:takeover(Realm), - halt(0); + done(zx_local:takeover(Realm)); do(["abdicate", Realm]) -> - ok = zx_local:abdicate(Realm), - halt(0); + done(zx_local:abdicate(Realm)); do(["drop", "realm", Realm]) -> - ok = zx_local:drop_realm(Realm), - halt(0); + done(zx_local:drop_realm(Realm)); do(["list", "pending", PackageName]) -> - zx_auth:list_pending(PackageName); + done(zx_auth:list_pending(PackageName)); do(["list", "resigns", Realm]) -> - zx_auth:list_resigns(Realm); + done(zx_auth:list_resigns(Realm)); do(["submit", PackageFile]) -> - zx_auth:submit(PackageFile); + done(zx_auth:submit(PackageFile)); do(["review", PackageString]) -> - zx_auth:review(PackageString); + done(zx_auth:review(PackageString)); do(["approve", PackageString]) -> PackageID = zx_lib:package_id(PackageString), - zx_auth:approve(PackageID); + done(zx_auth:approve(PackageID)); do(["reject", PackageString]) -> PackageID = zx_lib:package_id(PackageString), - zx_auth:reject(PackageID); + done(zx_auth:reject(PackageID)); do(["accept", PackageString]) -> - zx_auth:accept(PackageString); + done(zx_auth:accept(PackageString)); do(["add", "packager", Package, UserName]) -> - zx_auth:add_packager(Package, UserName); + done(zx_auth:add_packager(Package, UserName)); do(["add", "maintainer", Package, UserName]) -> - zx_auth:add_maintainer(Package, UserName); + done(zx_auth:add_maintainer(Package, UserName)); do(["add", "sysop", Package, UserName]) -> - zx_auth:add_sysop(Package, UserName); + done(zx_auth:add_sysop(Package, UserName)); do(["add", "package", PackageName]) -> - zx_auth:add_package(PackageName); + done(zx_auth:add_package(PackageName)); do(_) -> usage_exit(22). +-spec done(outcome()) -> no_return(). + +done(ok) -> + halt(0); +done({error, Reason}) when is_atom(Reason) -> + ok = log(error, "Operation failed with: ~tp", [Reason]), + halt(1); +done({error, Code}) when is_integer(Code) -> + halt(Code); +done({error, Info, Code}) -> + ok = log(error, Info), + halt(Code). + + -spec compatibility_check(Platforms) -> ok | no_return() when Platforms :: unix | win32. %% @private @@ -335,7 +330,7 @@ run(Identifier, RunArgs) -> end, {ok, PackageID} = ensure_installed(FuzzyID), ok = build(PackageID), - Dir = zx_lib:package_dir(PackageID), + Dir = zx_lib:path(lib, PackageID), {ok, Meta} = zx_lib:read_project_meta(Dir), prepare(PackageID, Meta, Dir, RunArgs). @@ -511,7 +506,7 @@ fetch_one(PackageID) -> %% input was found, or no match was found at all. resolve_installed_version({Realm, Name, Version}) -> - PackageDir = filename:join(["lib", Realm, Name]), + PackageDir = zx_lib:path(lib, Realm, Name), case filelib:is_dir(PackageDir) of true -> resolve_installed_version(PackageDir, Version); false -> not_found @@ -545,10 +540,10 @@ tuplize(String, Acc) -> %% - The package is not already installed %% - If this function crashes it will completely halt the system -install(PackageID) -> +install(PackageID = {Realm, Name, _}) -> {ok, PackageString} = zx_lib:package_string(PackageID), ok = log(info, "Installing ~ts", [PackageString]), - ZrpFile = filename:join("zsp", zx_lib:namify_zsp(PackageID)), + ZrpFile = filename:join(zx_lib:path(zsp, Realm, Name), zx_lib:namify_zsp(PackageID)), Files = zx_lib:extract_zsp_or_die(ZrpFile), TgzFile = zx_lib:namify_tgz(PackageID), {TgzFile, TgzData} = lists:keyfind(TgzFile, 1, Files), @@ -557,7 +552,7 @@ install(PackageID) -> {KeyID, Signature} = maps:get(sig, Meta), {ok, PubKey} = zx_key:load(public, KeyID), ok = ensure_package_dirs(PackageID), - PackageDir = filename:join("lib", PackageString), + PackageDir = zx_lib:path(lib, PackageID), ok = zx_lib:force_dir(PackageDir), ok = zx_key:verify(TgzData, Signature, PubKey), ok = erl_tar:extract({binary, TgzData}, [compressed, {cwd, PackageDir}]), @@ -570,34 +565,24 @@ install(PackageID) -> build(PackageID) -> {ok, CWD} = file:get_cwd(), - ok = file:set_cwd(zx_lib:package_dir(PackageID)), + ok = file:set_cwd(zx_lib:path(lib, PackageID)), ok = zx_lib:build(), file:set_cwd(CWD). - -%%% Directory & File Management - - -spec ensure_package_dirs(package_id()) -> ok. %% @private %% Procedure to guarantee that directory locations necessary for the indicated app to %% run have been created or halt execution. -ensure_package_dirs(PackageID = {Realm, Name, _}) -> - Package = {Realm, Name}, - PackageHome = zx_lib:package_dir(PackageID), - PackageData = zx_lib:package_dir("var", Package), - PackageConf = zx_lib:package_dir("etc", Package), - Dirs = [PackageHome, PackageData, PackageConf], - ok = lists:foreach(fun zx_lib:force_dir/1, Dirs), - log(info, "Created dirs:~n\t~ts~n\t~ts~n\t~ts", Dirs). +ensure_package_dirs(PackageID) -> + Dirs = [zx_lib:path(D, PackageID) || D <- [etc, var, tmp, log, lib]], + lists:foreach(fun zx_lib:force_dir/1, Dirs). %%% Usage - -spec usage_exit(Code) -> no_return() when Code :: integer(). %% @private diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_conn.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_conn.erl index 30f5ef6..544ce60 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_conn.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_conn.erl @@ -396,7 +396,7 @@ request_zsp(Socket, PackageID) -> receive_zsp(Socket, PackageID) -> receive {tcp, Socket, Bin} -> - ZrpPath = filename:join("zsp", zx_lib:namify_zsp(PackageID)), + ZrpPath = zx_lib:zsp_path(PackageID), ok = file:write_file(ZrpPath, Bin), ok = zx_net:send(Socket, ok), log(info, "Wrote ~ts", [ZrpPath]); @@ -520,7 +520,7 @@ terminate() -> %% sourced, but exit with an error if it cannot locate or acquire the package. % %ensure_dep(Socket, PackageID) -> -% ZrpFile = filename:join("zsp", namify_zsp(PackageID)), +% ZrpFile = zx_lib:zsp_path(PackageID), % ok = % case filelib:is_regular(ZrpFile) of % true -> ok; diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_daemon.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_daemon.erl index 6b836c8..8428ef0 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_daemon.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_daemon.erl @@ -172,7 +172,7 @@ {meta = none :: none | zx:package_meta(), home = none :: none | file:filename(), argv = none :: none | [string()], - sys_conf = zx_conf_sys:load() :: zx_conf_sys:data(), + sys_conf = zx_sys_conf:load() :: zx_sys_conf:data(), id = 0 :: id(), actions = [] :: [request()], requests = maps:new() :: requests(), @@ -1366,8 +1366,7 @@ cx_load() -> %% where any number of wild things might be going on in the user's filesystem). cx_populate() -> - Home = zx_lib:zomp_dir(), - Pattern = filename:join(Home, "*.realm"), + Pattern = filename:join([zx_lib:path(etc), "*", "realm.conf"]), case filelib:wildcard(Pattern) of [] -> {error, no_realms}; RealmFiles -> {ok, cx_populate(RealmFiles, [])} @@ -1481,7 +1480,7 @@ cx_write_cache({Realm, -spec cx_cache_file(zx:realm()) -> file:filename(). cx_cache_file(Realm) -> - filename:join(zx_lib:zomp_dir(), Realm ++ ".cache"). + filename:join(zx_lib:path(var, Realm), "realm.cache"). -spec cx_realms(conn_index()) -> [zx:realms()]. diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_key.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_key.erl index 6f9b6cb..ca59de2 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_key.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_key.erl @@ -12,7 +12,7 @@ -copyright("Craig Everett "). -license("GPL-3.0"). --export([ensure_keypair/1, have_public_key/1, have_private_key/1, +-export([ensure_keypair/1, have_key/2, keypath/2, prompt_keygen/0, generate_rsa/1, load/2, verify/3]). @@ -26,42 +26,45 @@ %% Check if both the public and private key based on KeyID exists. ensure_keypair(KeyID = {Realm, KeyName}) -> - case {have_public_key(KeyID), have_private_key(KeyID)} of + case {have_key(public, KeyID), have_key(private, KeyID)} of {true, true} -> true; {false, true} -> - Message = "Public key for ~tp/~tp cannot be found", + Message = "Public key ~tp/~tp cannot be found", ok = log(error, Message, [Realm, KeyName]), halt(1); {true, false} -> - Message = "Private key for ~tp/~tp cannot be found", + Message = "Private key ~tp/~tp cannot be found", ok = log(error, Message, [Realm, KeyName]), halt(1); {false, false} -> - Message = "Key pair for ~tp/~tp cannot be found", + Message = "Key pair ~tp/~tp cannot be found", ok = log(error, Message, [Realm, KeyName]), halt(1) end. --spec have_public_key(zx:key_id()) -> boolean(). +-spec have_key(Type, KeyID) -> boolean() + when Type :: public | private, + KeyID :: zx:key_id(). %% @private -%% Determine whether the public key indicated by KeyID is in the keystore. +%% Determine whether the indicated key is present. -have_public_key({Realm, KeyName}) -> - PublicKeyFile = KeyName ++ ".pub.der", - PublicKeyPath = filename:join([zx_lib:zomp_dir(), "key", Realm, PublicKeyFile]), - filelib:is_regular(PublicKeyPath). +have_key(Type, KeyID) -> + filelib:is_regular(keypath(Type, KeyID)). --spec have_private_key(zx:key_id()) -> boolean(). +-spec keypath(Type, KeyID) -> Path + when Type :: public | private, + KeyID :: zx:key_id(), + Path :: file:filename(). %% @private -%% Determine whether the private key indicated by KeyID is in the keystore. +%% Given KeyID, return the path to the key type indicated. -have_private_key({Realm, KeyName}) -> - PrivateKeyFile = KeyName ++ ".key.der", - PrivateKeyPath = filename:join([zx_lib:zomp_dir(), "key", Realm, PrivateKeyFile]), - filelib:is_regular(PrivateKeyPath). +keypath(public, {Realm, KeyName}) -> + filename:join(zx_lib:path(key, Realm), KeyName ++ ".pub.der"); +keypath(private, {Realm, KeyName}) -> + filename:join(zx_lib:path(key, Realm), KeyName ++ ".key.der"). @@ -111,12 +114,10 @@ prompt_keygen() -> %% filenames derived from Prefix. %% NOTE: The current version of this command is likely to only work on a unix system. -generate_rsa({Realm, KeyName}) -> - KeyDir = filename:join([zx_lib:zomp_dir(), "key", Realm]), - ok = zx_lib:force_dir(KeyDir), - PemFile = filename:join(KeyDir, KeyName ++ ".pub.pem"), - KeyFile = filename:join(KeyDir, KeyName ++ ".key.der"), - PubFile = filename:join(KeyDir, KeyName ++ ".pub.der"), +generate_rsa(KeyID = {Realm, KeyName}) -> + PemFile = filename:join(zx_lib:path(key, Realm), KeyName ++ ".pub.pem"), + KeyFile = keypath(private, KeyID), + PubFile = keypath(public, KeyID), ok = lists:foreach(fun zx_lib:halt_if_exists/1, [PemFile, KeyFile, PubFile]), ok = log(info, "Generating ~p and ~p. Please be patient...", [KeyFile, PubFile]), ok = gen_p_key(KeyFile), @@ -223,22 +224,17 @@ openssl() -> when Type :: private | public, KeyID :: zx:key_id(), Result :: {ok, DecodedKey :: term()} - | {error, Reason :: term()}. + | {error, Reason :: file:posix()}. %% @private %% Hide the details behind reading and loading DER encoded RSA key files. -load(Type, {Realm, KeyName}) -> - {DerType, Path} = +load(Type, KeyID) -> + DerType = case Type of - private -> - KeyDer = KeyName ++ ".key.der", - P = filename:join([zx_lib:zomp_dir(), "key", Realm, KeyDer]), - {'RSAPrivateKey', P}; - public -> - PubDer = KeyName ++ ".pub.der", - P = filename:join([zx_lib:zomp_dir(), "key", Realm, PubDer]), - {'RSAPublicKey', P} + private -> 'RSAPrivateKey'; + public -> 'RSAPublicKey' end, + Path = keypath(Type, KeyID), ok = log(info, "Loading key from file ~ts", [Path]), case file:read_file(Path) of {ok, Bin} -> {ok, public_key:der_decode(DerType, Bin)}; diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl index 7d5051e..e0dc405 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_lib.erl @@ -18,20 +18,21 @@ path/1, path/2, path/3, path/4, ppath/2, force_dir/1, mktemp_dir/1, list_realms/0, - hosts_cache_file/1, get_prime/1, realm_meta/1, + get_prime/1, realm_meta/1, read_project_meta/0, read_project_meta/1, read_package_meta/1, write_project_meta/1, write_project_meta/2, - write_terms/2, + write_terms/2, exec_shell/1, valid_lower0_9/1, valid_label/1, valid_version/1, string_to_version/1, version_to_string/1, package_id/1, package_string/1, - package_dir/1, package_dir/2, namify_zsp/1, namify_tgz/1, + zsp_path/1, find_latest_compatible/2, installed/1, realm_conf/1, load_realm_conf/1, extract_zsp_or_die/1, halt_if_exists/1, build/0, - rm_rf/1, rm/1]). + rm_rf/1, rm/1, + b_to_t/1, b_to_ts/1]). -include("zx_logger.hrl"). @@ -184,14 +185,6 @@ mktemp_dir({Realm, Name}) -> end. --spec hosts_cache_file(zx:realm()) -> file:filename(). -%% @private -%% Given a Realm name, construct a realm's .hosts filename and return it. - -hosts_cache_file(Realm) -> - filename:join(zomp_dir(), Realm ++ ".hosts"). - - -spec list_realms() -> [zx:realm()]. %% @private %% Check the filesystem for etc/[Realm Name]/realm.conf files. @@ -247,7 +240,8 @@ read_project_meta() -> -spec read_project_meta(Dir) -> Result when Dir :: file:filename(), Result :: {ok, zx:package_meta()} - | {error, file:posix()}. + | {error, file:posix()} + | {error, file:posix(), non_neg_integer()}. %% @private %% Read the `zomp.meta' file from the indicated directory, if possible. @@ -256,9 +250,10 @@ read_project_meta(Dir) -> case file:consult(Path) of {ok, Meta} -> {ok, maps:from_list(Meta)}; + {error, enoent} -> + {error, "No project zomp.meta file. Wrong directory? Not initialized?", 2}; Error -> - ok = log(error, "Failed to open \"zomp.meta\" with ~tp", [Error]), - ok = log(error, "Wrong directory?"), + ok = log(error, "Read from zomp.meta failed with: ~tp", [Error]), Error end. @@ -268,10 +263,8 @@ read_project_meta(Dir) -> Result :: {ok, zx:package_meta()} | {error, file:posix()}. -read_package_meta({Realm, Name, Version}) -> - {ok, VersionString} = version_to_string(Version), - Path = filename:join([zomp_dir(), "lib", Realm, Name, VersionString]), - read_project_meta(Path). +read_package_meta(PackageID) -> + read_project_meta(path(lib, PackageID)). -spec write_project_meta(Meta) -> Result @@ -319,6 +312,21 @@ write_terms(Filename, List) -> file:write_file(Filename, Text). +-spec exec_shell(CMD) -> ok + when CMD :: string(). +%% @private +%% Print the output of an os:cmd/1 event only if there is any. + +exec_shell(CMD) -> + case os:cmd(CMD) of + "" -> + ok; + Out -> + Trimmed = string:trim(Out, trailing, "\r\n"), + log(info, "os:cmd(~tp) -> ~ts", [CMD, Trimmed]) + end. + + -spec valid_lower0_9(string()) -> boolean(). %% @private %% Check whether a provided string is a valid lower0_9. @@ -570,31 +578,6 @@ package_string(_) -> {error, invalid_package_id}. --spec package_dir(zx:package_id()) -> file:filename(). -%% @private -%% Returns the path to a package installation. Crashes if PackageID is not a valid -%% identitifer or if the version is incomplete (it is not possible to create a path -%% to a partial version number). - -package_dir({Realm, Name, Version = {X, Y, Z}}) - when is_integer(X), is_integer(Y), is_integer(Z) -> - {ok, PackageDir} = package_string({Realm, Name}), - {ok, VersionDir} = version_to_string(Version), - filename:join([zomp_dir(), "lib", PackageDir, VersionDir]). - - --spec package_dir(Prefix, Package) -> PackageDataDir - when Prefix :: string(), - Package :: zx:package(), - PackageDataDir :: file:filename(). -%% @private -%% Create an absolute path to an application directory prefixed by the inclued argument. - -package_dir(Prefix, {Realm, Name}) -> - PackageString = package_string({Realm, Name, {z, z, z}}), - filename:join([zomp_dir(), Prefix, PackageString]). - - -spec namify_zsp(PackageID) -> ZrpFileName when PackageID :: zx:package_id(), ZrpFileName :: file:filename(). @@ -626,6 +609,12 @@ namify(PackageID, Suffix) -> PackageString ++ "." ++ Suffix. +-spec zsp_path(zx:package_id()) -> file:filename(). + +zsp_path(PackageID) -> + filename:join(path(zsp, element(1, PackageID)), namify_zsp(PackageID)). + + -spec find_latest_compatible(Version, Versions) -> Result when Version :: zx:version(), Versions :: [zx:version()], @@ -670,26 +659,24 @@ latest_compatible(Version, Versions) -> %% True to its name, tells whether a package's install directory is found. installed(PackageID) -> - filelib:is_dir(package_dir(PackageID)). + filelib:is_dir(path(lib, PackageID)). - - --spec realm_conf(Realm) -> RealmFileName +-spec realm_conf(Realm) -> Path when Realm :: string(), - RealmFileName :: file:filename(). + Path :: file:filename(). %% @private -%% Take a realm name, and return the name of the realm filename that would result. +%% Given a realm name return the path to its conf file. realm_conf(Realm) -> - Realm ++ ".realm". + filename:join(path(etc, Realm), "realm.conf"). -spec load_realm_conf(Realm) -> Result when Realm :: zx:realm(), Result :: {ok, RealmConf} | {error, Reason}, - RealmConf :: list(), + RealmConf :: map(), Reason :: badarg | terminated | system_limit @@ -699,13 +686,13 @@ realm_conf(Realm) -> %% Load the config for the given realm or halt with an error. load_realm_conf(Realm) -> - Path = filename:join(path(etc, Realm), "realm.conf"), + Path = realm_conf(Realm), case file:consult(Path) of {ok, C} -> - C; - {error, enoent} -> - ok = log(warning, "Realm ~tp is not configured.", [Realm]), - halt(1) + {ok, maps:from_list(C)}; + Error -> + ok = log(warning, "Loading realm conf ~ts failed with: ~tp", [Path, Error]), + Error end. @@ -792,6 +779,30 @@ rm(Path) -> end. +-spec b_to_t(binary()) -> {ok, term()} | error. +%% @private +%% A wrapper for the binary_to_term/1 BIF to hide the try..catch mess in the places we +%% don't want to crash on funky input. + +b_to_t(Binary) -> + try + binary_to_term(Binary) + catch + error:badarg -> error + end. + + +-spec b_to_ts(binary()) -> {ok, term()} | error. +%% A wrapper for the binary_to_term/2 BIF to hide the try..catch mess in the places we +%% don't want to crash on funky input. + +b_to_ts(Binary) -> + try + binary_to_term(Binary, [safe]) + catch + error:badarg -> error + end. + %%% Error exits diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl index caf448d..b1b17c5 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_local.erl @@ -25,7 +25,7 @@ %%% Functions --spec initialize(Type, PackageString) -> ok +-spec initialize(Type, PackageString) -> zx:outcome() when Type :: app | lib, PackageString :: string(). %% @private @@ -33,32 +33,35 @@ %% and interaction with the user to determine a few details. initialize(Type, RawPackageString) -> - ok = - case filelib:is_file("zomp.meta") of - false -> ok; - true -> error_exit("This project is already Zompified.", ?LINE) - end, - PackageID = {Realm, Name, _} = - case zx_lib:package_id(RawPackageString) of - {ok, {R, N, {z, z, z}}} -> - {R, N, {0, 1, 0}}; - {ok, {R, N, {X, z, z}}} -> - {R, N, {X, 0, 0}}; - {ok, {R, N, {X, Y, z}}} -> - {R, N, {X, Y, 0}}; - {ok, ID} -> - ID; - {error, invalid_package_string} -> - error_exit("Invalid package string: ~tp", [RawPackageString], ?LINE) - end, + case filelib:is_file("zomp.meta") of + false -> initialize2(Type, RawPackageString); + true -> {error, "This project is already Zompified.", 17} + end. + + +initialize2(Type, RawPackageString) -> + case zx_lib:package_id(RawPackageString) of + {ok, {R, N, {z, z, z}}} -> + initialize3(Type, {R, N, {0, 1, 0}}); + {ok, {R, N, {X, z, z}}} -> + initialize3(Type, {R, N, {X, 0, 0}}); + {ok, {R, N, {X, Y, z}}} -> + initialize3(Type, {R, N, {X, Y, 0}}); + {ok, ID} -> + initialize3(Type, ID); + {error, invalid_package_string} -> + {error, "Invalid package string.", 22} + end. + + +initialize3(Type, PackageID) -> case package_exists(PackageID) of false -> Prefix = solicit_prefix(), initialize(Type, PackageID, Prefix); true -> - PackageName = zx_lib:package_string({Realm, Name, {z, z, z}}), - Message = "Package ~tp already exists. Try another.", - error_exit(Message, [PackageName], ?LINE) + Message = "Package already exists. Try another.", + {error, Message, 17} end. @@ -161,6 +164,7 @@ solicit_prefix() -> end end. + -spec update_source_vsn(zx:version()) -> ok. %% @private %% Use grep to tell us which files have a `-vsn' attribute and which don't. @@ -177,8 +181,8 @@ update_source_vsn(Version) -> SubF = "sed -i 's/-vsn(.*$/-vsn(\"~s\")./' $(grep -l '^-vsn(' src/*)", Add = lists:flatten(io_lib:format(AddF, [VersionString])), Sub = lists:flatten(io_lib:format(SubF, [VersionString])), - ok = exec_shell(Add), - ok = exec_shell(Sub), + _ = os:cmd(Add), + _ = os:cmd(Sub), log(info, "Source version attributes set"). @@ -240,22 +244,7 @@ initialize_app_file({_, Name, Version}, AppStart) -> zx_lib:write_terms(AppFile, [AppProfile]). --spec exec_shell(CMD) -> ok - when CMD :: string(). -%% @private -%% Print the output of an os:cmd/1 event only if there is any. - -exec_shell(CMD) -> - case os:cmd(CMD) of - "" -> - ok; - Out -> - Trimmed = string:trim(Out, trailing, "\r\n"), - log(info, "os:cmd(~tp) ->~n~ts", [CMD, Trimmed]) - end. - - --spec assimilate(PackageFile) -> ok +-spec assimilate(PackageFile) -> zx:outcome() when PackageFile :: file:filename(). %% @private %% Receives a path to a file containing package data, examines it, and copies it to a @@ -272,21 +261,23 @@ assimilate(PackageFile) -> {TgzFile, TgzData} = lists:keyfind(TgzFile, 1, Files), {KeyID, Signature} = maps:get(sig, Meta), {ok, PubKey} = zx_key:load(public, KeyID), - ok = - case public_key:verify(TgzData, sha512, Signature, PubKey) of - true -> - ZrpPath = filename:join("zsp", zx_lib:namify_zsp(PackageID)), - file:copy(PackageFile, ZrpPath); - false -> - error_exit("Bad package signature: ~ts", [PackageFile], ?LINE) - end, + case public_key:verify(TgzData, sha512, Signature, PubKey) of + true -> + ok = file:copy(PackageFile, zx_lib:zsp_path(PackageID)), + assimilate2(CWD, PackageID); + false -> + {error, "Bad package signature.", 1} + end. + + +assimilate2(CWD, PackageID) -> ok = file:set_cwd(CWD), Message = "~ts is now locally available.", {ok, PackageString} = zx_lib:package_string(PackageID), log(info, Message, [PackageString]). --spec set_dep(Identifier :: string()) -> ok. +-spec set_dep(Identifier :: string()) -> zx:outcome(). %% @private %% Set a specific dependency in the current project. If the project currently has a %% dependency on the same package then the version of that dependency is updated to @@ -296,14 +287,12 @@ assimilate(PackageFile) -> set_dep(Identifier) -> {ok, {Realm, Name, FuzzyVersion}} = zx_lib:package_id(Identifier), - Version = - case FuzzyVersion of - {X, Y, Z} when is_integer(X), is_integer(Y), is_integer(Z) -> - {X, Y, Z}; - _ -> - error_exit("Incomplete version tuple: ~tp", [FuzzyVersion]) - end, - set_dep({Realm, Name}, Version). + case FuzzyVersion of + {X, Y, Z} when is_integer(X), is_integer(Y), is_integer(Z) -> + set_dep({Realm, Name}, {X, Y, Z}); + _ -> + {error, "Incompelte version tuple.", 22} + end. -spec set_dep(zx:package(), zx:version()) -> ok. @@ -313,12 +302,8 @@ set_dep({Realm, Name}, Version) -> {ok, Meta} = zx_lib:read_project_meta(), Deps = maps:get(deps, Meta), case lists:member(PackageID, Deps) of - true -> - {ok, PackageString} = zx_lib:package_string(PackageID), - ok = log(info, "~ts is already a dependency", [PackageString]), - halt(0); - false -> - set_dep(PackageID, Deps, Meta) + true -> ok; + false -> set_dep(PackageID, Deps, Meta) end. @@ -351,27 +336,25 @@ set_dep(PackageID = {Realm, Name, NewVersion}, Deps, Meta) -> zx_lib:write_project_meta(NewMeta). --spec set_version(VersionString) -> ok +-spec set_version(VersionString) -> zx:outcome() when VersionString :: string(). %% @private %% Convert a version string to a new version, sanitizing it in the process and returning %% a reasonable error message on bad input. set_version(VersionString) -> - NewVersion = - case zx_lib:string_to_version(VersionString) of - {ok, {_, _, z}} -> - Message = "'set version' arguments must be complete, ex: 1.2.3", - error_exit(Message, ?LINE); - {ok, Version} -> - Version; - {error, invalid_version_string} -> - Message = "Invalid version string: ~tp", - error_exit(Message, [VersionString], ?LINE) - end, - {ok, Meta} = zx_lib:read_project_meta(), - {Realm, Name, OldVersion} = maps:get(package_id, Meta), - update_version(Realm, Name, OldVersion, NewVersion, Meta). + case zx_lib:string_to_version(VersionString) of + {error, invalid_version_string} -> + Message = "Invalid version string: ~tp", + {error, Message, 22}; + {ok, {_, _, z}} -> + Message = "'set version' arguments must be complete, ex: 1.2.3", + {error, Message, 22}; + {ok, NewVersion} -> + {ok, Meta} = zx_lib:read_project_meta(), + {Realm, Name, OldVersion} = maps:get(package_id, Meta), + update_version(Realm, Name, OldVersion, NewVersion, Meta) + end. -spec update_version(Realm, Name, OldVersion, NewVersion, OldMeta) -> ok @@ -390,25 +373,31 @@ set_version(VersionString) -> update_version(Realm, Name, OldVersion, NewVersion, OldMeta) -> PackageID = {Realm, Name, NewVersion}, NewMeta = maps:put(package_id, PackageID, OldMeta), - ok = zx_lib:write_project_meta(NewMeta), - ok = update_source_vsn(NewVersion), - ok = update_app_vsn(Name, NewVersion), - {ok, OldVS} = zx_lib:version_to_string(OldVersion), - {ok, NewVS} = zx_lib:version_to_string(NewVersion), - log(info, "Version changed from ~s to ~s.", [OldVS, NewVS]). + case zx_lib:write_project_meta(NewMeta) of + ok -> + ok = update_source_vsn(NewVersion), + ok = update_app_vsn(Name, NewVersion), + {ok, OldVS} = zx_lib:version_to_string(OldVersion), + {ok, NewVS} = zx_lib:version_to_string(NewVersion), + log(info, "Version changed from ~s to ~s.", [OldVS, NewVS]); + Error -> + ok = log(error, "Write to zomp.meta failed with: ~tp", [Error]), + Error + end. -spec list_realms() -> ok. %% @private -%% List all currently configured realms. The definition of a "configured realm" is a -%% realm for which a .realm file exists in $ZOMP_HOME. The realms will be printed to -%% stdout and the program will exit. +%% List all currently configured realms. list_realms() -> - lists:foreach(fun(R) -> io:format("~ts~n", [R]) end, zx_lib:list_realms()). + case zx_lib:list_realms() of + [] -> io:format("Oh noes! No realms are configured!~n"); + Realms -> lists:foreach(fun(R) -> io:format("~ts~n", [R]) end, Realms) + end. --spec list_packages(zx:realm()) -> ok. +-spec list_packages(zx:realm()) -> zx:outcome(). %% @private %% Contact the indicated realm and query it for a list of registered packages and print %% them to stdout. @@ -416,62 +405,59 @@ list_realms() -> list_packages(Realm) -> case zx_daemon:list_packages(Realm) of {ok, []} -> - log(info, "Realm ~tp has no packages available.", [Realm]); + io:format("Realm ~tp has no packages available.~n", [Realm]); {ok, Packages} -> Print = fun({R, N}) -> io:format("~ts-~ts~n", [R, N]) end, lists:foreach(Print, Packages); {error, bad_realm} -> - error_exit("Bad realm name.", ?LINE); - {error, no_realm} -> - error_exit("Realm \"~ts\" is not configured.", ?LINE); + {error, "Unconfigured realm or bad realm name.", 22}; {error, network} -> Message = "Network issues are preventing connection to the realm.", - error_exit(Message, ?LINE) + {error, Message, 101} end. --spec list_versions(PackageName :: string()) -> ok. +-spec list_versions(PackageName :: string()) -> zx:outcome(). %% @private %% List the available versions of the package indicated. The user enters a string-form %% package name (such as "otpr-zomp") and the return values will be full package strings %% of the form "otpr-zomp-1.2.3", one per line printed to stdout. -list_versions(PackageName) -> - Package = {Realm, Name} = - case zx_lib:package_id(PackageName) of - {ok, {R, N, {z, z, z}}} -> - {R, N}; - {error, invalid_package_string} -> - error_exit("~tp is not a valid package name.", [PackageName], ?LINE) - end, - case zx_daemon:list_versions(Package) of - {ok, []} -> - Message = "Package ~ts has no versions available.", - log(info, Message, [PackageName]); - {ok, Versions} -> - Print = - fun(Version) -> - {ok, PackageString} = zx_lib:package_string({Realm, Name, Version}), - io:format("~ts~n", [PackageString]) - end, - lists:foreach(Print, Versions); - {error, bad_realm} -> - error_exit("Bad realm name.", ?LINE); - {error, bad_package} -> - error_exit("Bad package name.", ?LINE); - {error, network} -> - Message = "Network issues are preventing connection to the realm.", - error_exit(Message, ?LINE) +list_versions(PackageString) -> + case zx_lib:package_id(PackageString) of + {ok, PackageID} -> + list_versions2(PackageID); + {error, invalid_package_string} -> + {error, "Invalid package name.", 22} end. --spec add_realm(Path) -> ok +list_versions2(PackageID) -> + case zx_daemon:list_versions(PackageID) of + {ok, []} -> + io:format("No versions available.~n"); + {ok, Versions} -> + Print = + fun(Version) -> + {ok, VersionString} = zx_lib:version_to_string(Version), + io:format("~ts~n", [VersionString]) + end, + lists:foreach(Print, Versions); + {error, bad_realm} -> + {error, "Bad realm name.", 22}; + {error, bad_package} -> + {error, "Bad package name.", 22}; + {error, network} -> + Message = "Network issues are preventing connection to the realm.", + {error, Message, 101} + end. + + +-spec add_realm(Path) -> zx:outcome() when Path :: file:filename(). %% @private -%% Add a .realm file to $ZOMP_HOME from a location in the filesystem. -%% Print the SHA512 of the .realm file for the user so they can verify that the file -%% is authentic. This implies, of course, that .realm maintainers are going to -%% post SHA512 sums somewhere visible. +%% Configure the system for a new realm by interpreting a .zrf file. +%% Also log the SHA512 of the .zrf for the user. add_realm(Path) -> case file:read_file(Path) of @@ -479,13 +465,30 @@ add_realm(Path) -> Digest = crypto:hash(sha512, Data), Text = integer_to_list(binary:decode_unsigned(Digest, big), 16), ok = log(info, "SHA512 of ~ts: ~ts", [Path, Text]), - add_realm(Path, Data); + add_realm2(Data); {error, enoent} -> - ok = log(warning, "FAILED: ~ts does not exist.", [Path]), - halt(1); + {error, "Realm bundle (.zrf) does not exist.", 2}; {error, eisdir} -> - ok = log(warning, "FAILED: ~ts is a directory, not a realm file.", [Path]), - halt(1) + {error, "Path is a directory, not a .zrf file.", 21} + end. + + +-spec add_realm2(Data) -> zx:outcome() + when Data :: binary(). + +add_realm2(Data) -> + case zx_lib:b_to_t(Data) of + {ok, {RealmConf, KeyDER}} -> + Realm = maps:get(realm, RealmConf), + ok = make_realm_dirs(Realm), + ConfPath = zx_lib:realm_conf(Realm), + zx_lib:write_terms(ConfPath, maps:to_list(RealmConf)), + KeyName = maps:get(key, RealmConf), + KeyPath = zx_lib:keypath(public, {Realm, KeyName}), + ok = file:write_file(KeyPath, KeyDER), + log(info, "Added realm ~tp.", [Realm]); + error -> + {error, "Invalid .zrf file.", 84} end. @@ -516,7 +519,7 @@ drop_dep(PackageID) -> end. --spec verup(Level) -> ok +-spec verup(Level) -> zx:outcome() when Level :: string(). %% @private %% Convert input string arguments to acceptable atoms for use in update_version/1. @@ -527,7 +530,7 @@ verup("patch") -> version_up(patch); verup(_) -> zx:usage_exit(22). --spec version_up(Level) -> ok +-spec version_up(Level) -> zx:outcome() when Level :: major | minor | patch. @@ -538,13 +541,13 @@ verup(_) -> zx:usage_exit(22). %% read for some reason. version_up(Arg) -> - Meta = - case zx_lib:read_project_meta() of - {ok, M} -> M; - Error -> error_exit("verup failed with: ~tp", [Error], ?LINE) - end, - PackageID = maps:get(package_id, Meta), - version_up(Arg, PackageID, Meta). + case zx_lib:read_project_meta() of + {ok, Meta} -> + PackageID = maps:get(package_id, Meta), + version_up(Arg, PackageID, Meta); + Error -> + Error + end. -spec version_up(Level, PackageID, Meta) -> ok @@ -582,7 +585,7 @@ package(TargetDir) -> ok = log(info, "Packaging ~ts", [TargetDir]), {ok, Meta} = zx_lib:read_project_meta(TargetDir), {Realm, _, _} = maps:get(package_id, Meta), - KeyDir = filename:join([zx_lib:zomp_dir(), "key", Realm]), + KeyDir = zx_lib:path(key, Realm), ok = zx_lib:force_dir(KeyDir), Pattern = KeyDir ++ "/*.key.der", case [filename:basename(F, ".key.der") || F <- filelib:wildcard(Pattern)] of @@ -712,12 +715,11 @@ dialyze() -> true -> log(info, "Using PLT: ~tp", [PLT]); false -> build_plt() end, - TmpDir = filename:join(zx_lib:zomp_dir(), "tmp"), Me = escript:script_name(), - EvilTwin = filename:join(TmpDir, filename:basename(Me ++ ".erl")), + EvilTwin = filename:join(zx_lib:path(tmp), filename:basename(Me ++ ".erl")), ok = log(info, "Temporarily reconstructing ~tp as ~tp", [Me, EvilTwin]), Sed = io_lib:format("sed 's/^#!.*$//' ~s > ~s", [Me, EvilTwin]), - ok = exec_shell(Sed), + ok = zx_lib:exec_shell(Sed), ok = case dialyzer:run([{init_plt, PLT}, {from, src_code}, {files, [EvilTwin]}]) of [] -> io:format("Dialyzer found no errors and returned no warnings! Yay!~n"); @@ -729,17 +731,14 @@ dialyze() -> file:delete(EvilTwin). --spec grow_a_pair() -> ok. +-spec grow_a_pair() -> zx:outcome(). %% @private %% Execute the key generation procedure for 16k RSA keys once and then terminate. grow_a_pair() -> ok = file:set_cwd(zx_lib:zomp_dir()), KeyID = zx_key:prompt_keygen(), - case zx_key:generate_rsa(KeyID) of - ok -> ok; - Error -> error_exit("grow_a_pair/0 error: ~tp", [Error], ?LINE) - end. + zx_key:generate_rsa(KeyID). -spec drop_key(zx:key_id()) -> ok. @@ -749,9 +748,7 @@ grow_a_pair() -> %% error exit value (this instruction is idempotent if used in shell scripts). drop_key({Realm, KeyName}) -> - ok = file:set_cwd(zx_lib:zomp_dir()), - KeyGlob = KeyName ++ ".{key,pub},der", - Pattern = filename:join([zx_lib:zomp_dir(), "key", Realm, KeyGlob]), + Pattern = filename:join(zx_lib:path(key, Realm), KeyName ++ ".{key,pub}.der"), case filelib:wildcard(Pattern) of [] -> log(warning, "Key ~ts/~ts not found", [Realm, KeyName]); @@ -981,7 +978,6 @@ create_realm(Realm, Address, Port, UserName, Email, RealName) -> {realmname, RealName}, {contact_info, {"email", Email}}, {keys, [KeyName]}], - ok = make_realm_dirs(Realm), RealmConfPath = filename:join(zx_lib:path(etc, Realm), "realm.conf"), ok = zx_lib:write_terms(RealmConfPath, RealmConf), UserConfPath = filename:join(zx_lib:path(etc, Realm), UserName ++ ".user"), @@ -1015,9 +1011,9 @@ create_realm(Realm, Address, Port, UserName, Email, RealName) -> %% Checks for remnants of a realm. realm_exists(Realm) -> - Dirs = [etc, var, tmp, log, key, zsp, lib], - Check = fun(D) -> filelib:is_file(zx_lib:path(D)) end, - Managed = lists:member(Realm, proplists:get_value(managed, zx_lib:read_sys_conf())), + Managed = lists:member(Realm, zx_sys_conf:managed(zx_sys_conf:load())), + Dirs = [zx_lib:path(D, Realm) || D <- [etc, var, tmp, log, key, zsp, lib]], + Check = fun(D) -> filelib:is_file(D) end, Found = lists:any(Check, Dirs), Managed or Found. @@ -1028,8 +1024,8 @@ realm_exists(Realm) -> %% or be certain some other way that the file:make_sure/1 calls will succeed. make_realm_dirs(Realm) -> - Dirs = [etc, var, tmp, log, key, zsp, lib], - Make = fun(D) -> ok = file:make_dir(zx_lib:path(D, Realm)) end, + Dirs = [zx_lib:path(D, Realm) || D <- [etc, var, tmp, log, key, zsp, lib]], + Make = fun(D) -> ok = file:make_dir(D) end, lists:foreach(Make, Dirs). @@ -1061,22 +1057,6 @@ create_realmfile(Realm, Dir) -> log(info, "Realm conf file written to ~ts", [ZRF]). --spec add_realm(Path, Data) -> ok - when Path :: file:filename(), - Data :: binary(). - -add_realm(Path, Data) -> - case erl_tar:extract({binary, Data}, [compressed, {cwd, zx_lib:zomp_dir()}]) of - ok -> - {Realm, _} = string:take(filename:basename(Path), ".", true), - log(info, "Realm ~ts is now visible to this system.", [Realm]); - {error, invalid_tar_checksum} -> - error_exit("~ts is not a valid realm file.", [Path], ?LINE); - {error, eof} -> - error_exit("~ts is not a valid realm file.", [Path], ?LINE) - end. - - -spec drop_realm(zx:realm()) -> ok. drop_realm(Realm) -> @@ -1108,9 +1088,9 @@ drop_realm(Realm) -> %% the realm exists, of course. takeover(Realm) -> - SysConf = zx_conf_sys:load(), - case zx_conf_sys:add_managed(Realm, SysConf) of - {ok, NewConf} -> zx_conf_sys:save(NewConf); + SysConf = zx_sys_conf:load(), + case zx_sys_conf:add_managed(Realm, SysConf) of + {ok, NewConf} -> zx_sys_conf:save(NewConf); {error, unconfigured} -> log(error, "Cannot take over an unconfigured realm.") end. @@ -1118,34 +1098,8 @@ takeover(Realm) -> -spec abdicate(zx:realm()) -> ok. abdicate(Realm) -> - SysConf = zx_conf_sys:load(), - case zx_conf_sys:rem_managed(Realm, SysConf) of - {ok, NewConf} -> zx_conf_sys:save(NewConf); + SysConf = zx_sys_conf:load(), + case zx_sys_conf:rem_managed(Realm, SysConf) of + {ok, NewConf} -> zx_sys_conf:save(NewConf); {error, unmanaged} -> log(error, "Cannot abdicate an unmanaged realm.") end. - - - -%%% Error exits - --spec error_exit(Error, Line) -> no_return() - when Error :: term(), - Line :: non_neg_integer(). -%% @private -%% Format an error message in a way that makes it easy to locate. - -error_exit(Error, Line) -> - error_exit(Error, [], Line). - - --spec error_exit(Format, Args, Line) -> no_return() - when Format :: string(), - Args :: [term()], - Line :: non_neg_integer(). -%% @private -%% Format an error message in a way that makes it easy to locate. - -error_exit(Format, Args, Line) -> - File = filename:basename(?FILE), - ok = log(error, "~ts:~tp: " ++ Format, [File, Line | Args]), - halt(1). diff --git a/zomp/lib/otpr/zx/0.1.0/src/zx_conf_sys.erl b/zomp/lib/otpr/zx/0.1.0/src/zx_sys_conf.erl similarity index 99% rename from zomp/lib/otpr/zx/0.1.0/src/zx_conf_sys.erl rename to zomp/lib/otpr/zx/0.1.0/src/zx_sys_conf.erl index 9777608..f9b2baf 100644 --- a/zomp/lib/otpr/zx/0.1.0/src/zx_conf_sys.erl +++ b/zomp/lib/otpr/zx/0.1.0/src/zx_sys_conf.erl @@ -1,5 +1,5 @@ %%% @doc -%%% zx_conf_sys: An interface to etc/sys.conf +%%% zx_sys_conf: An interface to etc/sys.conf %%% %%% It may seem overkill to write an interface module for a config file that only tracks %%% five things, but scattering this all around the project is just a bit too l33t for @@ -13,7 +13,7 @@ %%% Bad configuration data causes a reset to defaults so that the system can function. %%% @end --module(zx_conf_sys). +-module(zx_sys_conf). -author("Craig Everett "). -copyright("Craig Everett "). -license("GPL-3.0").