[comp.lang.icon] Message conventions

Paul_Abrahams%Wayne-MTS@UM.CC.UMICH.EDU (01/02/91)

 
This isn't exactly an Icon question, but.....
 
I've noticed that in many of the postings to icon-group, the messages have
excerpts from previous messages preceded by "> ".  Could anyone let me know
what software you're using to get this effect, and how you're using it? 
Thanks. 
 
Paul Abrahams
abrahams%wayne-mts@um.cc.umich.edu

ron@mlfarm.com (Ronald Florence) (01/02/91)

Paul Abrahams writes:
 
 > I've noticed that in many of the postings to icon-group, the messages have
 > excerpts from previous messages preceded by "> ".  Could anyone let me know
 > what software you're using to get this effect, and how you're using it? 
 > Thanks. 

The convention is used by many mailers and news readers, including the
Gnu Emacs mail readers, Elm, rn, and others.  Here is a short icon
program which will accomplish the same thing.  You can either pipe a
news-article or mail-item to `reply' directly from your mail or news
reader, or save the news-article or mail-item in a file and run
`reply' with the file as input.  You will have to customize edstr and
host to suit your editor and system, and may have to customize the
addressing conventions at the end of the code.  This should work for
Unix or ms-dos (the ms-dos is untested).  It may be useful on VMS or
other operating systems with some modifications.

---------------------------[reply.icn]---------------------------
# reply.icn
# ron@mlfarm.com, 2 Jan 91
# usage: reply < news-article or mail-item
#
# Configure edstr and host as needed for your editor and mail feed.

procedure main()

  find("UNIX",&features) & {
    console := "/dev/tty"
    tmpfile := "/tmp/"
  }
  find("MS-DOS",&features) & {
    console := "CON"
    tmpfile := ""
  }
  &clock ? while tab(upto(&digits)) do tmpfile ||:= tab(many(&digits))
  tmpfile ||:= ".tmp"

  edstr := "vi " || tmpfile || " < " || console
  host := "mlfarm.com"

  eoh := 0
  reply := open(tmpfile, "w") | stop("reply: cannot open temp file")
  while s := read() do {
    eoh = 1 & {
      write(reply, " > ", s)
      next
    }
    (match("From: ", s) | match("Reply-To: ", s)) & {
      start := s[find(" ",s)+1:0]
      if find("<", s) then {
	fullname := trim(start ? tab(upto("<")))
	address := s[find("<",s)+1:find(">",s)] 
      }
      else {
	address := trim(start ? tab(upto("(")) | tab(0))
	fullname := s[find("(",s)+1:find(")",s)]
      }
      quoter := (\fullname | address)
    }
    match("Date: ", s) & date := s[7:0]
    match("Message-Id: ", s) & id := s[find("<",s):find(">",s)+1]
    match("Subject: ", s) & subject := s
    match("Newsgroup: ", s) & newsgroup := (s ? tab(upto(",")) | tab(0))
    (\address & not any(&ascii, s)) & {
      eoh := 1
      write(reply, "In-reply-to: ", quoter, "'s message of ", date);
      \subject & write(reply, subject)
      \newsgroup & write(reply, newsgroup)
      write(reply, "\nIn ", id, ", ", quoter, " writes:\n")
    }
  }
  system(edstr)
  stdin := open(console, "r")
  writes("Send y/n? ")
  upto('nN',read(stdin)) & {
    remove(tmpfile)
    stop("Reply aborted.")
  }
  find("@",address) & address ? {
    name := tab(upto("@"))
    move(1)
    address := (tab(upto(" ")) | tab(0)) || "!" || name
  }
  address ||:= "@" || host
  mailstr := "mail " || address || " < " || tmpfile
  system(mailstr)
  write("Reply sent to " || address)
  remove(tmpfile)
end
-------------------------------[end]------------------------------
--

Ronald Florence			ron@mlfarm.com

ron@mlfarm.com (Ronald Florence) (01/06/91)

The version of reply.icn I posted earlier contained a subtle bug that
could break on some obscure headers.  The version below fixes the bug,
adds additional functionality, and thanks to Richard Goerwitz,
includes more robust code to create a temporary filename.  I've also
substituted some of Richard's elegant constructions for my quick and
dirty Icon hacks.

[Ralph -- use this version, please.]


----------------------------[reply.icn, 1.1]---------------------------
# reply.icn - replies to news or mail
# version 1.1 (ron@mlfarm.com, 5 Jan 91)
#
# usage: reply [quote-prefix] < news-article or mail-item
#
# Configuration:
#   - change smarthost to the name of your upstream mail feed.
#   - change the default editor for your operating system, or use the
#     EDITOR environment variable.
#   - if your upstream mail feed will not accept addresses in the format
#     site.domain!user@upstream-host.domain, you may need to change the
#     address parsing code.
#
# The default quote-prefix is " > ".

procedure main(arg)
  
  smarthost := "mlfarm.com"

  if find("UNIX", &features) then {
    console := "/dev/tty"
    tmpdir := "/tmp/"
    editor := "/bin/vi"
  }
  else if find("MS-DOS", &features) then {
    console := "CON"
    tmpdir := ""
    editor := "edlin"
  }
  else stop("reply: unsupported operating system")

  every tmpfile := tmpdir || "reply." || right(1 to 999,3,"0") do
    close(open(tmpfile)) | break
  reply := open(tmpfile, "w") | stop("reply: cannot open temp file")
  every s := !&input do s ? {
    =("From: " | "Reply-To: ") & {
      if find("<") then {
	fullname := trim(tab(upto('<')))
	address := (move(1), tab(find(">")))
      }
      else {
	address := trim(tab(upto('(') | 0))
	fullname := (move(1), tab(find(")")))
      }
      quoter := (\fullname | address)
    }
    =("Date: ") & date := tab(0)
    =("Message-Id: ") & id := (tab(find("<")), tab(find(">")+1))
    match("Subject: ") & subject := s
    match("Newsgroups: ") & newsgroup := tab(upto(',') | 0)
    match("References: ") & refs := s
    (\address & *s = 0) & {
      write(reply, "In-reply-to: ", quoter, "'s message of ", date);
      \subject & write(reply, subject)
      \newsgroup & write(reply, newsgroup)
      \refs & write(reply, refs || " " || id)
      write(reply, "\nIn ", id, ", ", quoter, " writes:\n")
      break
    }
  }
  
  prefix := \arg[1] | " > "
  every write(reply, prefix, !&input)

  edstr := (getenv("EDITOR") | editor) || " " || tmpfile || " < " || console
  system(edstr)
  stdin := open(console, "r")
  writes("Send y/n? ")
  upto('nN',read(stdin)) & {
    remove(tmpfile)
    stop("Reply aborted.")
  }
  find("@",address) & address ? {
    name := tab(upto('@'))
    address := (move(1), tab(upto(' ') | 0)) || "!" || name
  }
  address ||:= "@" || smarthost
  mailstr := "mail " || address || " < " || tmpfile
  system(mailstr)
  write("Reply sent to " || address)
  remove(tmpfile)
end
----------------------------------[eof]--------------------------------
--

Ronald Florence			ron@mlfarm.com

ron@mlfarm.com (Ronald Florence) (01/07/91)

Oops!  Some mailers and news-posters use Message-ID; others use
Message-Id.  To make reply.icn robust enough to get both, change
"Message-Id: " in line 48 to "Message-I".
--

Ronald Florence			ron@mlfarm.com

ron@mlfarm.com (Ronald Florence) (01/08/91)

Walter Underwood <hsi!hpsdel.sde.hp.com!wunder> writes:

 >    Oops!  Some mailers and news-posters use Message-ID; others use
 >    Message-Id.
 > 
 > The tags on header lines should be matched ignoring upper/lower case.
 > "mEsSaGe-iD:" is a perfectly legal tag, and equivalent to "Message-ID:".
 > The program may never see random case tags, but it will probably see all
 > upper case tags.  Anyway, the "right" fix is a case-insensitive match.

Walter is right (he even quoted RFC 822).  I'll spare everyone another
posting of reply.icn.  If anyone wants a version with the fix, write
me.  
--

Ronald Florence			ron@mlfarm.com