comparison after5.rb @ 85:e2b6a2e8b5c7 draft

Enable inter-member mail Support attachment files
author HIROSE Yuuji <yuuji@gentei.org>
date Mon, 16 Dec 2013 10:41:21 +0900
parents f67f5304baac
children 26c81703a80c
comparison
equal deleted inserted replaced
84:f67f5304baac 85:e2b6a2e8b5c7
2 # -*- coding: euc-jp -*- 2 # -*- coding: euc-jp -*-
3 # 3 #
4 # Associative Scheduling Table - after5 4 # Associative Scheduling Table - after5
5 # (C)2003, 2004, 2006, 2008, 2012, 2013 by HIROSE Yuuji [yuuji<at>gentei.org] 5 # (C)2003, 2004, 2006, 2008, 2012, 2013 by HIROSE Yuuji [yuuji<at>gentei.org]
6 # $Id: after5.rb,v 1.20 2012/12/03 15:54:20 yuuji Exp $ 6 # $Id: after5.rb,v 1.20 2012/12/03 15:54:20 yuuji Exp $
7 # Last modified Thu Dec 12 18:09:01 2013 on firestorm 7 # Last modified Mon Dec 16 10:38:55 2013 on firestorm
8 # See http://www.gentei.org/~yuuji/software/after5/ 8 # See http://www.gentei.org/~yuuji/software/after5/
9 # このスクリプトはEUCで保存してください。 9 # このスクリプトはEUCで保存してください。
10 $hgid = <<_HGID_.split[1..-2].join(" ") 10 $hgid = <<_HGID_.split[1..-2].join(" ")
11 $HGid$ 11 $HGid$
12 _HGID_ 12 _HGID_
60 def element(elt, attrs = nil, nl = nil) 60 def element(elt, attrs = nil, nl = nil)
61 attr = "" 61 attr = ""
62 lf = nl ? "\n" : "" 62 lf = nl ? "\n" : ""
63 if attrs.is_a?(Hash) 63 if attrs.is_a?(Hash)
64 for k in attrs.keys 64 for k in attrs.keys
65 attr += " %s=\"%s\"" % [k, attrs[k]] 65 attr += " %s=\"%s\"" % [k, attrs[k]]
66 end 66 end
67 end 67 end
68 body = yield 68 body = yield
69 sprintf "<%s%s>%s%s%s</%s>%s", elt, attr, lf, body, lf, elt, lf 69 sprintf "<%s%s>%s%s%s</%s>%s", elt, attr, lf, body, lf, elt, lf
70 end 70 end
1097 @myname='a5.cgi' if test(?f, "a5.cgi") 1097 @myname='a5.cgi' if test(?f, "a5.cgi")
1098 @conf = nil 1098 @conf = nil
1099 @schedulearea = {'rows'=>'4', 'cols'=>'60', 'name'=>'schedule'} 1099 @schedulearea = {'rows'=>'4', 'cols'=>'60', 'name'=>'schedule'}
1100 @oldagent = (%r,Mozilla/4, =~ ENV['HTTP_USER_AGENT']) 1100 @oldagent = (%r,Mozilla/4, =~ ENV['HTTP_USER_AGENT'])
1101 @lang = 0 1101 @lang = 0
1102 @mlbasedir = "ml"
1103 @attachmentdir = "a"
1104 @attachmentmax = 8*1024**2
1102 @mailmode = nil 1105 @mailmode = nil
1103 @mailadmdelimiter = "/" 1106 @mailadmdelimiter = "/"
1104 @mailadmsuffix = @mailadmdelimiter + "adm" 1107 @mailadmsuffix = @mailadmdelimiter + "adm"
1105 @saveprefsregexp = /^(display(mode|days)$|nt|headline)/ 1108 @saveprefsregexp = /^(display(mode|days)$|nt|headline)/
1106 @opt = { 1109 @opt = {
1353 'sendall_head' => ['「%s」宛のメイル送信', "Send message to `%s'"], 1356 'sendall_head' => ['「%s」宛のメイル送信', "Send message to `%s'"],
1354 'sendall_note' => ['メンバーへの連絡だけでなく、グループ非加入者がこれから加入する旨の通知などにも有用。', 1357 'sendall_note' => ['メンバーへの連絡だけでなく、グループ非加入者がこれから加入する旨の通知などにも有用。',
1355 "Send this message to all of group."], 1358 "Send this message to all of group."],
1356 'sendall_done' => ['送信完了', "sending message done"], 1359 'sendall_done' => ['送信完了', "sending message done"],
1357 'body' => ['本文', 'Body'], 1360 'body' => ['本文', 'Body'],
1361 'rcptto' => ['宛先', 'Recipients'],
1358 'member' => ['メンバー', 'Member'], 1362 'member' => ['メンバー', 'Member'],
1359 'personalmode' => ['自分のだけ表示モード', 'Display Personal Only'], 1363 'personalmode' => ['自分のだけ表示モード', 'Display Personal Only'],
1360 'normalmode' => ['全員分表示モード', "Display Everyone's"], 1364 'normalmode' => ['全員分表示モード', "Display Everyone's"],
1361 'display' => ['予定表示行: ', 'Display schedule of: '], 1365 'display' => ['予定表示行: ', 'Display schedule of: '],
1362 'nameonly' => ['名前のみ', 'Name Only'], 1366 'nameonly' => ['名前のみ', 'Name Only'],
1679 end 1683 end
1680 def sendMail(to, subject, body, from=nil, rcptto=nil, header={}, 1684 def sendMail(to, subject, body, from=nil, rcptto=nil, header={},
1681 thru=nil, spoolto=false) 1685 thru=nil, spoolto=false)
1682 # rcptto should be an Array 1686 # rcptto should be an Array
1683 body = NKF.nkf("-j", body) unless thru 1687 body = NKF.nkf("-j", body) unless thru
1684 subject = NKF.nkf("-jM", subject.strip) 1688 subject = NKF.nkf("-jM", (subject||"No subject").strip)
1685 to = safecopy(to) # cleanup tainted address 1689 to = safecopy(to) # cleanup tainted address
1686 subject.gsub!(/\n/, '') 1690 subject.gsub!(/\n/, '')
1687 begin 1691 begin
1688 if (m=open("|-", "w")) 1692 if (m=open("|-", "w"))
1689 header.each do |h, v| 1693 header.each do |h, v|
1697 Content-Transfer-Encoding: 7bit 1701 Content-Transfer-Encoding: 7bit
1698 Content-Type: Text/Plain; charset=iso-2022-jp" 1702 Content-Type: Text/Plain; charset=iso-2022-jp"
1699 # m.puts "Date: #{Time.now.strftime("%a, %d %b %Y %T %z")}" 1703 # m.puts "Date: #{Time.now.strftime("%a, %d %b %Y %T %z")}"
1700 m.print "\n" 1704 m.print "\n"
1701 end 1705 end
1702 m.print body, "\n" 1706 m.write body
1703 m.close 1707 m.close
1704 else 1708 else
1705 # exec(@attr['mail'], "-s", subject, to) 1709 # exec(@attr['mail'], "-s", subject, to)
1706 recipient = rcptto || to.split(/,\s*|\s+/) 1710 recipient = rcptto || to.split(/,\s*|\s+/)
1707 #p recipient 1711 #p recipient
1721 if ENV['MAILCMD'] 1725 if ENV['MAILCMD']
1722 #exec("qmail-inject", "yuuji@gentei.org", "yuuji@koeki-u.ac.jp") 1726 #exec("qmail-inject", "yuuji@gentei.org", "yuuji@koeki-u.ac.jp")
1723 open("/tmp/body", "w") {|w| w.print STDIN.readlines.join 1727 open("/tmp/body", "w") {|w| w.print STDIN.readlines.join
1724 w.puts "---" 1728 w.puts "---"
1725 w.puts recipient.join(",\n") 1729 w.puts recipient.join(",\n")
1730 w.puts header.inspect
1731 w.puts "ENV: #{ENV.inspect}"
1726 } 1732 }
1727 exit 0 1733 exit 0
1734 elsif header['Return-path'] && /-@/ =~ header['Return-path']
1735 # if VERP is requested
1736 mailcmd = ENV['MAILCMD'] || @opt['sendmail']
1737 contents = STDIN.readlines
1738 recipient.uniq.each {|r|
1739 local, domain = header['Return-path'].split("@")
1740 newlocal = local+r.sub("@", "=")
1741 verp = newlocal+"@"+domain
1742 verp = safecopy(verp)
1743 open("| #{mailcmd} -f#{verp} -- #{r}", "w") {|m|
1744 m.write contents.join
1745 }
1746 }
1728 else 1747 else
1729 #recipient.unshift "-f"+header['return-path'] if header['return-path'] 1748 recipient.unshift "-f"+header['Return-path'] if header['Return-path']
1730 exec(ENV['MAILCMD'] || @opt['sendmail'], *recipient) 1749 exec(ENV['MAILCMD'] || @opt['sendmail'], *recipient)
1731 end 1750 end
1732 end 1751 end
1733 exit 0; 1752 exit 0;
1734 end 1753 end
2720 hold = [] 2739 hold = []
2721 ret = [] 2740 ret = []
2722 skip = false 2741 skip = false
2723 while line = body.shift 2742 while line = body.shift
2724 case line.toeuc 2743 case line.toeuc
2725 when /^$/ 2744 # #Below does not work correctly when (from|subject): is final line
2726 hold << "\n" 2745 # when /^$/
2727 break 2746 # hold << "\n"
2728 ## when /^(subject|from): /i 2747 # break
2729 when /^(\S+): /i # if new header comes 2748 # ## when /^(subject|from): /i
2749 when /^(\S+): /i, /^$/ # if new header comes or header ends
2730 if /^subject:/i =~ hold[0] # check previous header in hold space 2750 if /^subject:/i =~ hold[0] # check previous header in hold space
2731 sj = hold.join.toeuc.sub("Subject: ", "").gsub(tag, "").strip 2751 sj = hold.join.toeuc.sub("Subject: ", "").gsub(tag, "").strip
2732 removeregexp && sj && sj.gsub!(removeregexp, "") 2752 removeregexp && sj && sj.gsub!(removeregexp, "")
2733 sj = sj.sub(/^(re: *)+/i, "Re: ").gsub("\n", "") 2753 sj = sj.sub(/^(re: *)+/i, "Re: ").gsub("\n", "")
2734 hold = ["Subject: "+NKF.nkf('-jM', tag+" "+sj).strip+"\n"] 2754 hold = ["Subject: "+NKF.nkf('-jM', tag+" "+sj).strip+"\n"]
2735 elsif /^from/i =~ hold[0] && fromhack.is_a?(String) 2755 elsif /^from/i =~ hold[0] && fromhack.is_a?(String)
2736 from = hold.join.toeuc.sub(/From: */i, "").strip 2756 from = hold.join.toeuc.sub(/From: */i, "").strip
2737 email, comment = parseaddress(from) 2757 email, comment = parseaddress(from)
2738 if (!comment || comment=="") && comment = @sc.ismembersemail(email) 2758 if (!comment || comment=="") && comment = @sc.ismembersemail(email)
2739 # Reverse conversion of uname<->email 2759 # Reverse conversion of uname<->email
2740 comment = @sc.nickname(comment) || "" 2760 comment = @sc.nickname(comment) || "whoareyou"
2741 end 2761 end
2742 hold = ["From: "+rewritefrom(email, comment, fromhack)+"\n"] 2762 hold = ["From: "+rewritefrom(email, comment, fromhack)+"\n"]
2763 end
2764 if /^$/ =~ line.toeuc
2765 hold << line
2766 break
2743 end 2767 end
2744 ret += hold 2768 ret += hold
2745 hold = [line] 2769 hold = [line]
2746 when /^\s/ # continued line 2770 when /^\s/ # continued line
2747 hold << line 2771 hold << line
2748 end 2772 end
2749 end 2773 end
2750 ret + hold + body 2774 ret + hold + body
2751 end 2775 end
2776 def extract_attachment(attachment)
2777 # Must return [text, href] strings to attached files
2778 href = ""; text = ""
2779 dir = @attachmentdir
2780 if %r,(https?://[^/]+), =~ @opt['url']
2781 server = $1
2782 else
2783 msg = "`url' not set in after5.cf"
2784 return [msg, msg]
2785 end
2786
2787 urlbase = sprintf("%s%s/%s",
2788 server, File.dirname(ENV['SCRIPT_NAME']), dir)
2789 count=0
2790 attachment.each {|a|
2791 basename = safecopy(File.basename(a['filename']))
2792 filename = safecopy(dir+"/"+basename)
2793 umask = File.umask(022)
2794 sz = a['value'].bytesize
2795 next if sz == 0
2796 count += 1
2797 if sz > @attachmentmax
2798 msg = sprintf("%d: %s is too large(%dMB), skipped\n",
2799 count, basename, sz/1024**2)
2800 text += msg; href += msg
2801 next
2802 end
2803 begin
2804 (test(?d, dir) && test(?w, dir)) or Dir.mkdir(dir)
2805 open(filename, "w") {|x| x.write a['value']}
2806 File.chmod(0664, filename)
2807 text += sprintf("%d: %s/%s\n", count, urlbase, basename)
2808 href += sprintf("%d: <a href=\"%s\">%s/%s</a>\n",
2809 count, filename, urlbase, basename)
2810 rescue
2811 ensure
2812 File.umask(umask)
2813 end
2814 }
2815 if count>0
2816 text="\n\n[[Attached files below]]\n"+text
2817 href="[[Attached files]]\n"+href
2818 end
2819 [text.chomp, href.chomp]
2820 end
2752 def defaultmladdress(name) 2821 def defaultmladdress(name)
2753 prefix = (@opt['mailprefix'] || "") 2822 prefix = (@opt['mailprefix'] || "")
2754 dash = prefix > '' ? "-" : "" 2823 dash = prefix > '' ? "-" : ""
2755 sprintf("%s%s%s@%s", prefix, dash, name, @opt['maildomain']) 2824 sprintf("%s%s%s@%s", prefix, dash, name, @opt['maildomain'])
2756 end 2825 end
2757 def list() 2826 def list()
2758 # For debug: 2827 # For debug:
2759 # LOCAL=1 DEFAULT=name ./after5.rb -list 2828 # LOCAL=1 DEFAULT=name ./after5.rb -list
2760 # $DEFAULT is ML name 2829 # $DEFAULT is ML name
2761 viamail = ENV['LOCAL'] && ENV['DEFAULT'] # called via mail 2830 viamail = ENV['LOCAL'] && ENV['DEFAULT'] # called via mail
2762 from = toadmin = groupmode = fromhack = nil 2831 from = toadmin = groupmode = fromhack = extract_report = nil
2763 unless @opt['mailprefix'] && @opt['maildomain'] 2832 unless @opt['mailprefix'] && @opt['maildomain']
2764 if viamail 2833 if viamail
2765 STDERR.print msg('sendall_err') % [@opt['conf']] 2834 STDERR.print msg('sendall_err') % [@opt['conf']]
2766 exit 0 2835 exit 0
2767 else 2836 else
2770 end 2839 end
2771 end 2840 end
2772 if viamail then 2841 if viamail then
2773 prohibitviahttp() 2842 prohibitviahttp()
2774 name = unquoted(ENV['DEFAULT']) 2843 name = unquoted(ENV['DEFAULT'])
2844 user = @sc.ismembersemail(ENV['SENDER'])
2775 if Regexp.new("(.*)("+Regexp.quote(@mailadmsuffix)+")") =~ name 2845 if Regexp.new("(.*)("+Regexp.quote(@mailadmsuffix)+")") =~ name
2776 # To: GROUP/adm*@domain 2846 # To: GROUP/adm*@domain
2777 # -> Forward to group administrator(s) 2847 # -> Forward to group administrator(s)
2778 name, toadmin = $1, $2 2848 name, toadmin = $1, $2
2779 sendMail("dummy", 'dummy', # Original To: and Subject: go through 2849 sendMail("dummy", 'dummy', # Original To: and Subject: go through
2796 "> "+STDIN.readlines.join("> ")) 2866 "> "+STDIN.readlines.join("> "))
2797 exit 0 # should exit 0 in mail mode 2867 exit 0 # should exit 0 in mail mode
2798 end 2868 end
2799 else # via http 2869 else # via http
2800 return nil unless checkauth 2870 return nil unless checkauth
2801 name = unquoted(@params['name'].untaint) 2871 # HERE CGI Params name, subject, attachment and body
2872 # comes with enctype=multipart/form-data,
2873 # So we get them via Array
2874 name = unquoted(@params['name'][0]['value'].untaint)
2875 user = @params['user']
2802 if @sc.isuser(name) 2876 if @sc.isuser(name)
2803 # groupmode = nil 2877 # groupmode = nil
2804 elsif grepgroup(name) 2878 elsif grepgroup(name)
2805 groupmode = true 2879 groupmode = true
2806 else 2880 else
2807 @O.print @H.p("No such group: #{name}") 2881 @O.print @H.p("No such group: #{name}")
2808 return true 2882 return true
2809 end 2883 end
2810 nick = @sc.nickname(@params['user']) 2884 nick = @sc.nickname(user)
2811 from = sprintf("%s <%s>", nick, @params['user']) 2885 from = sprintf("%s <%s>", nick, user)
2812 body = @params['body'].gsub("\r", "").untaint 2886 subj = @params['subject'][0]['value'] || "Message from "+@myname
2813 end 2887 body = @params['body'][0]['value'].gsub("\r", "").untaint
2814 2888 # Extract attachment file
2889 if @params['attachment'].is_a?(Array)
2890 body += (extract_report = extract_attachment(@params['attachment']))[0]
2891 end
2892 end
2893 # Variables here
2894 # name: Destination group/user name
2895 # user: Member account or nil(not member)
2896
2815 # Set values for header rewriting 2897 # Set values for header rewriting
2898 # We have to setup these variables:
2899 # to: Header To:
2900 # subj: Header Subject:
2901 # from: Header From:
2902 # rcpts: Array of recipients addresses
2903 # header: Hash of additional header values
2904 # body: String of mail body
2905 # spooling: Flag if spool ML files nor not
2906 # mldir: spooling directory name
2816 if groupmode # Run as ML 2907 if groupmode # Run as ML
2908 # To: should be ML address
2909 # Return-path: should be verp of PREFIX-RCPT@DOMAIN
2817 bracket = @sc.getgroupattr(name, 'subjtag') || @opt['mailbracket'] 2910 bracket = @sc.getgroupattr(name, 'subjtag') || @opt['mailbracket']
2818 xmlname = @sc.getgroupattr(name, 'xmlname') || name 2911 xmlname = @sc.getgroupattr(name, 'xmlname') || name
2819 mldir = "ml/"+name 2912 mldir = @mlbasedir+"/"+name
2820 to = @sc.getgroupattr(name, 'mladdress') || defaultmladdress(name) 2913 to = @sc.getgroupattr(name, 'mladdress') || defaultmladdress(name)
2821 if @sc.getgroupattr(name, 'fromhack') 2914 if @sc.getgroupattr(name, 'fromhack')
2822 fromhack = to 2915 fromhack = to
2823 end 2916 end
2824 spooling = @opt['mlspooling'] 2917 spooling = @opt['mlspooling']
2918 returnpath = to.sub("@", @mailadmsuffix+"-@")
2825 else # Run as p2p mail 2919 else # Run as p2p mail
2826 bracket = "NONE" # Throught Subject 2920 # To: should be Destination user name
2827 user = @params['user'] || ENV['SENDER'] 2921 # Return-path: should be PREFIX-USER@DOMAIN or $SENDER(not member)
2828 if @sc.ismembersemail(user) 2922 bracket = "NONE" # Through Subject
2829 sender = defaultmladdress(quoted(user)) 2923 if user
2924 returnpath = defaultmladdress(quoted(user))
2830 else 2925 else
2831 sender = user 2926 returnpath = ENV['SENDER']
2832 end 2927 end
2833 ###fromhack = sprintf("%s <%s>", nick, sender) 2928 ###fromhack = sprintf("%s <%s>", nick, sender)
2834 fromhack = sender 2929 fromhack = returnpath
2835 2930
2836 xmlname = name 2931 xmlname = name
2837 to = name 2932 to = name
2838 spooling = mldir = nil 2933 spooling = mldir = nil
2839 end 2934 end
2840 returnpath = to.sub("@", @mailadmsuffix+"-@")
2841 adminaddr = to.sub("@", @mailadmsuffix+"@") 2935 adminaddr = to.sub("@", @mailadmsuffix+"@")
2842 subj = @params['subject'] || "Message from "+@myname
2843 if bracket == "NONE" 2936 if bracket == "NONE"
2844 sjtag = "" 2937 sjtag = ""
2845 tagre = nil 2938 tagre = nil
2846 else 2939 else
2847 sjtag = bracket.gsub("%n", nickname(name)). 2940 sjtag = bracket.gsub("%n", nickname(name)).
2850 tagpt = Regexp.quote(bracket). # compute bracket pattern 2943 tagpt = Regexp.quote(bracket). # compute bracket pattern
2851 gsub("%n", Regexp.quote(nickname(name))). 2944 gsub("%n", Regexp.quote(nickname(name))).
2852 gsub("%i", Regexp.quote(name)). 2945 gsub("%i", Regexp.quote(name)).
2853 gsub(/%(\d*)c/, '\d+') 2946 gsub(/%(\d*)c/, '\d+')
2854 tagre = Regexp.new(tagpt) 2947 tagre = Regexp.new(tagpt)
2855 subj = sjtag.strip+" "+subj.gsub(Regexp.new(tagpt), "") 2948 if !viamail
2949 subj = sjtag.strip+" "+subj.gsub(Regexp.new(tagpt), "")
2950 end
2856 end 2951 end
2857 if viamail then 2952 if viamail then
2858 body = tagify_subj(STDIN.readlines, sjtag, tagre, fromhack).join 2953 body = tagify_subj(STDIN.readlines, sjtag, tagre, fromhack).join
2859 elsif fromhack # via http 2954 elsif fromhack # via http
2860 from = rewritefrom(@params['user'], nick, groupmode ? to : sender) 2955 from = rewritefrom(user, nick, groupmode ? to : returnpath)
2861 end 2956 end
2862 header = { 2957 header = {
2863 "X-ML-Driver" => ($hgid || @myname), 2958 "X-ML-Driver" => ($hgid || @myname),
2864 "X-ML-Driver-URI" => $myurl, 2959 "X-ML-Driver-URI" => $myurl,
2960 "Return-path" => returnpath
2865 } 2961 }
2866 if groupmode 2962 if groupmode
2867 header["Reply-to"] = to 2963 header["Reply-to"] = to
2868 header["X-ML-Name"] = xmlname 2964 header["X-ML-Name"] = xmlname
2869 header["X-ML-URI"] = sprintf("%s?-groupman+%s", @opt['url'], name) 2965 header["X-ML-URI"] = sprintf("%s?-groupman+%s", @opt['url'], name)
2870 header["Return-path"] = returnpath
2871 end 2966 end
2872 Dir.chdir @mydir 2967 Dir.chdir @mydir
2873 if groupmode 2968 if groupmode # (#includeself)
2874 rcpts = if grepgroup(name) 2969 rcpts = if viamail
2875 @sc.members(name) 2970 @sc.members(name)
2876 else 2971 else
2877 [name] 2972 @sc.members(name) + [user]
2878 end.collect {|u| mailaddress(u, name).split(/,\s*|\s+/)}.flatten 2973 end.collect {|u|
2974 mailaddress(u, name).split(/,\s*|\s+/)}.flatten.uniq
2879 else 2975 else
2880 rcpts = @sc.mailaddress(name).split(/,\s*|\s+/).flatten 2976 rcpts = @sc.mailaddress(name).split(/,\s*|\s+/).flatten
2881 rcpts += @sc.mailaddress(user).split(/,\s*|\s+/).flatten # +sender 2977 rcpts += @sc.mailaddress(user).split(/,\s*|\s+/).flatten # +sender
2882 end 2978 end
2883 ENV["QMAILINJECT"] = "r" # for ML mode, use verp 2979 # ENV["QMAILINJECT"] = "r" # for ML mode, use verp
2884 # 2980 # For vodafone, QMAILINJECT=r doesn't work correctly
2885 # On mail mode, check if sender can send message to list. 2981 # On mail mode, check if sender can send message to list.
2886 if viamail && @sc.getgroupattr(name, 'limitsender') 2982 if viamail && @sc.getgroupattr(name, 'limitsender')
2887 s = ENV['SENDER'] 2983 s = ENV['SENDER']
2888 if !catch(:senderok) { 2984 if !catch(:senderok) {
2889 throw :senderok, true if rcpts.grep(s)[0] 2985 throw :senderok, true if rcpts.grep(s)[0]
2905 spooling ? mldir : nil) 3001 spooling ? mldir : nil)
2906 if !viamail then 3002 if !viamail then
2907 @O.print @H.elementln("h1"){msg('sendall_done')} 3003 @O.print @H.elementln("h1"){msg('sendall_done')}
2908 @O.print @H.p(sprintf(msg('sendall_head'), 3004 @O.print @H.p(sprintf(msg('sendall_head'),
2909 nickname(name))+" "+msg('done')) 3005 nickname(name))+" "+msg('done'))
3006 @O.print @H.elementln("pre"){extract_report[1]}
2910 link2home() 3007 link2home()
2911 @O.print footer() 3008 @O.print footer()
2912 return true 3009 return true
2913 end 3010 end
2914 exit 0 3011 exit 0
2928 @mybase+' '+msg('sendall').sub("<br>", " ") 3025 @mybase+' '+msg('sendall').sub("<br>", " ")
2929 } 3026 }
2930 @O.print @H.elementln("h2") { 3027 @O.print @H.elementln("h2") {
2931 sprintf(msg('sendall_head'), nickname(name)) 3028 sprintf(msg('sendall_head'), nickname(name))
2932 } 3029 }
2933 list = groupmode ? @sc.members(name) : [name, user] 3030 if groupmode # (#includeself)
2934 @O.print @H.p(sprintf("%s: %s", msg('member'), 3031 list = @sc.members(name) # +user
3032 else
3033 list = [name, user]
3034 end
3035 @O.print @H.p(sprintf("%s: %s", msg('rcptto'),
2935 list.collect {|u| 3036 list.collect {|u|
2936 @H.element("abbr", "title"=>u){ 3037 @H.element("abbr", "title"=>u){
2937 @sc.nickname(u) 3038 @sc.nickname(u)
2938 } 3039 }
2939 }.join(",\n"))) 3040 }.join(",\n")))
2940 @O.print @H.p(sprintf("(total %d)", list.length))+"\n" 3041 @O.print @H.p(sprintf("(total %d)", list.length))+"\n"
2941 @O.print \ 3042 @O.print \
2942 @H.elementln("form", {'action' => @myname+'?-list', 'method'=>"POST"}) { 3043 @H.elementln("form", {
3044 'action' => @myname+'?-list', 'method'=>"POST",
3045 'enctype' => "multipart/form-data"}) {
2943 @H.elementln("table"){ 3046 @H.elementln("table"){
3047 @H.elementln("tr"){
3048 @H.element("td"){"To"} + \
3049 @H.element("td"){
3050 @H.element("code"){
3051 groupmode ? defaultmladdress(quoted(name)) : @sc.nickname(name)
3052 }
3053 }
3054 } + \
2944 @H.elementln("tr"){ 3055 @H.elementln("tr"){
2945 @H.element("td"){"Subject"} + \ 3056 @H.element("td"){"Subject"} + \
2946 @H.element("td"){ 3057 @H.element("td"){
2947 @H.text("subject", "", 40, 128) 3058 @H.text("subject", "", 40, 128)
3059 }
3060 } + \
3061 @H.elementln("tr"){
3062 @H.element("td"){"Attachment"} + \
3063 @H.element("td"){
3064 @H.element("input", "name"=>"attachment", "type"=>"file", 'multiple'=>true){}
2948 } 3065 }
2949 } + \ 3066 } + \
2950 @H.elementln("tr"){ 3067 @H.elementln("tr"){
2951 @H.element("td"){ 3068 @H.element("td"){
2952 msg('body') 3069 msg('body')
4097 query = ENV["QUERY_STRING"] 4214 query = ENV["QUERY_STRING"]
4098 else # executed from command line 4215 else # executed from command line
4099 query = ARGV.join("&") 4216 query = ARGV.join("&")
4100 end 4217 end
4101 4218
4102 for unit in query.split(/\&/) 4219 if ENV['CONTENT_TYPE'] &&
4103 if /^([a-z][-_0-9@%a-z.]*)=(.*)/i =~ unit 4220 %r,multipart/form-data.*boundary=(.*),i =~ ENV['CONTENT_TYPE']
4104 key, value = $1, $2 4221 boundary = $1
4105 #value.gsub!(/%(..)/){[$1.hex].pack("c")} # これでURLデコードが一発 4222 query.split("\r\n--"+boundary).each {|unit|
4106 decode!(value) 4223 if /Content-Disposition.*\bname=([\'\"])?(\S*)\1/i =~ unit
4107 decode!(key) 4224 argument.has_key?(key=$2) or argument[key]=[]
4108 value = Kconv::toeuc(value) # EUCに変換 4225 newvalue = Hash.new
4109 printf "[%s] = %s\n", key, value if $DEBUG 4226 if /^Content.*filename=([\'\"])?(\S*)\1/i =~ unit
4110 argument[key] = value 4227 newvalue['filename'] = $2
4228 end
4229 newvalue['value'] = unit.sub(/.*\r\n\r\n/m, "")
4230 if /^Content-type:\s*(\S*)/i =~ unit
4231 newvalue['content-type'] = $1
4232 else
4233 newvalue['value'].gsub!("\r\n", "\n")
4234 end
4235 argument[key] << newvalue
4236 end
4237 }
4238 if $DEBUG
4239 open("/tmp/body", "w"){|x|
4240 x.write query.split("\r\n--"+boundary+"\r\n")[-1]
4241 argument.each{|k,v|
4242 x.printf(" %s => %s\n", k.inspect, v.inspect)}
4243 x.printf("boundary=\n%s\n",boundary)
4244 x.printf("ENV=%s\n",ENV.inspect)
4245 x.write query}
4246 end
4247 else
4248 for unit in query.split(/\&/)
4249 if /^([a-z][-_0-9@%a-z.]*)=(.*)/i =~ unit
4250 key, value = $1, $2
4251 #value.gsub!(/%(..)/){[$1.hex].pack("c")} # これでURLデコードが一発
4252 decode!(value)
4253 decode!(key)
4254 value = Kconv::toeuc(value) # EUCに変換
4255 printf "[%s] = %s\n", key, value if $DEBUG
4256 argument[key] = value
4257 end
4111 end 4258 end
4112 end 4259 end
4113 argument 4260 argument
4114 end 4261 end
4115 def getcookie() 4262 def getcookie()

yatex.org