diff --git a/after5.rb b/after5.rb index 4d60e75..b63bc21 100755 --- a/after5.rb +++ b/after5.rb @@ -4,7 +4,7 @@ # Associative Scheduling Table - after5 # (C)2003, 2004, 2006, 2008, 2012, 2013 by HIROSE Yuuji [yuujigentei.org] # $Id: after5.rb,v 1.20 2012/12/03 15:54:20 yuuji Exp $ -# Last modified Mon Dec 16 10:56:24 2013 on firestorm +# Last modified Thu Dec 19 11:33:07 2013 on firestorm # See http://www.gentei.org/~yuuji/software/after5/ # ���Υ�����ץȤ�EUC����¸���Ƥ��������� $hgid = <<_HGID_.split[1..-2].join(" ") @@ -303,10 +303,12 @@ } map end - def ismembersemail(email) + def ismembersemail(email, grp = nil) @usermap.keys.each {|u| return u if u==email - return u if mailaddress(u).split(/,\s*|\s+/).grep(email)[0] + return u if mailaddress(u, grp).split(/,\s*|\s+/).collect{|m| + m.sub(/^(skip|off):/i, "") + }.grep(email)[0] } nil end @@ -350,7 +352,8 @@ end end def mailaddress(user, grp = nil) - grp ? mail4grp(user, grp) : \ + grp ? \ + mail4grp(user, grp) : \ (getuserattr(user, 'email') || user) end def setnickname(user, nickname) @@ -579,12 +582,21 @@ end end def mail4grp(usr, group) + # If members/user file contains only "skip:" keyword, + # return "skip:email@add.re.ss" + default = mailaddress(usr) file = File.expand_path((group+"/members/"+usr).untaint, @groupmapdir) if test(?s, file.untaint) - open(file, "r"){|f|f.gets.chomp}.untaint - else - mailaddress(usr) + rcpt = open(file, "r"){|f|f.gets.chomp}.untaint + if /^(off|skip):/ =~ rcpt && /@/ !~ rcpt + rcpt = "skip:"+default + end + return rcpt end + default + end + def delivergrpmail(user, grp) + end def ismember(user, grouporuser) return user if user==grouporuser @@ -1354,6 +1366,7 @@ And then prepare .qmail-$mailprefix-default file as below. | ./#{@myname} -list"], 'sendall_head' => ['��%s�װ��Υᥤ������', "Send message to `%s'"], + 'sendmem_head' => ['��%s�פ��󰸤Υᥤ������', "Send message to `%s'"], 'sendall_note' => ['���С��ؤ�Ϣ������Ǥʤ������롼��������Ԥ����줫���������ݤ����Τʤɤˤ�ͭ�ѡ�', "Send this message to all of group."], 'sendall_done' => ['������λ', "sending message done"], @@ -1389,6 +1402,7 @@ 'Though you are not member of group A, you are treated as a member of A, if you join to the group B, which is a member of A. Think the nesting of groups carefully, please. Group administrator can change the group nickname.'], 'address2send' => ['��ʬ�����ä��Ƥ��륰�롼�פΥ��С��ꥹ�Ȥ���Ƭ����ʬ������ľ��ˤ���������ˤϡ�����ML����å�������ɤΰ�����������뤫��������롣������ML���Ȥ˼�ʬ�ؤ���������Ѥ�����衣', 'The first entry of member list of a group to which you belongs, is you. Entry box just after your name is for address list you want to deliver messages to that ML. Thus, you can define different addresses for each ML.'], + 'skip:' => ['ML�ؤ��������ѥᥤ�륢�ɥ쥹�ϡ����ɥ쥹�����˶������줺�� skip: ���դ�����Ͽ�Ǥ����(��: skip:hoge@example.com��ML��Ͽ���С��Τߤ���Ƥ����ML�˽񤤤ƥ��顼�򿩤�ä��Ȥ��ˤϡ���ƥ��ɥ쥹�� skip: �Ĥ�����Ͽ���Ȥ��Ȥ����衣', "You can prefix `skip:' without any blanks to email address to register POST-ONLY address for the ML(eg. skip:you@example.com). When you get rejecting message from ML which allows only members to post, try to add POST-ONLY address to your email addresses entry of that group."], 'wholemembers' => ['���롼���⥰�롼�פ��θ������ǡ����ߥ��롼�� %s �ؤ����Τϰʲ��Υ��С��������롣', "Consiering the groups registered in another group, notification to the group `%s' is send to members as follows."], 'noadmingroup' => ['�����Ǥ��륰�롼�פϤʤ��ä�', @@ -1683,11 +1697,12 @@ end def sendMail(to, subject, body, from=nil, rcptto=nil, header={}, thru=nil, spoolto=false) - # rcptto should be an Array + # rcptto should be an Array or nil body = NKF.nkf("-j", body) unless thru subject = NKF.nkf("-jM", (subject||"No subject").strip) to = safecopy(to) # cleanup tainted address subject.gsub!(/\n/, '') + rcptto.reject!{|i| /^(skip|off):/i =~ i} if rcptto.is_a?(Array) begin if (m=open("|-", "w")) header.each do |h, v| @@ -2776,20 +2791,29 @@ def extract_attachment(attachment) # Must return [text, href] strings to attached files href = ""; text = "" - dir = @attachmentdir + dir = @attachmentdir + Time.now.strftime("/%Y%m") if %r,(https?://[^/]+), =~ @opt['url'] server = $1 else msg = "`url' not set in after5.cf" return [msg, msg] end - + kakasi = @opt['kakasi'] && @opt['kakasi']+" -Ha -Ka -Ja -Ea -ka" urlbase = sprintf("%s%s/%s", server, File.dirname(ENV['SCRIPT_NAME']), dir) count=0 attachment.each {|a| basename = safecopy(File.basename(a['filename'])) - filename = safecopy(dir+"/"+basename) + encname = (kakasi ? + IO.popen(kakasi, "r+") do |k| + k.puts basename + k.close_write # force flush + k.gets.chomp.downcase + end + : + basename + ).gsub(/([^-_0-9a-z=,.@])/){"~"+$1.unpack("H*")[0].to_s} + filename = safecopy(dir+"/"+encname) umask = File.umask(022) sz = a['value'].bytesize next if sz == 0 @@ -2801,12 +2825,13 @@ next end begin - (test(?d, dir) && test(?w, dir)) or Dir.mkdir(dir) + require 'fileutils' + (test(?d, dir) && test(?w, dir)) or FileUtils.mkdir_p(dir) open(filename, "w") {|x| x.write a['value']} File.chmod(0664, filename) - text += sprintf("%d: %s/%s\n", count, urlbase, basename) + text += sprintf("%d: %s/%s\n", count, urlbase, encname) href += sprintf("%d: %s/%s\n", - count, filename, urlbase, basename) + count, filename, urlbase, encname) rescue ensure File.umask(umask) @@ -2841,7 +2866,7 @@ if viamail then prohibitviahttp() name = unquoted(ENV['DEFAULT']) - user = @sc.ismembersemail(ENV['SENDER']) + user = @sc.ismembersemail(ENV['SENDER']) # should here be (,name)?? if Regexp.new("(.*)("+Regexp.quote(@mailadmsuffix)+")") =~ name # To: GROUP/adm*@domain # -> Forward to group administrator(s) @@ -2883,7 +2908,7 @@ end nick = @sc.nickname(user) from = sprintf("%s <%s>", nick, user) - subj = @params['subject'][0]['value'] || "Message from "+@myname + subj = @params['subject'][0]['value'].toeuc || "Message from "+@myname body = @params['body'][0]['value'].gsub("\r", "").untaint # Extract attachment file if @params['attachment'].is_a?(Array) @@ -2985,7 +3010,7 @@ s = ENV['SENDER'] if !catch(:senderok) { throw :senderok, true if rcpts.grep(s)[0] - throw :senderok, true if @sc.ismembersemail(s) + throw :senderok, true if @sc.ismembersemail(s, name) } # sender is not allowed to send to ML sendMail(s, "You are not allowed to send to this ML", @@ -3003,9 +3028,9 @@ spooling ? mldir : nil) if !viamail then @O.print @H.elementln("h1"){msg('sendall_done')} - @O.print @H.p(sprintf(msg('sendall_head'), + @O.print @H.p(sprintf(msg(groupmode ? 'sendall_head' : 'sendmem_head'), nickname(name))+" "+msg('done')) - @O.print @H.elementln("pre"){extract_report[1]} + @O.print @H.elementln("pre"){extract_report[1].toeuc} link2home() @O.print footer() return true @@ -3312,9 +3337,12 @@ } + \ '' + \ @H.p(msg('address2send')) + \ + @H.p(msg('skip:')) + \ @H.p(msg('groupwarn', 'shortnameplz')) + \ @H.submit_reset("GO") } # form + link2home() + @O.print footer() end def groupnamesString() @H.elementln("p", {'class'=>'listup'}){ @@ -4228,7 +4256,7 @@ if /^Content.*filename=([\'\"])?(\S*)\1/i =~ unit newvalue['filename'] = $2 end - newvalue['value'] = unit.sub(/.*\r\n\r\n/m, "") + newvalue['value'] = unit.sub(/.*?\r\n\r\n/m, "") # Shortest match if /^Content-type:\s*(\S*)/i =~ unit newvalue['content-type'] = $1 else