home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / lang / perl / 4975 < prev    next >
Encoding:
Internet Message Format  |  1992-07-27  |  10.7 KB

  1. Path: sparky!uunet!usc!sol.ctr.columbia.edu!emory!wrdis01!mcgough
  2. From: mcgough@wrdis01.af.mil (Jeffrey B. McGough)
  3. Newsgroups: comp.lang.perl
  4. Subject: Pgnews 2.0 (Larry Wall Please Look)
  5. Message-ID: <2844@wrdis01.af.mil>
  6. Date: 27 Jul 92 18:28:58 GMT
  7. Distribution: na
  8. Organization: 1926CCSG Robins AFB
  9. Lines: 365
  10.  
  11. Hey,
  12.  
  13. Well this is the next version of pgnews say pgnews 2.0? [:^)
  14.  
  15. The additions to this version are:
  16. Make the From_ line more rfc976 compliant for mailers like ELM...
  17. This was supplied by Chris Sherman sherman@unx.sas.com...
  18. Thanks Chris...
  19.  
  20. Added -h option to allow command line specification of NNTP
  21. server.
  22. Thanks to Barry Hassler...
  23.  
  24. Added $VERSION, no it doesn't do anything it just hangs around [:^)
  25.  
  26. Added 15 minute timeout to the select stuff so that it would not
  27. hang on a dead socket...
  28. Exception:
  29. While actually slurping up the article the select does not work???
  30. Barry Hassler seems to think that at that point PERL has
  31. already sucked the whole thing into its own memory buffers...
  32. Leaving nothing for the select to work on.
  33. Care to comment Larry???
  34. Anyway I have commented out that particular select until we can get
  35. some kind of work around... any takers [:^)
  36.  
  37. Jeffrey B. McGough
  38. .sig at the end...
  39.  
  40. --- pgnews below ---
  41. #! /bin/sh
  42. # This is a shell archive.  Remove anything before this line, then unpack
  43. # it by saving it into a file and typing "sh file".  To overwrite existing
  44. # files, type "sh file -c".  You can also feed this as standard input via
  45. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  46. # will see the following message at the end:
  47. #        "End of shell archive."
  48. # Contents:  pgnews
  49. # Wrapped by mcgough@wrdis01 on Mon Jul 27 14:17:14 1992
  50. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  51. if test -f 'pgnews' -a "${1}" != "-c" ; then 
  52.   echo shar: Will not clobber existing file \"'pgnews'\"
  53. else
  54. echo shar: Extracting \"'pgnews'\" \(8260 characters\)
  55. sed "s/^X//" >'pgnews' <<'END_OF_FILE'
  56. X#!/usr/local/bin/perl 
  57. X#/****************************************************
  58. X#*****************************************************
  59. X#**
  60. X#** SOURCE NAME | pgnews, (Perl Get News)
  61. X#**             | 
  62. X#**    SYNOPSIS | pgnews [-h hostname]
  63. X#**             | 
  64. X#** DESCRIPTION | pgnews goes to a specified NNTP server
  65. X#**             | and retrieves news articles by newsgroup
  66. X#**             | and saves them to a specified file in
  67. X#**             | mailbox format.
  68. X#**             | Please see the NOTES section.
  69. X#**             | 
  70. X#**     CHANGES | Programmer:         Date:     Reason/Comments
  71. X#**             | Jeffrey B. McGough  09-05-91  initial
  72. X#**             | Jeffrey B. McGough  09-06-91  Added select (see FIXES)
  73. X#**             | Jeffrey B. McGough  10-06-91  Fixed erronious end of article
  74. X#**             | Jeffrey B. McGough  07-09-92  Fixed dup article bug
  75. X#**             | Jeffrey B. McGough  07-13-92  (See FIXES)
  76. X#**             | Jeffrey B. McGough  07-27-92  VERSION 2.0 (See FIXES)
  77. X#**             | 
  78. X#**       NOTES | Pgnews needs a file named .pgnews to read
  79. X#**             | its newsgroup, last message, and savefile from.
  80. X#**             | .pgnews format is:
  81. X#**             | newsgroup number savefile
  82. X#**             | Example:
  83. X#**             | comp.unix.wizards 7800 cuw
  84. X#**             | comp.unix.shell 3203 cus
  85. X#**             | comp.unix.questions 546 cuq
  86. X#**             | 
  87. X#**             | comp.unix.wizards will be saved to file cuw in
  88. X#**             | mailbox format starting at article 7800 etc.
  89. X#**             | 
  90. X#**       FIXES | 09-06-91: added select on S to keep the client
  91. X#**             | from getting out of sync.
  92. X#**             | Jeffrey B. McGough  mcgough@wrdis01.af.mil
  93. X#**             | 
  94. X#**             | 10-06-91: Fixed an overlooked END of ARTICLE
  95. X#**             | bug... Thanks to a member(s) of the issos
  96. X#**             | group at Ohio State.
  97. X#**             | Jeffrey B. McGough  mcgough@wrdis01.af.mil
  98. X#**             | 
  99. X#**             | 07-09-92: Fixed a duplicate article bug
  100. X#**             | pointed out to me by kenr@bridge.cc.rochester.edu
  101. X#**             | and gort@bridge.cc.rochester.edu. Thanks
  102. X#**             | for the help with the fix.
  103. X#**             | Jeffrey B. McGough  mcgough@wrdis01.af.mil
  104. X#**             | 
  105. X#**             | 07-13-92: Added code to take a -h option
  106. X#**             | for a host to use as a server...
  107. X#**             | Thanks to Barry Hassler...
  108. X#**             | Added code written by sherman@unx.sas.com
  109. X#**             | to make the header From_ line more RFC976
  110. X#**             | compatable for the ELM mailer...
  111. X#**             | Jeffrey B. McGough  mcgough@wrdis01.af.mil
  112. X#**             | 
  113. X#**             | 07-27-92: Added 15 minute timeout to the
  114. X#**             | select stuff. Just in case the server goes
  115. X#**             | away we won't sit around forever listening
  116. X#**             | to a dead connection...
  117. X#**             | Exception to the time out:
  118. X#**             | While in the loop where we slurp up the
  119. X#**             | article from the server, the select will not
  120. X#**             | work...
  121. X#**             | A friend of mine (Barry Hassler) seems to think
  122. X#**             | that at that point Perl has already sucked
  123. X#**             | the whole thing into its own buffers...
  124. X#**             | Care to comment Larry?
  125. X#**             | Anyway I commented out that select. If anyone
  126. X#**             | has any ideas please let me know...
  127. X#**             | Went ahead and built VERSION 2.0
  128. X#**             | Jeffrey B. McGough  mcgough@wrdis01.af.mil
  129. X#**             | 
  130. X#****************************************************/
  131. X
  132. Xrequire 'sys/socket.ph'; # The way I coded the sockets is this necessary?
  133. X
  134. X$VERSION = '2.0';
  135. X
  136. X$port = 119; # For NNTP
  137. X# HOSTNAME for the server...
  138. X#$host = 'localhost';
  139. X$host = 'emory.mathcs.emory.edu';
  140. X# Pack format...
  141. X$sockaddr = 'S n a4 x8';
  142. X
  143. X$DOMAIN = 2;
  144. X$STYLE = 1;
  145. X
  146. Xwhile ($arg = shift(@ARGV))
  147. X{
  148. X    if ($arg =~ /-.*h/)
  149. X    {
  150. X        $host=shift(@ARGV);
  151. X        if ($host eq "")
  152. X        {
  153. X            printf ("Need host name after -h\n");
  154. X            exit 1;
  155. X        }
  156. X        next;
  157. X    }
  158. X
  159. X    printf "Unknown option: '%s'\n", $arg;
  160. X    exit 1;
  161. X}
  162. X
  163. X
  164. X$newsfile = '.pgnews';
  165. X$nnewsfile = '.pgnews.new';
  166. X
  167. X$rin = $rout = '';
  168. X
  169. X($name, $aliases, $proto) = getprotobyname('tcp');
  170. X($name, $aliases, $type, $len, $hostaddr) = gethostbyname($host);
  171. X
  172. X$sock = pack($sockaddr, $DOMAIN, $port, $hostaddr);
  173. X
  174. Xsocket(S, $DOMAIN, $STYLE, $proto) || die $!;
  175. Xconnect(S, $sock) || die $!;
  176. Xselect(S); $| = 1; select(STDOUT);
  177. X#set up for select
  178. Xvec($rin, fileno(S), 1) = 1;
  179. X#this select will block until the server gives us something.
  180. X$nfound = select($rout=$rin, undef, undef, 900);
  181. Xif ($nfound == 0)
  182. X{
  183. X    print "Socket timed out...";
  184. X    exit 1;
  185. X}
  186. X$_ = <S>; #Read one line to see if we got a good connection.
  187. Xif ($_ !~ /^2../)
  188. X{
  189. X    print;
  190. X    die "Service unavailable";
  191. X}
  192. Xopen(GRP, "< $newsfile") || die "Could not open $newsfile: $!";
  193. Xopen(NGRP, "> $nnewsfile") || die "Could not open $nnewsfile: $!";
  194. Xselect(NGRP); $| = 1; select(STDOUT);
  195. Xwhile(<GRP>)
  196. X{
  197. X    chop;
  198. X    ($grp, $lgot, $file) = split;
  199. X    print(S "group $grp\n");
  200. X    #this select will block until the server gives us something.
  201. X    $nfound = select($rout=$rin, undef, undef, 900);
  202. X    if ($nfound == 0)
  203. X    {
  204. X        print "Socket timed out...";
  205. X        exit 1;
  206. X    }
  207. X    $_ = <S>; #Make sure the group change worked...
  208. X    ($stat, $num, $first, $last) = split;
  209. X    if( $stat !~ /^2../ )
  210. X    {
  211. X        print;
  212. X        warn "Bad group";
  213. X        print(NGRP "$grp $lgot $file\n");
  214. X        next;
  215. X    }
  216. X    # good group open output file...
  217. X    open(OUTFILE, ">>$file") || die "Could not open $file";
  218. X
  219. X    if ( $first > $lgot )
  220. X    {
  221. X        $lgot = $first;
  222. X    }
  223. X    if ( $lgot <= $last )
  224. X    {
  225. X        foreach $art ($lgot..$last)
  226. X        {
  227. X            print(S "article $art\n");
  228. X            #this select will block until the server gives us something.
  229. X            $nfound = select($rout=$rin, undef, undef, 900);
  230. X            if ($nfound == 0)
  231. X            {
  232. X                print "Socket timed out...";
  233. X                exit 1;
  234. X            }
  235. X            $_ = <S>; #get error if one exists
  236. X            if($_ !~ /^2../)
  237. X            {
  238. X                print;
  239. X                warn "No article by that number";
  240. X            }
  241. X            else
  242. X            {
  243. X# We now slurp the whole article into the array article...
  244. X# HMMM is this good or bad...
  245. X# It gives me the WILLIES   [:^)    Jeffrey B. McGough
  246. X                @article = ();
  247. X                do
  248. X                {
  249. X# The next few lines have been commented out because they don't work
  250. X# JBM 07-27-92
  251. X#                    $nfound = select($rout=$rin, undef, undef, 900);
  252. X#                    if ($nfound == 0)
  253. X#                    {
  254. X#                        print "Socket timed out...";
  255. X#                        exit 1;
  256. X#                    }
  257. X                    $lgot = $art;
  258. X                    $_ = <S>;
  259. X                    s/\r//;
  260. X                    if( $_ ne ".\n")
  261. X                    {
  262. X                        s/^\.//;
  263. X                        push(@article,$_);
  264. X                        s/^\./../;
  265. X                    }    
  266. X                    else
  267. X                    {
  268. X                        push(@article,"\n");
  269. X                    }
  270. X                } until $_ eq ".\n";
  271. X                # replace the Path: with a from line
  272. X                splice(@article, 0, 1, &from_line(@article));
  273. X                print OUTFILE @article;
  274. X            }
  275. X        }    
  276. X    }
  277. X    else
  278. X    {
  279. X        $lgot -= 1;
  280. X    }
  281. X    close(OUTFILE);
  282. X    $lgot += 1;
  283. X    print(NGRP "$grp $lgot $file\n");
  284. X}
  285. Xclose(NGRP);
  286. Xclose(GRP);
  287. Xsystem("mv $nnewsfile $newsfile");
  288. Xprint( S "quit\n");
  289. Xclose(S);
  290. X
  291. X# We parse through @article to build a more proper From_ line
  292. Xsub from_line
  293. X{
  294. X
  295. X    local(@article) = @_;
  296. X
  297. X    local($header) = $true;        # we are in the header of the mail
  298. X    local($date,$month,$year,$time,$day);
  299. X
  300. X    for (@article)
  301. X    {
  302. X        if ($header == $true)
  303. X        {
  304. X            if (/^Path: ([^ \n]+)/)
  305. X            {
  306. X                $path = $1;
  307. X            }
  308. X            elsif (/^Date: /)
  309. X            {
  310. X                if (/^Date: (\d*) (\D*) (\d*) (\S*)/) 
  311. X                {
  312. X                    $date = $1;
  313. X                    $month = $2;
  314. X                    $year = $3; 
  315. X                    $time = $4;
  316. X                }
  317. X                elsif (/^Date: (\D*), (\d*) (\D*) (\d*) (\S*)/)
  318. X                {
  319. X                    $day = $1;
  320. X                    $date = $2;
  321. X                    $month = $3;
  322. X                    $year = $4; 
  323. X                    $time = $5;
  324. X                }
  325. X                $year =~ s/^([0-9])([0-9])$/19$1$2/;    # convert 2 digit year to 4 
  326. X                if ($day eq "")
  327. X                {
  328. X                    $day = &day_of_week($month,$date,$year);
  329. X                }
  330. X            }
  331. X            $header = $false if /^\n$/;
  332. X        }
  333. X    }
  334. X    $from_line = sprintf("From %s %s %s %2s %s %s %s\n",
  335. X        $path, $day, $month, $date, $time, $year);
  336. X    return($from_line);
  337. X}
  338. X
  339. X# This gives us the day of week from the date...
  340. Xsub day_of_week
  341. X{
  342. X    local($month,$date,$year) = @_;
  343. X    local($day);
  344. X
  345. X
  346. X    if ($month <= 2)
  347. X    { 
  348. X        $month += 12;
  349. X        $year--;
  350. X    }
  351. X
  352. X    $day = ($date + $month * 2 + int(($month + 1) * 6 / 10) + $year + 
  353. X        int($year / 4) - int($year / 100) + int($year / 400) + 2) % 7;
  354. X
  355. X    if ($day == 0)
  356. X    {
  357. X         $day = 7;
  358. X    }
  359. X
  360. X    return (NULL, Sun, Mon, Tue, Wed, Thu, Fri, Sat, Sun)[$day];
  361. X}
  362. END_OF_FILE
  363. if test 8260 -ne `wc -c <'pgnews'`; then
  364.     echo shar: \"'pgnews'\" unpacked with wrong size!
  365. fi
  366. chmod +x 'pgnews'
  367. # end of 'pgnews'
  368. fi
  369. echo shar: End of shell archive.
  370. exit 0
  371. -- 
  372. Lator,                                       We cheat the other guy,
  373.                                              and pass the savings on to you.
  374. Jeffrey B. McGough
  375. WR-ALC UNIX Systems Administrator                    (mcgough@wrdis01.af.mil)
  376.