From 92bafb48f42089e1ab3814209ac7e8bc7524b0cb Mon Sep 17 00:00:00 2001 From: Claes Wikstrom Date: Thu, 9 Mar 2006 21:58:10 +0000 Subject: [PATCH] removed the ability change userid, also stopped writing to /tmp/yaws and started to write to /home/klacke/.yaws instead. This is much better since we cannot now ever get into the situations where file ownership and umask stop us from controlling a daemon. Also cleaned up the start flags to the yaws script, all old flags are still there for backward scompatibilty. git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/yaws@951 9fbdc01b-0d2c-0410-bfb7-fb27d70d8b52 --- include/yaws.hrl | 13 +- man/yaws.1 | 92 ++++++++----- man/yaws.conf.5 | 13 +- scripts/yaws.template | 110 ++++++++-------- src/Makefile | 2 +- src/yaws.erl | 184 +++++++------------------- src/yaws_404.erl | 2 +- src/yaws_api.erl | 16 +-- src/yaws_cgi.erl | 6 +- src/yaws_compile.erl | 8 +- src/yaws_config.erl | 100 ++++++++++----- src/yaws_ctl.erl | 26 ++-- src/yaws_html.erl | 16 +-- src/yaws_log.erl | 24 ++-- src/yaws_ls.erl | 12 +- src/yaws_revproxy.erl | 6 +- src/yaws_server.erl | 88 +++---------- src/yaws_session_server.erl | 2 +- src/yaws_ssl.erl | 249 ------------------------------------ src/yaws_sup.erl | 9 +- 20 files changed, 329 insertions(+), 649 deletions(-) delete mode 100644 src/yaws_ssl.erl diff --git a/include/yaws.hrl b/include/yaws.hrl index 5d40b3301..f7279f83f 100644 --- a/include/yaws.hrl +++ b/include/yaws.hrl @@ -75,14 +75,15 @@ max_num_cached_bytes = 1000000, %% 1 MEG max_size_cached_file = 8000, large_file_chunk_size = 10240, - log_wrap_size = 1000000, % wrap logs after 1M + log_wrap_size = 10000000, % wrap logs after 10M cache_refresh_secs = 30, % seconds (auto zero when debug) include_dir = [], %% list of inc dirs for .yaws files phpexe = "php", %% cgi capable php executable yaws, %% server string - username, %% maybe run as a different user than root - uid, %% unix uid of user that started yaws - id = "default" %% string identifying this instance of yaws + %username, %% maybe run as a different user than root + %uid, %% unix uid of user that started yaws + id = "default", %% string identifying this instance of yaws + tmpdir }). @@ -256,5 +257,7 @@ traceoutput, conf, runmod, - embedded}). + embedded, + id + }). diff --git a/man/yaws.1 b/man/yaws.1 index e68a94045..8df4a7ca0 100644 --- a/man/yaws.1 +++ b/man/yaws.1 @@ -16,106 +16,131 @@ dynamic content. See the user docs for more information on that topic. .TP -\fB\-i\fR +\fB\-i | --interactive\fR Interactive mode. This will start yaws in interactive mode with an erlang prompt. All error_logger messages will be written to the tty as well in this mode. Use this when developing yaws code. .TP -\fB\-D\fR +\fB\-w | --winteractive\fR +Cygwin inteactive mode (werl) +\fB\--daemon\fR Daemon mode. This will start yaws as a daemon. .TP -\fB\-heart\fR +\fB\--heart\fR This will cause the yaws system to be automatically restarted -in case it should crash. This switch also require the \fI-D\fR +in case it should crash. This switch also require the \fI--daemon\fR switch to be present. .TP -\fB\-d\fR +\fB\--debug\fR Debug mode. This will produce some auxilliary error output for some error conditions. It will also start the otp sasl lib for additional error printouts. .TP -\fB\-c file\fR +\fB\--conf file\fR Use a different configuration file than the default. The default configuration file when running as root is /etc/yaws.conf. When running as a non priviliged user, yaws will search for its configuration file in the following order. First in $HOME/yaws.conf, then in ./yaws.conf and finally in /etc/yaws.conf .TP -\fB\-r module\fR +\fB\--runmod module\fR Tells yaws to call \fImodule:start/0\fR at startup. This makes it possible to startup user specific applications together with yaws. .TP -\fB\-pa path\fR +\fB\--pa path\fR Add path to the yaws system search path .TP -\fB\-t\fR +\fB\--tracetraf\fR Traffic trace mode. All traffic will be written to a trace file called trace.traffic in the log directory. .TP -\fB\-T\fR +\fB\--tracehttp\fR HTTP trace mode. All HTTP messages will be written to a trace file called trace.http in the log directory. .TP -\fB\-x\fR -When yaws is put into trace mode using either -T or -t, traces are written to files. If we provide the -x flag, the trace will also be written to stdout. +\fB\--traceout\fR +When yaws is put into trace mode using either --tracetraf or --tracehttp, traces are written to files. If we provide the --traceout flag, the trace will also be written to stdout. .TP -\fB\-M dir\fR +\fB\--trace\fR +Sames as --tracetraf --traceout. I.e. trace everything and write to stdout. + +.TP +\fB\--mnesiadir dir\fR Start Mnesia in directory .TP -\fB\-sname xxx\fR +\fB\--sname xxx\fR Start yaws as a distributed erlang node with name +using the unqualified hostname as nodename postfix + +.TP +\fB\--name xxx\fR +Start yaws as a distributed erlang node with name using the +fully qualified hostname as nodename postfix .TP -\fB\-proto_dist Mod\fR +\fB\--proto_dist Mod\fR Use module Mod for erlang distribution. This is typically only used when we want to run erlang distribution over SSL. .TP -\fB\-erlarg STRING\fR +\fB\--erlarg STRING\fR Pass STRING as an additional argument to the "erl" program. +.TP +\fB\--id ID\fR +This flag sets the id. If we're starting a daemon (or an interactive +system) it gives the Yaws server the identity ID. This means that the +server will write all internal files into the directory +$HOME/.yaws/ID. In particular it will write a file called +$HOME/.yaws/ID/ctl which contains the portnumber the daemon +is listening on for control request by the control command such +as "yaws --hup" etc. + +If we're invoking a control command which should perform some +control function on the daemon, we mau have to give the --id flag also +to the control command. If we don't do this the control command +may interact with the wrong daemon due to finding the wrong "ctl" file. + +The daemon may also optionally specify the "id" in the yaws.conf +configuration file. + .SH CONTROL OPTIONS .PP The following list of options are are used to control the daemon from the "outside" while it is running. .TP -\fB\-I id\fR -Only useful with the control commands, -h, -s and -S, -j and -load. It interacts -with the yaws server named "id" (as specified in the conf file for -that yaws server) - - -.TP -\fB\-h [-I id]\fR +\fB\--hup [--id ID]\fR HUP the daemon. This forces the daemon to reread the configuration file. It also makes the daemon empty all its internal content caches. Hence when updating the doc root, HUPing the daemon is the fastest way to see the content updates. .TP -\fB\-s [-I id]\fR +\fB\--stop [-I id]\fR Stop the daemon (called id) .TP -\fB\-ls \fR -Lists current ids and status of all yaws servers on localhost. +\fB\--ls \fR +Lists current ids and status of all yaws servers on localhost. In practice this +amounts to a listdir in $HOME/.yaws/yaws - and check wether the different +systems who has created files there are alive. .TP -\fB-S [-I id]\fR +\fB--status [-I id]\fR Query a running yaws daemon for its status, and print it. .TP -\fB-load Modules [-I id]\fR +\fB--load Modules [-I id]\fR Try to (re)load erlang modules into a running daemon. This is useful after modifying appmods or modules used by scripts. .TP -\fB-j [-I id] http | traffic | off\fR +\fB--ctltrace [--id ID] http | traffic | off\fR Control the trace capabilities of a running yaws daemon. If the http or traffic option is given, the daemon will write a log for debug purposes into the logdir. @@ -124,10 +149,11 @@ for debug purposes into the logdir. .SH MISC OPTIONS .TP -\fB-check YawsFile [IncDirs]\fR -Test compile a `.yaws' file. +\fB--check YawsFile [IncDirs ....]\fR +Test compile a `.yaws' file. Useful in Makefiles when we want to ensure +that all .yaws files are syntactically correct .TP -\fB\-v\fR +\fB\--version\fR output version information and exit .SH AUTHOR Written by Claes Wikstrom diff --git a/man/yaws.conf.5 b/man/yaws.conf.5 index 3201da29e..2b1f94b34 100644 --- a/man/yaws.conf.5 +++ b/man/yaws.conf.5 @@ -49,15 +49,14 @@ id of a yaws server to control it using the different ctl commands such as: .nf -# /usr/local/bin/yaws -I foobar -s +# /usr/local/bin/yaws --id foobar --stop .fi -To stop the Yaws server with id "foobar". Only the user that started -the server called foobar is allowd to stop and control it. This is achieved -through file permissions on the control file which will reside in -"/tmp/yaws/foobar/ctl" - -There can never be two yaws servers on the same machine with identical ids. +To stop the Yaws server with id "foobar". Each Yaws server will write +its internals data into a file called $HOME/.yaws/yaws/ID where ID the +identity of the server. In particular it will write a file called +$HOME/.yaws/yaws/ID/ctl which contain the portnumber where the server is +listening for control commands. .TP \fB include_dir = Directory\fR diff --git a/scripts/yaws.template b/scripts/yaws.template index 0c383ab4a..452f53870 100755 --- a/scripts/yaws.template +++ b/scripts/yaws.template @@ -22,40 +22,40 @@ help() echo "usage: " echo "" echo - echo " yaws -i -- interactive (no daemon) mode" - echo " yaws -w -- cygwin interactive (werl) " - echo " yaws -D -- daemon mode" + echo " yaws -i | --interactive -- interactive (no daemon) mode" + echo " yaws -w | --winteractive -- cygwin interactive (werl) " + echo " yaws --daemon -- daemon mode" echo "" echo "" echo " Auxilliary flags for the daemon: " - echo " -I Id -- Set system id" - echo " -d -- debug mode " - echo " -c File -- set config file" - echo " -r mod -- call mod:start/0 at startup" - echo " -t -- trace all traffic" - echo " -T -- trace http traffic" - echo " -x -- trace output to stdout" - echo " -v -- print version" - echo " -pa path -- add path" - echo " -M dir -- start Mnesia in dir" - echo " -proto_dist Mod -- use Mod for distrib" - echo " -sname xxx -- start with sname xxx" - echo " -name xxx -- start with name xxx" - echo " -r mod -- call mod:start/0 at startup" - echo " -heart -- auto restart yaws if it crashes" - echo " -erlarg X -- pass argument X to $erl" + echo " --id Id -- Set system id" + echo " --debug -- debug mode " + echo " --conf File -- set config file" + echo " --tracetraf -- trace traffic" + echo " --tracehttp -- trace http traffic" + echo " --traceout -- trace output to stdout" + echo " --version -- print version" + echo " --pa path -- add load path" + echo " --mnesiadir dir -- start Mnesia in dir" + echo " --proto_dist Mod -- use Mod for distrib" + echo " --sname xxx -- start with sname xxx" + echo " --name xxx -- start with name xxx" + echo " --runmod mod -- call mod:start/0 at startup" + echo " --heart -- auto restart yaws if it crashes" + echo " --erlarg X -- pass argument X to $erl" echo "" echo "ctl functions ... " - echo " yaws -h [-I id] -- hup the daemon " - echo " yaws -s [-I id] -- stop the daemon " - echo " yaws -S [-I id] -- query the daemon status " - echo " yaws -load Modules -- load modules " - echo " yaws -j traffic|http -- toggle trace of running daemon" - echo " yaws -check YawsFile [IncDirs] -- test compile File " + echo " yaws --hup [-id ID] -- hup the daemon, reload conf + echo " yaws --stops [--id ID] -- stop the daemon " + echo " yaws --status [--id ID] -- query the daemon status " + echo " yaws --load Modules -- load modules " + echo " yaws --ls -- list Yaws nodes and their status + echo " yaws --ctltrace traffic|http -- toggle trace of running daemon" + echo " yaws --check YawsFile [IncDirs] -- test compile File " exit 1 } @@ -80,72 +80,75 @@ do arg=$1 shift; case $arg in - -i) + -i|--interactive) interactive="true"; debug=" -yaws debug "; daemon="";; - -w) + -w|--winteractive) interactive="true"; debug=" -yaws debug "; daemon=""; erl=$werl;; - -D) + -D|--daemon) daemon=" -detached ";; - -d) + -d|--debug) debug=" -boot start_sasl -yaws debug ";; - -t) + -t|--tracetraf) trace=" -yaws trace traffic ";; - -T) + -T|--tracehttp) trace=" -yaws trace http ";; - -I) + -I|--id) id=$1 shift;; - -x) + -x|--traceout) traceoutput=" -yaws traceoutput ";; - -M) + --trace) + traceoutput=" -yaws traceoutput "; + trace=" -yaws trace traffic ";; + -M|--mnesiadir) mnesia=" -mnesia dir '"$1"' -run mnesia start" shift;; - -c) + -c|--conf) conf=" -conf $1 " shift;; - -pa) + -pa|--pa) xpath=" ${xpath} -pa $1 " shift;; - -r) + -r|--runmod) runmod=" -runmod $1 " shift;; - -h) + -h|--hup) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl hup";; - -s) + -s|--stop) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl stop";; - -ls) + -ls|--ls) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl ls";; - -S) + -S|--status) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl status";; - -load) + -load|--load) $erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl load ${id} $* exit 0;; - -j) + -j|--ctltrace) ex="$erl -noshell -pa ${yawsdir}${delim}ebin -s yaws_ctl trace $1" shift;; - -v) + -v|--version) exec $erl -noshell -pa ${yawsdir}${delim}ebin -s yaws printversion; exit 0;; - -sname) + --sname|-sname) sname=" -sname $1 " shift;; - -name) + -name|--name) sname=" -name $1 " shift;; - -heart) + -heart|--heart) heart=" -heart ";; - -proto_dist) + -proto_dist|--proto_dist) pdist=" -proto_dist $1 " shift;; - -erlarg) + -erlarg|--erlarg) erlarg="$erlarg $1 " shift;; - -check) + -check|--check) mkdir /tmp/yaws 2> /dev/null mkdir /tmp/yaws/${ID} 2> /dev/null out=`exec $erl -noshell -pa ${yawsdir}${delim}ebin ${xpath} -s yaws_ctl check ${id} $*` @@ -166,6 +169,9 @@ if [ ! -z "${ex}" ]; then exit 0 fi +if [ ! -z "${id}" ]; then + id="-yaws id ${id}" +fi trace="${trace} ${traceoutput}" @@ -175,10 +181,10 @@ if [ -z "$heart" ] || [ -z "$daemon" ]; then HEART_COMMAND=""; else ## ............................this line - export HEART_COMMAND="${ENV_PGM} HEART=true \"$erl\" ${daemon} ${heart} -pa ${yawsdir}${delim}ebin ${xpath} ${sname} ${pdist} ${erlarg} ${debug} -s yaws $trace $conf $runmod $mnesia"; + export HEART_COMMAND="${ENV_PGM} HEART=true \"$erl\" ${daemon} ${heart} -pa ${yawsdir}${delim}ebin ${xpath} ${sname} ${pdist} ${erlarg} ${debug} -s yaws ${trace} ${conf} ${runmod} ${mnesia} ${id}"; fi ## keep this line in sync with ....^ -exec "$erl" ${daemon} ${heart} -pa ${yawsdir}${delim}ebin ${xpath} ${sname} ${pdist} ${erlarg} ${debug} -s yaws $trace $conf $runmod $mnesia +exec "$erl" ${daemon} ${heart} -pa ${yawsdir}${delim}ebin ${xpath} ${sname} ${pdist} ${erlarg} ${debug} -s yaws ${trace} ${conf} ${runmod} ${mnesia} ${id} diff --git a/src/Makefile b/src/Makefile index b9807a153..d54d7cb35 100644 --- a/src/Makefile +++ b/src/Makefile @@ -57,7 +57,7 @@ yaws_vsn.erl: yaws_vsn.template ../vsn.mk charset.def: if [ ! -z "$(DEFAULT_CHARSET)" ]; then \ echo $(DEFAULT_CHARSET) > charset.def; \ - else rm charset.def; touch charset.def; fi + else rm charset.def 2> /dev/null; touch charset.def; fi mime_types.erl: mime.types mime_type_c.erl charset.def $(ERL) -noshell -pa ../ebin -s mime_type_c compile diff --git a/src/yaws.erl b/src/yaws.erl index 42a527b12..0ce5ed650 100644 --- a/src/yaws.erl +++ b/src/yaws.erl @@ -271,11 +271,8 @@ old_integer_to_hex(I) when I>=16 -> old_integer_to_hex(N) ++ old_integer_to_hex(I rem 16). - - %% hex_to_integer - hex_to_integer(Hex) -> case catch erlang:list_to_integer(Hex, 16) of {'EXIT', _} -> @@ -465,8 +462,6 @@ is_modified_p(FI, UTC_string) -> end. - - ticker(Time, Msg) -> S = self(), spawn_link(yaws, ticker, [Time, S, Msg]). @@ -475,38 +470,6 @@ ticker(Time, To, Msg) -> yaws_ticker:ticker(Time, To, Msg). -fmt_ip({A,B,C,D}) -> - [integer_to_list(A), $., - integer_to_list(B), $., - integer_to_list(C), $., - integer_to_list(D)]. - - - -parse_ip(Val) -> - case string:tokens(Val, [$.]) of - Nums = [_X1, _X2, _X3,_X4] -> - L = lists:map( - fun(S) -> (catch list_to_integer(S)) end, - Nums), - case lists:zf(fun(I) when integer(I), - 0 =< I, - I =< 255 -> - true; - (_) -> - false - end, L) of - L2 when length(L2) == 4 -> - list_to_tuple(L2); - _ -> - error - end; - _ -> - error - end. - - - address() -> ?F("
~s Server at ~s
", [ @@ -515,7 +478,6 @@ address() -> - is_space($\s) -> true; is_space($\r) -> @@ -1537,44 +1499,39 @@ erase_header(location) -> put(outh, (get(outh))#outh{location = undefined}). - - - - - -setuser(undefined) -> - ignore; -setuser(User) -> - erl_ddll:load_driver(filename:dirname(code:which(?MODULE)) ++ - "/../priv/", "setuid_drv"), - P = open_port({spawn, "setuid_drv " ++ [$s|User]}, []), - receive - {P, {data, "ok " ++ IntList}} -> - {ok, IntList} - end. +% setuser(undefined) -> +% ignore; +% setuser(User) -> +% erl_ddll:load_driver(filename:dirname(code:which(?MODULE)) ++ +% "/../priv/", "setuid_drv"), +% P = open_port({spawn, "setuid_drv " ++ [$s|User]}, []), +% receive +% {P, {data, "ok " ++ IntList}} -> +% {ok, IntList} +% end. getuid() -> case os:type() of - {win32, _} -> - {ok, "XXX"}; - _ -> - erl_ddll:load_driver(filename:dirname(code:which(?MODULE)) ++ - "/../priv/", "setuid_drv"), - P = open_port({spawn, "setuid_drv g"},[]), - receive - {P, {data, "ok " ++ IntList}} -> - {ok, IntList} - end + {win32, _} -> + {ok, "XXX"}; + _ -> + erl_ddll:load_driver(filename:dirname(code:which(?MODULE)) ++ + "/../priv/", "setuid_drv"), + P = open_port({spawn, "setuid_drv g"},[]), + receive + {P, {data, "ok " ++ IntList}} -> + {ok, IntList} + end end. idu(User) -> erl_ddll:load_driver(filename:dirname(code:which(?MODULE)) ++ - "/../priv/", "setuid_drv"), + "/../priv/", "setuid_drv"), P = open_port({spawn, "setuid_drv " ++ [$u|User]}, []), receive - {P, {data, "ok " ++ IntList}} -> - {ok, IntList} + {P, {data, "ok " ++ IntList}} -> + {ok, IntList} end. user_to_home(User) -> @@ -1586,42 +1543,15 @@ user_to_home(User) -> Home end. + + uid_to_name(Uid) -> erl_ddll:load_driver(filename:dirname(code:which(?MODULE)) ++ - "/../priv/", "setuid_drv"), + "/../priv/", "setuid_drv"), P = open_port({spawn, "setuid_drv " ++ [$n|integer_to_list(Uid)]}, []), receive - {P, {data, "ok " ++ Name}} -> - Name - end. - - - -tmp_dir() -> - case os:type() of - {win32,_} -> - case os:getenv("TEMP") of - false -> - case os:getenv("TMP") of - %% - %% No temporary path set? - %% Then try standard paths. - %% - false -> - case file:read_file_info("C:/WINNT/Temp") of - {error, _} -> - "C:/WINDOWS/Temp"; - {ok, _} -> - "C:/WINNT/Temp" - end; - PathTMP -> - PathTMP - end; - PathTEMP -> - PathTEMP - end; - _ -> - "/tmp" + {P, {data, "ok " ++ Name}} -> + Name end. @@ -1635,6 +1565,27 @@ exists(F) -> end. +mkdir(Path) -> + [Hd|Parts] = filename:split(Path), + mkdir([Hd], Parts). +mkdir(Ack, []) -> + ensure_exist(filename:join(Ack)); +mkdir(Ack, [H|T]) -> + ensure_exist(filename:join(Ack ++ [H])), + mkdir(Ack ++ [H], T). + +ensure_exist(Path) -> + case file:read_file_info(Path) of + {ok, _} -> ok; + _ -> case file:make_dir(Path) of + ok -> ok; + ERR -> + error_logger:format("Failed to mkdir ~p: ~p~n", + [Path, ERR]) + end + end. + + %% %% %% http/tcp send receive functions @@ -1928,43 +1879,6 @@ slash_append([], T) -> slash_append([H|T], X) -> [H | slash_append(T,X)]. - - - -%% aux help function -uid_change_files(GC, Dir, Files) -> - case GC#gconf.username of - undefined -> - %% uid change feature not used - ok; - _Uname when GC#gconf.uid /= "0" -> - %% we're not root and can't do anything about the sitiation - ok; - Uname -> - case (catch list_to_integer(element(2,yaws:idu(Uname)))) of - Int when integer(Int) -> - file:change_owner(Dir, Int), - lists:foreach( - fun(FN) -> - F=filename:join([Dir,FN]), - case file:change_owner(F, Int) of - ok -> ok; - {error, Rsn} -> - error_logger:format("Failed to chown " - "~p: ~p", - [F, Rsn]), - erlang:fault(Rsn) - end - end, Files); - Err -> - error_logger:format("Bad username ~p cannot get " - "numeric uid~n", [Uname]), - erlang:fault(Err) - end - end. - - - flag(CurFlag, Bit, true) -> CurFlag bor Bit; flag(CurFlag, Bit, false) -> diff --git a/src/yaws_404.erl b/src/yaws_404.erl index 52a1e79ad..e47b151bc 100644 --- a/src/yaws_404.erl +++ b/src/yaws_404.erl @@ -37,7 +37,7 @@ out404(Arg, GC, SC) -> -not_found_body(Path, GC, SC) -> +not_found_body(Path, _GC, SC) -> L = ["" "" "404 Not Found" diff --git a/src/yaws_api.erl b/src/yaws_api.erl index 2ebef7d35..23afad266 100644 --- a/src/yaws_api.erl +++ b/src/yaws_api.erl @@ -726,19 +726,6 @@ rest_dir (N, Path, [ _H | T ] ) -> rest_dir (N , Path , T). url_decode_q_split(Path) -> url_decode_q_split(Path, []). -% url_decode_q_split([$%, $C, $2, $%, Hi, Lo | Tail], Ack) -> -% Hex = yaws:hex_to_integer([Hi, Lo]), -% url_decode_q_split(Tail, [Hex|Ack]); -% url_decode_q_split([$%, $C, $3, $%, Hi, Lo | Tail], Ack) when Hi > $9 -> -% Hex = yaws:hex_to_integer([Hi+4, Lo]), -% url_decode_q_split(Tail, [Hex|Ack]); -% url_decode_q_split([$%, $C, $3, $%, Hi, Lo | Tail], Ack) when Hi < $A -> -% Hex = yaws:hex_to_integer([Hi+4+7, Lo]), -% url_decode_q_split(Tail, [Hex|Ack]); - - -%% Removed the above hackery, (klacke) - url_decode_q_split([$%, Hi, Lo | Tail], Ack) -> Hex = yaws:hex_to_integer([Hi, Lo]), if Hex == 0 -> exit(badurl); @@ -1702,8 +1689,7 @@ setconf(GC0, Groups0) -> yaws_config:can_soft_setconf(GC, Groups, OLDGC, OldGroups)} of {true, true} -> yaws_config:soft_setconf(GC, Groups, OLDGC, OldGroups); - {true, false} when OLDGC == undefined; - OLDGC#gconf.username == undefined -> + {true, false} when OLDGC == undefined -> yaws_config:hard_setconf(GC, Groups); _ -> {error, need_restart} diff --git a/src/yaws_cgi.erl b/src/yaws_cgi.erl index 68e7db9fb..86a062c2f 100644 --- a/src/yaws_cgi.erl +++ b/src/yaws_cgi.erl @@ -161,10 +161,10 @@ deep_drop_prefix(_, _) -> get_socket_peername(Socket={sslsocket,_,_}) -> {ok, {IP, _Port}}=ssl:peername(Socket), - yaws:fmt_ip(IP); + inet_parse:ntoa(IP); get_socket_peername(Socket) -> {ok, {IP, _Port}}=inet:peername(Socket), - yaws:fmt_ip(IP). + inet_parse:ntoa(IP). cgi_env(Arg, Scriptfilename, Pathinfo, ExtraEnv, SC) -> @@ -235,7 +235,7 @@ tohttp_c(C) -> %% Get Host part from a host string that can contain host or host:port host(Host) -> case string:tokens(Host, ":") of - [Hostname, Port] -> Hostname; + [Hostname, _Port] -> Hostname; [Hostname] -> Hostname; _Other -> Host end. diff --git a/src/yaws_compile.erl b/src/yaws_compile.erl index c6346ff18..a5887a31f 100644 --- a/src/yaws_compile.erl +++ b/src/yaws_compile.erl @@ -123,7 +123,7 @@ compile_file(C, LineNo, Chars = "" ++ _Tail, html, NumChars, Ack,Es) C2 = C#comp{outfile = ["
\n"]},  %% use as accumulator
     compile_file(C2,  LineNo+1, line() , verbatim , Len, [{data, NumChars} | Ack], Es);
 
-compile_file(C, LineNo,  Chars = "" ++ Tail, verbatim, NumChars, Ack, Es) ->
+compile_file(C, LineNo,  Chars = "" ++ _Tail, verbatim, NumChars, Ack, Es) ->
     Data = list_to_binary(lists:reverse(["
\n" | C#comp.outfile])), Len = length(Chars), compile_file(C#comp{outfile = undefined}, LineNo, line(), html, 0, @@ -139,7 +139,7 @@ compile_file(C, LineNo, Chars, verbatim, NumChars, Ack,Es) -> length(Chars), Ack,Es) end; -compile_file(C, LineNo, Chars = "" ++ Tail, erl, NumChars, Ack, Es) -> +compile_file(C, LineNo, _Chars = "" ++ Tail, erl, NumChars, Ack, Es) -> ?Debug("stop erl:~p",[LineNo]), file:close(C#comp.outfd), case proc_compile_file(C#comp.outfile, comp_opts(C#comp.gc)) of @@ -206,7 +206,7 @@ compile_file(C, LineNo, [], binding, NumChars, Ack, Es) -> compile_file(C, LineNo, "%%"++Chars, binding, NumChars, Ack, Es) -> compile_file(C, LineNo, Chars, html, 0, [{binding, NumChars+2}|Ack], Es); -compile_file(C, LineNo, [H|T], binding, NumChars, Ack, Es) -> +compile_file(C, LineNo, [_H|T], binding, NumChars, Ack, Es) -> compile_file(C, LineNo, T, binding, NumChars+1, Ack, Es). @@ -273,7 +273,7 @@ new_out_file_name(Tail) -> %% this will generate 10 lines new_out_file(Line, C, Tail, GC) -> Module = new_out_file_name(Tail), - OutFile = filename:join([yaws:tmp_dir(), "yaws", GC#gconf.id, Module ++ ".erl"]), + OutFile = filename:join([GC#gconf.tmpdir, "yaws", GC#gconf.id, Module ++ ".erl"]), ?Debug("Writing outout file~s~n", [OutFile]), {ok, Out} = file:open(OutFile, [write]), ok = io:format(Out, "-module(~s).~n-compile(export_all).~n~n", [Module]), diff --git a/src/yaws_config.erl b/src/yaws_config.erl index 71d4729ef..1597aba04 100644 --- a/src/yaws_config.erl +++ b/src/yaws_config.erl @@ -23,7 +23,8 @@ -export([load/1, toks/1, - make_default_gconf/1]). + tmp_dir/0, + make_default_gconf/2]). %% where to look for yaws.conf @@ -53,7 +54,7 @@ load(E) -> error_logger:info_msg("Yaws: Using config file ~s~n", [File]), case file:open(File, [read]) of {ok, FD} -> - GC = make_default_gconf(E#env.debug), + GC = make_default_gconf(E#env.debug, E#env.id), GC2 = if E#env.traceoutput == undefined -> GC; true -> @@ -66,6 +67,7 @@ load(E) -> ?Debug("FLOAD: ~p", [R]), case R of {ok, GC5, Cs} -> + yaws:mkdir(GC#gconf.tmpdir), Cs2 = add_yaws_auth(Cs), validate_cs(GC5, Cs2); Err -> @@ -108,7 +110,6 @@ add_yaws_auth(SC, Dirs, A) -> ok end, - io:format("AAAA A = ~p~n", [A]), lists:map( fun(Dir) -> FN=[SC#sconf.docroot , [$/|Dir], [$/|".yaws_auth"]], @@ -226,7 +227,7 @@ add_port(SC, Port) -> end. -make_default_gconf(Debug) -> +make_default_gconf(Debug, Id) -> Y = yaws_dir(), #gconf{yaws_dir = Y, ebin_dir = [filename:join([Y, "examples/ebin"])], @@ -249,10 +250,41 @@ make_default_gconf(Debug) -> ?GC_FAIL_ON_BIND_ERR bor ?GC_PICK_FIRST_VIRTHOST_ON_NOMATCH end, - uid = element(2, yaws:getuid()), - yaws = "Yaws " ++ yaws_vsn:version()}. + %uid = element(2, yaws:getuid()), + tmpdir = tmp_dir(), + yaws = "Yaws " ++ yaws_vsn:version(), + id = Id + }. + +tmp_dir() -> + case os:type() of + {win32,_} -> + case os:getenv("TEMP") of + false -> + case os:getenv("TMP") of + %% + %% No temporary path set? + %% Then try standard paths. + %% + false -> + case file:read_file_info("C:/WINNT/Temp") of + {error, _} -> + "C:/WINDOWS/Temp"; + {ok, _} -> + "C:/WINNT/Temp" + end; + PathTMP -> + PathTMP + end; + PathTEMP -> + PathTEMP + end; + _ -> + filename:join([os:getenv("HOME"), ".yaws"]) + end. + make_default_sconf() -> Y = yaws_dir(), #sconf{docroot = filename:join([Y, "www"])}. @@ -372,6 +404,16 @@ fload(FD, globals, GC, C, Cs, Lno, Chars) -> {error, ?F("Expect directory at line ~w", [Lno])} end; + ["tmpdir", '=', Dir] -> + Dir = filename:absname(Dir), + case is_dir(Dir) of + true -> + fload(FD, globals, GC#gconf{tmpdir=[Dir|GC#gconf.include_dir]}, + C, Cs, Lno+1, Next); + false -> + {error, ?F("Expect directory at line ~w", [Lno])} + end; + %% keep this bugger for backward compat for a while ["keepalive_timeout", '=', Val] -> case (catch list_to_integer(Val)) of @@ -429,14 +471,8 @@ fload(FD, globals, GC, C, Cs, Lno, Chars) -> {error, ?F("Expect 0 or positive integer at line ~w", [Lno])} end; - ["username", '=' , Uname] -> - case os:type() of - {win32, _} -> - {error, "username feature not supported on win32"}; - _ -> - fload(FD, globals, GC#gconf{username = Uname}, - C, Cs, Lno+1, Next) - end; + ["username", '=' , _Uname] -> + {error, "username feature not supported anymore - use fdsrv"}; ["copy_error_log", '=', Bool] -> case is_bool(Bool) of @@ -464,9 +500,11 @@ fload(FD, globals, GC, C, Cs, Lno, Chars) -> false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; - ["id", '=', String] -> + ["id", '=', String] when GC#gconf.id == undefined -> fload(FD, globals, GC#gconf{id=String},C, Cs, Lno+1, Next); - + ["id", '=', String] -> + error_logger:format("Ignoring 'id = ~p' setting at line ~p~n", [String,Lno]), + fload(FD, globals, GC, C, Cs, Lno+1, Next); ["pick_first_virthost_on_nomatch", '=', Bool] -> case is_bool(Bool) of {true, Val} -> @@ -485,6 +523,7 @@ fload(FD, globals, GC, C, Cs, Lno, Chars) -> false -> {error, ?F("Expect true|false at line ~w", [Lno])} end; + ['<', "server", Server, '>'] -> %% first server fload(FD, server, GC, #sconf{servername = Server}, @@ -567,10 +606,10 @@ fload(FD, server, GC, C, Cs, Lno, Chars) -> C2 = C#sconf{rhost = Val}, fload(FD, server, GC, C2, Cs, Lno+1, Next); ["listen", '=', IP] -> - case yaws:parse_ip(IP) of - error -> + case inet_parse:address(IP) of + {error, _} -> {error, ?F("Expect IP address at line ~w:", [Lno])}; - Addr -> + {ok,Addr} -> C2 = C#sconf{listen = Addr}, fload(FD, server, GC, C2, Cs, Lno+1, Next) end; @@ -1191,19 +1230,14 @@ soft_setconf(GC, Groups, OLDGC, OldGroups) -> end, Rems = remove_old_scs(lists:flatten(OldGroups), Groups), Adds = soft_setconf_scs(lists:flatten(Groups), OldGroups), - case lists:keysearch(add_sconf,1,Adds) of - {value, _} when OLDGC#gconf.username /= undefined -> - {error, need_restart}; - _ -> - lists:foreach( - fun({delete_sconf, SC}) -> - delete_sconf(SC); - ({add_sconf, SC}) -> - add_sconf(SC); - ({update_sconf, SC}) -> - update_sconf(SC) - end, Rems ++ Adds) - end. + lists:foreach( + fun({delete_sconf, SC}) -> + delete_sconf(SC); + ({add_sconf, SC}) -> + add_sconf(SC); + ({update_sconf, SC}) -> + update_sconf(SC) + end, Rems ++ Adds). @@ -1262,7 +1296,6 @@ can_hard_gc(New, Old) -> true; New#gconf.yaws_dir == Old#gconf.yaws_dir, New#gconf.runmods == Old#gconf.runmods, - New#gconf.username == Old#gconf.username, New#gconf.logdir == Old#gconf.logdir -> true; true -> @@ -1281,7 +1314,6 @@ can_soft_gc(G1, G2) -> G1#gconf.flags == G2#gconf.flags, G1#gconf.logdir == G2#gconf.logdir, G1#gconf.log_wrap_size == G2#gconf.log_wrap_size, - G1#gconf.username == G2#gconf.username, G1#gconf.id == G2#gconf.id -> true; true -> diff --git a/src/yaws_ctl.erl b/src/yaws_ctl.erl index 8cf23ab44..718301480 100644 --- a/src/yaws_ctl.erl +++ b/src/yaws_ctl.erl @@ -82,8 +82,8 @@ run_listen(GC) -> "called ~s~n" "either problems with permissions or " " earlier runs of yaws ~nwith the same id " - " <~p> as this, check /tmp/yaws/* for perms~n", - [ctl_file(GC#gconf.id), GC#gconf.id]) + " <~p> as this, check ~p for perms~n", + [ctl_file(GC#gconf.id), GC#gconf.id, sys_dir()]) end; Err -> e("Cannot get sockname for ctlsock: ~p",[Err] ) @@ -120,10 +120,13 @@ w_ctl_file(Sid, Port) -> ctl_file(Sid) -> - filename:join([yaws:tmp_dir(), + filename:join([yaws_config:tmp_dir(), "yaws", Sid, "ctl"]). +sys_dir() -> + filename:join([yaws_config:tmp_dir(), + "yaws"]). @@ -205,8 +208,6 @@ actl_trace(What) -> [What, filename:join([GC#gconf.logdir, "trace." ++ atom_to_list(What)])]) - - end; false -> "Need either http | traffic | off as argument\n" @@ -341,7 +342,7 @@ s_cmd(Fd, SID, Term) -> %% List existing yaws nodes on this machine ls(_) -> - case file:list_dir("/tmp/yaws") of + case file:list_dir(sys_dir()) of {ok, List} -> io:format("~-15s~-10s~-10s~n", ["Id", "Status", "Owner"]), @@ -360,8 +361,8 @@ ls(_) -> lls(Dir) -> Ctl = ctl_file(Dir), case {file:read_file_info(Ctl), - file:read_file_info(filename:join("/tmp/yaws/", Dir))} of - {{ok, FI}, {ok, DI}} -> + file:read_file_info(filename:join([sys_dir(), Dir]))} of + {{ok, _FI}, {ok, DI}} -> User = yaws:uid_to_name(DI#file_info.uid), Running = case connect(Dir) of {ok, Sock} -> @@ -371,15 +372,13 @@ lls(Dir) -> "hanging??"; {error, eacces} -> "unknown"; - Err -> + _Err -> "stopped" end, io:format("~-15s~-10s~-10s~n", [Dir, Running, User]); - - - {{ok, FI}, {error, _}} -> + {{ok, _FI}, {error, _}} -> %% sick case, ignore; @@ -389,7 +388,6 @@ lls(Dir) -> io:format("~-15s~-10s~-10s~n", [Dir, "stopped", User]); - _Err -> io:format("~-15s~-10s~-10s~n", [Dir, "unknown", "unknown"]) @@ -418,7 +416,7 @@ load(X) -> actl(SID, {load, Modules}). check([Id, File| IncludeDirs]) -> - GC = yaws_config:make_default_gconf(false), + GC = yaws_config:make_default_gconf(false, undefined), GC2 = GC#gconf{include_dir = lists:map(fun(X) -> atom_to_list(X) end, IncludeDirs), id = atom_to_list(Id) diff --git a/src/yaws_html.erl b/src/yaws_html.erl index ff34505f4..97da7e8b0 100644 --- a/src/yaws_html.erl +++ b/src/yaws_html.erl @@ -29,7 +29,7 @@ h2e(Input) -> % parse(Tokens, Stack, Acc) -parse([], {T,A,L}, [], Acc) -> +parse([], {T,A,_L}, [], Acc) -> {T, A, lists:reverse(Acc)}; parse([], {T,A,L}, [{CTag,CAcc}|Stack], Acc) -> io:format("Unterminated tag '~p' at line ~p\n", [T,L]), @@ -42,7 +42,7 @@ parse([{begin_tag,T,A,L}|Tokens], CTag, Stack, Acc) -> parse(Tokens, {T,A,L}, [{CTag,Acc}|Stack],[]) end; -parse([{end_tag,T,[],L}|Tokens], {T,A,_}, [{CTag,CAcc}|Stack], Acc) -> +parse([{end_tag,T,[],_L}|Tokens], {T,A,_}, [{CTag,CAcc}|Stack], Acc) -> E = case Acc of [Single] -> {T,A,Single}; @@ -51,7 +51,7 @@ parse([{end_tag,T,[],L}|Tokens], {T,A,_}, [{CTag,CAcc}|Stack], Acc) -> end, parse(Tokens, CTag, Stack, [E|CAcc]); -parse([{end_tag,T1,[],L1}|Tokens], CTag = {T2,A,L2}, Stack, Acc) -> +parse([{end_tag,T1,[],L1}|Tokens], CTag = {T2,_A,L2}, Stack, Acc) -> case tag_type(T1) of leaf -> % ignore parse(Tokens, CTag, Stack, Acc); @@ -62,7 +62,7 @@ parse([{end_tag,T1,[],L1}|Tokens], CTag = {T2,A,L2}, Stack, Acc) -> {error, Msg} end; -parse([{data, Data, Line}|Tokens], CTag, Stack, Acc) -> +parse([{data, Data, _Line}|Tokens], CTag, Stack, Acc) -> case skip_space(Data, 0) of {[], _} -> parse(Tokens, CTag, Stack, Acc); @@ -121,13 +121,13 @@ next_token(_Tag, R, Tokens, L) -> %% '<' + [*['=']]* ['/'] '>' scan_tag([$/|I], L) -> - {R0,L0} = skip_space(I, L), + {_R0,L0} = skip_space(I, L), {Name,R1,L1} = scan_tag_name(I, L0), {R2,L2} = skip_space(R1, L1), {Args,R3,L3} = scan_tag_args(R2, L2), {{end_tag,list_to_atom(lowercase(Name)),Args,L0}, R3, L3}; scan_tag(I, L) -> - {R0,L0} = skip_space(I, L), + {_R0,L0} = skip_space(I, L), {Name,R1,L1} = scan_tag_name(I, L0), {R2,L2} = skip_space(R1, L1), {Args,R3,L3} = scan_tag_args(R2, L2), @@ -249,7 +249,7 @@ char_class($\t) -> space; char_class(C) when C >= $a, C =< $z -> alpha; char_class(C) when C >= $A, C =< $Z -> alpha; char_class(C) when C >= $0, C =< $9 -> digit; -char_class(C) -> other. +char_class(_C) -> other. % @@ -271,7 +271,7 @@ skip_comment([], L) -> {[], L}; skip_comment([$-,$-,$>|R],L) -> {R,L}; skip_comment([$\n|R],L) -> skip_comment(R,L+1); skip_comment([$\r|R],L) -> skip_comment(R,L+1); -skip_comment([C|R],L) -> skip_comment(R,L). +skip_comment([_C|R],L) -> skip_comment(R,L). % diff --git a/src/yaws_log.erl b/src/yaws_log.erl index 4101d86be..6900a9cf6 100644 --- a/src/yaws_log.erl +++ b/src/yaws_log.erl @@ -16,7 +16,7 @@ -behaviour(gen_server). %% External exports --export([start_link/0, uid_change/1]). +-export([start_link/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]). @@ -80,14 +80,14 @@ actl_trace(What) -> %% change owner of logfiles and logdir %% only called when we lower rights after socket(s) are opened -uid_change(GC) -> - case file:list_dir(GC#gconf.logdir) of - {ok, L} -> - yaws:uid_change_files(GC, GC#gconf.logdir,L); - {error, Rsn} -> - error_logger:format("Failed to listdir ~p : ~p", - [GC#gconf.logdir, Rsn]) - end. +% uid_change(GC) -> +% case file:list_dir(GC#gconf.logdir) of +% {ok, L} -> +% yaws:uid_change_files(GC, GC#gconf.logdir,L); +% {error, Rsn} -> +% error_logger:format("Failed to listdir ~p : ~p", +% [GC#gconf.logdir, Rsn]) +% end. @@ -334,7 +334,7 @@ do_alog(ServerName, Ip, User, Req, Status, Length, Referrer, do_auth_log(ServerName, IP, Path, Item, State) -> AL = State#state.auth_log, - I = [yaws:fmt_ip(IP), + I = [inet_parse:ntoa(IP), " ", State#state.now, " ", ServerName, " " ,"\"", Path,"\"", case Item of @@ -438,12 +438,12 @@ terminate(_Reason, _State) -> fmt_alog(Time, Ip, User, Req, Status, Length, Referrer, UserAgent) -> - [fmt_ip(Ip), " - ", User, [$\s], Time, [$\s, $"], Req, [$",$\s], + [inet_parse:ntoa(Ip), " - ", User, [$\s], Time, [$\s, $"], Req, [$",$\s], Status, [$\s], Length, [$\s,$"], Referrer, [$",$\s,$"], UserAgent, [$",$\n]]. fmt_ip(IP) when tuple(IP) -> - yaws:fmt_ip(IP); + inet_parse:ntoa(IP); fmt_ip(undefined) -> "0.0.0.0"; fmt_ip(HostName) -> diff --git a/src/yaws_ls.erl b/src/yaws_ls.erl index 459a7e941..bf876a29f 100644 --- a/src/yaws_ls.erl +++ b/src/yaws_ls.erl @@ -44,7 +44,11 @@ list_directory(Arg, CliSock, List, DirName, Req, DoAllZip) -> dir_header(DirName,DirStr), table_head(Direction), parent_dir(), - if DoAllZip == true -> allzip() end, + if DoAllZip == true -> + allzip(); + true -> + [] + end, %% if DoAllGZip == true -> alltgz() end, %% if DoAllBZip2 == true -> alltbz2() end, @@ -212,8 +216,10 @@ is_user_dir(SP) -> case SP of [$/,$~ | T] -> User = string:sub_word(T,1,$/), case catch yaws:user_to_home(User) of - Home -> {true,Home}; - _ -> false + {'EXIT', _} -> + false; + Home -> + {true,Home} end; _ -> false end. diff --git a/src/yaws_revproxy.erl b/src/yaws_revproxy.erl index f1ecf22ba..6c9edd6d1 100644 --- a/src/yaws_revproxy.erl +++ b/src/yaws_revproxy.erl @@ -33,7 +33,7 @@ %% with redirection). %% I did not yet check that. -init(CliSock, ARG, DecPath, QueryPart, {Prefix, URL}, N) -> +init(CliSock, ARG, _DecPath, _QueryPart, {Prefix, URL}, N) -> GC=get(gc), SC=get(sc), %% Connect to the backend server case connect_url(URL, SC) of @@ -233,7 +233,7 @@ nonl([]) -> -get_chunk(Fd, _N, N,_) -> +get_chunk(_Fd, N, N, _) -> []; get_chunk(Fd, N, Asz,SSL) -> case yaws:do_recv(Fd, N, SSL) of @@ -352,7 +352,7 @@ ploop(From0, To, Pid) -> %% Before reentering the ploop in expect_header mode (new request/reply), %% We must check the if we need to keep the connection alive %% or if we must close it. -ploop_keepalive(_From = #psock{httpconnection="close"}, To, Pid) -> +ploop_keepalive(_From = #psock{httpconnection="close"}, _To, _Pid) -> ?Debug("Connection closed by proxy: No keep-alive~n",[]), done; %% Close the connection ploop_keepalive(From, To, Pid) -> diff --git a/src/yaws_server.erl b/src/yaws_server.erl index 2b6e09976..5d5c789ea 100644 --- a/src/yaws_server.erl +++ b/src/yaws_server.erl @@ -78,7 +78,7 @@ stats() -> E = SC#sconf.ets, L = ets:match(E, {{urlc_total, '$1'}, '$2'}), {SC#sconf.servername, - flatten(yaws:fmt_ip(SC#sconf.listen)), + flatten(inet_parse:ntoa(SC#sconf.listen)), G(map(fun(P) -> list_to_tuple(P) end, L))} end, SCS) end, S#state.pairs), @@ -97,7 +97,7 @@ l2a(A) when atom(A) -> A. %% {stop, Reason} %%---------------------------------------------------------------------- -init(Env) -> %% #env{Trace, TraceOut, Conf, RunMod, Embedded}) -> +init(Env) -> %% #env{Trace, TraceOut, Conf, RunMod, Embedded, Id}) -> process_flag(trap_exit, true), put(start_time, calendar:local_time()), %% for uptime case Env#env.embedded of @@ -131,7 +131,7 @@ init(Env) -> %% #env{Trace, TraceOut, Conf, RunMod, Embedded}) -> init:stop(), {stop, E}; Dir -> - GC = yaws_config:make_default_gconf(true), + GC = yaws_config:make_default_gconf(true, Env#env.id), yaws_log:setdir(GC#gconf{logdir = Dir}, []), error_logger:error_msg("Yaws: bad conf: ~s " "terminating~n",[E]), @@ -176,25 +176,7 @@ init2(GC, Sconfs, RunMod, Embedded, FirstTime) -> L2 = lists:zf( fun(Group) -> start_group(GC, Group) end, Sconfs), - - yaws_log:uid_change(GC), - - - %% and now finally, we've opened the ctl socket and are - %% listening to all sockets we can possibly change uid - - GC2 = case (catch yaws:setuser(GC#gconf.username)) of - ignore -> - GC; - {ok, NewUid} -> - error_logger:info_msg("Changed uid to ~s~n", [NewUid]), - GC#gconf{uid = NewUid}; - Other -> - error_logger:error_msg("Failed to set user:~n~p", [Other]), - erlang:fault(Other) - end, - foreach(fun({Pid, _}) -> Pid ! {newuid, GC2#gconf.uid} end, L2), - {ok, #state{gc = GC2, + {ok, #state{gc = GC, pairs = L2, mnum = 0, embedded = Embedded}}. @@ -320,8 +302,8 @@ handle_call({add_sconf, SC}, From, State) -> false -> {reply, ok, State}; {true, Pair} -> - Pid = element(1, Pair), - Pid ! {newuid, GC#gconf.uid}, + %Pid = element(1, Pair), + %Pid ! {newuid, GC#gconf.uid}, P2 = [Pair | State#state.pairs], {reply, ok, State#state{pairs = P2}} end @@ -403,18 +385,6 @@ gen_tcp_listen(Port, Opts) -> gen_tcp:listen(Port, Opts). -set_writeable(Dir) -> - set_dir_mode(Dir, 8#777). - -set_dir_mode(Dir, Mode) -> - case file:read_file_info(Dir) of - {ok, FI} -> - file:write_file_info(Dir, FI#file_info{mode = Mode}); - _Err -> - error_logger:format("Failed to read_file_info(~s)~n", [Dir]) - end. - - gserv(_Top, _, []) -> proc_lib:init_ack(none); @@ -432,7 +402,7 @@ gserv(Top, GC, Group0) -> call_start_mod(SC), error_logger:info_msg( "Yaws: Listening to ~s:~w for servers~s~n", - [yaws:fmt_ip(SC#sconf.listen), + [inet_parse:ntoa(SC#sconf.listen), SC#sconf.port, catch map( fun(S) -> @@ -442,11 +412,7 @@ gserv(Top, GC, Group0) -> end, Group) ]), proc_lib:init_ack({self(), Group}), - N = receive - {newuid, UID} -> - UID - end, - GS = #gs{gconf = GC#gconf{uid = N}, + GS = #gs{gconf = GC, group = Group, ssl = SSLBOOL, l = Listen}, @@ -454,7 +420,7 @@ gserv(Top, GC, Group0) -> gserv_loop(GS, [], 0, Last); {_,Err} -> error_logger:format("Yaws: Failed to listen ~s:~w : ~p~n", - [yaws:fmt_ip(SC#sconf.listen), + [inet_parse:ntoa(SC#sconf.listen), SC#sconf.port, Err]), proc_lib:init_ack({error, "Can't listen to socket: ~p ",[Err]}), exit(normal) @@ -462,15 +428,10 @@ gserv(Top, GC, Group0) -> setup_dirs(GC) -> - TD0 = filename:join([yaws:tmp_dir(),"yaws"]), + TD0 = filename:join([GC#gconf.tmpdir,"yaws"]), file:make_dir(TD0), - set_dir_mode(TD0, 8#777), - TD1 = filename:join([TD0, GC#gconf.id]), file:make_dir(TD1), - set_dir_mode(TD1, 8#755), - yaws:uid_change_files(GC, TD1, []), - case file:list_dir(TD1) of {ok, LL} -> foreach( @@ -780,7 +741,7 @@ acceptor0(GS, Top) -> inet:peername(Client) end, Str = ?F("New (~p) connection from ~s:~w~n", - [GS#gs.ssl, yaws:fmt_ip(IP),Port]), + [GS#gs.ssl, inet_parse:ntoa(IP),Port]), yaws_log:trace_traffic(from_client, Str); _ -> ok @@ -967,7 +928,7 @@ comp_sname(_,_)-> false. -pick_sconf(GC, H, [SC|Group], ssl) -> +pick_sconf(GC, H, [SC|_Group], ssl) -> case comp_sname(H#headers.host, SC#sconf.servername) of true -> SC; @@ -1124,14 +1085,14 @@ bad_request(CliSock, Req, _Head) -> port(CliSock) -> case inet:peername(CliSock) of {ok, {IP, _Port}} -> - yaws:fmt_ip(IP); + inet_parse:ntoa(IP); _ -> "unknown" end; true -> case ssl:peername(CliSock) of {ok, {IP, _Port}} -> - yaws:fmt_ip(IP); + inet_parse:ntoa(IP); _ -> "unknown" end @@ -1416,7 +1377,7 @@ is_auth(ARG, Req_dir,H,[{Auth_dir, {yes, _} -> maybe_auth_log({ok, User}, ARG), true; - {no, Rsn} -> + {no, _Rsn} -> maybe_auth_log({401, User, Password}, ARG), {false, Realm} end @@ -1795,7 +1756,7 @@ do_yaws(CliSock, ARG, UT, N) -> Es == 0 -> deliver_dyn_file(CliSock, Spec, ARG, UT, N); Other -> - del_old_files(Other), + del_old_files(get(gc),Other), {ok, [{errors, Errs}| Spec]} = yaws_compile:compile_file(UT#urltype.fullpath), ?Debug("Spec for file ~s is:~n~p~n",[UT#urltype.fullpath, Spec]), @@ -1804,12 +1765,12 @@ do_yaws(CliSock, ARG, UT, N) -> end. -del_old_files([]) -> +del_old_files(_, []) -> ok; -del_old_files([{_FileAtom, spec, _Mtime1, Spec, _}]) -> +del_old_files(GC, [{_FileAtom, spec, _Mtime1, Spec, _}]) -> foreach( fun({mod, _, _, _, Mod, _Func}) -> - F=filename:join([yaws:tmp_dir(), "yaws", + F=filename:join([GC#gconf.tmpdir, "yaws", yaws:to_list(Mod) ++ ".erl"]), code:purge(Mod), code:purge(Mod), @@ -1864,9 +1825,6 @@ get_client_data_all(CliSock, Bs, SSlBool) -> exit(normal) end. - - - %% Return values: %% continue, done, {page, Page} @@ -2103,8 +2061,6 @@ end_streaming({Z, Priv}, CliSock) -> done_or_continue(). - - %% what about trailers ?? skip_data(List, Fd, Sz) when list(List) -> @@ -2191,7 +2147,7 @@ handle_out_reply({yssi, Yfile}, LineNo, YawsFile, UT, [ARG]) -> Es == 0 -> deliver_dyn_file(CliSock, Spec ++ [yssi], ARG, UT2, N); Other -> - del_old_files(Other), + del_old_files(get(gc), Other), {ok, [{errors, Errs}| Spec]} = yaws_compile:compile_file(UT2#urltype.fullpath), ?Debug("Spec for file ~s is:~n~p~n", @@ -2651,20 +2607,16 @@ get_more_post_data(PPS, ARG) -> case get_client_data(ARG#arg.clisock, N, is_ssl(SC#sconf.ssl)) of Bin when binary(Bin) -> -% io:format("Got ~p\n", [size(Bin)]), {partial, Bin}; Else -> -% io:format("Got error ~p\n", [Else]), {error, Else} end; true -> case get_client_data(ARG#arg.clisock, Len - PPS, is_ssl(SC#sconf.ssl)) of Bin when binary(Bin) -> -% io:format("Got tail ~p\n", [size(Bin)]), Bin; Else -> -% io:format("Got tail error ~p\n", [Else]), {error, Else} end end. diff --git a/src/yaws_session_server.erl b/src/yaws_session_server.erl index 4b4f567b3..64201612d 100644 --- a/src/yaws_session_server.erl +++ b/src/yaws_session_server.erl @@ -158,7 +158,7 @@ handle_call(stop, _From, State) -> -report_timedout_sess(S) -> +report_timedout_sess(_S) -> %%error_logger:info_msg("Session timedout: ~p ", [S#ysession.opaque]). silence. diff --git a/src/yaws_ssl.erl b/src/yaws_ssl.erl deleted file mode 100644 index 540e06204..000000000 --- a/src/yaws_ssl.erl +++ /dev/null @@ -1,249 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% File : yaws_ssl.erl -%%% Author : Claes Wikstrom -%%% Purpose : -%%% Created : 24 May 2002 by Claes Wikstrom -%%%---------------------------------------------------------------------- - --module(yaws_ssl). --author('klacke@hyber.org'). - -%-export([ssl_get_headers/1, get_chunked_client_data/1]). - -%% module isn't used any more -%% replaced by builtin support for http in OTP ssl module - --include("../include/yaws.hrl"). --include("../include/yaws_api.hrl"). --include("yaws_debug.hrl"). - --include_lib("kernel/include/file.hrl"). - - -%% Boring code, we need to parse HTTP here since -%% the standard ssl mode in erlang doesn't have tonys -%% funcky http mode parsing .... and I dont have the -%% energy to add it there :-( - - -%% FIXME: Stupid code... -%% -%% To be more exact: Gets data until "\r\n\r\n" is received, but at -%% most Num bytes. Returns data as a list. -%% -%% Should be replaced by something cleaner (and faster), but at least -%% it works for now (as long as the header is not longer than Num -%% bytes, that is). -%% -%% cschultz - - -contains_rnrn([]) -> - false; -contains_rnrn("\r\n\r\n" ++ _) -> - true; -contains_rnrn([X|XS]) -> - contains_rnrn(XS). - - -recv(CliSock, Num) -> - recv(CliSock, Num, []). - -recv(CliSock, 0, D) -> {ok, D}; -recv(CliSock, Num, D) -> - case yaws:cli_recv(CliSock, Num, ssl) of - {ok, Data} -> - ?Debug("GOT chunk of size ~p.~n", [size(Data)]), - D2 = D ++ binary_to_list(Data), - case contains_rnrn(D2) of - true -> {ok, D2}; - false -> - recv(CliSock, Num - size(Data), D2) - end; - {error, closed} -> - ?Debug("No more chunk to get.~n", []), - {ok, D}; - E -> E - end. - -ssl_get_headers(CliSock) -> - ssl_get_headers(CliSock,[]). - -ssl_get_headers(CliSock, Prev) -> - case recv(CliSock, 2048) of - {ok, []} -> - closed; - {ok, Data0} -> - Data = Prev ++ Data0, - ?Debug("GOT ssl data ~p~n", [Data]), - {R, Trail} = get_req(Data), - ?Debug("Parsed request ~p~n", [R]), - case R of - bad_request -> - {#http_request{method=bad_request, version={0,9}}, - #headers{}, - % Returning <<>> here - % is wrong if we got - % data after - % "\r\n\r\n". - <<>>}; - _ -> - case get_headers(CliSock, #headers{}, Trail) of - need_more -> - ssl_get_headers(CliSock, Data); - {H,Trail2} -> - {R, H, list_to_binary(Trail2)} - end - end; - _Err -> - ?Debug("cli recv ret ~p~n", [_Err]), - exit(normal) - end. - -get_req("\r\n\r\n" ++ _) -> - bad_request; -get_req("\r\n" ++ Data) -> - get_req(Data); -get_req(Data) -> - {FirstLine, Trail} = lists:splitwith(fun not_eol/1, Data), - R = parse_req(FirstLine), - {R, Trail}. - - -not_eol($\r)-> - false; -not_eol($\n) -> - false; -not_eol(_) -> - true. - - -get_word(Line)-> - {Word, T} = lists:splitwith(fun(X)-> X /= $\ end, Line), - {Word, lists:dropwhile(fun(X) -> X == $\ end, T)}. - - -parse_req(Line) -> - {MethodStr, L1} = get_word(Line), - ?Debug("Method: ~p~n", [MethodStr]), - case L1 of - [] -> - bad_request; - _ -> - {URI, L2} = get_word(L1), - {VersionStr, L3} = get_word(L2), - ?Debug("URI: ~p~nVersion: ~p~nL3: ~p~n", - [URI, VersionStr, L3]), - case L3 of - [] -> - R = #http_request{method=case MethodStr of - "GET" -> 'GET'; - "POST" -> 'POST'; - "HEAD" -> 'HEAD'; - "OPTIONS" -> 'OPTIONS'; - "TRACE" -> 'TRACE'; - "PUT" -> 'PUT'; - "DELETE" -> 'DELETE'; - S -> S - end, - path = case URI of - "*" -> - % Is this correct? - "*"; - P -> - % FIXME: Handle - % absolute URIs - {abs_path, P} - end - }, - case VersionStr of - [] -> R#http_request{version={0,9}}; - "HTTP/1.0" -> - R#http_request{version={1,0}}; - "HTTP/1.1" -> - R#http_request{version={1,1}}; - _ -> - bad_request - end; - _ -> - bad_request - end - end. - - - - -get_headers(CliSock, H, Tail) -> - case yaws_api:get_line(Tail) of - {line, Line, Tail2} -> - get_headers(CliSock, parse_line(Line, H), Tail2); - {lastline, Line, Tail2} -> - {parse_line(Line, H), Tail2}; - need_more -> - need_more - end. - - -parse_line("Connection:" ++ Con, H) -> - H#headers{connection = space_strip(Con)}; -parse_line("Host:" ++ Con, H) -> - H#headers{host = space_strip(Con)}; -parse_line("Accept:" ++ Con, H) -> - H#headers{accept = space_strip(Con)}; -parse_line("If-Modified-Since:" ++ Con, H) -> - H#headers{accept = space_strip(Con)}; -parse_line("If-Match:" ++ Con, H) -> - H#headers{if_match = space_strip(Con)}; -parse_line("If-None-Match:" ++ Con, H) -> - H#headers{if_none_match = space_strip(Con)}; -parse_line("If-Range:" ++ Con, H) -> - H#headers{if_range = space_strip(Con)}; -parse_line("If-Unmodified-Since:" ++ Con, H) -> - H#headers{if_unmodified_since = space_strip(Con)}; -parse_line("Range:" ++ Con, H) -> - H#headers{range = space_strip(Con)}; -parse_line("User-Agent:" ++ Con, H) -> - H#headers{user_agent = space_strip(Con)}; -parse_line("Accept-Ranges:" ++ Con, H) -> - H#headers{accept_ranges = space_strip(Con)}; -parse_line("Authorization:" ++ Con, H) -> - A = yaws:parse_auth(space_strip(Con)), - H#headers{authorization = A}; -parse_line("Keep-Alive:" ++ Con, H) -> - H#headers{keep_alive = space_strip(Con)}; -parse_line("Referer:" ++ Con, H) -> - H#headers{referer = space_strip(Con)}; -parse_line("Content-type:"++Con, H) -> - H#headers{content_type = space_strip(Con)}; -parse_line("Content-Type:"++Con, H) -> - H#headers{content_type = space_strip(Con)}; -parse_line("Content-Length:"++Con, H) -> - H#headers{content_length = space_strip(Con)}; -parse_line("Content-length:"++Con, H) -> - H#headers{content_length = space_strip(Con)}; -parse_line("Cookie:"++Con, H) -> - H#headers{cookie = [space_strip(Con)|H#headers.cookie]}; -parse_line("Accept-Encoding:"++Con, H) -> - Other = H#headers.other, - H#headers{other=[{http_header, undefined, 'Accept-Encoding', - undefined, space_strip(Con)} - |Other]}; -parse_line(S, H) -> - case lists:splitwith(fun(C)->C /= $: end, S) of - {Name, [$:|Val]} -> - Other = H#headers.other, - H#headers{other=[{http_header, undefined, Name, undefined, - space_strip(Val)} - |Other]}; - _ -> H - end. - - - -space_strip(S) -> - yaws:strip_spaces(S, both). - - -get_chunked_client_data(Sock) -> - exit(nyi). - diff --git a/src/yaws_sup.erl b/src/yaws_sup.erl index b8109d96e..65c97643c 100644 --- a/src/yaws_sup.erl +++ b/src/yaws_sup.erl @@ -101,9 +101,16 @@ get_app_args() -> {ok, Emb} -> Emb end, + Id = case application:get_env(yaws, id) of + undefined -> + undefined; + {ok, Id0} -> + Id0 + end, + #env{debug = Debug, trace = Trace, traceoutput = TraceOutput, conf = Conf, - runmod = RunMod, embedded = Embedded}. + runmod = RunMod, embedded = Embedded, id = Id}. %%---------------------------------------------------------------------- %%----------------------------------------------------------------------