home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume16 / news_split / part01 next >
Encoding:
Internet Message Format  |  1991-02-02  |  13.0 KB

  1. From: fmc@cnam.cnam.fr (Frederic Chauveau)
  2. Newsgroups: comp.sources.misc
  3. Subject: v16i084:  News to Archive, Part01/01
  4. Message-ID: <1991Jan29.011309.21458@sparky.IMD.Sterling.COM>
  5. Date: 29 Jan 91 01:13:09 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: d2607b56 048721ee 878b808f 0ffef980
  8.  
  9. Submitted-by: fmc@cnam.cnam.fr (Frederic Chauveau)
  10. Posting-number: Volume 16, Issue 84
  11. Archive-name: news_split/part01
  12.  
  13. Ok, here it is version 1.5. It runs (tested) on Ultrix. I've provided
  14. a replacement for scandir if you don't have the function. I couldn't
  15. test it on other machines but it compiles Ok on a sony RISC (4.3bsd
  16. looking a bit like MIPS/OS). Still no man page but a (simpleton)
  17. Makefile. I ran it for the last couple of month on comp.sources.* with
  18. (apparently) no troubles. 
  19.  
  20. I've added to compilation flags:
  21.  
  22. NOUNISTD if you don't have /usr/include/unistd.h (replaced by sys/file.h)
  23. DIRENT if your struct direct (default) is called something else (like
  24. struct dirent on Ultrix, but they provide an alias).
  25.  
  26. It should run Ok on all bsd-derived version of Un*x, don't know for
  27. SysV.
  28.  
  29. Frederic Chauveau
  30.  
  31. ---- Cut Here and unpack ----
  32. #!/bin/sh
  33. # This is news_split, a shell archive (shar 3.32)
  34. # made 01/21/1991 10:14 UTC by fmc@cnam.cnam.fr
  35. # Source directory /users/labinf/fmc/tools/news_split
  36. #
  37. # existing files will NOT be overwritten
  38. #
  39. # This shar contains:
  40. # length  mode       name
  41. # ------ ---------- ------------------------------------------
  42. #   2608 -rw-r--r-- README
  43. #    196 -rw-r--r-- Makefile
  44. #   6441 -rw-r--r-- news_split.c
  45. #
  46. if touch 2>&1 | fgrep 'amc' > /dev/null
  47.  then TOUCH=touch
  48.  else TOUCH=true
  49. fi
  50. # ============= README ==============
  51. if test X"$1" != X"-c" -a -f 'README'; then
  52.     echo "File already exists: skipping 'README'"
  53. else
  54. echo "x - extracting README (Text)"
  55. sed 's/^X//' << 'SHAR_EOF' > README &&
  56. X/*
  57. X * news_split        [fmc] 15/01/91        Version 1.5
  58. X *            Browse a given NewsGroup (usualy comp.sources.???
  59. X *            and try to update/maintain a directory for the
  60. X *            sources found in it. 
  61. X *            I use it to maintain the ~ftp/pub/comp.sources.???
  62. X *            from the equivalent News directories.
  63. X *
  64. X *            Variables for you to overide :
  65. X *            - LOGFILE a one argument string to generate 
  66. X *               the log file name. Default to "%s.log" where
  67. X *              %s will be the group name (eg. comp.sources.???)
  68. X *            - NEWS_SPOOL the root of the News Spool tree. 
  69. X *              When looking for group.misc.name we will cd to
  70. X *              NEWS_SPOOL/group/misc/name
  71. X *            - FTP_DIR the root of destination tree. Usualy
  72. X *              the absolute name of ~ftp/pub.
  73. X */
  74. X
  75. XUsage: news_split [-sn] group_name ... group_name
  76. X
  77. XThe group_name is in Usenet format (eg. comp.sources.games). A file with
  78. Xthe same name is created, containing the Min and Max article number already
  79. Xprocessed. 
  80. X
  81. XA log file is created for each group processed. This logfile can be used to
  82. Xmaintain an index of the created files. (See LOGFILE above)
  83. X
  84. XIf the '-s' flag is present, new files will supercede old files in case of
  85. Xconflicting names. This is the default.
  86. X
  87. XIf the '-n' flag is present, new files will not supercede old files.
  88. X
  89. XYou can merge group_name and options on the command line.
  90. X
  91. XKnown Bugs/Limitations. 
  92. X
  93. XIt works on Ultrix 4.0 and later. The main system dependencies should
  94. Xbe the scandir function. I've provided a replacement but it has not been
  95. Xchecked. 
  96. X
  97. XThe header format is the most limitating factor. We're looking for :
  98. X
  99. Xa Subject line ("^Subject:") 
  100. Xa Posting-number line ("^Posting-number:") and
  101. Xa Archive-name line ("^Archive-name:").
  102. X
  103. Xin the first 30 lines, or before the first line beginning with a '#',
  104. Xwhichever happend first.
  105. X
  106. XFrom the Subject line we get a first subject as the word following Subject:
  107. XFrom the Post line we get a Volume-number and perhaps an Issue number.
  108. XFrom the Arch line (if present) we get a destination filename.
  109. X
  110. XThe destination file will be :
  111. X
  112. X  if No Archive-name line, and Posting-number isn't recognized as an
  113. X     Information posting, we copy the file under the subject name (i.e.
  114. X     vxxxcnnn usualy.)
  115. X
  116. X  if We have a volume number VV (from the Posting-number line) and an issue
  117. X     number, we save as FTP_DIR/group_name/volumeVV/filename, where
  118. X     filename comes from the archive-name line.
  119. X
  120. X  if we have a volume number VV (from the Posting-number line) and an info
  121. X     number NN (From the Posting-number line) we save as
  122. X     FTP_DIR/group_name/volumeVV/InfoNN.
  123. X
  124. XElse we warn that we couldn't parse the Posting-number line.
  125. X
  126. SHAR_EOF
  127. $TOUCH -am 0121095891 README &&
  128. chmod 0644 README ||
  129. echo "restore of README failed"
  130. set `wc -c README`;Wc_c=$1
  131. if test "$Wc_c" != "2608"; then
  132.     echo original size 2608, current size $Wc_c
  133. fi
  134. fi
  135. # ============= Makefile ==============
  136. if test X"$1" != X"-c" -a -f 'Makefile'; then
  137.     echo "File already exists: skipping 'Makefile'"
  138. else
  139. echo "x - extracting Makefile (Text)"
  140. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  141. X
  142. X# for system with no scandir function add -DNOSCANDIR to CFLAGS
  143. X
  144. XCFLAGS = -O
  145. X
  146. X# you should add -ldir
  147. X
  148. XLDFLAGS =
  149. X
  150. Xnews_split : news_split.o
  151. X    $(CC) $(CFLAGS) news_split.o -o news_split $(LDFLAGS)
  152. X
  153. SHAR_EOF
  154. $TOUCH -am 0121095291 Makefile &&
  155. chmod 0644 Makefile ||
  156. echo "restore of Makefile failed"
  157. set `wc -c Makefile`;Wc_c=$1
  158. if test "$Wc_c" != "196"; then
  159.     echo original size 196, current size $Wc_c
  160. fi
  161. fi
  162. # ============= news_split.c ==============
  163. if test X"$1" != X"-c" -a -f 'news_split.c'; then
  164.     echo "File already exists: skipping 'news_split.c'"
  165. else
  166. echo "x - extracting news_split.c (Text)"
  167. sed 's/^X//' << 'SHAR_EOF' > news_split.c &&
  168. X/*
  169. X * news_split        [fmc] 15/01/91        Version 1.5
  170. X *            Browse a given NewsGroup (usualy comp.sources.???
  171. X *            and try to update/maintain a directory for the
  172. X *            sources found in it. 
  173. X *            I use it to maintain the ~ftp/pub/comp.sources.???
  174. X *            from the equivalent News directories.
  175. X *
  176. X *            Variables for you to overide :
  177. X *            - LOGFILE a one argument string to generate 
  178. X *               the log file name. Default to "%s.log" where
  179. X *              %s will be the group name (eg. comp.sources.???)
  180. X *            - NEWS_SPOOL the root of the News Spool tree. 
  181. X *              When looking for group.misc.name we will cd to
  182. X *              NEWS_SPOOL/group/misc/name
  183. X *            - FTP_DIR the root of destination tree. Usualy
  184. X *              the absolute name of ~ftp/pub.
  185. X *            
  186. X *            Compile with $(CC) -o news_split news_split.c
  187. X *            Usage: news_split [-sn] group_name ... group_name
  188. X *
  189. X *    CopyLeft and CopyWrong Frederic Chauveau [fmc@cnam.cnam.fr]
  190. X */
  191. X
  192. X#include <stdio.h>
  193. X#ifdef NOUNISTD
  194. X#include <sys/file.h>
  195. X#else
  196. X#include <unistd.h>
  197. X#endif
  198. X#include <ctype.h>
  199. X#include <sys/types.h>
  200. X#include <sys/dir.h>
  201. X
  202. X#ifndef LOGFILE
  203. X#define LOGFILE "%s.log"
  204. X#endif /* no LOGFILE */
  205. X
  206. X#ifndef NEWS_SPOOL
  207. X#define NEWS_SPOOL "/usr/spool/news"
  208. X#endif /* no NEWS_SPOOL */
  209. X
  210. X#ifndef FTP_DIR
  211. X#define FTP_DIR "/local/ftp/pub"
  212. X#endif /* no FTP_DIR */
  213. X
  214. XFILE *logfile;
  215. Xchar Supercede = 1;
  216. X
  217. X#ifndef DIRENT
  218. X#define DIRENT struct direct
  219. X#endif
  220. X
  221. X#ifdef NOSCANDIR
  222. X
  223. Xint scandir(DirName,NameList,Select,Sort)
  224. Xchar *DirName;
  225. XDIRENT *(*NameList[]);
  226. Xint (*Select)(), (*Sort)(); {
  227. X  int c = 0;
  228. X  DIRENT **tab, *entry;
  229. X  DIR *dirp;
  230. X
  231. X  dirp = opendir(DirName);
  232. X  while (entry = readdir(dirp))
  233. X    c += (Select ? (*Select)(entry) : 1);
  234. X  tab = (DIRENT **) malloc(c * sizeof(DIRENT *));
  235. X  rewinddir(dirp); c = 0;
  236. X  while (entry = readdir(dirp))
  237. X    if (!Select || (*Select)(entry))
  238. X      tab[c++] = entry;
  239. X  if (Sort)
  240. X    qsort(tab,c,sizeof(DIRENT *),Sort);
  241. X  *NameList = tab;
  242. X  return c;
  243. X}
  244. X
  245. X#endif /* NOSCANDIR */  
  246. X
  247. XDirSelect(dp)
  248. XDIRENT *dp; {
  249. X  return isdigit(dp->d_name[0]);
  250. X}
  251. X
  252. Xvoid CreateDirAndFile(dirn,infile)
  253. Xchar *dirn;
  254. XFILE *infile; {
  255. X  FILE *outfile;
  256. X  char *p = dirn;
  257. X  char buf[BUFSIZ];
  258. X
  259. X  while (p = (char *) strchr(p+1,'/'))
  260. X    {
  261. X      *p = '\0';
  262. X      mkdir(dirn,0766);
  263. X      *p = '/';
  264. X    }
  265. X  if (access(dirn,F_OK) != -1)
  266. X    {
  267. X      fprintf(stderr,"  Warning: %s %s\n",
  268. X          (Supercede ? "Superceding" : "Not Superceding"),dirn);
  269. X      fprintf(logfile,"  Warning: %s %s\n",
  270. X          (Supercede ? "Superceding" : "Not Superceding"),dirn);
  271. X      if (!Supercede)
  272. X    return;
  273. X    }
  274. X  outfile = fopen(dirn,"w");
  275. X  if (!outfile)
  276. X    {
  277. X      FILE *foo = stderr;
  278. X      *stderr = *logfile;
  279. X      perror(dirn);
  280. X      *stderr = *foo;
  281. X      perror(dirn);
  282. X    }
  283. X  else
  284. X    {
  285. X      rewind(infile);
  286. X      while (fgets(buf,BUFSIZ,infile))
  287. X    fputs(buf,outfile);
  288. X      fclose(outfile);
  289. X    }
  290. X}  
  291. X
  292. Xvoid SaveIt(pnumb,aname,subj,infile,group)
  293. Xchar *pnumb, *aname, *group;
  294. XFILE *infile; {
  295. X  int vol, iss;
  296. X  char dirn[BUFSIZ];
  297. X
  298. X  pnumb[strlen(pnumb)-1] = '\0';
  299. X  if (sscanf(pnumb,"Posting-number: Volume %d, Info%*[^0-9] %d",&vol,&iss) != 2)
  300. X    {
  301. X      if (sscanf(pnumb,"Posting-number: Volume %d %*[^0-9] %d",&vol,&iss) != 2)
  302. X    {
  303. X      fprintf(stderr," Couldn't get volume for article [%s]\n",pnumb);
  304. X      fprintf(logfile," Couldn't get volume for article [%s]\n",pnumb);
  305. X      sprintf(dirn,"%s/%s/%s",FTP_DIR,group,subj);
  306. X      CreateDirAndFile(dirn,infile);
  307. X    }
  308. X    }
  309. X  else
  310. X      sprintf(aname,"Archive-name: Info%d\n",iss);
  311. X  if (!aname[0])
  312. X    {
  313. X      sprintf(dirn,"%s/%s/%s",FTP_DIR,group,subj);
  314. X      CreateDirAndFile(dirn,infile);
  315. X    }
  316. X  else
  317. X    {
  318. X      aname += 14; aname[strlen(aname)-1] = '\0';
  319. X      sprintf(dirn,"%s/%s/volume%d/%s",FTP_DIR,group,vol,aname);
  320. X      fprintf(logfile,"Volume %3d, Issue %3d :\t\t%s\n",vol,iss,aname);
  321. X      CreateDirAndFile(dirn,infile);
  322. X    }
  323. X}
  324. X
  325. Xvoid ProcArticle(art,group)
  326. Xchar *art, *group; {
  327. X  FILE *inp;
  328. X  char buf[BUFSIZ], postnum[BUFSIZ], archnam[BUFSIZ], subject[BUFSIZ];
  329. X  int i = 0;
  330. X
  331. X  if (!(inp = fopen(art,"r")))
  332. X    {
  333. X      perror(art);
  334. X      return;
  335. X    }
  336. X  *postnum = *archnam = *subject = '\0';
  337. X  while (fgets(buf,BUFSIZ,inp))
  338. X    {
  339. X      if ((*postnum && *archnam && *subject) ||
  340. X      (*buf == '#') || (i > 30))
  341. X    {
  342. X      SaveIt(postnum,archnam,subject,inp,group);
  343. X      break;
  344. X    }
  345. X      if (!strncmp("Subject:",buf,8))
  346. X    sscanf(buf,"Subject: %[^ :]",subject);
  347. X      else if (!strncmp("Posting-number",buf,14))
  348. X    strcpy(postnum,buf);
  349. X      else if (!strncmp("Archive-name",buf,12))
  350. X    strcpy(archnam,buf);
  351. X      i++;
  352. X    }
  353. X  fclose(inp);
  354. X}
  355. X
  356. XGroupToDir(group,dirname)
  357. Xchar *group, *dirname; {
  358. X  char *p;
  359. X  strcpy(dirname,group);
  360. X  
  361. X  for (p = (char *) strchr(dirname,'.'); p; p = (char *) strchr(p,'.'))
  362. X    *p++ = '/';
  363. X}
  364. X
  365. Xvoid ProcGroup(group,first,last)
  366. Xint *first, *last;
  367. Xchar *group; {
  368. X  register int i, art_num, max, nf = *first, nl = *last;
  369. X  char dirname[BUFSIZ];
  370. X  DIRENT **namelist;
  371. X
  372. X  chdir(NEWS_SPOOL);
  373. X  GroupToDir(group,dirname);
  374. X  chdir(dirname);
  375. X  max = scandir(".",&namelist,DirSelect,NULL);
  376. X  if (max == -1)
  377. X    {
  378. X      perror(dirname);
  379. X      fprintf(stderr,"Cannot scan %s/%s\n",NEWS_SPOOL,group);
  380. X      return;
  381. X    }
  382. X  for (i = 0; i < max; i++)
  383. X    {
  384. X      art_num = atoi(namelist[i]->d_name);
  385. X      if (art_num < *first)
  386. X    ProcArticle(namelist[i]->d_name,group);
  387. X      else if (art_num > *last)
  388. X    ProcArticle(namelist[i]->d_name,group);
  389. X      if (art_num && art_num < nf)
  390. X    nf = art_num;
  391. X      if (art_num && art_num > nl)
  392. X    nl = art_num;
  393. X    }
  394. X  *first = nf;
  395. X  *last = nl;
  396. X}
  397. X
  398. Xvoid Usage(s)
  399. Xchar *s; {
  400. X  fprintf(stderr,"Unknown option %s, valid flags are -s or -n\n",s);
  401. X}
  402. X
  403. Xmain(argc,argv)
  404. Xchar **argv; {
  405. X  FILE *tmp;
  406. X  int first, last;
  407. X  char cwd[BUFSIZ], Logname[BUFSIZ];
  408. X  
  409. X  getcwd(cwd,BUFSIZ);
  410. X  while (++argv, --argc)
  411. X    {
  412. X      if (**argv == '-')
  413. X    {
  414. X      switch (argv[0][1])
  415. X        {
  416. X        case 's' : case 'S' : Supercede = 1; break;
  417. X        case 'n' : case 'N' : Supercede = 0; break;
  418. X        default: Usage(*argv); exit(1);
  419. X        }
  420. X      continue;
  421. X    }
  422. X      tmp = fopen(*argv,"r");
  423. X      sprintf(Logname,LOGFILE,*argv);
  424. X      logfile = fopen(Logname,"a");
  425. X
  426. X      if (!tmp)
  427. X    {
  428. X      first = 9999;
  429. X      last = 0;
  430. X    }
  431. X      else
  432. X    {
  433. X      fscanf(tmp,"%d %d",&first,&last);
  434. X      fclose(tmp);
  435. X    }
  436. X      fprintf(logfile,"Processing group %s (%d %d)\n",*argv,first,last);
  437. X      fprintf(stderr,"Processing group %s (%d %d)\n",*argv,first,last);
  438. X      ProcGroup(*argv,&first,&last);
  439. X      chdir(cwd);
  440. X      tmp = fopen(*argv,"w");
  441. X      fprintf(tmp,"%d %d\n",first,last);
  442. X      fclose(tmp);
  443. X      fclose(logfile);
  444. X    }
  445. X}
  446. X
  447. X      
  448. SHAR_EOF
  449. $TOUCH -am 0121101391 news_split.c &&
  450. chmod 0644 news_split.c ||
  451. echo "restore of news_split.c failed"
  452. set `wc -c news_split.c`;Wc_c=$1
  453. if test "$Wc_c" != "6441"; then
  454.     echo original size 6441, current size $Wc_c
  455. fi
  456. fi
  457. exit 0
  458.  
  459.                             [fmc]
  460.  
  461. -------------------------------------------------------------------------------
  462. Frederic Chauveau             Conservatoire National des Arts et Metiers
  463. fmc@cnam.cnam.fr
  464. -------------------------------------------------------------------------------
  465. Paradise is exactly like where you are right now, only much, much better.
  466.                                William S. Burroughs
  467. -------------------------------------------------------------------------------
  468.  
  469. exit 0 # Just in case...
  470. -- 
  471. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  472. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  473. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  474. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  475.