home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1993 #2
/
Image.iso
/
unix
/
wang40.zip
/
SA000042.TXT
Wrap
Text File
|
1993-06-15
|
42KB
|
1,567 lines
[ Article crossposted from alt.binaries.pictures.utilities ]
[ Author was Jonathan Wang ]
[ Posted on Mon, 14 Jun 1993 15:45:26 GMT ]
Some of my friends urged me to post this util for public use so that our
netters can use their time more productively, instead of wasting it by doing
those time consuming downloads and reassembling of files from USENET.
wang.c V4.0 is planned to be a friendly USENET download-and-assemble
utility, aimed at grabbing picture & audio files, zipped packages,
and any other uuencoded binary posts. Instead of: 1)saving the articles
from the newsreader, 2)getting rid of the news header and other trash,
3)concatenating them into proper order, and 4)piping it to uudecode, now all
you have to do is to type "wang". Use "wang -h" for further help.
Some old USENET folks may still remember the previous wang.c versions that
appeared last year. Thanks to hundreds of loyal wang.c users, I, as a
unix C newcomer, have the courage to keep updating this util to
a new version. The new version has a greatly enhanced ability to
"understand" the subject line, and most important of all, the ability
to access USENET directly without any newsreader.
wang.c is by no means meant to challenge the masterpiece pearl script
of aub, and the other existing decoders. The objective is only to facilitate
the lazy netters like myself who are satisfied at getting the job done,
instead of getting it done perfectly. After downloading this package,
you can simply type in "make wang", and then, type "wang". Boom! it goes.
Important Notice:
By default, wang will download EVERYTHING from one newsgroup at a time
if you don't specify a range. Take the group alt.binaries.pictures.misc
for example: it will take about half an hour to download some 150 pictures.
That means there exists the potential for filling up your disk and
slowing down your system. Please avoid using "nohup wang &" and log
off. KEEP your eyes on this monster! I advise my dear users to consult
the sysadms before using it.
I still haven't tested it thoroughly. All I can tell now is that
it will run on sysv, bsd and sunos. If you can get it compiled on
any other platforms, please let me know. Yes, theoretically, it will
run on any unix box which supports TCP/IP. No, it won't compile on a PC.
My sincere acknowledgement and admiration goes to Iain Lea, the author of
the famous tin newreader. All my networking code has been stolen from
this genius mind and subsequently adapted to solve this problem.
No Copyright is hereby claimed. Sell it if you can. But I do appreciate
if you will mention my name.
Jonathan Wang, June, 1933.
#! /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 the files:
# README
# nntplib.c
# nntplib.h
# nntpservers
# wang.c
# This archive created: Mon Jun 14 11:42:28 1993
export PATH; PATH=/bin:$PATH
if test -f 'README'
then
echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'
Some of my friends urged me to post this util for public use so that our
netters can use their time more productively, instead of wasting it by doing
those time consuming downloads and reassembling of files from USENET.
wang.c V4.0 is planned to be a friendly USENET download-and-assemble
utility, aimed at grabbing picture & audio files, zipped packages,
and any other uuencoded binary posts. Instead of: 1)saving the articles
from the newsreader, 2)getting rid of the news header and other trash,
3)concatenating them into proper order, and 4)piping it to uudecode, now all
you have to do is to type "wang". Use "wang -h" for further help.
Some old USENET folks may still remember the previous wang.c versions that
appeared last year. Thanks to hundreds of loyal wang.c users, I, as a
unix C newcomer, have the courage to keep updating this util to
a new version. The new version has a greatly enhanced ability to
"understand" the subject line, and most important of all, the ability
to access USENET directly without any newsreader.
wang.c is by no means meant to challenge the masterpiece pearl script
of aub, and the other existing decoders. The objective is only to facilitate
the lazy netters like myself who are satisfied at getting the job done,
instead of getting it done perfectly. After downloading this package,
you can simply type in "make wang", and then, type "wang". Boom! it goes.
Important Notice:
By default, wang will download EVERYTHING from one newsgroup at a time
if you don't specify a range. Take the group alt.binaries.pictures.misc
for example: it will take about half an hour to download some 150 pictures.
That means there exists the potential for filling up your disk and
slowing down your system. Please avoid using "nohup wang &" and log
off. KEEP your eyes on this monster! I advise my dear users to consult
the sysadms before using it.
I still haven't tested it thoroughly. All I can tell now is that
it will run on sysv, bsd and sunos. If you can get it compiled on
any other platforms, please let me know. Yes, theoretically, it will
run on any unix box which supports TCP/IP. No, it won't compile on a PC.
My sincere acknowledgement and admiration goes to Iain Lea, the author of
the famous tin newreader. All my networking code has been stolen from
this genius mind and subsequently adapted to solve this problem.
No Copyright is hereby claimed. Sell it if you can. But I do appreciate
if you will mention my name.
Jonathan Wang, June, 1933.
SHAR_EOF
fi # end of overwriting check
if test -f 'nntplib.c'
then
echo shar: will not over-write existing file "'nntplib.c'"
else
cat << \SHAR_EOF > 'nntplib.c'
/*
* Project : tin - a threaded Netnews reader
* Module : nntplib.c
* Author : S.Barber & I.Lea
* Created : 12-01-91
* Updated : 07-11-92
* Notes : NNTP client routines taken from clientlib.c 1.5.11 (10-02-91)
* Copyright : (c) Copyright 1991-93 by Stan Barber & Iain Lea
* Permission is hereby granted to copy, reproduce, redistribute
* or otherwise use this software as long as: there is no
* monetary profit gained specifically from the use or
* reproduction or this software, it is not sold, rented,
* traded or otherwise marketed, and this copyright notice
* is included prominently in any copy made.
*/
/**************************/
#define NNTP_ABLE 1
#define NNTP_ONLY 1
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <ctype.h>
#include "nntplib.h"
/**************************/
/* #include "tin.h" */
#ifdef NNTP_ONLY
# ifndef NNTP_ABLE
# define NNTP_ABLE
# endif
#endif
#ifndef CDROM_ABLE
FILE *nntp_rd_fp = NULL;
FILE *nntp_wr_fp = NULL;
extern int errno;
#ifdef NNTP_ABLE
# ifdef TLI
# include <fcntl.h>
# include <tiuser.h>
# include <stropts.h>
# include <sys/socket.h>
# ifdef WIN_TCP
# include <sys/in.h>
# else
# include <netinet/in.h>
# endif
# define IPPORT_NNTP ((unsigned short) 119)
# include <netdb.h> /* All TLI implementations may not have this */
# else
# ifdef apollo
# include </bsd4.3/usr/include/sys/socket.h>
# include </bsd4.3/usr/include/netinet/in.h>
# include </bsd4.3/usr/include/netdb.h>
# else
# include <sys/socket.h>
# include <netinet/in.h>
# ifndef EXCELAN
# include <netdb.h>
# endif
# endif
# endif /* !TLI */
# ifndef BSD
# define index(a,b) strchr(a,b)
# define bcopy(a,b,c) memcpy(b,a,c)
# define bzero(a,b) memset(a,'\0',b)
# endif
# ifdef EXCELAN
# if __STDC__
int connect (int, struct sockaddr *);
unsigned short htons (unsigned short);
unsigned long rhost (char **);
int rresvport (int);
int socket (int, struct sockproto *, struct sockaddr_in *, int);
# endif
# endif
# ifdef DECNET
# include <netdnet/dn.h>
# include <netdnet/dnetdb.h>
# endif
#endif /* NNTP_ABLE */
/*
* getserverbyfile Get the name of a server from a named file.
* Handle white space and comments.
* Use NNTPSERVER environment variable if set.
*
* Parameters: "file" is the name of the file to read.
*
* Returns: Pointer to static data area containing the
* first non-ws/comment line in the file.
* NULL on error (or lack of entry in file).
*
* Side effects: None.
*/
char *getserverbyfile (file)
char *file;
{
#ifdef NNTP_ABLE
register FILE *fp;
register char *cp;
static char buf[256];
if (cp = (char *) getenv ("NNTPSERVER")) {
(void) strcpy (buf, cp);
return (buf);
}
if (file == NULL)
return (NULL);
if ((fp = fopen (file, "r")) == NULL)
return (NULL);
while (fgets (buf, sizeof (buf), fp) != NULL) {
if (*buf == '\n' || *buf == '#') {
continue;
}
cp = (char *) index(buf, '\n');
if (cp) {
*cp = '\0';
}
(void) fclose (fp);
return (buf);
}
(void) fclose (fp);
#endif /* NNTP_ABLE */
return (NULL); /* No entry */
}
/*
* server_init Get a connection to the remote server.
*
* Parameters: "machine" is the machine to connect to.
* "service" is the service to connect to on the machine.
* "port" is the servive port to connect to.
*
* Returns: -1 on error
* server's initial response code on success.
*
* Side effects: Connects to server.
* "nntp_rd_fp" and "nntp_wr_fp" are fp's
* for reading and writing to server.
*/
int server_init (machine, service, port)
char *machine;
char *service;
unsigned short port;
{
#ifdef NNTP_ABLE
int sockt_rd, sockt_wr;
char line[256];
#ifdef DECNET
char *cp;
cp = (char *) index(machine, ':');
if (cp && cp[1] == ':') {
*cp = '\0';
sockt_rd = get_dnet_socket (machine, service);
} else {
sockt_rd = get_tcp_socket (machine, service, port);
}
#else
sockt_rd = get_tcp_socket (machine, service, port);
#endif
if (sockt_rd < 0)
return (-1);
/*
* Now we'll make file pointers (i.e., buffered I/O) out of
* the socket file descriptor. Note that we can't just
* open a fp for reading and writing -- we have to open
* up two separate fp's, one for reading, one for writing.
*/
if ((nntp_rd_fp = (FILE *) fdopen (sockt_rd, "r")) == NULL) {
perror ("server_init: fdopen #1");
return (-1);
}
sockt_wr = dup (sockt_rd);
#ifdef TLI
if (t_sync (sockt_rd) < 0) { /* Sync up new fd with TLI */
t_error ("server_init: t_sync");
nntp_rd_fp = NULL; /* from above */
return (-1);
}
#endif
if ((nntp_wr_fp = (FILE *) fdopen (sockt_wr, "w")) == NULL) {
perror ("server_init: fdopen #2");
nntp_rd_fp = NULL; /* from above */
return (-1);
}
/*
* Now get the server's signon message
*/
(void) get_server (line, sizeof (line));
return (atoi (line));
#else
return (-1);
#endif /* NNTP_ABLE */
}
/*
* get_tcp_socket -- get us a socket connected to the specified server.
*
* Parameters: "machine" is the machine the server is running on.
* "service" is the service to connect to on the server.
* "port" is the port to connect to on the server.
*
* Returns: Socket connected to the server if
* all is ok, else -1 on error.
*
* Side effects: Connects to server.
*
* Errors: Printed via perror.
*/
int get_tcp_socket (machine, service, port)
char *machine; /* remote host */
char *service; /* nttp/smtp etc. */
unsigned short port; /* tcp port number */
{
#ifdef NNTP_ABLE
int s = -1;
struct sockaddr_in sin;
#ifdef TLI
struct hostent *gethostbyname (), *hp;
struct t_call *callptr;
/*
* Create a TCP transport endpoint.
*/
if ((s = t_open ("/dev/tcp", O_RDWR, (struct t_info*) 0)) < 0){
t_error ("t_open: can't t_open /dev/tcp");
return (-1);
}
if (t_bind (s, (struct t_bind *) 0, (struct t_bind *) 0) < 0) {
t_error ("t_bind");
t_close (s);
return (-1);
}
bzero((char *) &sin, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_port = htons (port);
if (!isdigit(*machine) ||
(long)(sin.sin_addr.s_addr = inet_addr (machine)) == -1) {
if((hp = gethostbyname (machine)) == NULL) {
fprintf (stderr, "gethostbyname: %s: host unknown\n", machine);
t_close (s);
return (-1);
}
bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
}
/*
* Allocate a t_call structure and initialize it.
* Let t_alloc() initialize the addr structure of the t_call structure.
*/
if ((callptr = (struct t_call *) t_alloc (s,T_CALL,T_ADDR)) == NULL){
t_error ("t_alloc");
t_close (s);
return (-1);
}
callptr->addr.maxlen = sizeof (sin);
callptr->addr.len = sizeof (sin);
callptr->addr.buf = (char *) &sin;
callptr->opt.len = 0; /* no options */
callptr->udata.len = 0; /* no user data with connect */
/*
* Connect to the server.
*/
if (t_connect (s, callptr, (struct t_call *) 0) < 0) {
t_error ("t_connect");
t_close (s);
return (-1);
}
/*
* Now replace the timod module with the tirdwr module so that
* standard read() and write() system calls can be used on the
* descriptor.
*/
if (ioctl (s, I_POP, (char *) 0) < 0) {
perror ("I_POP(timod)");
t_close (s);
return (-1);
}
if (ioctl (s, I_PUSH, "tirdwr") < 0) {
perror ("I_PUSH(tirdwr)");
t_close (s);
return (-1);
}
#else /* !TLI */
#ifndef EXCELAN
struct servent *getservbyname(), *sp;
struct hostent *gethostbyname(), *hp;
#ifdef h_addr
int x = 0;
register char **cp;
static char *alist[1];
#endif /* h_addr */
unsigned long inet_addr();
static struct hostent def;
static struct in_addr defaddr;
static char namebuf[256];
if ((sp = getservbyname (service, "tcp")) == NULL) {
fprintf (stderr, "%s/tcp: Unknown service.\n", service);
return (-1);
}
/* If not a raw ip address, try nameserver */
if (!isdigit(*machine) ||
(long)(defaddr.s_addr = inet_addr (machine)) == -1)
hp = gethostbyname (machine);
else {
/* Raw ip address, fake */
(void) strcpy (namebuf, machine);
def.h_name = namebuf;
#ifdef h_addr
def.h_addr_list = alist;
#endif
def.h_addr = (char *) &defaddr;
def.h_length = sizeof (struct in_addr);
def.h_addrtype = AF_INET;
def.h_aliases = 0;
hp = &def;
}
if (hp == NULL) {
fprintf (stderr, "\n%s: Unknown host.\n", machine);
return (-1);
}
bzero((char *) &sin, sizeof (sin));
sin.sin_family = hp->h_addrtype;
sin.sin_port = sp->s_port;
#else /* EXCELAN */
bzero((char *) &sin, sizeof (sin));
sin.sin_family = AF_INET;
#endif /* EXCELAN */
/*
* The following is kinda gross. The name server under 4.3
* returns a list of addresses, each of which should be tried
* in turn if the previous one fails. However, 4.2 hostent
* structure doesn't have this list of addresses.
* Under 4.3, h_addr is a #define to h_addr_list[0].
* We use this to figure out whether to include the NS specific
* code...
*/
#ifdef h_addr
/*
* get a socket and initiate connection -- use multiple addresses
*/
for (cp = hp->h_addr_list; cp && *cp; cp++) {
s = socket (hp->h_addrtype, SOCK_STREAM, 0);
if (s < 0) {
perror ("socket");
return (-1);
}
bcopy(*cp, (char *) &sin.sin_addr, hp->h_length);
if (x < 0) {
fprintf (stderr, "Trying %s", (char *) inet_ntoa (sin.sin_addr));
}
x = connect (s, (struct sockaddr *) &sin, sizeof (sin));
if (x == 0) {
break;
}
fprintf (stderr, "\nConnection to %s: ", (char *) inet_ntoa (sin.sin_addr));
perror ("");
(void) close (s);
}
if (x < 0) {
fprintf (stderr, "Giving up...\n");
return (-1);
}
#else /* no name server */
#ifdef EXCELAN
if ((s = socket (SOCK_STREAM,(struct sockproto *)NULL,&sin,SO_KEEPALIVE)) < 0) {
/* Get the socket */
perror ("socket");
return (-1);
}
bzero((char *) &sin, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_port = htons (IPPORT_NNTP);
/* set up addr for the connect */
if ((sin.sin_addr.s_addr = rhost (&machine)) == -1) {
fprintf (stderr, "\n%s: Unknown host.\n", machine);
return (-1);
}
/* And then connect */
if (connect (s, (struct sockaddr *)&sin) < 0) {
perror ("connect");
(void) close (s);
return (-1);
}
#else /* not EXCELAN */
if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
perror ("socket");
return (-1);
}
/* And then connect */
bcopy (hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
if (connect (s, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
perror ("connect");
(void) close (s);
return (-1);
}
#endif /* !EXCELAN */
#endif /* !h_addr */
#endif /* !TLI */
return (s);
#else
return (-1);
#endif /* NNTP_ABLE */
}
#ifdef DECNET
/*
* get_dnet_socket -- get us a socket connected to the server.
*
* Parameters: "machine" is the machine the server is running on.
* "service" is the name of the service to connect to.
*
* Returns: Socket connected to the news server if
* all is ok, else -1 on error.
*
* Side effects: Connects to server.
*
* Errors: Printed via nerror.
*/
int get_dnet_socket (machine, service)
char *machine;
char *service;
{
#ifdef NNTP_ABLE
int s, area, node;
struct sockaddr_dn sdn;
struct nodeent *getnodebyname(), *np;
bzero((char *) &sdn, sizeof (sdn));
switch (s = sscanf (machine, "%d%*[.]%d", &area, &node)) {
case 1:
node = area;
area = 0;
case 2:
node += area*1024;
sdn.sdn_add.a_len = 2;
sdn.sdn_family = AF_DECnet;
sdn.sdn_add.a_addr[0] = node % 256;
sdn.sdn_add.a_addr[1] = node / 256;
break;
default:
if ((np = getnodebyname (machine)) == NULL) {
fprintf (stderr, "%s: Unknown host.\n", machine);
return (-1);
} else {
bcopy(np->n_addr, (char *) sdn.sdn_add.a_addr, np->n_length);
sdn.sdn_add.a_len = np->n_length;
sdn.sdn_family = np->n_addrtype;
}
break;
}
sdn.sdn_objnum = 0;
sdn.sdn_flags = 0;
sdn.sdn_objnamel = strlen ("NNTP");
bcopy("NNTP", &sdn.sdn_objname[0], sdn.sdn_objnamel);
if ((s = socket (AF_DECnet, SOCK_STREAM, 0)) < 0) {
nerror ("socket");
return (-1);
}
/* And then connect */
if (connect (s, (struct sockaddr *) &sdn, sizeof (sdn)) < 0) {
nerror ("connect");
close (s);
return (-1);
}
return (s);
#else
return (-1);
#endif /* NNTP_ABLE */
}
#endif
/*
* handle_server_response
*
* Print some informative messages based on the server's initial
* response code. This is here so inews, rn, etc. can share
* the code.
*
* Parameters: "response" is the response code which the
* server sent us, presumably from "server_init",
* above.
* "nntpserver" is the news server we got the
* response code from.
*
* Returns: -1 if the error is fatal (and we should exit).
* 0 otherwise.
*
* Side effects: None.
*/
int handle_server_response (response, nntpserver)
int response;
char *nntpserver;
{
#ifdef NNTP_ABLE
switch (response) {
case OK_NOPOST: /* fall through */
printf ("NOTE: This machine does not have permission to post articles.\n");
printf (" Please don't waste your time trying.\n\n");
case OK_CANPOST:
return (0);
break;
case ERR_ACCESS:
printf ("This machine does not have permission to use the %s news server.\n", nntpserver);
return (-1);
break;
default:
printf ("Unexpected response code from %s news server: %d\n",
nntpserver, response);
return (-1);
break;
}
/*NOTREACHED*/
#else
return (-1);
#endif /* NNTP_ABLE */
}
/*
* put_server -- send a line of text to the server, terminating it
* with CR and LF, as per ARPA standard.
*
* Parameters: "string" is the string to be sent to the
* server.
*
* Returns: Nothing.
*
* Side effects: Talks to the server.
*
* Note: This routine flushes the buffer each time
* it is called. For large transmissions
* (i.e., posting news) don't use it. Instead,
* do the fprintf's yourself, and then a final
* fflush.
*/
void put_server (string)
char *string;
{
#ifdef NNTP_ABLE
fprintf (nntp_wr_fp, "%s\r\n", string);
(void) fflush (nntp_wr_fp);
#endif /* NNTP_ABLE */
}
/*
* get_server -- get a line of text from the server. Strips
* CR's and LF's.
*
* Parameters: "string" has the buffer space for the
* line received.
* "size" is the size of the buffer.
*
* Returns: -1 on error, 0 otherwise.
*
* Side effects: Talks to server, changes contents of "string".
*/
int get_server (string, size)
char *string;
int size;
{
#ifdef NNTP_ABLE
register char *cp;
while (fgets (string, size, nntp_rd_fp) == NULL) {
if (errno != EINTR) {
return (-1);
}
}
if ((cp = (char *) index(string, '\r')) != NULL) {
*cp = '\0';
} else if ((cp = (char *) index(string, '\n')) != NULL) {
*cp = '\0';
}
return (0);
#else
return (-1);
#endif /* NNTP_ABLE */
}
/*
* close_server -- close the connection to the server, after sending
* the "quit" command.
*
* Parameters: None.
*
* Returns: Nothing.
*
* Side effects: Closes the connection with the server.
* You can't use "put_server" or "get_server"
* after this routine is called.
*/
void close_server ()
{
#ifdef NNTP_ABLE
char ser_line[256];
if (nntp_wr_fp == NULL || nntp_rd_fp == NULL)
return;
put_server ("QUIT");
(void) get_server (ser_line, sizeof (ser_line));
(void) fclose (nntp_wr_fp);
(void) fclose (nntp_rd_fp);
#endif /* NNTP_ABLE */
}
#endif /* CDROM_ABLE */
SHAR_EOF
fi # end of overwriting check
if test -f 'nntplib.h'
then
echo shar: will not over-write existing file "'nntplib.h'"
else
cat << \SHAR_EOF > 'nntplib.h'
/*
* Project : tin - a threaded Netnews reader
* Module : nntplib.h
* Author : I.Lea
* Created : 01-04-91
* Updated : 18-11-92
* Notes : nntp.h 1.5.11/1.6 with extensions for tin & CD-ROM
* Copyright : You may freely copy or redistribute this software,
* so long as there is no profit made from its use, sale
* trade or reproduction. You may not change this copy-
* right notice, and it must be included in any copy made
*/
#ifndef NNTP_SERVER_FILE
# define NNTP_SERVER_FILE "/etc/nntpserver"
#endif
#define NNTP_TCP_NAME "nntp"
#define NNTP_TCP_PORT ((unsigned short) 119)
#ifndef SMTP_SERVER_FILE
# define SMTP_SERVER_FILE "/etc/smtpserver"
#endif
#define SMTP_TCP_NAME "smtp"
#define SMTP_TCP_PORT ((unsigned short) 25)
/*
* External routine declarations
*/
extern char *getserverbyfile();
/* extern int server_init(); */
extern int get_tcp_socket();
extern int handle_server_response();
extern void put_server();
extern int get_server();
extern void close_server();
/*
* External file descriptors for the server connection
*/
extern FILE *nntp_wr_fp;
/*
* Response codes for NNTP server
*
* @(#)Header: nntp.h,v 1.81 92/03/12 02:08:31 sob Exp $
*
* First digit:
*
* 1xx Informative message
* 2xx Command ok
* 3xx Command ok so far, continue
* 4xx Command was correct, but couldn't be performed
* for some specified reason.
* 5xx Command unimplemented, incorrect, or a
* program error has occured.
*
* Second digit:
*
* x0x Connection, setup, miscellaneous
* x1x Newsgroup selection
* x2x Article selection
* x3x Distribution
* x4x Posting
*/
#define CHAR_INF '1'
#define CHAR_OK '2'
#define CHAR_CONT '3'
#define CHAR_ERR '4'
#define CHAR_FATAL '5'
#define INF_HELP 100 /* Help text on way */
#define INF_AUTH 180 /* Authorization capabilities */
#define INF_DEBUG 199 /* Debug output */
#define OK_CANPOST 200 /* Hello; you can post */
#define OK_NOPOST 201 /* Hello; you can't post */
#define OK_SLAVE 202 /* Slave status noted */
#define OK_GOODBYE 205 /* Closing connection */
#define OK_GROUP 211 /* Group selected */
#define OK_GROUPS 215 /* Newsgroups follow */
#define OK_XMOTD 217 /* News motd follows */
#define OK_XINDEX 218 /* Tin style index follows */
#define OK_XOVERVIEW 219 /* .overview style index follows */
#define OK_ARTICLE 220 /* Article (head & body) follows */
#define OK_HEAD 221 /* Head follows */
#define OK_BODY 222 /* Body follows */
#define OK_NOTEXT 223 /* No text sent -- stat, next, last */
#define OK_NEWNEWS 230 /* New articles by message-id follow */
#define OK_NEWGROUPS 231 /* New newsgroups follow */
#define OK_XFERED 235 /* Article transferred successfully */
#define OK_POSTED 240 /* Article posted successfully */
#define OK_AUTHSYS 280 /* Authorization system ok */
#define OK_AUTH 281 /* Authorization (user/pass) ok */
#define OK_BIN 282 /* binary data follows */
#define OK_SPLIST 283 /* spooldir list follows */
#define OK_SPSWITCH 284 /* Switching to a different spooldir */
#define OK_SPNOCHANGE 285 /* Still using same spooldir */
#define OK_SPLDIRCUR 286 /* Current spooldir */
#define OK_SPLDIRAVL 287 /* Available spooldir */
#define OK_SPLDIRERR 288 /* Unavailable spooldir or invalid entry */
#define CONT_XFER 335 /* Continue to send article */
#define CONT_POST 340 /* Continue to post article */
#define NEED_AUTHINFO 380 /* authorization is required */
#define NEED_AUTHDATA 381 /* <type> authorization data required */
#define ERR_GOODBYE 400 /* Have to hang up for some reason */
#define ERR_NOGROUP 411 /* No such newsgroup */
#define ERR_NCING 412 /* Not currently in newsgroup */
#define ERR_XMOTD 417 /* No news motd file */
#define ERR_XINDEX 418 /* No tin index for this group */
#define ERR_XOVERVIEW 419 /* No .overview index for this group */
#define ERR_NOCRNT 420 /* No current article selected */
#define ERR_NONEXT 421 /* No next article in this group */
#define ERR_NOPREV 422 /* No previous article in this group */
#define ERR_NOARTIG 423 /* No such article in this group */
#define ERR_NOART 430 /* No such article at all */
#define ERR_GOTIT 435 /* Already got that article, don't send */
#define ERR_XFERFAIL 436 /* Transfer failed */
#define ERR_XFERRJCT 437 /* Article rejected, don't resend */
#define ERR_NOPOST 440 /* Posting not allowed */
#define ERR_POSTFAIL 441 /* Posting failed */
#define ERR_NOAUTH 480 /* authorization required for command */
#define ERR_AUTHSYS 481 /* Authorization system invalid */
#define ERR_AUTHREJ 482 /* Authorization data rejected */
#define ERR_INVALIAS 483 /* Invalid alias on spooldir cmd */
#define ERR_INVNOSPDIR 484 /* No spooldir file found */
#define ERR_COMMAND 500 /* Command not recognized */
#define ERR_CMDSYN 501 /* Command syntax error */
#define ERR_ACCESS 502 /* Access to server denied */
#define ERR_FAULT 503 /* Program fault, command not performed */
#define ERR_AUTHBAD 580 /* Authorization Failed */
/*
* RFC 977 defines this; don't change it.
*/
#define NNTP_STRLEN 512
SHAR_EOF
fi # end of overwriting check
if test -f 'nntpservers'
then
echo shar: will not over-write existing file "'nntpservers'"
else
cat << \SHAR_EOF > 'nntpservers'
/**********************************************************/
/* This is a short list of public accessable NNTP servers */
/* by Jonathan Wang, May 13, 1993 */
/* wang@astro.temple.edu */
/* */
/* 200: Posting OK; 201: No posting */
/* */
/* Note: I DO NOT have the authorization to use them */
/* Using these services at your own risk */
/**********************************************************/
aardvark.ucs.uoknor.edu 201
ac.dal.ca 201
acad.drake.edu 201
acavax.lynchburg.edu 200
aqueous.ml.csiro.AU 200
bert.eecs.uic.edu 201
blaze.trentu.ca 201
bunyip.cc.uq.oz.au 201
buzzard.eecs.umich.edu 200
cc.ntnu.edu.tw 200
cc.usu.edu 201
ccds3.ntu.edu.tw 200
ccnews.nctu.edu.tw 200
ccsvax.sfasu.edu 200
ccvax.ucd.ie 200
cronkite.ocis.temple.edu 200
crux.rp.CSIRO.AU 200
csc.canberra.edu.au 201
csun.edu 200
cv3.cv.nrao.edu 200
dec8.ncku.edu.tw 200
desire.wright.edu 200
donau.et.tudelft.nl 200
emba-news.uvm.edu 201
embl-heidelberg.de 200
fac.cabot.nf.ca 200
falcon.aamrl.wpafb.af.mil 200
fang.dsto.gov.au 200
faraday.ece.cmu.edu 200
fission.dt.wdc.com 200
flash.pax.tpa.com.au 200
foxhound.dsto.gov.au 200
gaia.ucs.orst.edu 201
gmuvax.gmu.edu 201
gneiss.bmr.gov.au 200
grumpy.symantec.com 200
guardian.up.edu 201
hack.dragoman.com 201
hkuxb.hku.hk 201
hmcvax.claremont.edu 201
inca.comlab.ox.ac.uk 201
informatik.uni-koblenz.de 200
iris.resntl.bhp.com.au 201
iti.gov.sg 201
jabaru.cec.edu.au 200
jvnc.net 201
lambda.msfc.nasa.gov 201
SHAR_EOF
fi # end of overwriting check
if test -f 'wang.c'
then
echo shar: will not over-write existing file "'wang.c'"
else
cat << \SHAR_EOF > 'wang.c'
/******************************************************************/
/* wang.c version 4.0 */
/* by Jonathan Wang, May 20, 1993 */
/* wang@astro.ocis.temple.edu */
/* */
/* USENET binary files download and assemble utility */
/* type wang -h for help */
/******************************************************************/
char nntpserver[255]= "128.8.10.5"; /*umd5.umd.edu*/
char newsgroup[255]= "alt.binaries.pictures.misc";
int index_start=0;
int index_end=0;
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "nntplib.c"
#define MAXFILES 2048
struct superblock
{
char Filename[255];
int Part;
int Parts;
int Article;
/*char Newsgroup[255]; */
} Filereg[MAXFILES];
#define LEN 255
char line[LEN], buf[LEN];
int filecount=0;
struct superblock nextfilereg();
/*************************************************************/
main(argc, argv)
int argc;
char *argv[];
{
ArgumentProcess(argc, argv);
puts("Warning: This program may generate up to 250 picture files.");
puts(" i.e., appox. 20M disk space will be used.");
puts("Please make appropriate preparation and inform your sysadm.");
puts("FYI: The priority is lowered to +10\n");
nice(10); /* don't wanna sysadm freak out */
puts("setting up connection ...");
server_init(nntpserver, "nntp", 119);
SubjectAnalysis();
Retrieve();
close_server();
}/* end of main */
/**********************************************************/
ArgumentProcess(argc, argv)
int argc;
char *argv[];
{
int i;
for (i=1; i<argc; i++)
{
if ( strcmp(argv[i],"-s") == 0 )
strcpy(nntpserver,argv[i+1]);
else if ( strcmp(argv[i], "-g") == 0 )
strcpy(newsgroup,argv[i+1]);
else if ( strcmp(argv[i], "-n") == 0 )
{
index_start = atoi(argv[i+1]);
index_end = atoi(argv[i+3]);
}
else if ( strcmp(argv[i], "-h") == 0 )
{
printf("Usage: %s [-s nntpServer] [-g newsGroup] [-n start - end]\n\n",
argv[0]);
printf("-s nntpServer\tThe news server. The default server is:\n\
\t\t%s\n\
\tYou are encouraged to use your local news server\n\
\tso as to cut the the transmission time and \n\
\tthe network load.\n",nntpserver);
printf("-g newsGroup\tThe newsgroup. The default newsgroup is:\n\
\t\t%s\n",newsgroup);
printf("-n start - end\tStart and Ending number of Articles.\n\
\tThe default is all the available articles.\n\
\tPlease refer to the available article numbers\n\
\teach time the program runs.\n\
\tYou are strongly recommended to use this option\n\
\tto control the limit of incoming articles.\n\n\
Please be aware that the space beween each identifier is required.\n");
exit(0);
}
} /* end of for */
} /* end of ArgumentProcess */
/**********************************************************/
/* basically same as the old wang.c */
/* instead of reading from a file, now we read from USENET*/
Retrieve()
{
struct superblock reg;
reg = nextfilereg();
while (*(reg.Filename)) /* not empty */
{
printf("\nDecoding file %s (Article %d)...",
reg.Filename, reg.Article);
if (MakeOnePicture(reg)) /* successful? */
printf("\tDone.");
reg = nextfilereg();
} /* end of while */
printf("\n==================== DONE ====================\n");
} /* end of Retrieve */
/***************************************/
MakeOnePicture(reg)
struct superblock reg;
{
int count, where;
int part = 0;
FILE *uu; /* pipe */
/* check if every part is in */
for (count =1; count < reg.Parts + 1; count ++)
{
if (whereispart(count, reg) == 0)
{
printf("Part %d not found, decoding of file %s aborted\n",
count, reg.Filename);
return(0);
}
}
fflush(stdout);
if ( (uu=popen("uudecode","w") ) == NULL)
perror("unable to pipe open uudecode");
for (count =1 ;count <reg.Parts+1; count++)
{
where=whereispart(count,reg);
DownLoad(Filereg[where].Article,uu);
Filereg[where].Filename[0] = '\0'; /* mark it USED */
}
pclose(uu);
return(1); /* success */
} /* end of MakeOnePicture */
/***************************************/
int whereispart(partno, reg)
int partno;
struct superblock reg;
{
int count;
for (count =1; count <filecount +1; count++)
if ( (Filereg[count].Part == partno)
&& (strcmp(Filereg[count].Filename, reg.Filename) == 0))
return(count);
/* part not found: mark them USED */
for (count=1; count <filecount +1; count++)
if ( strcmp(Filereg[count].Filename, reg.Filename) == 0)
Filereg[count].Filename[0] = '\0';
return(0);
} /* end of whereispart() */
/***************************************/
DownLoad(article,to)
int article;
FILE *to;
{
char buf[LEN], a[LEN], b[LEN];
int ret,len;
sprintf(line,"body %d", article);
put_server(line);
/* find the start point */
while ( (ret=get_server(buf,LEN)) != -1)
{
if (strcmp(buf,".") == 0)
return(1); /* reach file end without any meaningful contents */
if ( ( (strncmp(buf, "begin ", 6) == 0) && (isdigit(buf[6])) )
||
( (buf[0]=='M') && (strlen(buf) >59) && (strlen(buf) <71) ) )
{
a[0]=b[0]='\0';
fprintf(to,"%s\n",buf);
break; /* real stuff begins */
}
}
if (ret==-1)
perror("cannot get_server at body command");
/* pipe everthing to uudecode */
while ( (ret=get_server(buf,LEN)) != -1)
{
if (strcmp(buf,".")==0)
break;
if (strncmp(buf, "end", 3) == 0)
{
if (b[0])
fprintf(to,"%s\n",b);
if (a[0])
fprintf(to,"%s\n",a);
fprintf(to,"%s\n",buf);
}
/* else if (strncmp(buf,"END", 3) == 0)
break;
*/
else
{
len=strlen(buf);
if ( (buf[0] != 'M' || len <60 || len >70 )
&& (strncmp(buf,"begin ", 5)) )
{
strcpy(b,a);
strcpy(a,buf);
continue;
}
a[0]=b[0]='\0';
fprintf(to,"%s\n",buf);
}
} /* end of 2nd while */
if (ret==-1)
perror("get_server err 2nd at body command");
}
/***************************************/
struct superblock
nextfilereg()
{
int count;
static struct superblock nulblock =
{ "\0", 0, 0, 0 };
for (count=1; count<filecount +1; count++) /*filecount start at 1 */
if ( Filereg[count].Filename[0] != '\0') /* USED? */
return(Filereg[count]);
return(nulblock);
} /* end of nextfilereg() */
/***********************************************************/
/* Read a subject line, getinfo, and store into superblock */
SubjectAnalysis()
{
char trash[LEN];
char start[LEN], end[LEN];
int ret;
/* borrowed from update.c */
sprintf(line, "group %s\n", newsgroup);
put_server(line);
ret=get_server(buf, LEN);
if (ret == -1)
perror("cannot get_server after group command");
else if ( strncmp(buf, "411", 3) == 0 )
{
fprintf(stderr,"no such group as %s\n", newsgroup);
exit(0);
}
sscanf(buf,"%s%s%s%s", trash,trash, start, end);
printf("The available articles are Numbered %s to %s\n", start, end);
#ifndef DEBUG
puts("Gathering info ...");
#endif
if (index_start == 0)
{
index_start = atoi(start);
index_end = atoi(end);
}
sprintf(line, "xhdr subject %d-%d\n",index_start, index_end );
put_server(line);
while ( (ret=get_server(buf,LEN)) != -1 )
{
if ( strcmp(buf,".") == 0 )
break;
getinfo(buf);
}
if (ret==-1)
perror("get_server error in xhdr");
} /* end of SubjectAnalysis */
/***************************************************************/
/* get filename, part info, article number from subject line */
/* store into Filereg[filecount++] */
#include <ctype.h>
char word[LEN],oldword[LEN];
getinfo(buf)
char *buf;
{
int t1,t2;
filecount++;
#ifdef DEBUG
puts(buf);
#endif
if (GetArticleNumber(buf) == 0)
fprintf(stderr,"get article number error: buf=%s",buf);
if ( isRE(buf) )
{
#ifdef DEBUG
puts("Regarding ... -- TRASH");
#endif
filecount--; /* don't want this into Filereg */
return;
}
t1=GetSubject(buf);
t2=GetPartInfo(buf);
if ( t1 && (Filereg[filecount].Part != 0)
&& (Filereg[filecount].Parts != 0) )
;
else if ( (!t1) && (Filereg[filecount].Part !=0 )
&& (Filereg[filecount].Parts != 0) )
strcpy(Filereg[filecount].Filename, getword(buf));
else if ( t1 && ( !t2 ) ) /* for careless poster */
Filereg[filecount].Part= Filereg[filecount].Parts= 1;
else
{
#ifdef DEBUG
puts("part 0, or text file -- TRASH");
#endif
filecount--; /* don't want this into Filereg */
return;
}
#ifdef DEBUG
printf("\tarticle=%d, filename=%s, part= %d, parts=%d\n",
Filereg[filecount].Article, Filereg[filecount].Filename,
Filereg[filecount].Part, Filereg[filecount].Parts);
#endif
}
/******************************************/
GetArticleNumber(buf)
char *buf;
{
char tmp[LEN];
strcpy(tmp,getword(buf));
if (!isnumber(tmp))
return(0);
else
{
Filereg[filecount].Article=atoi(tmp);
return(1);
}
}
/******************************************/
GetSubject(buf)
char *buf;
{
char line[LEN];
strcpy(line,buf); /* don't wanna destroy buf */
do
{
strcpy(word,getword(line));
if ( (word[0] == '.')
&& isstring(oldword)
&& isstring(peekword(line)) )
{
sprintf(Filereg[filecount].Filename,"%s.%s",oldword,getword(line));
return(1);
}
strcpy(oldword,word);
}while (word[0]!='\0');
return(0);
}
/**********************************************/
GetPartInfo(buf)
char *buf;
{
char line[LEN];
strcpy(line,buf);
do
{
strcpy(word,getword(line));
if ( ( (word[0] == '/') || (strcmp(word,"of") == 0))
&& isnumber(oldword)
&& isnumber(peekword(line)) )
{
Filereg[filecount].Part=atoi(oldword);
Filereg[filecount].Parts=atoi(getword(line));
return(1);
}
strcpy(oldword,word);
}while (word[0]!='\0');
return(0);
}
/*****************************************/
getword(line)
char *line;
{
int i;
char backup[LEN];
char tmp;
if (line[0] == '\0')
/* is it empty? -- different machines treat isspace differently */
return("\0");
strcpy(backup,line);
if (isspace(backup[0])) /* space? ignor */
strcpy(backup,line+1);
if (backup[0] == '\0') /* is it empty ? */
return("\0");
if (!isalnum(backup[0])) /* begin with non alnum? return it */
{
strcpy(line,backup+1);
backup[1]='\0';
return(backup);
}
for (i=0; backup[i] != '\0'; i++)
{
if (!isalnum(backup[i]))
{
strcpy(line,backup+i);
backup[i]='\0';
return(backup);
}
else if (isupper(backup[i]))
{
tmp=tolower(backup[i]);
backup[i]=tmp;
}
}
line[0]='\0';
return (backup);
}
/***********************************************/
peekword(line)
char *line;
{
int i;
char backup[LEN];
char tmp;
if (line[0] == '\0')
return("\0");
strcpy(backup,line);
if (isspace(backup[0])) /* space? ignore */
strcpy(backup,line+1);
if (backup[0] == '\0')
return("\0");
if (!isalnum(backup[0]))
{
backup[i]='\0';
return(backup);
}
for (i=0; backup[i]!='\0' ;i++)
if (!isalnum(backup[i]))
{
backup[i]='\0';
return(backup);
}
else if (isupper(backup[i]))
{
tmp=tolower(backup[i]);
backup[i]=tmp;
}
return(backup);
}
/**************************************************/
int isstring(string)
char *string;
{
int i;
for (i=0;i<strlen(string);i++)
if (!isalnum(string[i]))
return(0);
return(1);
}
/*************************************************/
int isnumber(string)
char *string;
{
int i;
for (i=0;i<strlen(string); i++)
if (!isdigit(string[i]))
return(0);
return(1);
}
/*************************************************/
isRE(buf)
char *buf;
{
char line[LEN];
char word[LEN];
strcpy(line,buf);
do
{
strcpy(word, getword(line));
}
while (!isstring(word)); /* find first string */
return(!strcmp(word,"re"));
}
/*********************** END **********************/
SHAR_EOF
fi # end of overwriting check
# End of shell archive
exit 0