Skip to content
Browse files

Initial commit.

  • Loading branch information...
0 parents commit d7ebc3c68c6e7d825ce3b1d62051bc032a1deaf8 @KirinDave KirinDave committed Jul 10, 2007
Showing with 38,497 additions and 0 deletions.
  1. +5,445 −0 ChangeLog
  2. +27 −0 LICENSE
  3. +55 −0 Makefile
  4. +82 −0 README
  5. +18 −0 applications/chat/Makefile
  6. BIN applications/chat/chat/angel.png
  7. BIN applications/chat/chat/bigsmile.png
  8. BIN applications/chat/chat/burp.png
  9. +222 −0 applications/chat/chat/chat.js
  10. +106 −0 applications/chat/chat/chat.yaws
  11. +4 −0 applications/chat/chat/chat_read.yaws
  12. +10 −0 applications/chat/chat/chat_write.yaws
  13. BIN applications/chat/chat/cool.png
  14. BIN applications/chat/chat/crossedlips.png
  15. BIN applications/chat/chat/cry.png
  16. BIN applications/chat/chat/embarrassed.png
  17. BIN applications/chat/chat/farted.png
  18. +4 −0 applications/chat/chat/index.yaws
  19. BIN applications/chat/chat/kiss.png
  20. +24 −0 applications/chat/chat/login.yaws
  21. BIN applications/chat/chat/moneymouth.png
  22. BIN applications/chat/chat/oneeye.png
  23. BIN applications/chat/chat/sad.png
  24. BIN applications/chat/chat/scream.png
  25. BIN applications/chat/chat/smile.png
  26. BIN applications/chat/chat/think.png
  27. BIN applications/chat/chat/tongue.png
  28. BIN applications/chat/chat/wink.png
  29. BIN applications/chat/chat/yell.png
  30. +53 −0 applications/chat/include.mk
  31. +46 −0 applications/chat/src/Makefile
  32. +384 −0 applications/chat/src/chat.erl
  33. +18 −0 applications/mail/Makefile
  34. +60 −0 applications/mail/README
  35. +21 −0 applications/mail/TODO
  36. 0 applications/mail/ebin/.empty
  37. +53 −0 applications/mail/include.mk
  38. +11 −0 applications/mail/mail/compose.yaws
  39. BIN applications/mail/mail/down.gif
  40. +12 −0 applications/mail/mail/headers.yaws
  41. +4 −0 applications/mail/mail/index.yaws
  42. +14 −0 applications/mail/mail/listop.yaws
  43. +20 −0 applications/mail/mail/login.yaws
  44. +11 −0 applications/mail/mail/logout.yaws
  45. +120 −0 applications/mail/mail/mail.js
  46. +22 −0 applications/mail/mail/mail.yaws
  47. +45 −0 applications/mail/mail/reply.yaws
  48. +11 −0 applications/mail/mail/send.yaws
  49. +13 −0 applications/mail/mail/showmail.yaws
  50. BIN applications/mail/mail/spacer.gif
  51. BIN applications/mail/mail/tab-bg_active.gif
  52. BIN applications/mail/mail/tab-bg_inactive.gif
  53. BIN applications/mail/mail/tab-hr.gif
  54. BIN applications/mail/mail/tab-left_active.gif
  55. BIN applications/mail/mail/tab-left_inactive.gif
  56. BIN applications/mail/mail/tab-right_active.gif
  57. BIN applications/mail/mail/tab-right_inactive.gif
  58. BIN applications/mail/mail/tool-delete.gif
  59. BIN applications/mail/mail/tool-div.gif
  60. BIN applications/mail/mail/tool-newmail.gif
  61. BIN applications/mail/mail/tool-send.gif
  62. BIN applications/mail/mail/up.gif
  63. BIN applications/mail/mail/view-mark.gif
  64. +50 −0 applications/mail/src/Makefile
  65. +35 −0 applications/mail/src/attachment.erl
  66. +20 −0 applications/mail/src/defs.hrl
  67. +2,891 −0 applications/mail/src/mail.erl
  68. +321 −0 applications/mail/src/mail_html.erl
  69. +9 −0 applications/mail/src/mail_vsn.template
  70. +304 −0 applications/mail/src/smtp.erl
  71. +24 −0 applications/mail/src/yaws-webmail.conf
  72. +1 −0 applications/mail/vsn.mk
  73. +42 −0 applications/wiki/Makefile
  74. +69 −0 applications/wiki/README
  75. 0 applications/wiki/ebin/.keepme
  76. +53 −0 applications/wiki/include.mk
  77. +35 −0 applications/wiki/scripts/Makefile
  78. +17 −0 applications/wiki/scripts/addFile.src
  79. +17 −0 applications/wiki/scripts/getPassword.src
  80. +17 −0 applications/wiki/scripts/importFiles.src
  81. +72 −0 applications/wiki/scripts/updateWiki.src
  82. +58 −0 applications/wiki/src/Makefile
  83. +67 −0 applications/wiki/src/utils.erl
  84. +2,509 −0 applications/wiki/src/wiki.erl
  85. +92 −0 applications/wiki/src/wiki_diff.erl
  86. +574 −0 applications/wiki/src/wiki_format_txt.erl
  87. +26 −0 applications/wiki/src/wiki_plugin_backlinks.erl
  88. +12 −0 applications/wiki/src/wiki_plugin_dummy.erl
  89. +46 −0 applications/wiki/src/wiki_plugin_menu.erl
  90. +108 −0 applications/wiki/src/wiki_split.erl
  91. +152 −0 applications/wiki/src/wiki_templates.erl
  92. +122 −0 applications/wiki/src/wiki_to_html.erl
  93. +94 −0 applications/wiki/src/wiki_utils.erl
  94. +9 −0 applications/wiki/src/wiki_vsn.template
  95. +104 −0 applications/wiki/src/wiki_yaws.erl
  96. +2 −0 applications/wiki/start.sh
  97. +1 −0 applications/wiki/vsn.mk
  98. +9 −0 applications/wiki/wiki.conf
  99. BIN applications/wiki/wiki/ALockedPage.wob
  100. BIN applications/wiki/wiki/AnUnlockedPage.wob
  101. BIN applications/wiki/wiki/Examples.wob
  102. BIN applications/wiki/wiki/FormattingWikiPages.wob
  103. BIN applications/wiki/wiki/WikiPreferences.files/allpages.gif
  104. BIN applications/wiki/wiki/WikiPreferences.files/back.gif
  105. +30 −0 applications/wiki/wiki/WikiPreferences.files/custom.css
  106. BIN applications/wiki/wiki/WikiPreferences.files/edit.gif
  107. BIN applications/wiki/wiki/WikiPreferences.files/editfiles.gif
  108. BIN applications/wiki/wiki/WikiPreferences.files/editme.gif
  109. BIN applications/wiki/wiki/WikiPreferences.files/forward.gif
  110. BIN applications/wiki/wiki/WikiPreferences.files/ftp.png
  111. BIN applications/wiki/wiki/WikiPreferences.files/history.gif
  112. BIN applications/wiki/wiki/WikiPreferences.files/home.gif
  113. BIN applications/wiki/wiki/WikiPreferences.files/http.png
  114. BIN applications/wiki/wiki/WikiPreferences.files/https.png
  115. BIN applications/wiki/wiki/WikiPreferences.files/icon.gif
  116. BIN applications/wiki/wiki/WikiPreferences.files/index.gif
  117. BIN applications/wiki/wiki/WikiPreferences.files/interwiki.png
  118. BIN applications/wiki/wiki/WikiPreferences.files/kamera.gif
  119. BIN applications/wiki/wiki/WikiPreferences.files/lastedited.gif
  120. BIN applications/wiki/wiki/WikiPreferences.files/mailto.png
  121. +47 −0 applications/wiki/wiki/WikiPreferences.files/template.html
  122. +129 −0 applications/wiki/wiki/WikiPreferences.files/template2.html
  123. +37 −0 applications/wiki/wiki/WikiPreferences.files/template_info.html
  124. +45 −0 applications/wiki/wiki/WikiPreferences.files/template_info2.html
  125. BIN applications/wiki/wiki/WikiPreferences.files/url.png
  126. BIN applications/wiki/wiki/WikiPreferences.files/zombies.gif
  127. BIN applications/wiki/wiki/WikiPreferences.wob
  128. +14 −0 applications/wiki/wiki/addFile.yaws
  129. +10 −0 applications/wiki/wiki/allPages.yaws
  130. +8 −0 applications/wiki/wiki/allRefsToMe.yaws
  131. +10 −0 applications/wiki/wiki/changePassword.yaws
  132. +10 −0 applications/wiki/wiki/changePassword2.yaws
  133. +11 −0 applications/wiki/wiki/copyFiles.yaws
  134. +10 −0 applications/wiki/wiki/createNewPage.yaws
  135. +11 −0 applications/wiki/wiki/deleteFiles.yaws
  136. +10 −0 applications/wiki/wiki/editFiles.yaws
  137. +10 −0 applications/wiki/wiki/editPage.yaws
  138. +10 −0 applications/wiki/wiki/editTag.yaws
  139. +10 −0 applications/wiki/wiki/finalDeletePage.yaws
  140. +8 −0 applications/wiki/wiki/getMidSize.yaws
  141. +8 −0 applications/wiki/wiki/getThumb.yaws
  142. +10 −0 applications/wiki/wiki/importFiles.yaws
  143. +9 −0 applications/wiki/wiki/index.yaws
  144. +10 −0 applications/wiki/wiki/lastEdited.yaws
  145. +10 −0 applications/wiki/wiki/previewNewPage.yaws
  146. +10 −0 applications/wiki/wiki/previewPage.yaws
  147. +10 −0 applications/wiki/wiki/previewTagged.yaws
  148. +11 −0 applications/wiki/wiki/putPassword.yaws
  149. +19 −0 applications/wiki/wiki/searchPage.yaws
  150. +10 −0 applications/wiki/wiki/sendMeThePassword.yaws
  151. +10 −0 applications/wiki/wiki/showHistory.yaws
  152. +10 −0 applications/wiki/wiki/showOldPage.yaws
  153. +11 −0 applications/wiki/wiki/showPage.yaws
  154. +11 −0 applications/wiki/wiki/slideShow.yaws
  155. +10 −0 applications/wiki/wiki/storeFiles.yaws
  156. +10 −0 applications/wiki/wiki/storeNewPage.yaws
  157. +8 −0 applications/wiki/wiki/storePage.yaws
  158. +10 −0 applications/wiki/wiki/storeTagged.yaws
  159. +11 −0 applications/wiki/wiki/thumbIndex.yaws
  160. +10 −0 applications/wiki/wiki/wikiZombies.yaws
  161. +31 −0 applications/yapp/Makefile
  162. +32 −0 applications/yapp/README
  163. 0 applications/yapp/doc/.empty
  164. 0 applications/yapp/ebin/.empty
  165. +3 −0 applications/yapp/priv/docroot/END.inc
  166. +36 −0 applications/yapp/priv/docroot/HEAD.inc
  167. +37 −0 applications/yapp/priv/docroot/add.yaws
  168. +48 −0 applications/yapp/priv/docroot/add_post.yaws
  169. +7 −0 applications/yapp/priv/docroot/index.yaws
  170. +38 −0 applications/yapp/priv/docroot/list.yaws
  171. +45 −0 applications/yapp/priv/docroot/remove.yaws
  172. +42 −0 applications/yapp/priv/docroot/remove_post.yaws
  173. +25 −0 applications/yapp/src/Makefile
  174. +8 −0 applications/yapp/src/yapp.app.src
  175. +384 −0 applications/yapp/src/yapp.erl
  176. +47 −0 applications/yapp/src/yapp_app.erl
  177. +103 −0 applications/yapp/src/yapp_event_handler.erl
  178. +75 −0 applications/yapp/src/yapp_handler.erl
  179. +223 −0 applications/yapp/src/yapp_mnesia_server.erl
  180. +37 −0 applications/yapp/src/yapp_registry.erl
  181. +141 −0 applications/yapp/src/yapp_server.erl
  182. +55 −0 applications/yapp/src/yapp_sup.erl
  183. +1 −0 applications/yapp/vsn.mk
  184. 0 bin/.foobar
  185. +52 −0 c_src/Makefile
  186. +407 −0 c_src/epam.c
  187. +137 −0 c_src/setuid_drv.c
  188. +1,410 −0 config.guess
  189. +1,508 −0 config.sub
  190. +4,761 −0 configure
  191. +228 −0 configure.in
  192. +107 −0 debian/rules
  193. +34 −0 doc/Makefile
  194. +120 −0 doc/README.rss
  195. +4,226 −0 doc/a.eps
  196. +4,226 −0 doc/b.eps
  197. +387 −0 doc/layout.eps
  198. BIN doc/yaws.pdf
  199. +2,099 −0 doc/yaws.tex
  200. +266 −0 doc/yaws_head.eps
  201. 0 ebin/.empty
  202. 0 examples/ebin/.empty
  203. 0 examples/include/.empty
  204. +97 −0 include.mk.in
  205. +28 −0 include/erlsom.hrl
  206. +48 −0 include/soap.hrl
  207. +271 −0 include/yaws.hrl
  208. +94 −0 include/yaws_api.hrl
  209. +11 −0 include/yaws_dav.hrl
  210. +250 −0 install-sh
  211. +11 −0 man/Makefile
  212. +165 −0 man/yaws.1
  213. +631 −0 man/yaws.conf.5
Sorry, we could not display the entire diff because too many files (498) changed.
5,445 ChangeLog
5,445 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
27 LICENSE
@@ -0,0 +1,27 @@
+
+Copyright (c) 2006, Claes Wikstrom, klacke@hyber.org
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of "Yaws" nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
55 Makefile
@@ -0,0 +1,55 @@
+
+SUBDIRS = c_src src man www/shopingcart www/code doc scripts
+include ./include.mk
+
+
+all debug clean:
+ @set -e ; \
+ for d in $(SUBDIRS) ; do \
+ if [ -f $$d/Makefile ]; then ( cd $$d && $(MAKE) $@ ) || exit 1 ; fi ; \
+ done
+
+
+install: all
+ set -e ; \
+ for d in $(SUBDIRS) ; do \
+ if [ -f $$d/Makefile ]; then ( cd $$d && $(MAKE) $@ ) || exit 1 ; fi ; \
+ done
+ @echo "-------------------------------"
+ @echo
+ @echo "** etc files went into ${ETCDIR}"
+ @echo "** executables went into ${prefix}/bin"
+ @echo "** library files went into ${prefix}/lib/yaws"
+ @echo "** var files went into ${VARDIR}"
+ @echo "** default docroot went into ${VARDIR}/yaws/www"
+ @echo
+ @echo "--------------------------------"
+
+
+docs:
+ ( cd doc && $(MAKE) docs )
+
+conf_clean:
+ -rm include.mk config.cache config.status config.log 2> /dev/null
+
+local_install: all
+ (cd scripts && $(MAKE) local_install)
+
+
+touch:
+ find . -name '*' -print | xargs touch -m
+ find . -name '*.erl' -print | xargs touch -m
+
+
+
+
+foo:
+ @echo "-------------------------------"
+ @echo
+ @echo "** etc files will go into ${ETCDIR}"
+ @echo "** executables will go into ${prefix}/bin"
+ @echo "** library file will go into ${prefix}/lib/yaws"
+ @echo "** var files will go into ${VARDIR}"
+ @echo
+ @echo "--------------------------------"
+
82 README
@@ -0,0 +1,82 @@
+
+This is yaws, a webserver for dynamic content written in Erlang.
+
+
+To build and install
+
+
+1. Get and install an erlang system (http://www.erlang.org)
+
+2. ./configure --prefix=/usr/local
+ This will install everything under /usr/local including var files
+ in /usr/local/var/run/yaws and etc files in
+ /usr/local/etc/yaws.*
+
+ A plain ./configure will install executables under
+ /usr/local/bin and libs in /usr/local/lib/yaws etc and
+ var files will end up under /usr/local/etc and /usr/local/var
+
+
+Note: We can also change the target directory for etc and var
+ directories by using:
+
+ --localstatedir=DIR for files that should go in /var
+ --sysconfdir=DIR for files that should go in /etc
+ --disable-pam If we for some reason do not want pam support
+ --with-extrainclude=DIR Will add DIR to the include path
+ May be useful if e.g. pam is installed
+ somewhere where its usually not found
+ --with-defaultcharset=String Will set the default charset used
+ in generated page headers. Usually never needed.
+
+This way you can precisely control where you install Yaws (This is
+usefull for computers where you do not have right access to the
+standard systemdirs).
+
+For example:
+./configure --prefix=/home/install/yaws --localstatedir=/home/install/yaws/var --sysconfdir=/home/install/etc
+
+
+2b. Note to packagers (rpm, deb ...) All install targets support the
+ DESTDIR variable.
+ Thus, if we do ./configure --prefix=/usr; make
+ we can subsequently do:
+ DESTDIR=/foo/bar make install
+ All yaws files will be installed under DESTDIR, but all
+ code will assume yaws should be installed under /usr
+
+
+3. make
+ This will build the system
+
+ make docs
+ (Optionnal) You can issue this command if you want to build Yaws
+ documentation.
+
+ make local_install
+ and perform something we call a
+ local install. It will create an executable script in the $HOMe/bin
+ directory and a config file in $HOME/yaws.conf. This is for developers
+ only
+
+4. To test the build, Start as bin/yaws -i
+ This will start a webserver at http://0.0.0.0:8000
+ Terminate through ^C or > init:stop()
+
+5. as root make install
+
+6. as root Start as /usr/local/bin/yaws -i
+ (this starts an interactive system)
+
+7. This will create a webserver at http://${host} and one at https://${host}
+
+8. as root Edit /etc/yaws.conf
+
+9. Create content in /var/yaws
+
+10a. Start as /usr/local/bin/yaws --daemon --heart
+ This will start a daemon (--daemon) which will be autorestarted when/if
+ it crashes or hangs (--heart)
+
+10b. Or start interactive system as /usr/local/bin/yaws -i
+
18 applications/chat/Makefile
@@ -0,0 +1,18 @@
+SUBDIRS = src
+include ./include.mk
+
+
+all debug clean install:
+ @set -e ; \
+ for d in $(SUBDIRS) ; do \
+ if [ -f $$d/Makefile ]; then ( cd $$d && $(MAKE) $@ ) || exit 1 ; fi ; \
+ done
+
+
+touch:
+ find . -name '*' -print | xargs touch -m
+ find . -name '*.erl' -print | xargs touch -m
+
+
+
+
BIN applications/chat/chat/angel.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/bigsmile.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/burp.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
222 applications/chat/chat/chat.js
@@ -0,0 +1,222 @@
+// -*- Fundamental -*-
+// File: chat.js (/var/www/chat.js)
+// Author: Johan Bevemyr
+// Created: Thu Nov 18 18:25:53 2004
+// Purpose:
+
+
+// Uncomment this to get debug printouts in a separate window.
+
+
+
+/*
+
+var _console=null;
+var _console_txt = null;
+var _cnt = 0;
+
+function debug(msg)
+{
+ var re = new RegExp("<","gi");
+ msg = msg.replace(re, "&lt;")
+
+ if ((_console==null) || (_console.closed)) {
+ _console = window.open("","console","width=600,height=300,resizable=yes,scrollbars=yes");
+ _console.document.open("text/plain");
+ _console.document.writeln("<pre>");
+ }
+ _cnt++;
+ _console.document.write(_cnt + ": ");
+ _console.document.writeln(msg);
+}
+
+*/
+
+
+function debug(msg) {
+}
+
+
+function sendmsg() {
+ var message = document.getElementById("msg").value;
+
+ debug("sendmsg: sending "+message);
+ xml_sender.abort();
+ xml_sender.open("POST", "chat_write.yaws", false);
+ message = expandSmilies(message);
+ xml_sender.send(message);
+ debug("sendmsg: sent "+message);
+ document.getElementById("msg").value = "";
+}
+
+
+var smilies = new Array();
+smilies[":-)~"] = "tongue.png";
+smilies["O :-)"] = "angel.png";
+smilies[":-)"] = "smile.png";
+smilies[":-("] = "sad.png";
+smilies[":-D"] = "bigsmile.png";
+smilies[":-?"] = "burp.png";
+smilies["8-)"] = "cool.png";
+smilies[":-X"] = "crossedlips.png";
+smilies[":,-("] = "cry.png";
+smilies[":-6"] = "farted.png";
+smilies[":*"] = "kiss.png";
+smilies[":-$"] = "moneymouth.png";
+smilies["0-)"] = "oneeye.png";
+smilies[":-@"] = "scream.png";
+smilies[":-/"] = "think.png";
+smilies[",-)"] = "wink.png";
+smilies[":O"] = "yell.png";
+
+function smilies_toolbar() {
+ var tool="";
+ var smile;
+
+ for (smile in smilies) {
+ tool += ("<img src='"+smilies[smile]+"' onmousedown='return addText(\""+
+ smile+"\")'></img> ");
+ }
+
+ return tool;
+}
+
+function expandSmilies(message) {
+ var smile;
+
+ for (smile in smilies) {
+ var i = 0;
+ i = message.indexOf(smile,i);
+ while(i >= 0) {
+ message = message.substring(0,i)+"<img src='"+smilies[smile]+"'>"+
+ message.substring(i+smile.length);
+ i = message.indexOf(smile,i);
+ }
+ }
+
+ return message;
+}
+
+
+function create_xmlhttp() {
+ var xmlhttp;
+
+ try {
+ xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (e) {
+ try {
+ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (E) {
+ xmlhttp = false;
+ }
+ }
+
+ if (!xmlhttp && typeof XMLHttpRequest!='undefined')
+ xmlhttp = new XMLHttpRequest();
+
+ return xmlhttp;
+}
+
+var xml_sender = create_xmlhttp();
+var xml_reader = create_xmlhttp();
+
+var intialized = false;
+
+function reader_init0() {
+ initialized = false;
+ reader_init();
+}
+
+
+function reader_init() {
+ var h = function() {
+ debug("reader_init(): got " + xml_reader.readyState);
+
+ if (xml_reader.readyState == 4) {
+ var msgs = document.getElementById("msgs");
+ var memb = document.getElementById("members");
+ var reply = xml_reader.responseText;
+
+ debug("reader_init(): something");
+
+ if (reply.substring(0,2) == "ok") {
+ var msg = reply.substring(2);
+ var messages = "";
+ var members = "";
+
+ while(msg.length > 0) {
+ var op = msg.substring(0,1);
+ var i = msg.indexOf(":");
+ var len = parseInt(msg.substring(1,i));
+ var body = msg.substring(i+1, i+len+1);
+
+ msg = msg.substring(i+len+1);
+
+ debug("msg = " + msg);
+ debug("i = " + i);
+ debug("len = " + len);
+ debug("body = " + body);
+ debug("op = " + op);
+
+ switch(op) {
+ case "m":
+ messages += body.replace(/\n/g,"<br>")+"<br>";
+ break;
+ case "e":
+ members = body;
+ break;
+ default:
+ }
+ }
+
+ if (messages.length > 0)
+ msgs.innerHTML = msgs.innerHTML + messages;
+
+ if (members.length > 0)
+ memb.innerHTML = members;
+
+ move_to_end(msgs);
+ setTimeout("reader_init()", 0);
+ }
+ else if (reply.substring(0,7) == "timeout") {
+ setTimeout("reader_init()", 0);
+ }
+ else {
+ // alert("Chat server got unsupported reply.'" + reply+"'");
+ }
+ }
+ }
+
+ debug("reader_init(): waiting");
+
+ if (initialized) {
+ xml_reader.open("GET", "chat_read.yaws", true);
+ } else {
+ xml_reader.open("GET", "chat_read.yaws?init=true", true);
+ initialized = true;
+ }
+
+ if (window.XMLHttpRequest) {
+ xml_reader.onload=h;
+ }
+ else {
+ xml_reader.onreadystatechange=h;
+ }
+
+ xml_reader.send(null);
+ debug("reader_init: sent read request");
+}
+
+function move_to_end(element) {
+ try {
+ element.scrollTop = element.scrollHeight;
+ } catch(E) {
+ }
+}
+
+function stop_all() {
+ try {
+ xml_reader.abort();
+ } catch (E) {
+ }
+}
106 applications/chat/chat/chat.yaws
@@ -0,0 +1,106 @@
+<html>
+<erl>
+out(A) ->
+ case chat:check_session(A) of
+ {ok, Session} ->
+ chat:dynamic_headers();
+ Error ->
+ Error++[break]
+ end.
+</erl>
+
+<script>
+
+function handleEnter(event) {
+ if (event == null)
+ event = window.event;
+
+ var keyCode = event.keyCode ? event.keyCode : event.which ?
+ event.which : event.charCode;
+
+ if (keyCode == 13) {
+ sendmsg();
+ return false;
+ }
+}
+
+function addSmiley(ref) {
+ var text = document.getElementById("msg");
+
+ text.value = text.value+"<img src='"+ref+"'>";
+
+ text.focus();
+
+ return false;
+}
+
+function addText(ref) {
+ var text = document.getElementById("msg");
+
+ text.value = text.value+ref;
+
+ text.focus();
+
+ return false;
+}
+
+</script>
+
+<style>
+
+body {
+ font: 10px/15px Verdana, Lucida, Arial, sans-serif;
+}
+
+h1 {
+ font: 15px/20px Verdana, Lucida, Arial, sans-serif;
+ font-weight: bold;
+}
+
+#msgs {
+ border:1px solid #ccc;
+ height: 25em;
+ width: 500px;
+ background-color: #f5f5ff;
+ overflow: auto;
+ float: left;
+ padding: 2px;
+}
+
+#members {
+ border:1px solid #ccc;
+ height: 25em;
+ width: 100px;
+ background-color: #f5f5ff;
+ overflow: auto;
+ margin: 2px;
+ padding: 2px;
+}
+
+#msg {
+ width: 614px;
+ clear: both;
+}
+
+</style>
+
+<script src="chat.js"></script>
+
+<body onload="setTimeout('reader_init0()', 0);" onunload="stop_all()">
+
+
+<H1> Welcome to the chat room </h1>
+
+<div id="msgs"></div>
+<div id="members"></div>
+
+<textarea id="msg" rows="3" value=""
+ onKeyPress="return handleEnter(event)">
+</textarea>
+<br>
+
+<script>
+document.write(smilies_toolbar());
+</script>
+
+</html>
4 applications/chat/chat/chat_read.yaws
@@ -0,0 +1,4 @@
+<erl>
+out(A) ->
+ chat:chat_read(A).
+</erl>
10 applications/chat/chat/chat_write.yaws
@@ -0,0 +1,10 @@
+<erl>
+out(A) ->
+ case chat:check_session(A) of
+ Session ->
+ chat:chat_write(A);
+ Error ->
+ Error
+ end.
+
+</erl>
BIN applications/chat/chat/cool.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/crossedlips.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/cry.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/embarrassed.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/farted.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 applications/chat/chat/index.yaws
@@ -0,0 +1,4 @@
+<erl>
+out(A) ->
+ {redirect_local, {rel_path, "chat.yaws"}}.
+</erl>
BIN applications/chat/chat/kiss.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 applications/chat/chat/login.yaws
@@ -0,0 +1,24 @@
+<erl>
+
+out(A) ->
+ L = case (A#arg.req)#http_request.method of
+ 'GET' ->
+ yaws_api:parse_query(A);
+ 'POST' ->
+ yaws_api:parse_post(A)
+ end,
+ case {lists:keysearch("user", 1, L),
+ lists:keysearch("password", 1, L)} of
+ {{value, {_, User}}, {value, {_,Passwd}}} ->
+ case chat:login(User, Passwd) of
+ {ok, Cookie} ->
+ [yaws_api:setcookie("sessionid", Cookie),
+ {redirect_local, {rel_path,"chat.yaws"}}];
+ {error, Reason} ->
+ chat:display_login(A, Reason)
+ end;
+ _ ->
+ chat:display_login(A, "badly formated POST/GET")
+ end.
+
+</erl>
BIN applications/chat/chat/moneymouth.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/oneeye.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/sad.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/scream.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/smile.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/think.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/tongue.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/wink.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/chat/chat/yell.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 applications/chat/include.mk
@@ -0,0 +1,53 @@
+###-*-makefile-*- ; force emacs to enter makefile-mode
+
+
+# these the items can be edited
+
+INSTALLPREFIX=/var/yaws
+
+CHATINSTALLDIR=$(INSTALLPREFIX)/chat
+EBININSTALLDIR=$(INSTALLPREFIX)/ebin
+
+ERL=$(shell which erl)
+ERLC=$(shell which erlc)
+
+
+## don't edit below here
+
+EMULATOR=beam
+ifdef debug
+ ERLC_FLAGS+=-Ddebug
+endif
+
+ifdef trace
+ ERLC_FLAGS=+trace
+endif
+
+ifdef export_all
+ ERLC_FLAGS+=-Dexport_all
+endif
+
+
+INSTALL=install -c
+INSTALL_DATA=${INSTALL} -m 644
+
+
+# Hmm, don't know if you are supposed to like this better... ;-)
+APPSCRIPT = '$$vsn=shift; $$mods=""; while(@ARGV){ $$_=shift; s/^([A-Z].*)$$/\'\''$$1\'\''/; $$mods.=", " if $$mods; $$mods .= $$_; } while(<>) { s/%VSN%/$$vsn/; s/%MODULES%/$$mods/; print; }'
+
+# Targets
+
+../ebin/%.app: %.app.src ../vsn.mk Makefile
+ perl -e $(APPSCRIPT) "$(VSN)" $(MODULES) < $< > $@
+
+../ebin/%.appup: %.appup
+ cp $< $@
+
+../ebin/%.$(EMULATOR): %.erl
+ $(ERLC) -b $(EMULATOR) $(ERLC_FLAGS) -o ../ebin $<
+
+%.$(EMULATOR): %.erl
+ $(ERLC) -b $(EMULATOR) $(ERLC_FLAGS) $<
+
+
+
46 applications/chat/src/Makefile
@@ -0,0 +1,46 @@
+include ../include.mk
+
+ifeq ($(TYPE),debug)
+DEBUG_FLAGS = -Ddebug
+else
+DEBUG_FLAGS =
+endif
+
+#include ../vsn.mk
+#VSN=$(YAWS_VSN)
+MODULES=chat
+
+HDR_FILES=
+
+EBIN_FILES=$(MODULES:%=../ebin/%.$(EMULATOR))
+
+ERLC_FLAGS+=-W +debug_info $(DEBUG_FLAGS) -I../../../include -pa ../../chat
+
+#
+# Targets
+#
+
+all: $(EBIN_FILES)
+
+$(EBIN_FILES) : $(HDR_FILES)
+
+debug:
+ $(MAKE) TYPE=debug
+
+clean:
+ rm -f $(EBIN_FILES)
+
+install: all
+ install -d $(CHATINSTALLDIR)
+ install -d $(EBININSTALLDIR)
+ (cd ../ebin; find . -name '*' -print | xargs tar cf - ) | (cd $(EBININSTALLDIR); tar xf - )
+ (cd ../chat; find . -name '*' -print | xargs tar cf - ) | (cd $(CHATINSTALLDIR); tar xf - )
+
+
+
+tags:
+ erl -noshell -pa ../ebin -s chat_debug mktags
+
+xref:
+ erl -noshell -pa ../ebin -s chat_debug xref ../ebin
+
384 applications/chat/src/chat.erl
@@ -0,0 +1,384 @@
+% -*- Erlang -*-
+% File: chat.erl (chat.erl)
+% Author: Johan Bevemyr
+% Created: Thu Nov 18 21:27:41 2004
+% Purpose:
+
+-module('chat').
+-author('jb@son.bevemyr.com').
+
+-define(COLOR1, "#ffc197").
+-define(COLOR2, "#ff6600").
+-define(COLOR3, "#887da7").
+-define(COLOR4, "#afa2d3").
+-define(LOCATION, "test").
+
+%% There is a bug in the erlang inet driver which causes yaws
+%% to ignore requests after a POST. This bug is present in the
+%% now current release R10B-3. We have submitted a bugfix to
+%% erlbugs so it may be fixed in some future release. Until then...
+
+-define(ERL_BUG, true).
+
+-export([check_session/1, get_user/1, login/2, chat_server_init/0,
+ session_server/0,dynamic_headers/0, display_login/2]).
+
+-export([chat_read/1, chat_write/1]).
+
+-include("../../../include/yaws_api.hrl").
+
+-record(user, {last_read,
+ buffer=[],
+ user,
+ pid,
+ color,
+ cookie}).
+
+
+login(User, Password) ->
+ session_server(),
+ erlang:send(chat_server, {new_session, User, self()}),
+ receive
+ {session_manager, Cookie, Session} ->
+ chat_server ! {join_message, User},
+ {ok, Cookie};
+ _ ->
+ error
+ end.
+
+%% FIXME: way to simple session handling. The system will behave
+%% very badly if two users log in with the same user name!!!
+
+check_session(A) ->
+ H = A#arg.headers,
+ case yaws_api:find_cookie_val("sessionid", H#headers.cookie) of
+ [] ->
+ display_login(A, "not logged in");
+ CVal ->
+ case check_cookie(CVal) of
+ error ->
+ display_login(A, "not logged in");
+ Session ->
+ {ok, Session}
+ end
+ end.
+
+check_cookie(Cookie) ->
+ session_server(),
+ chat_server ! {get_session, Cookie, self()},
+ receive
+ {session_manager, {ok, Session}} ->
+ Session;
+ {session_manager, error} ->
+ error
+ end.
+
+get_user(Session) ->
+ Session#user.user.
+
+display_login(A, Status) ->
+ (dynamic_headers() ++
+ [{ehtml,
+ [{body, [{onload,"document.f.user.focus();"},{bgcolor,?COLOR3}],
+ [{table, [{border,0},{bgcolor,?COLOR2},{cellspacing,1},
+ {width,"100%"}],
+ {tr,[{bgcolor,?COLOR1},{height,30}],
+ {td,[{nowrap,true},{align,left},{valign,middle}],
+ {b,[],
+ {font, [{size,4},{color,black}],
+ ["Chat at ", ?LOCATION]}}}}},
+ {pre_html, io_lib:format("<p>Your login status is: ~s</p>",
+ [Status])},
+ {form,
+ [{method,post},
+ {name,f},
+ {action, "login.yaws"},
+ {autocomplete,"off"}],
+ {table,[{cellspacing, "5"}],
+ [{tr, [],
+ [{td, [], {p, [], "Username:"}},
+ {td, [], {input, [{name, user},
+ {type, text},
+ {size, "20"}]}}
+ ]},
+ {tr, [],
+ [{td, [], {p, [], "Password:"}},
+ {td, [], {input, [{name, password},
+ {type, password},
+ {size, "20"}]}}]},
+ {tr, [],
+ {td, [{align, "right"}, {colspan, "2"}],
+ {input, [{type, submit},
+ {value, "Login"}]}}}
+ ]}}]
+ }]
+ }]).
+
+
+session_server() ->
+ case whereis(chat_server) of
+ undefined ->
+ Pid = proc_lib:spawn(?MODULE, chat_server_init, []),
+ register(chat_server, Pid);
+ _ ->
+ done
+ end.
+
+%%
+
+chat_server_init() ->
+ process_flag(trap_exit, true),
+ io:format("Starting chat server\n"),
+ put(color_idx, 0),
+ chat_server([]).
+
+%%
+
+chat_server(Users0) ->
+ Users = gc_users(Users0),
+ %% io:format("Users = ~p\n", [Users]),
+ receive
+ {get_session, Cookie, From} ->
+ %% io:format("get_session ~p\n", [Cookie]),
+ case lists:keysearch(Cookie, #user.cookie, Users) of
+ {value, Session} ->
+ From ! {session_manager, {ok, Session}};
+ false ->
+ From ! {session_manager, error}
+ end,
+ chat_server(Users);
+ {new_session, User, From} ->
+ Cookie = integer_to_list(random:uniform(1 bsl 50)),
+ Session = #user{cookie=Cookie, user=User, color=pick_color()},
+ From ! {session_manager, Cookie, Session},
+ chat_server([Session|Users]);
+ {write, Session, Msg} ->
+ NewUsers = send_to_all(msg,
+ fmt_msg(Session#user.user, Msg,
+ Session#user.color),
+ Users),
+ chat_server(NewUsers);
+ {send_to, User, Msg} ->
+ NewUsers = send_to_one(msg, Msg, Users, User),
+ chat_server(NewUsers);
+ {join_message, User} ->
+ NewUsers0 = send_to_all(msg,fmt_join(User), Users),
+ NewUsers1 = send_to_all(members,
+ fmt_members(NewUsers0), NewUsers0),
+ chat_server(NewUsers1);
+ {members, User} ->
+ NewUsers1 = send_to_one(members,
+ fmt_members(Users),
+ Users, User),
+ chat_server(NewUsers1);
+ {left_message, User} ->
+ NewUsers0 = send_to_all(msg,fmt_left(User), Users),
+ NewUsers1 = send_to_all(members,
+ fmt_members(NewUsers0), NewUsers0),
+ chat_server(NewUsers1);
+ {read, Session, Pid} ->
+ %% io:format("~p want read ~p\n", [Session#user.user, Pid]),
+ NewUsers = user_read(Users, Session, Pid),
+ chat_server(NewUsers);
+ {cancel_read, Pid} ->
+ NewUsers = cancel_read(Users, Pid),
+ chat_server(NewUsers)
+ after
+ 5000 ->
+ chat_server(Users)
+ end.
+
+
+%%
+
+cancel_read([], _Pid) ->
+ [];
+cancel_read([U|Us], Pid) when U#user.pid == Pid ->
+ Now = inow(now()),
+ [U#user{pid=undefined,last_read=Now}|Us];
+cancel_read([U|Us], Pid) ->
+ [U|cancel_read(Us, Pid)].
+
+%%
+
+user_read(Users, User, Pid) ->
+ user_read(Users, User, Pid, Users).
+
+user_read([], User, Pid, All) ->
+ All;
+
+user_read([U|Users], User, Pid, All) when U#user.cookie == User#user.cookie ->
+ if U#user.buffer /= [] ->
+ Pid ! {msgs,lists:reverse(U#user.buffer)},
+ [U#user{buffer=[]}|Users];
+ true ->
+ [U#user{pid=Pid}|Users]
+ end;
+
+user_read([U|Users], User, Pid, All) ->
+ [U|user_read(Users, User, Pid, All)].
+
+%%
+
+send_to_all(Type, Msg, Users) ->
+ Now = inow(now()),
+ F = fun(U) ->
+ if U#user.pid /= undefined ->
+ %% io:format("Sending ~p to ~p\n", [Msg, U#user.user]),
+ U#user.pid ! {msgs, [{Type, Msg}]},
+ U#user{pid=undefined, last_read = Now};
+ true ->
+ U#user{buffer=[{Type,Msg}|U#user.buffer]}
+ end
+ end,
+ lists:map(F, Users).
+
+%%
+
+send_to_one(Type, Msg, Users, User) ->
+ Now = inow(now()),
+ F = fun(U) when U#user.cookie == User#user.cookie ->
+ if U#user.pid /= undefined ->
+ %% io:format("Sending ~p to ~p\n", [Msg, U#user.user]),
+ U#user.pid ! {msgs, [{Type, Msg}]},
+ U#user{pid=undefined, last_read = Now};
+ true ->
+ U#user{buffer=[{Type,Msg}|U#user.buffer]}
+ end;
+ (U) ->
+ U
+ end,
+ lists:map(F, Users).
+
+%%
+
+
+gc_users(Users) ->
+ Now = inow(now()),
+ gc_users(Users, Now).
+
+gc_users([], _Now) ->
+ [];
+gc_users([U|Us], Now) ->
+ if U#user.pid == undefined, (Now-U#user.last_read > 10) ->
+ self() ! {left_message, U#user.user},
+ gc_users(Us, Now);
+ true ->
+ [U|gc_users(Us, Now)]
+ end.
+
+%
+
+inow(Now) ->
+ {MSec, Sec, _} = Now,
+ MSec*1000000 + Sec.
+
+%
+
+dynamic_headers() ->
+ [yaws_api:set_content_type("text/html"),
+ {header, {cache_control, "no-cache"}},
+ {header, "Expires: -1"}].
+
+%
+
+chat_read(A) ->
+ session_server(),
+ case check_session(A) of
+ {ok, Session} ->
+ chat_server ! {read, Session, self()},
+ if length(A#arg.querydata) > 0 ->
+ chat_server ! {members, Session};
+ true ->
+ ok
+ end,
+ receive
+ {msgs, Messages} ->
+ M = [fmt_type(Type,L) || {Type, L} <- Messages],
+ dynamic_headers()++[{html, ["ok",M]}, break]
+ after
+ 20000 ->
+ catch erlang:send(chat_server, {cancel_read, self()}),
+ dynamic_headers()++[{html, "timeout"}, break]
+ end;
+ Error ->
+ dynamic_headers()++[{html, "error"}, break]
+ end.
+
+type2tag(msg) -> $m;
+type2tag(members) -> $e.
+
+%
+
+fmt_type(Type, L) ->
+ Data = list_to_binary(L),
+ [type2tag(Type), integer_to_list(size(Data)),":", Data].
+
+%
+
+-ifdef(ERL_BUG).
+chat_write(A) ->
+ session_server(),
+ case check_session(A) of
+ {ok, Session} ->
+ chat_server ! {write, Session, A#arg.clidata},
+ [{html, "ok"},
+ break];
+ Error ->
+ Error
+ end.
+-else.
+chat_write(A) ->
+ session_server(),
+ case check_session(A) of
+ {ok, Session} ->
+ chat_server ! {write, Session,A#arg.clidata},
+ [{header, {connection,"close"}},
+ {html, "ok"},
+ break];
+ Error ->
+ Error
+ end.
+-endif.
+
+%%
+
+fmt_join(User) ->
+ ["<strong>",date_str()," ",User, " joined</strong>"].
+
+%%
+
+fmt_left(User) ->
+ ["<strong>",date_str()," ",User," left</strong>"].
+
+%%
+
+fmt_msg(User, Msg, Color) ->
+ ["<font color=",Color,">",date_str()," <strong>",User,":</strong></font> ",
+ Msg].
+
+%%
+
+fmt_members(Users) ->
+ [[U#user.user,"<br>"] || U <- Users].
+
+%%
+
+date_str() ->
+ {_,{H,M,S}} = calendar:local_time(),
+ io_lib:format("<small>(~2.2.0w:~2.2.0w:~2.2.0w)</small>", [H,M,S]).
+
+%%
+
+pick_color() ->
+ Nr = get(color_idx),
+ put(color_idx, (Nr+1) rem 4),
+ colors(Nr).
+
+%%
+
+colors(0) -> "blue";
+colors(1) -> "orange";
+colors(2) -> "red";
+colors(3) -> "green".
+
18 applications/mail/Makefile
@@ -0,0 +1,18 @@
+SUBDIRS = src
+include ./include.mk
+
+
+all debug clean install:
+ @set -e ; \
+ for d in $(SUBDIRS) ; do \
+ if [ -f $$d/Makefile ]; then ( cd $$d && $(MAKE) $@ ) || exit 1 ; fi ; \
+ done
+
+
+touch:
+ find . -name '*' -print | xargs touch -m
+ find . -name '*.erl' -print | xargs touch -m
+
+
+
+
60 applications/mail/README
@@ -0,0 +1,60 @@
+
+
+This is a very basic WebMail application which is completely
+stateless, by design. I didn't want any SQL databases etc
+for storing the emails.
+
+The reason for building it was that I needed a local WebMail
+and I didn't want to install an Apache with python or PHP,
+and besides all those relied on some local store (mbox, MySQL
+etc) which I didn't want. Also, Klacke told me that he never
+finished the other webmail app so I started from scratch.
+
+A few important things are still missing. The most notable is the
+ability to handle attached files and email on multipart format...
+
+
+To install
+----------
+
+- Modify include.mk for your local paths
+
+Run 'make' and 'make install'
+
+
+
+- Edit/Create /etc/mail/yaws-webmail.conf
+
+(Make install will create a good template for the conf
+ file in /etc/mail)
+
+
+
+Two things need to be edited in /etc/yaws.conf
+
+1. yaws must find the beam code for mail.beam,
+ By default (include.mk) that gets installed in
+ /var/yaws/ebin
+
+ This path must be added to /etc/yaws conf as in:
+
+ ebin_dir = /var/yaws/ebin
+
+
+
+2. The virtual server that is supposed to run the webmail
+ must have an appmod called 'attachment' installed.
+
+ Here is an example:
+
+ <server flinta>
+ port = 80
+ appmods = attachment
+ listen = 0.0.0.0
+ docroot = /var/yaws/mail
+ </server>
+
+
+
+
+/Johan Bevemyr
21 applications/mail/TODO
@@ -0,0 +1,21 @@
+Things to do
+
+ - handle attachments in received emails
+ - optionally include old text as quoted text in reply. We
+ need to select the text part for the quote if the email
+ is of type multipart/alternative. We select text/html
+ to display.
+ - page large inboxes with 20 emails per page (sorted in
+ reverse order with most recently received emails first)
+ - write an attachement cache to limit the delays when
+ fetching an attachement
+ - code outgoing emails as quoted-printable (must limit max
+ line length to 74 according to RFC ???)
+
+ - Sort by 'From', 'Subject' and 'Nr'
+ - Implement mail forwarding
+ - Support imap mail backend system.
+ - Properly decode encoded attachments.
+
+
+
0 applications/mail/ebin/.empty
No changes.
53 applications/mail/include.mk
@@ -0,0 +1,53 @@
+###-*-makefile-*- ; force emacs to enter makefile-mode
+
+
+# these the items can be edited
+
+INSTALLPREFIX=/var/yaws
+
+MAILINSTALLDIR=$(INSTALLPREFIX)/mail
+EBININSTALLDIR=$(INSTALLPREFIX)/ebin
+
+ERL=$(shell which erl)
+ERLC=$(shell which erlc)
+
+
+## don't edit below here
+
+EMULATOR=beam
+ifdef debug
+ ERLC_FLAGS+=-Ddebug
+endif
+
+ifdef trace
+ ERLC_FLAGS=+trace
+endif
+
+ifdef export_all
+ ERLC_FLAGS+=-Dexport_all
+endif
+
+
+INSTALL=install -c
+INSTALL_DATA=${INSTALL} -m 644
+
+
+# Hmm, don't know if you are supposed to like this better... ;-)
+APPSCRIPT = '$$vsn=shift; $$mods=""; while(@ARGV){ $$_=shift; s/^([A-Z].*)$$/\'\''$$1\'\''/; $$mods.=", " if $$mods; $$mods .= $$_; } while(<>) { s/%VSN%/$$vsn/; s/%MODULES%/$$mods/; print; }'
+
+# Targets
+
+../ebin/%.app: %.app.src ../vsn.mk Makefile
+ perl -e $(APPSCRIPT) "$(VSN)" $(MODULES) < $< > $@
+
+../ebin/%.appup: %.appup
+ cp $< $@
+
+../ebin/%.$(EMULATOR): %.erl
+ $(ERLC) -b $(EMULATOR) $(ERLC_FLAGS) -o ../ebin $<
+
+%.$(EMULATOR): %.erl
+ $(ERLC) -b $(EMULATOR) $(ERLC_FLAGS) $<
+
+
+
11 applications/mail/mail/compose.yaws
@@ -0,0 +1,11 @@
+<erl>
+
+out(A) ->
+ case mail:check_session(A) of
+ {ok, Session} ->
+ mail:compose(Session);
+ Error ->
+ Error
+ end.
+
+</erl>
BIN applications/mail/mail/down.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 applications/mail/mail/headers.yaws
@@ -0,0 +1,12 @@
+<erl>
+
+out(A) ->
+ case mail:check_session(A) of
+ {ok, Session} ->
+ {ok, Nr} = queryvar(A, "nr"),
+ mail:showheaders(Session, list_to_integer(Nr));
+ Error ->
+ Error
+ end.
+
+</erl>
4 applications/mail/mail/index.yaws
@@ -0,0 +1,4 @@
+<erl>
+out(A) ->
+ {redirect_local, {rel_path, "mail.yaws"}}.
+</erl>
14 applications/mail/mail/listop.yaws
@@ -0,0 +1,14 @@
+<erl>
+
+out(A) ->
+ case mail:check_session(A) of
+ {ok, Session} ->
+ L = yaws_api:parse_post(A),
+ Op = mail:get_val("cmd", L, ""),
+ ToDelete = [M || {M,Op} <- L, Op=="yes"],
+ mail:delete(Session, ToDelete);
+ Error ->
+ Error
+ end.
+
+</erl>
20 applications/mail/mail/login.yaws
@@ -0,0 +1,20 @@
+<erl>
+
+out(A) ->
+ L = case (A#arg.req)#http_request.method of
+ 'GET' ->
+ yaws_api:parse_query(A);
+ 'POST' ->
+ yaws_api:parse_post(A)
+ end,
+ User = mail:getopt("user", L, ""),
+ Passwd = mail:getopt("password", L, ""),
+ case mail:login(User, Passwd) of
+ {ok, Cookie} ->
+ [yaws_api:setcookie("mailsession", Cookie),
+ {redirect_local, {rel_path,"mail.yaws"}}];
+ {error, Reason} ->
+ mail:display_login(A, Reason)
+ end.
+
+</erl>
11 applications/mail/mail/logout.yaws
@@ -0,0 +1,11 @@
+<erl>
+
+out(A) ->
+ case mail:check_session(A) of
+ {ok, Session} ->
+ mail:logout(Session);
+ Error ->
+ Error
+ end.
+
+</erl>
120 applications/mail/mail/mail.js
@@ -0,0 +1,120 @@
+/* -*- Java -*-
+ *
+ * File: mail.js
+ * Author: Johan Bevemyr
+ * Created: Sun Feb 15 23:40:56 2004
+ * Purpose: support functions for webmail
+ */
+
+function setCmd(val) {
+ if (val == 'delete') {
+ var msg = 'Are you sure you want to delete this message?';
+ if (!confirm(msg))
+ return;
+ }
+ document.compose.cmd.value=val;
+ document.compose.submit();
+}
+
+function changeActive(depth) {
+ var msg = document.getElementById('msg-body:msg'+depth);
+ var hdr = document.getElementById('msg-body:hdr'+depth);
+ var bm = document.getElementById('msg-button:'+depth);
+ var bh = document.getElementById('hdr-button:'+depth);
+
+ if (msg.style.display == 'block') {
+ msg.style.display = 'none';
+ hdr.style.display = 'block';
+ bm.style.display = 'none';
+ bh.style.display = 'block';
+ } else {
+ msg.style.display = 'block';
+ hdr.style.display = 'none';
+ bm.style.display = 'block';
+ bh.style.display = 'none';
+ }
+}
+
+function setComposeCmd(val) {
+ if (document.compose.to.value.length == 0) {
+ alert('The To: field must not be empty.');
+ document.compose.to.focus();
+ return;
+ }
+
+ try {
+ document.compose.message.value = editor.getHTML();
+ } catch (e) {
+ var rExp;
+ var text=document.compose.html_message.value;
+
+ rExp=/&aring;/gi;
+ text.replace(rExp, "å");
+
+ rExp=/&aring;/gi;
+ text.replace(rExp, "Å");
+
+ document.compose.message.value = text;
+ }
+
+ // alert(editor.getHTML());
+
+ if (document.compose.message.value.length == 0) {
+ alert('The message field must not be empty.');
+ document.compose.html_message.focus();
+ return;
+ }
+
+ /* check for attachements */
+ if (document.compose.file1.value.length > 0) {
+ document.compose.attached.value="yes";
+ } else if (document.compose.file2.value.length > 0) {
+ document.compose.attached.value="yes";
+ } else if (document.compose.file3.value.length > 0) {
+ document.compose.attached.value="yes";
+ } else if (document.compose.file4.value.length > 0) {
+ document.compose.attached.value="yes";
+ } else if (document.compose.file5.value.length > 0) {
+ document.compose.attached.value="yes";
+ } else if (document.compose.file6.value.length > 0) {
+ document.compose.attached.value="yes";
+ } else if (document.compose.file7.value.length > 0) {
+ document.compose.attached.value="yes";
+ } else if (document.compose.file8.value.length > 0) {
+ document.compose.attached.value="yes";
+ } else if (document.compose.file9.value.length > 0) {
+ document.compose.attached.value="yes";
+ } else if (document.compose.file10.value.length > 0) {
+ document.compose.attached.value="yes";
+ }
+
+ document.compose.cmd.value=val;
+ document.compose.submit();
+}
+
+function changeActiveTab(i) {
+ var j;
+
+ for( j=0; j < tabCount; ++j ) {
+ if( i==j ) {
+ activateTab(j);
+ }
+ else {
+ deactivateTab(j);
+ }
+ }
+}
+
+function activateTab(i) {
+ document.getElementById( "tab-left:"+i ).src="tab-left_active.gif";
+ document.getElementById( "tab-bg:"+i ).style.background="url(tab-bg_active.gif)";
+ document.getElementById( "tab-right:"+i ).src="tab-right_active.gif";
+ document.getElementById( "tab-body:"+i ).style.display='block';
+}
+
+function deactivateTab(i) {
+ document.getElementById( "tab-left:"+i ).src="tab-left_inactive.gif";
+ document.getElementById( "tab-bg:"+i ).style.background="url(tab-bg_inactive.gif)";
+ document.getElementById( "tab-right:"+i ).src="tab-right_inactive.gif";
+ document.getElementById( "tab-body:"+i ).style.display='none';
+}
22 applications/mail/mail/mail.yaws
@@ -0,0 +1,22 @@
+<erl>
+
+out(A) ->
+ case mail:check_session(A) of
+ {ok, Session} ->
+ L = yaws_api:parse_query(A),
+ Refresh =
+ case lists:keysearch("refresh",1,L) of
+ {value, _} -> true;
+ _ -> false
+ end,
+ Sort =
+ case lists:keysearch("sort",1,L) of
+ {value, {_,SortStr}} -> list_to_atom(SortStr);
+ _ -> undefined
+ end,
+ mail:list(Session, {Refresh, Sort});
+ Error ->
+ Error
+ end.
+
+</erl>
45 applications/mail/mail/reply.yaws
@@ -0,0 +1,45 @@
+<erl>
+
+out(A) ->
+ case mail:check_session(A) of
+ {ok, Session} ->
+ L = yaws_api:parse_post(A),
+ Cmd = mail:get_val("cmd", L, reply),
+ case Cmd of
+ "reply" ->
+ From = yaws_api:url_decode(mail:get_val("from", L, "")),
+ Subject = yaws_api:url_decode(mail:get_val("subject", L, "")),
+ To = yaws_api:url_decode(mail:get_val("to", L, "")),
+ Cc = yaws_api:url_decode(mail:get_val("cc", L, "")),
+ Bcc = yaws_api:url_decode(mail:get_val("bcc", L, "")),
+ Quote = yaws_api:url_decode(mail:get_val("quote", L, "")),
+ NewCc =
+ if To == [] -> Cc;
+ Cc == [] -> To;
+ true -> To ++ ", " ++ Cc
+ end,
+ mail:compose(Session,"",From,NewCc,Bcc,"RE: "++Subject,
+ Quote);
+ "delete" ->
+ Nr = mail:get_val("nr", L, ""),
+ mail:delete(Session, [Nr])
+ end;
+ Error ->
+ Error
+ end.
+
+</erl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
11 applications/mail/mail/send.yaws
@@ -0,0 +1,11 @@
+<erl>
+
+out(A) ->
+ case mail:check_session(A) of
+ {ok, Session} ->
+ mail:send(Session,A);
+ Error ->
+ Error
+ end.
+
+</erl>
13 applications/mail/mail/showmail.yaws
@@ -0,0 +1,13 @@
+<erl>
+
+out(A) ->
+ case mail:check_session(A) of
+ {ok, Session} ->
+ L = yaws_api:parse_query(A),
+ {value, {_,Nr}} = lists:keysearch("nr",1,L),
+ mail:showmail(Session, list_to_integer(Nr));
+ Error ->
+ Error
+ end.
+
+</erl>
BIN applications/mail/mail/spacer.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/mail/mail/tab-bg_active.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/mail/mail/tab-bg_inactive.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/mail/mail/tab-hr.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/mail/mail/tab-left_active.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/mail/mail/tab-left_inactive.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN applications/mail/mail/tab-right_active.gif
Diff not rendered.
BIN applications/mail/mail/tab-right_inactive.gif
Diff not rendered.
BIN applications/mail/mail/tool-delete.gif
Diff not rendered.
BIN applications/mail/mail/tool-div.gif
Diff not rendered.
BIN applications/mail/mail/tool-newmail.gif
Diff not rendered.
BIN applications/mail/mail/tool-send.gif
Diff not rendered.
BIN applications/mail/mail/up.gif
Diff not rendered.
BIN applications/mail/mail/view-mark.gif
Diff not rendered.
50 applications/mail/src/Makefile
@@ -0,0 +1,50 @@
+include ../include.mk
+
+ifeq ($(TYPE),debug)
+DEBUG_FLAGS = -Ddebug
+else
+DEBUG_FLAGS =
+endif
+
+include ../vsn.mk
+VSN=$(YAWS_VSN)
+MODULES=mail attachment smtp mail_html
+
+EBIN_FILES=$(MODULES:%=../ebin/%.$(EMULATOR))
+
+ERLC_FLAGS+=-W +debug_info $(DEBUG_FLAGS) -I../../../include -pa ../../mail
+
+#
+# Targets
+#
+
+all: $(EBIN_FILES)
+
+mail_vsn.erl: mail_vsn.template
+ . ../vsn.mk; sed "s/%VSN%/${MAIL_VSN}/" < mail_vsn.template > mail_vsn.erl
+
+debug:
+ $(MAKE) TYPE=debug
+
+clean:
+ rm -f $(EBIN_FILES) mail_vsn.erl
+
+install: all
+ install -d $(MAILINSTALLDIR)
+ install -d $(EBININSTALLDIR)
+ install -d $(DESTDIR)/etc/mail
+ @if [ -f $(DESTDIR)/etc/mail/yaws-webmail.conf ]; \
+ then echo "$(DESTDIR)/etc/mail/yaws-webmail.conf already exists"; \
+ else \
+ cp yaws-webmail.conf $(DESTDIR)/etc/mail/yaws-webmail.conf; fi
+ (cd ../ebin; find . -name '*' -print | xargs tar cf - ) | (cd $(EBININSTALLDIR); tar xf - )
+ (cd ../mail; find . -name '*' -print | xargs tar cf - ) | (cd $(MAILINSTALLDIR); tar xf - )
+
+
+
+tags:
+ erl -noshell -pa ../ebin -s mail_debug mktags
+
+xref:
+ erl -noshell -pa ../ebin -s mail_debug xref ../ebin
+
35 applications/mail/src/attachment.erl
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%%% File : attachment.erl
+%%% Author : <klacke@hyber.org>
+%%% Description :
+%%%
+%%% Created : 4 Feb 2004 by <klacke@hyber.org>
+%%%-------------------------------------------------------------------
+-module(attachment).
+-compile(export_all).
+
+out(A) ->
+ case mail:check_session(A) of
+ {ok, Session} ->
+ case {yaws_api:queryvar(A, "nr"),yaws_api:queryvar(A,"form")} of
+ {{ok, Nr},{ok,"text"}} ->
+ mail:send_attachment_plain(Session, yaws:to_integer(Nr));
+ {{ok, Nr},_} ->
+ mail:send_attachment(Session, yaws:to_integer(Nr));
+ _ ->
+ err()
+ end;
+ Error ->
+ err()
+ end.
+
+
+err() ->
+ [{status, 404},
+ {header, {connection, "close"}}].
+
+
+
+
+
+
20 applications/mail/src/defs.hrl
@@ -0,0 +1,20 @@
+% -*- Erlang -*-
+% File: defs.hrl (/mnt/disk2/jb/work/yaws/yaws/applications/mail/src/defs.hrl)
+% Author: Johan Bevemyr
+% Created: Wed Oct 29 23:39:30 2003
+% Purpose:
+
+-ifndef(DEFS_HRL).
+-define(DEFS_HRL, true).
+
+
+%% Create config file in /etc/mail/yaws-webmail.conf
+
+-record(cfg, {ttl = 1800, % 30 minuter TTL
+ popserver = "localhost",
+ maildomain = "foo.bar",
+ smtpserver = "localhost",
+ sendtimeout = 3000}).
+
+
+-endif.
2,891 applications/mail/src/mail.erl
@@ -0,0 +1,2891 @@
+% -*- Erlang -*-
+% File: mail.erl (~jb/mail.erl)
+% Author: Johan Bevemyr
+% Created: Sat Oct 25 10:59:24 2003
+% Purpose:
+
+% RFC 822
+% RFC 1939
+% RFC 2048
+
+-module('mail').
+-author('jb@trut.bluetail.com').
+
+-export([parse_headers/1, list/2, list/3, ploop/5,pop_request/4, diff/2,
+ session_manager_init/0, check_cookie/1, check_session/1,
+ login/2, display_login/2, stat/3, showmail/2, compose/1, compose/7,
+ send/6, send/2, get_val/3, logout/1, base64_2_str/1, retr/4,
+ delete/2, send_attachment/2, send_attachment_plain/2,
+ wrap_text/2, getopt/3, decode/1]).
+
+-include("../../../include/yaws_api.hrl").
+-include("defs.hrl").
+
+-record(info,
+ {
+ nr,
+ size,
+ headers
+ }).
+
+-record(mail,
+ {
+ from="",
+ from_fmt="",
+ from_fmt_lc="",
+ to="",
+ cc="",
+ bcc="",
+ subject="",
+ subject_fmt="",
+ subject_fmt_lc="",
+ date="",
+ date_pst=date(),
+ date_fmt="",
+ content_type,
+ transfer_encoding,
+ content_disposition,
+ other = []
+ }).
+
+-record(pstate,
+ {
+ port,
+ user,
+ pass,
+ cmd,
+ acc = [],
+ from,
+ lines,
+ reply=[],
+ more=true,
+ remain,
+ dotstate=0
+ }).
+
+-record(satt, {
+ num,
+ filename,
+ ctype,
+ data}).
+
+-record(session,
+ {
+ user,
+ passwd,
+ cookie,
+ listing,
+ sorting=rev_nr,
+ attachments = [] %% list of #satt{} records
+ }).
+
+-define(RETRYTIMEOUT, 300).
+-define(RETRYCOUNT, 5).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+build_toolbar(Entries) ->
+ {table, [{bgcolor,"c0c0c0"},{cellpadding,0},{cellspacing,0},{border,0}],
+ [{tr,[],{td, [{colspan,20},{height,1},{bgcolor,white}],
+ {img, [{src,"spacer.gif"}, {width,1},{height,1},
+ {alt,""}, {border,0}],[]}}},
+ {tr,[], build_toolbar(Entries, -1)},
+ {tr,[],{td, [{colspan,20},{height,1},{bgcolor,gray}],
+ {img, [{src,"spacer.gif"}, {width,1},{height,1},
+ {alt,""}, {border,0}],[]}}},
+ {tr,[],{td, [{colspan,20},{height,1}],
+ {img, [{src,"spacer.gif"}, {width,1},{height,1},
+ {alt,""}, {border,0}],[]}}}]}.
+
+build_toolbar([], Used) ->
+ Percent = integer_to_list(100-Used)++"%",
+ [{td, [nowrap,{width,Percent},{valign,middle},{align,left}],[]}];
+build_toolbar([{[],Url,Cmd}|Rest], Used) ->
+ if Used == -1 ->
+ [];
+ true ->
+ [{td, [nowrap,{width,"1%"},{valign,middle},{align,left}],
+ {img, [{src,"tool-div.gif"},{width,2},{height,16},
+ {alt,""},{border,0},{hspace,2}]}}]
+ end ++
+ [{td, [nowrap,{width,"2%"},{valign,middle},{align,left}],
+ [{a, [{class,nolink}, {href,Url}],
+ {font, [{size,2},{color,"#000000"},{title,Cmd}],Cmd}}]} |
+ build_toolbar(Rest, Used+3)];
+build_toolbar([{Gif,Url,Cmd}|Rest], Used) ->
+ (if Used == -1 ->
+ [];
+ true ->
+ [{td, [nowrap,{width,"1%"},{valign,middle},{align,left}],
+ {img, [{src,"tool-div.gif"},{width,2},{height,16},
+ {alt,""},{border,0},{hspace,2}]}}]
+ end ++
+ [{td, [nowrap,{width,"2%"},{valign,middle},{align,left}],
+ {a, [{class,nolink},
+ {href,Url}],
+ [{img, [{src,Gif},{vspace,2},{width,20},
+ {height,20},{alt,Cmd},{border,0}],[]}]}
+
+ },
+ {td, [nowrap,{width,"2%"},{valign,middle},{align,left}],
+ [{a, [{class,nolink},
+ {href,Url}],
+ {font, [{size,2},{color,"#000000"},{title,Cmd}], Cmd}}]} |
+ build_toolbar(Rest, Used+4)]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+ %
+
+delete(Session, ToDelete) ->
+ tick_session(Session#session.cookie),
+ Req = [del(M) || M <- ToDelete],
+ pop_request(Req, popserver(),
+ Session#session.user, Session#session.passwd),
+ {redirect_local, {rel_path, "mail.yaws?refresh=true"}}.
+
+-record(send, {param,
+ last = false,
+ encoding,
+ estate="",
+ boundary="",
+ from="",
+ to="",
+ cc="",
+ bcc="",
+ subject="",
+ message="",
+ attached="",
+ port,
+ session,
+ line_start=true
+ }).
+
+
+send(Session, A) ->
+ State = prepare_send_state(A#arg.state, Session),
+ case yaws_api:parse_multipart_post(A) of
+ {cont, Cont, Res} ->
+ case catch sendChunk(Res, State) of
+ {done, Result} ->
+ Result;
+ {cont, NewState} ->
+ {get_more, Cont, NewState};
+ {error, Reason} ->
+ {ehtml,
+ format_error("Failed to send email. Reason: "++
+ to_string(Reason))}
+ end;
+ {result, Res} ->
+ case catch sendChunk(Res, State#send{last=true}) of