[comp.sources.misc] v17i015: news_split - News to Archive, Part01/01

fmc@cnam.cnam.fr (Frederic Chauveau) (02/24/91)

Submitted-by: Frederic Chauveau <fmc@cnam.cnam.fr>
Posting-number: Volume 17, Issue 15
Archive-name: news_split/part01
Supersedes: news_split1.6: Volume 17, Issue 1

This brings news_split to patch level 2. 
As the shar file is only 18k, I am submitting it full.

[fmc]

---- Cut Here and unpack ----
#!/bin/sh
# This is news_split, a shell archive (shar 3.32)
# made 02/22/1991 15:23 UTC by fmc@cnam.cnam.fr
# Source directory /users/labinf/fmc/tools/news_split
#
# existing files will NOT be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   8228 -rw-r--r-- news_split.c
#    130 -rw-r--r-- patchlevel.h
#    660 -rw-r--r-- Makefile
#   3402 -rw-r--r-- README
#   2256 -rw-r--r-- INSTALL
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= news_split.c ==============
if test X"$1" != X"-c" -a -f 'news_split.c'; then
	echo "File already exists: skipping 'news_split.c'"
else
echo "x - extracting news_split.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > news_split.c &&
X
X/*
X * news_split		[fmc] 21/02/91		Version 1.8
X *			Browse a given NewsGroup (usualy comp.sources.???
X *			and try to update/maintain a directory for the
X *			sources found in it. 
X *			I use it to maintain the ~ftp/pub/comp.sources.???
X *			from the equivalent News directories.
X *
X *			Usage: news_split [-sn#a] [-l logdir] group ... group
X *			    or news_split [-sn#a] [-l logdir] -f groupfile
X *
X *			In the second case, groupfile is a file containing 
X *			each group to be processed, one per line.
X *
X *	CopyLeft and CopyWrong Frederic Chauveau [fmc@cnam.cnam.fr]
X */
X
X#include <stdio.h>
X#ifdef NOUNISTD
X#include <sys/file.h>
X#else
X#include <unistd.h>
X#endif
X#include <ctype.h>
X#include <errno.h>
X#include <sys/types.h>
X#include <sys/dir.h>
X#include "patchlevel.h"
X
X#ifndef NEWS_SPOOL
X#define NEWS_SPOOL "/usr/spool/news"
X#endif /* no NEWS_SPOOL */
X
X#ifndef FTP_DIR
X#define FTP_DIR "/local/ftp/pub"
X#endif /* no FTP_DIR */
X
X#ifndef LOGFILE
X#define LOGFILE "%s/Index.ns"
X#endif /* no LOGFILE */
X
X#ifndef LOGDIR
X#define LOGDIR FTP_DIR
X#endif
X
XFILE *logfile;
Xchar *logdir = LOGDIR;
X
Xchar logname[BUFSIZ];
Xchar Supercede_P = 1;
Xchar force_number = 0;
X
X#ifndef DIRENT
X#define DIRENT struct direct
X#endif
X
X#ifdef NOSCANDIR
X
Xint scandir(DirName,NameList,Select,Sort)
Xchar *DirName;
XDIRENT *(*NameList[]);
Xint (*Select)(), (*Sort)(); {
X  int c = 0;
X  DIRENT **tab, *entry;
X  DIR *dirp;
X
X  dirp = opendir(DirName);
X  while (entry = readdir(dirp))
X    c += (Select ? (*Select)(entry) : 1);
X  tab = (DIRENT **) malloc(c * sizeof(DIRENT *));
X  rewinddir(dirp); c = 0;
X  while (entry = readdir(dirp))
X    if (!Select || (*Select)(entry))
X      tab[c++] = entry;
X  if (Sort)
X    qsort(tab,c,sizeof(DIRENT *),Sort);
X  *NameList = tab;
X  return c;
X}
X
X#endif /* NOSCANDIR */  
X
XDirSelect(dp)
XDIRENT *dp; {
X  return isdigit(dp->d_name[0]);
X}
X
Xvoid CreateDirAndFile(dirname,infile)
Xchar *dirname;
XFILE *infile; {
X  FILE *outfile;
X  char *p = dirname;
X  char buf[BUFSIZ];
X
X  while (p = (char *) strchr(p+1,'/'))
X    {
X      *p = '\0';
X      if (mkdir(dirname,0766) && (errno != EEXIST))
X	{
X	  FILE *foo = stderr;
X	  *stderr = *logfile;
X	  perror(dirname);
X	  *stderr = *foo;
X	  perror(dirname);
X	  return;
X	}
X      *p = '/';
X    }
X  if (!infile)
X    return;
X#ifdef COMPRESS
X  strcat(dirname,".Z");
X#endif
X  if (access(dirname,F_OK) != -1)
X    {
X      fprintf(stderr,"  Warning: %s %s\n",
X	      (Supercede_P ? "Superceding" : "Not Superceding"),dirname);
X      fprintf(logfile,"  Warning: %s %s\n",
X	      (Supercede_P ? "Superceding" : "Not Superceding"),dirname);
X      if (!Supercede_P)
X	return;
X    }
X#ifdef COMPRESS
X  sprintf(buf,"%s > %s",COMPRESS,dirname); /* .Z already tacked at the end */
X  outfile = popen(buf,"w");
X#else    
X  outfile = fopen(dirname,"w");
X#endif
X  if (!outfile)
X    {
X      FILE *foo = stderr;
X      *stderr = *logfile;
X      perror(dirname);
X      *stderr = *foo;
X      perror(dirname);
X    }
X  else
X    {
X      rewind(infile);
X      while (fgets(buf,BUFSIZ,infile))
X	fputs(buf,outfile);
X#ifdef COMPRESS
X      pclose(outfile);
X#else
X      fclose(outfile);
X#endif
X    }
X}  
X
Xvoid SaveIt(pnumb,aname,subj,anumb,infile,group)
Xchar *pnumb, *aname, *group, *subj, *anumb;
XFILE *infile; {
X  int vol, iss;
X  char dirname[BUFSIZ];
X
X  pnumb[strlen(pnumb)-1] = '\0';
X  if (force_number)
X    {
X      fprintf(logfile,"Art #%s: %s",anumb,subj);
X      sprintf(dirname,"%s/%s/%s",FTP_DIR,group,anumb);
X      CreateDirAndFile(dirname,infile);
X      return;
X    }      
X  if (sscanf(pnumb,"Posting-number: Volume %d, Info%*[^0-9] %d",&vol,&iss) != 2)
X    {
X      if (sscanf(pnumb,"Posting-number: Volume %d %*[^0-9] %d",&vol,&iss) != 2)
X	{
X	  fprintf(stderr," Couldn't get volume for article [%s]\n",anumb);
X	  fprintf(logfile," Couldn't get volume for article [%s]\n",anumb);
X	  sprintf(dirname,"%s/%s/%s",FTP_DIR,group,anumb);
X	  CreateDirAndFile(dirname,infile);
X	}
X    }
X  else
X      sprintf(aname,"Archive-name: Info%d\n",iss);
X  if (!aname[0])
X    {
X      sprintf(dirname,"%s/%s/%s",FTP_DIR,group,subj);
X      CreateDirAndFile(dirname,infile);
X    }
X  else
X    {
X      aname += 14; aname[strlen(aname)-1] = '\0';
X      sprintf(dirname,"%s/%s/volume%d/%s",FTP_DIR,group,vol,aname);
X      fprintf(logfile,"Volume %3d, Issue %3d :\t\t%s\n",vol,iss,aname);
X      CreateDirAndFile(dirname,infile);
X    }
X}
X
Xvoid ProcArticle(art,group)
Xchar *art, *group; {
X  FILE *inp;
X  char buf[BUFSIZ], postnum[BUFSIZ], archnam[BUFSIZ];
X  char subject[BUFSIZ];
X  int i = 0;
X
X  if (!(inp = fopen(art,"r")))
X    {
X      perror(art);
X      return;
X    }
X  *postnum = *archnam = *subject = '\0';
X  while (fgets(buf,BUFSIZ,inp))
X    {
X      if ((*postnum && *archnam && *subject) ||
X	  (*buf == '#') || (i > 30))
X	{
X	  SaveIt(postnum,archnam,subject,art,inp,group);
X	  break;
X	}
X      if (!strncmp("Subject:",buf,8)) 
X	{
X	  if (force_number)
X	    strcpy(subject,buf+8);
X	  else
X	    sscanf(buf,"Subject: %[^ :]",subject);
X	}
X      else if (!strncmp("Posting-number",buf,14))
X	strcpy(postnum,buf);
X      else if (!strncmp("Archive-name",buf,12))
X	strcpy(archnam,buf);
X      i++;
X    }
X  fclose(inp);
X}
X
XGroupToDir(group,dirname)
Xchar *group, *dirname; {
X  char *p;
X  strcpy(dirname,group);
X  
X  for (p = (char *) strchr(dirname,'.'); p; p = (char *) strchr(p,'.'))
X    *p++ = '/';
X}
X
Xvoid ProcGroup(group,first,last)
Xint *first, *last;
Xchar *group; {
X  register int i, art_num, max, nf = *first, nl = *last;
X  char dirname[BUFSIZ];
X  DIRENT **namelist;
X
X  chdir(NEWS_SPOOL);
X  GroupToDir(group,dirname);
X  chdir(dirname);
X  max = scandir(".",&namelist,DirSelect,NULL);
X  if (max == -1)
X    {
X      perror(dirname);
X      fprintf(stderr,"Cannot scan %s/%s\n",NEWS_SPOOL,group);
X      return;
X    }
X  for (i = 0; i < max; i++)
X    {
X      art_num = atoi(namelist[i]->d_name);
X      if (art_num < *first)
X	ProcArticle(namelist[i]->d_name,group);
X      else if (art_num > *last)
X	ProcArticle(namelist[i]->d_name,group);
X      if (art_num && art_num < nf)
X	nf = art_num;
X      if (art_num && art_num > nl)
X	nl = art_num;
X    }
X  *first = nf;
X  *last = nl;
X}
X
XFILE *OpenLog(group_name)
Xchar *group_name; {
X  char tmp[BUFSIZ], ln[BUFSIZ];
X  FILE *logfile;
X
X  sprintf(tmp,LOGFILE,group_name);
X  sprintf(ln,"%s/%s",logdir,tmp);
X  CreateDirAndFile(ln,NULL);
X  if (!(logfile = fopen(ln,"w")))
X    {
X      perror(ln);
X      logfile = stderr;
X    }
X  return logfile;
X}
X
Xvoid ProcName(group_name, backtodir)
Xchar *group_name, *backtodir; {
X  FILE *tmp;
X  int first, last;
X  long now;
X
X  now = time((long *) 0);
X  logfile = OpenLog(group_name);
X  tmp = fopen(group_name,"r");
X  if (!tmp)
X    {
X      first = 9999;
X      last = 0;
X    }
X  else
X    {
X      fscanf(tmp,"%d %d",&first,&last);
X      fclose(tmp);
X    }
X  fprintf(logfile," -- Processing group %s (%d %d) at %s",group_name,first,
X	  last,ctime(&now));
X  fprintf(stderr,"Processing group %s (%d %d)\n",group_name,first,last);
X  ProcGroup(group_name,&first,&last);
X  chdir(backtodir);
X  tmp = fopen(group_name,"w");
X  fprintf(tmp,"%d %d\n",first,last);
X  fclose(tmp);
X  if (logfile != stderr)
X    fclose(logfile);
X  fprintf(stderr,"Processed  group %s (%d %d)\n",group_name,first,last);
X}
X
X
Xvoid Usage(s,pn)
Xchar *s, *pn; {
X  fprintf(stderr,"Unknown option %s\n",s);
X  fprintf(stderr,"Usage: %s [-sn] [-l logdir] [-f group_file | group1 .. groupn]\n",pn);
X  exit(1);
X}
X
Xmain(argc,argv)
Xchar **argv; {
X  FILE *from_file = NULL;
X  char cwd[BUFSIZ], *pname = *argv;
X  
X  getcwd(cwd,BUFSIZ);
X  while (++argv, --argc)
X    {
X      if (**argv == '-')
X	{
X	  switch (argv[0][1])
X	    {
X	    case 's' : case 'S' : Supercede_P = 1; break;
X	    case 'n' : case 'N' : Supercede_P = 0; break;
X	    case 'l' : case 'L' : logdir = argv[1]; argv++; argc--; break;
X	    case '#' : force_number = 1; break;
X	    case 'a' : force_number = 0; break;
X	    case 'f' : case 'F' : 
X	      from_file = fopen(argv[1],"r"); 
X	      if (!from_file)
X		{
X		  perror(argv[1]);
X		  argv++; argc--; 
X		}
X	      break;
X	    default: Usage(*argv,pname);
X	    }
X	  continue;
X	}
X      if (from_file)
X	{
X	  char gname[BUFSIZ];
X
X	  while (fgets(gname,BUFSIZ,from_file))
X	    {
X	      gname[strlen(gname)-1] = '\0';
X	      ProcName(gname,cwd);
X	    }
X	  fclose(from_file);
X	  from_file = NULL;
X	}
X      else 
X	ProcName(*argv,cwd);
X    }
X}
X
X	  
SHAR_EOF
$TOUCH -am 0222162391 news_split.c &&
chmod 0644 news_split.c ||
echo "restore of news_split.c failed"
set `wc -c news_split.c`;Wc_c=$1
if test "$Wc_c" != "8228"; then
	echo original size 8228, current size $Wc_c
fi
fi
# ============= patchlevel.h ==============
if test X"$1" != X"-c" -a -f 'patchlevel.h'; then
	echo "File already exists: skipping 'patchlevel.h'"
else
echo "x - extracting patchlevel.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > patchlevel.h &&
X/*
X * patchlevel.hfor news_split.
X * First patch updates from v1.6 to v1.7
X * there was NO PATCHLEVEL 1
X */
X
X#define PATCHLEVEL 2
SHAR_EOF
$TOUCH -am 0222111391 patchlevel.h &&
chmod 0644 patchlevel.h ||
echo "restore of patchlevel.h failed"
set `wc -c patchlevel.h`;Wc_c=$1
if test "$Wc_c" != "130"; then
	echo original size 130, current size $Wc_c
fi
fi
# ============= Makefile ==============
if test X"$1" != X"-c" -a -f 'Makefile'; then
	echo "File already exists: skipping 'Makefile'"
else
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
XALLFILES = news_split.c patchlevel.h Makefile README INSTALL
X
X# for system with no scandir function add -DNOSCANDIR to CFLAGS
X# for system with no <unistd.h> file, add -dNOUNISTD  to CFLAGS
X# if you want to save in compressed format add
X#	 -DCOMPRESS=\"compress\" to CFLAGS
X
XCFLAGS = -O -DCOMPRESS=\"compress\i

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.