1%%%----------------------------------------------------------------------
2%%% File    : yaws_sup.erl
3%%% Author  : Claes Wikstrom <klacke@bluetail.com>
4%%% Purpose :
5%%% Created : 16 Jan 2002 by Claes Wikstrom <klacke@bluetail.com>
6%%%----------------------------------------------------------------------
7
8-module(yaws_sup).
9-author('klacke@bluetail.com').
10-include("../include/yaws.hrl").
11
12-behaviour(supervisor).
13
14%% External exports
15-export([start_link/0]).
16
17%% supervisor callbacks
18-export([init/1]).
19-export([get_app_args/0, child_specs/0]).
20
21-import(lists, [member/2]).
22
23%%%----------------------------------------------------------------------
24%%% API
25%%%----------------------------------------------------------------------
26start_link() ->
27    supervisor:start_link({local, ?MODULE}, ?MODULE, []).
28
29%%%----------------------------------------------------------------------
30%%% Callback functions from supervisor
31%%%----------------------------------------------------------------------
32
33%%----------------------------------------------------------------------
34%%----------------------------------------------------------------------
35init([]) ->
36    ChildSpecs = child_specs(),
37
38    %% The idea behind this is if we're running in an embedded env,
39    %% typically the supervisor above us wants to control the restarts.
40    %%
41    %% If we're running standalone --heart can restart the entire node
42    %% If heart is not used, we die.
43    %% 0, 1 means that we never want supervisor restarts
44    {ok,{{one_for_all, 0, 1}, ChildSpecs}}.
45
46%%----------------------------------------------------------------------
47%%----------------------------------------------------------------------
48child_specs() ->
49    YawsLog = {yaws_log, {yaws_log, start_link, []},
50               permanent, 5000, worker, [yaws_log]},
51
52    YawsTrace = {yaws_trace, {yaws_trace, start_link, []},
53                 permanent, 5000, worker, [yaws_trace]},
54
55    YawsServArgs = [_Env = get_app_args()],
56    YawsServ = {yaws_server, {yaws_server, start_link, YawsServArgs},
57                permanent, 120000, worker, [yaws_server]},
58
59    %% and this guy will restart auxiliary procs that can fail
60    Sup = {yaws_sup_restarts,
61           {yaws_sup_restarts, start_link, []},
62           transient, infinity, supervisor, [yaws_sup_restarts]},
63
64    %% supervisor for websocket callback processes
65    WSSup = {yaws_ws_sup,
66             {yaws_ws_sup, start_link, []},
67             transient, infinity, supervisor, [yaws_ws_sup]},
68
69    [YawsLog, YawsTrace, YawsServ, Sup, WSSup].
70
71%%----------------------------------------------------------------------
72%%----------------------------------------------------------------------
73get_app_args() ->
74    AS=init:get_arguments(),
75    Debug = case application:get_env(yaws, debug) of
76                undefined ->
77                    member({yaws, ["debug"]}, AS);
78                {ok, Val}  ->
79                    Val
80            end,
81    Trace = case application:get_env(yaws, trace) of
82                undefined ->
83                    case {member({yaws, ["trace", "http"]}, AS),
84                          member({yaws, ["trace", "traffic"]}, AS)} of
85                        {true, _} ->
86                            {true, http};
87                        {_, true} ->
88                            {true, traffic};
89                        _ ->
90                            false
91                    end;
92                {ok, http} ->
93                    {true, http};
94                {ok, traffic} ->
95                    {true, traffic};
96                _ ->
97                    false
98            end,
99    TraceOutput = case application:get_env(yaws, traceoutput) of
100                      undefined ->
101                          member({yaws, ["traceoutput"]}, AS);
102                      {ok, Val3}  ->
103                          Val3
104                  end,
105    Conf = case application:get_env(yaws, conf) of
106               undefined ->
107                   find_c(AS);
108               {ok, File} ->
109                   {file, File}
110           end,
111    RunMod = case application:get_env(yaws, runmod) of
112                 undefined ->
113                     find_runmod(AS);
114                 {ok,Mod} ->
115                     {ok,Mod}
116             end,
117    Embedded = case application:get_env(yaws, embedded) of
118                   undefined ->
119                       false;
120                   {ok, Emb} ->
121                       Emb
122               end,
123    Id = case application:get_env(yaws, id) of
124             undefined ->
125                 "default";
126             {ok, Id0} when is_atom(Id0) ->
127                 atom_to_list(Id0);
128             {ok, Id0} ->
129                 Id0
130         end,
131    Enc = case application:get_env(yaws, encoding) of
132              undefined ->
133                  case {member({yaws, ["encoding", "latin1"]}, AS),
134                        member({yaws, ["encoding", "unicode"]}, AS)} of
135                      {true, _} -> latin1;
136                      {_, true} -> unicode;
137                      _         -> latin1
138                  end;
139              {ok, latin1} ->
140                  latin1;
141              {ok, unicode} ->
142                  unicode;
143              _ ->
144                  latin1
145          end,
146
147    #env{debug = Debug, trace = Trace,
148         traceoutput = TraceOutput, conf = Conf,
149         runmod = RunMod, embedded = Embedded, id = Id,
150         encoding = Enc}.
151
152%%----------------------------------------------------------------------
153%%----------------------------------------------------------------------
154find_c([{conf, [File]} |_]) ->
155    {file, File};
156find_c([_|T]) ->
157    find_c(T);
158find_c([]) ->
159    false.
160
161%%----------------------------------------------------------------------
162%%----------------------------------------------------------------------
163find_runmod([{runmod, [Mod]} |_]) ->
164    {ok,l2a(Mod)};
165find_runmod([_|T]) ->
166    find_runmod(T);
167find_runmod([]) ->
168    false.
169
170%%----------------------------------------------------------------------
171%%----------------------------------------------------------------------
172l2a(L) when is_list(L) -> list_to_atom(L);
173l2a(A) when is_atom(A) -> A.
174