|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T n
Length: 10668 (0x29ac) Types: TextFile Names: »nntpxfer.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦5cced586a⟧ »EurOpenD3/news/nntp/nntp.1.5.7.tar.Z« └─⟦7340f105e⟧ └─⟦this⟧ »./xfer/nntpxfer.c«
/* * nntpxfer * * Connects to the specified nntp server, and transfers all new news * since the last successful invocation. * * last successful invocation date and time are stored in a file at * /usr/spool/news/nntp.<hostname> as * groups YYMMDD HHMMSS distributions\n * in case you need to edit it. You can also override this on * the command line in the same format, in which case the file won't * be updated. * * Brian Kantor, UCSD 1986 * (some bug fixes by ambar@athena.mit.edu) * Modified to use NNTP distribution conf.h file and nntpxmit's get_tcp_conn.c * subroutines so that nntpxfer could be used on more systems. * Stan Barber, November 7, 1989 <sob@bcm.tmc.edu> * */ #include "../common/conf.h" #include <sys/types.h> #ifdef NDIR #include <ndir.h> #else #include <sys/dir.h> #endif #ifdef USG #include <time.h> #else #include <sys/time.h> #endif #include <stdio.h> #include <errno.h> #include <ctype.h> #ifndef NONETDB #include <netdb.h> #endif #include <signal.h> #ifdef DBM #include <dbm.h> #endif char *malloc(); char *strcpy(); char *strcat(); char *rindex(); long time(); u_long inet_addr(); extern int errno; char *artlist[MAX_ARTICLES]; int server; /* stream socket to the nntp server */ int newart, dupart, misart; char * Pname; main(argc, argv) int argc; char *argv[]; { FILE *dtfile; /* where last xfer date/time stored */ char buf[BUFSIZ]; char lastdate[16]; char distributions[BUFSIZ]; char dtname[128]; char newsgroups[BUFSIZ]; char lasttime[16]; int connected = 0; /* 1 = connected */ int i; int omitupdate = 0; /* 1 = don't update datetime */ long clock; long newdate, newtime; struct tm *now; Pname = ((Pname = rindex(argv[0], '/')) ? Pname + 1 : argv[0]); /* OPTIONS argv[1] MUST be the host name argv[2-4] MAY be "newsgroups YYMMDD HHMMSS" argv[5] MAY be distributions (otherwise use 2-4/5 from the file "/usr/spool/news/nntp.hostname") */ if (argc != 2 && argc != 5 && argc != 6) { (void) printf("Usage: %s host [groups YYMMDD HHMMSS [<dist>]]\n", argv[0]); exit(1); } if (argc > 2) { omitupdate++; (void) strcpy(newsgroups, argv[2]); (void) strcpy(lastdate, argv[3]); (void) strcpy(lasttime, argv[4]); (void) strcpy(distributions, ""); if (argc > 5) (void) strcpy(distributions, argv[5]); } else { (void) strcpy(dtname, "/usr/spool/news/nntp."); (void) strcat(dtname, argv[1]); dtfile = fopen(dtname, "r"); if (dtfile == NULL) { (void) printf("%s not found; using * 860101 000000 \n", dtname); (void) strcpy(newsgroups, "*"); (void) strcpy(lastdate, "860101"); (void) strcpy(lasttime, "000000"); (void) strcpy(distributions, ""); } else { if (fscanf(dtfile, "%s %s %s %s", newsgroups, lastdate, lasttime, distributions) < 3) { (void) printf("%s invalid; using * 860101 000000\n", dtname); (void) strcpy(newsgroups, "*"); (void) strcpy(lastdate, "860101"); (void) strcpy(lasttime, "000000"); (void) strcpy(distributions, ""); } (void) fclose(dtfile); } clock = time((long *)0); now = gmtime(&clock); newdate = (now->tm_year * 10000) + ((now->tm_mon + 1) * 100) + now->tm_mday; newtime = (now->tm_hour * 10000) + (now->tm_min * 100) + now->tm_sec; } #ifdef DEBUG (void) printf("newsgroups = '%s'\n", newsgroups); (void) printf("date = '%s'\n", lastdate); (void) printf("time = '%s'\n", lasttime); (void) printf("distributions = '%s'\n", distributions); (void) printf("now is = %06d %06d\n", newdate, newtime); #endif #ifdef DBM if (dbminit(HISTORY_FILE) < 0) { perror("couldn't open history file"); exit(1); } #endif if ((server = get_tcp_conn(argv[1],"nntp")) < 0) { perror("could not open socket"); exit(1); } #ifdef DEBUG (void) printf("connected to nntp server at %s\n", argv[1]); #endif /* * ok, at this point we're connected to the nntp daemon * at the distant host. */ /* get the greeting herald */ (void) sockread(buf); #ifdef DEBUG (void) printf("%s\n", buf); #endif if (buf[0] != '2') /* uh-oh, something's wrong! */ { (void) printf("protocol error: got '%s'\n", buf); (void) close(server); exit(1); } /* first, tell them we're a slave process to get priority */ sockwrite("SLAVE"); (void) sockread(buf); #ifdef DEBUG (void) printf("%s\n", buf); #endif if (buf[0] != '2') /* uh-oh, something's wrong! */ { (void) printf("protocol error: got '%s'\n", buf); (void) close(server); exit(1); } /* now, ask for a list of new articles */ if (strlen(distributions)) (void) sprintf(buf,"NEWNEWS %s %s %s GMT <%s>", newsgroups, lastdate, lasttime, distributions); else (void) sprintf(buf,"NEWNEWS %s %s %s GMT", newsgroups, lastdate, lasttime); sockwrite(buf); (void) sockread(buf); #ifdef DEBUG (void) printf("%s\n", buf); #endif if (buf[0] != '2') /* uh-oh, something's wrong! */ { (void) printf("protocol error: got '%s'\n", buf); (void) close(server); exit(1); } /* and here comes the list, terminated with a "." */ #ifdef DEBUG (void) printf("data\n"); #endif dupart = newart = 0; while (1) { (void) sockread(buf); if (!strcmp(buf,".")) break; if (wewant(buf)) { if (newart > MAX_ARTICLES) { omitupdate++; continue; } artlist[newart] = malloc((unsigned)(strlen(buf)+1)); (void) strcpy(artlist[newart], buf); newart++; } else dupart++; } #ifdef DEBUG (void) printf(".\n%d new, %d dup articles\n", newart, dupart); #endif /* now that we know which articles we want, retrieve them */ for (i=0; i < newart; i++) (void) artfetch(artlist[i]); #ifdef DEBUG (void) printf("%d missing articles\n", misart); #endif /* we're all done, so tell them goodbye */ sockwrite("QUIT"); (void) sockread(buf); #ifdef DEBUG (void) printf("%s\n", buf); #endif if (buf[0] != '2') /* uh-oh, something's wrong! */ { (void) printf("error: got '%s'\n", buf); (void) close(server); exit(1); } (void) close(server); /* do we want to update the timestamp file? */ if (!omitupdate) { (void) sprintf(buf, "%s %06d %06d %s\n", newsgroups, newdate, newtime, distributions); #ifdef DEBUG (void) printf("updating %s:\n\t%s\n", dtname, buf); #endif dtfile = fopen(dtname, "w"); if (dtfile == NULL) { perror(dtname); exit(1); } (void) fputs(buf,dtfile); (void) fclose(dtfile); } exit(0); } artfetch(articleid) char *articleid; { int lines = 0; char buf[BUFSIZ]; FILE *inews; /* now, ask for the article */ (void) sprintf(buf,"ARTICLE %s", articleid); sockwrite(buf); (void) sockread(buf); #ifdef DEBUG (void) printf("%s\n", buf); #endif if (buf[0] == '4') /* missing article, just skipit */ { misart++; return(0); } if (buf[0] != '2') /* uh-oh, something's wrong! */ { (void) printf("protocol error: got '%s'\n", buf); (void) close(server); exit(1); } #ifdef DEBUG (void) printf("command: %s\n", RNEWS); #endif if ( (inews = popen(RNEWS, "w")) == NULL) { perror(RNEWS); exit(1); } /* and here comes the article, terminated with a "." */ #ifdef DEBUG (void) printf("data\n"); #endif while (1) { (void) sockread(buf); if (buf[0] == '.' && buf[1] == '\0') break; lines++; (void) strcat(buf,"\n"); (void) fputs(((buf[0] == '.') ? buf + 1 : buf), inews); } #ifdef DEBUG (void) printf(".\n%d lines\n", lines); #endif (void) fflush(inews); (void) pclose(inews); return(0); } int sockread(buf) char *buf; { char c; int j = 0; #ifdef BSD43 fd_set rf; #else BSD43 int rf; #endif BSD43 #ifndef EXCELAN struct timeval tv; #endif int r; char *p = buf; while ( 1 ) { #ifndef EXCELAN tv.tv_sec = 1800; /* 15 minutes */ tv.tv_usec = 0L; #ifdef BSD43 FD_ZERO(&rf); FD_SET(server, &rf); r = select(20, (fd_set *)&rf, (fd_set *)0, (fd_set *)&rf, &tv);#else BSD43 rf = 1 << server; r = select(20, (int *)&rf, (int *)0, (int *)&rf, &tv); #endif BSD43 #else rf = 1 << server; r = select(20, (long *)&rf, (long *)0, 110000L); #endif if (r < 0) { if (errno == EINTR) continue; perror("getsock select"); exit(1); } if (r == 0) { printf("read timed out.\n"); exit(1); } if (read (server,&c,1) <= 0) break; /* mask off any chance parity bits */ *p = c & 0x7f; /* look for end of line (== LF) */ if (c == 0x0a) { if (j > 0 && *(p-1) == 0x0d) *(p-1) = '\0'; else *p = '\0'; return(strlen(buf)); } j++; p++; } perror("sockread"); (void) close(server); exit(1); /* NOTREACHED */ } sockwrite(buf) char *buf; { register int sz; char buf2[BUFSIZ]; #ifdef DEBUG (void) printf(">>> %s\n", buf); #endif (void) strcpy(buf2,buf); (void) strcat(buf2,"\r\n"); sz = strlen(buf2); if (write(server,buf2,sz) != sz) { (void) printf("write error on server socket\n"); (void) close(server); exit(1); } } int wewant(articleid) char *articleid; { #ifdef DBM datum k, d; #else FILE *k; char *histfile(); FILE *histfp; /* USG history file */ char line[BUFSIZ]; int len; #endif char id[BUFSIZ]; char *p; /* remove any case sensitivity */ (void) strcpy(id, articleid); p = id; #ifndef CNEWS while (*p) { if (isupper(*p)) *p = tolower(*p); p++; } #endif #ifdef DBM k.dptr = id; k.dsize = strlen(articleid) + 1; d = fetch(k); if (d.dptr) { #ifdef DEBUG (void) printf("dup: '%s'\n", articleid); #endif return(0); } #ifdef DEBUG (void) printf("new: '%s'\n", articleid); #endif return(1); #else histfp = fopen(histfile(articleid), "r"); if (histfp == NULL) { #ifdef DEBUG (void) printf("new: '%s'\n", articleid); #endif return(1); } len = strlen(articleid); while (fgets(line, sizeof (line), histfp)) if (!strncmp(articleid, line, len)) break; if (feof(histfp)) { (void) fclose(histfp); #ifdef DEBUG (void) printf("new: '%s'\n", articleid); #endif return (1); } (void) fclose(histfp); #ifdef DEBUG (void) printf("dup: '%s' %s\n", articleid,line); #endif return(0); #endif } char * errmsg(n) register int n; { extern int sys_nerr; extern char *sys_errlist[]; return((n >= 0 && n < sys_nerr) ? sys_errlist[n] : "unknown error"); } #ifndef DBM /* ** Generate the appropriate history subfile name */ char * histfile(hline) char *hline; { char chr; /* least significant digit of article number */ static char subfile[BUFSIZ]; chr = findhfdigit(hline); sprintf(subfile, "%s.d/%c", HISTORY_FILE, chr); return subfile; } findhfdigit(fn) char *fn; { register char *p; register int chr; p = index(fn, '@'); if (p != NULL && p > fn) chr = *(p - 1); else chr = '0'; if (!isdigit(chr)) chr = '0'; return chr; } #endif