ron@mlfarm.com (Ronald Florence) (01/09/91)
It won't put gnus-post or Pnews out of business, but it works, both for original postings and follow-ups. The code borrows from Richard Goerwitz's tempname generator and from reply.icn. The limited ms-dos support is untested. Perhaps someone can suggest how to include support for VMS or other systems in this and reply.icn. I hope this is useful to someone. -- Ronald Florence ron@mlfarm.com #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # post.icn # This archive created: Wed Jan 9 10:26:12 1991 # By: Ronald Florence (Maple Lawn Farm, Stonington, CT) export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'post.icn' then echo shar: "will not over-write existing file 'post.icn'" else cat << \SHAR_EOF > 'post.icn' ############################################################################ # # Name: post.icn # # Title: News Poster # # Author: Ronald Florence (ron@mlfarm.com) # # Date: January 8, 1991 # ############################################################################ # # This program posts a news article to Usenet via uux or mail. # Given an optional argument (the name of a file containing a # news article), it creates a follow-up article, with an # attribution and quoted text. # # usage: post [news-article] # ############################################################################ # # Configure: smarthost, mode, editor or EDITOR environment variable. # ############################################################################ # # Requires: UNIX or MS-DOS. # Bugs: ms-dos requires hard-coded system info. # ############################################################################ global sitename, domain, tz procedure main(arg) smarthost := "news-feed" # Your news feed. mode := "uux" # Use "mail" for a sendnews feed. domain := ".UUCP" if (find("UNIX", &features) & find("pipes", &features)) then { console := "/dev/tty" tmpdir := "/tmp/" (inf := open("logname", "pr")) & (logname := !inf) & close(inf) # Uuname sometimes pads with spaces. (inf := open("uuname -l", "pr")) & (sitename := trim(!inf)) & close(inf) (tz := getenv("TZ")) & tz ?:= (tab(many(&letters)), tab(upto(&letters))) sigfile := getenv("HOME") || "/.signature" editor := "/bin/vi" } else if find("MS-DOS", &features) then { console := "CON" tmpdir := "" logname := &null sitename := &null tz := &null # Hours off GMT. sigfile := &null editor := "edlin" } (\logname & \sitename & \tz) | stop("post: missing system info") article := open(tmpfile := tempname(tmpdir), "w") | stop("post: cannot write temp file") write(article, "Path: ", sitename, "!", logname) write(article, "From: ", logname, "@", sitename, domain) if \arg[1] then { inf := open(arg[1]) | { remove(tmpfile) stop("post: cannot read ", arg[1]) } reply_headers(inf, article) every write(article, " > ", !inf) close(inf) } else { write(article, query("Newsgroups: ")) write(article, query("Subject: ")) every write(article, req_headers()) write(article, "\n") } edstr := (getenv("EDITOR") | editor) || " " || tmpfile || " < " || console system(edstr) writes("Are you sure you want to post this to Usenet y/n? ") stdin := open(console) upto('nN', read(stdin)) & { remove(tmpfile) stop("Article aborted.") } # Try to append the .signature. \sigfile & (inf := open(sigfile)) & { article := open(tmpfile, "a") write(article, "--") every write(article, !inf) close(inf) } # Don't force an immediate poll. if find("uux", mode) then mode ||:= " - -r" # Sendnews format requires an initial `N'. else if find("mail", mode) then { inf := open(tmpfile) outf := open(tmp2 := tempname(tmpdir), "w") every write(outf, "N", !inf) remove(tmpfile) rename(tmp2, tmpfile) } mode ||:= " " || smarthost || "!rnews < " || tmpfile (system(mode) = 0) & write("Article posted!") remove(tmpfile) end procedure tempname(dir) every temp_name := dir || "article." || right(1 to 999,3,"0") do { close(open(temp_name)) & next suspend \temp_name } end procedure reply_headers(infile, art) every s := !infile do s ? { # Case-insensitive matches for headers. tab(match("from: ", map(&subject))) & { 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) } tab(match("date: ", map(&subject))) & date := tab(0) tab(match("message-id: ", map(&subject))) & id := tab(0) match("subject: ", map(&subject)) & subject := s match("newsgroups: ", map(&subject)) & newsgroup := tab(upto(',') | 0) match("references: ", map(&subject)) & refs := s (\quoter & *s = 0) & { # Newsgroup and subject are required. write(art, \newsgroup | query("Newsgroup: ")) write(art, \subject | query("Subject: ")) # Message-ID and Date go here. every write(art, req_headers()) # Threaded readers need References. write(art, \refs | "References:", " ", id) write(art, "In-reply-to: ", quoter, "'s message of ", date) write(art, "\nIn ", id, ", ", quoter, " writes:\n") return } } end procedure req_headers() # Crude, but it's a unique id. uniq := "<" &date || &clock ? while tab(upto(&digits)) do uniq ||:= tab(many(&digits)) uniq ||:= "@" || sitename || domain || ">" # Date in RFC 822 format. &dateline ? { month := left((tab(find(" ")+1), tab(many(&letters))), 3) || " " date := (tab(upto(&digits)), tab(many(&digits))) || " " || month date ||:= (tab(upto(&digits)), right(tab(many(&digits)), 2)) } # GMT would be better; this is allowed. if (tz > 0) then zone := " -" else zone := " +" zone ||:= left(right(abs(tz), 2, "0"), 4, "0") suspend "Message-ID: " || uniq suspend "Date: " || date || " " || &clock || zone end procedure query(prompt) writes(prompt) ans := read() return prompt || ans end SHAR_EOF if test 5403 -ne "`wc -c < 'post.icn'`" then echo shar: "error transmitting 'post.icn'" '(should have been 5403 characters)' fi fi exit 0 # End of shell archive -- Ronald Florence ron@mlfarm.com
ron@mlfarm.com (Ronald Florence) (01/12/91)
This patch will add (Full Name) to the From line of outgoing postings from post.icn. Most of the changes are added lines, so if you don't have `patch' it shouldn't be too onerous to do manually. If your passwd file keeps full names between a "-" and a "(", try setting "unixtype" to "usg". Use "bsd" for Xenix, V7 or other passwd files which have the full name the first item after the colon in the field. The ms-dos support relies on a hard-coded full name (ugh!). *** post.icn~ Tue Jan 8 19:57:00 1991 --- post.icn Thu Jan 10 23:15:24 1991 *************** *** 19,25 **** # ############################################################################ # ! # Configure: smarthost, mode, editor or EDITOR environment variable. # ############################################################################ # --- 19,25 ---- # ############################################################################ # ! # Configure: smarthost, mode, unixtype, editor or EDITOR env. variable. # ############################################################################ # *************** *** 34,39 **** --- 34,40 ---- smarthost := "news-feed" # Your news feed. mode := "uux" # Use "mail" for a sendnews feed. + unixtype := "bsd" # Use "usg" for "-Full Name(" passwd file. domain := ".UUCP" if (find("UNIX", &features) & find("pipes", &features)) then { *************** *** 43,48 **** --- 44,57 ---- # Uuname sometimes pads with spaces. (inf := open("uuname -l", "pr")) & (sitename := trim(!inf)) & close(inf) (tz := getenv("TZ")) & tz ?:= (tab(many(&letters)), tab(upto(&letters))) + \logname & (inf := open("/etc/passwd")) & every s := !inf do s ? { + =(logname) & { + every tab(upto(':')+1) \4 + if find("bsd", unixtype) then fullname := tab(upto(':')) + else fullname := (tab(upto('-')+1), tab(upto('('))) + break + } + } sigfile := getenv("HOME") || "/.signature" editor := "/bin/vi" } *************** *** 52,57 **** --- 61,67 ---- logname := &null sitename := &null tz := &null # Hours off GMT. + fullname := &null sigfile := &null editor := "edlin" } *************** *** 59,65 **** article := open(tmpfile := tempname(tmpdir), "w") | stop("post: cannot write temp file") write(article, "Path: ", sitename, "!", logname) ! write(article, "From: ", logname, "@", sitename, domain) if \arg[1] then { inf := open(arg[1]) | { --- 69,77 ---- article := open(tmpfile := tempname(tmpdir), "w") | stop("post: cannot write temp file") write(article, "Path: ", sitename, "!", logname) ! writes(article, "From: ", logname, "@", sitename, domain) ! \fullname & writes(article, " (", fullname, ")") ! write(article) if \arg[1] then { inf := open(arg[1]) | { -- Ronald Florence ron@mlfarm.com