home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
unix
/
sit_shar
/
macbinfilt.c
next >
Wrap
C/C++ Source or Header
|
1991-01-30
|
4KB
|
167 lines
/*
* macbinfilt -- filters usenet articles from comp.binaries.mac into a form
* suitable for xbin to decode. Will rearange parts of file if they are not
* in order. Strips out all extraneous lines.
* Does all of this by making many bold assumtions--but it's worked so far.
*
* Only works on one article at a time. All files on the input line are
* considered parts of the same article.
*
* If you have the sysV regualar expression routines (regcmp, regex) then
* define HAVE_REGCMP for a more robust pattern match.
*
* --Tom Bereiter
* ..!{rutgers,ames}!cs.utexas.edu!halley!rolex!twb
*/
#include <stdio.h>
int cur_part,part,divert_part;
int max_part;
#define IBUFSZ 512
char ibuf[IBUFSZ];
char pname[80];
FILE *ofs=stdout;
FILE *saveofs;
FILE *parts[100];
#ifdef HAVE_REGCMP
#define EXP ".*[Pp][Aa][Rr][Tt][ \t]*([0-9]+)$0[ \t]*[Oo][Ff][ \t]*([0-9]+)$1"
#else
#define EXP "part %d of %d"
#endif
char *exp;
main(argc,argv) char **argv[]; {
FILE *fs;
int i,rc=0;
#ifdef HAVE_REGCMP
exp = (char *)regcmp(EXP,0);
#else
exp = EXP;
#endif
fputs("(This file must be converted with BinHex 4.0)\n\n",ofs);
if (argc == 1)
filter(stdin);
else while (--argc) {
if ((fs=fopen(*++argv,"r"))==NULL) {
perror(*argv); exit(-1); }
filter(fs);
fclose(fs);
}
/* add any remaining parts */
for (i=cur_part+1; i<=max_part; i++)
if (parts[i])
putpart(i);
else {
fprintf(stderr,"Missing part %d\n",i);
rc = -1;
}
exit(rc);
}
/* valid xbin chars + '\n' and '\r' */
#define Btst(i) (bmap[i>>3] & (1<<(i&07)))
char bmap[]={0x00,0x24,0x00,0x00,0xfe,0x3f,0x7f,0x07,
0xff,0x7f,0x7f,0x0f,0x7f,0x3f,0x07,0x00};
/* filter out extraneous lines and look for lines of the form:
* part n of m
* A line is considered valid if it has only valid xbin characters and is
* either greater than 60 characters or ends in a ':'
*/
filter(fs) FILE *fs; {
register char *p,*inp;
reget:
while ((inp=fgets(ibuf,IBUFSZ,fs))) {
for (p=inp; *p; p++)
if (Btst(*p) == 0) { /* invalid character */
checkparts(inp);
goto reget;
}
if (p-inp > 60 || inp[(p-inp)-2]==':') /* arbitrary max or end */
fputs(ibuf,ofs);
}
if (divert_part) /* diversion in progress */
end_oseq();
}
checkparts(str) char *str; {
char *p;
char num0[40], num1[40];
#ifdef HAVE_REGEXP
if (regex(exp, str, num0,num1)!=NULL) {
part = atoi(num0);
max_part = atoi(num1);
fprintf(stderr,"part %d of %d\n",part,max_part);
dopart();
}
#else
for (p=str; *p; p++) /* rescan for 'part' string */
if (*p==exp[0])
if (sscanf(p,exp,&part,&max_part) == 2) {
dopart();
break;
}
#endif
}
dopart() {
if (divert_part) { /* diversion in progress */
if (part == divert_part) /* another mention of current part */
return;
end_oseq();
}
if (part == cur_part+1) /* OK: next in sequence */
cur_part = part;
else if (part > cur_part) /* out of sequence */
oseq();
else /* "can't" happen */
fprintf(stderr,"Part %d unexpected\n",part);
}
/* part out of sequence */
oseq() {
int i;
/* try and fill in gap */
for (i=cur_part+1; i<part; i++)
if (parts[i]) {
putpart(i);
cur_part = i;
}
else goto isgap;
/* all missing parts restored -- continue */
return;
isgap:
/* start diversion */
divert_part = part;
saveofs = ofs;
sprintf(pname,"part%d",part);
if ((ofs = fopen(pname,"w+")) == NULL) {
perror(pname); exit(-1); }
parts[part] = ofs;
}
end_oseq() {
divert_part = 0;
ofs = saveofs;
}
putpart(n) {
FILE *fs;
register int c;
fs = parts[n];
rewind(fs);
while ((c=getc(fs))!=EOF)
putc(c,ofs);
fclose(fs);
sprintf(pname,"part%d",n);
unlink(pname);
}