|
|
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 s
Length: 12384 (0x3060)
Types: TextFile
Names: »scansub.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦e7f64e0c0⟧ »EurOpenD3/mail/vmh.tar.Z«
└─⟦dcb95597f⟧
└─⟦this⟧ »SAVE/scansub.c«
#ifdef COMMENT
Proprietary Rand Corporation, 1981.
Further distribution of this software
subject to the terms of the Rand
license agreement.
Ripped off from mh scansub routine -- jdg
Added state hack for empty msgs. 10/31/82
rewrote cpy routine to handle cntrl characters
#endif
/* clean up multiple places where all the fields are defined! */
#include "hm.h"
#include <stdio.h>
#include <ctype.h>
#include <sys/time.h>
#include "adrparse.h"
#define Block
#define _FROM 1
#define _NOTFROM 0
#define SMSGN DMAXFOLDER /* Length */
#define SFLGS 2 /* Width of flag field */
#define SDATE 7 /* Length of Date field */
#define STIME 8 /* Length of time field */
#define SNDATE 6 /* Length of numeric date */
#define SNTIME 4 /* Length of numeric time */
#define SFROM 16 /* Length of " " */
#define SLINE 79 /* size of line */
#define BSUBJ 20 /* Room needed in Sub field to */
/* add stuff from the body */
int local;
int hostseen;
char *frmtok();
scansub(inb, innum, outfd)
FILE *inb; /* Open msg file (not the folder) */
int innum; /* Msg number of the current msg */
FILE *outfd; /* Where to print the result */
{
char buf[BUFSIZ], name[NAMESZ], tobuf[32], frombuf[32];
register char *cp, **tok1;
int state, subsz, first, compnum;
static char *myname;
int f_msgn; /* Start of msg name field */
int f_smsgn; /* Length */
int f_flgs; /* Start of flags field */
int f_sflgs; /* Width of flag field */
int f_date; /* Start of Date field */
int f_sdate; /* Length */
int f_from; /* Start of From field */
int f_sfrom; /* Length of " " */
int f_subj; /* Start of Subject field */
int f_ssubj; /* Size of Subject field */
int f_bsubj; /* Room needed in Sub field to */
/* add stuff from the body */
int f_replied; /* Set if msg annotated with "Replied" */
/* or if group x bit is set. */
int f_perused; /* Set if owner x bit is set. */
struct stat sb; /* owner and group x bit determines if */
/* msg is "seen" or "replied" */
f_perused = 0;
f_msgn = MSGN;
f_smsgn = SMSGN;
f_flgs = f_msgn + f_smsgn;
f_sflgs = SFLGS;
f_date = f_flgs + f_sflgs;
f_sdate = SDATE;
f_from = f_date + f_sdate + 1;
f_sfrom = SFROM;
f_subj = f_from + f_sfrom + 2;
f_ssubj = SLINE - f_subj;
f_bsubj = BSUBJ;
local = 0; hostseen = 0;
if(!myname)
myname = getenv("USER");
tobuf[0] = 0; frombuf[0] = 0;
buf[0] = 0;
first = 0;
state = FLD;
compnum = 1;
f_perused = 0;
f_replied = 0;
/*
* stat the open message, and make note of owner and group
* execute bits.
*/
if( fstat( fileno(inb), &sb ) != 0 )
punt( "scansub: Can't fstat msg" );
if( IfSeen(sb.st_mode))
f_perused = 1;
if( IfReply(sb.st_mode))
f_replied = 1;
for(;;) {
state = m_getfld(state, name, buf, sizeof buf, inb);
/******/ if (state == FILEEOF) state = BODYEOF; /*** Hack [empty msgs] ***/
if(!first++ && state != FILEEOF) { /*##*/
sfill(scanl, sizeof scanl);
scanl[sizeof scanl - 1] = 0;
subsz = 0;
tobuf[0] = 0;
}
switch(state) {
case FLD:
case FLDEOF:
case FLDPLUS:
compnum++;
if(uleq(name, "from"))
frombuf[cpyfrm(buf,frombuf,sizeof frombuf,_FROM)]
= 0;
else if(uleq(name, "date"))
cpydat(buf, &scanl[f_date], f_sdate);
else if(uleq(name, "subject") && scanl[f_subj] == ' ')
subsz = cpy(buf, &scanl[f_subj], f_ssubj);
else if(uleq(name, "to") && !tobuf[0])
tobuf[
cpyfrm(buf,tobuf,sizeof tobuf-1,_NOTFROM)]=0;
else if(uleq(name, "replied"))
f_replied = 1;
while(state == FLDPLUS) {
state=m_getfld(state,name,buf,sizeof buf,inb);
}
if(state == FLDEOF)
goto putscan;
continue;
case BODY:
case BODYEOF:
compnum = -1;
if(subsz < f_ssubj - f_bsubj) {
int bodsz;
scanl[f_subj+subsz+1] = '<';
scanl[f_subj+subsz+2] = '<';
bodsz= cpy(buf, scanl+f_subj+subsz+3,
f_ssubj-subsz-3);
if(bodsz < f_ssubj - subsz - 3)
scanl[f_subj+subsz+3 + bodsz] = '>';
if(bodsz < f_ssubj - subsz - 4)
scanl[f_subj+subsz+4 + bodsz] = '>';
subsz = f_ssubj;
}
body:
state = FILEEOF; /* stop now since scan cmd */
if(state == BODYEOF || state == FILEEOF) {
char *tempstr, *getcpy();
putscan: cpymsgn(m_name(innum), &scanl[f_msgn], f_smsgn);
tempstr = getcpy(frombuf);
tok1= brkstring(tempstr, " ", "\n");
if(!frombuf[0] || uleq(frombuf, myname) ||
(local && uleq(*tok1, myname))) {
cpy("To:", &scanl[f_from], 3);
cpy(tobuf, &scanl[f_from+3], f_sfrom-3);
} else
cpy(frombuf, &scanl[f_from], f_sfrom);
trim(scanl);
free(tempstr); /* do we care if brkstring */
/* changes the frombuffer? */
/*
* Set flasgs ....
*/
if( !f_perused ) scanl[UNSEENADDR] = '>';
if ( f_replied ) scanl[REPLYADDR] = '-';
if (outfd != NULL) /* If an outfd */
fputs(scanl, outfd); /* Put it! */
return(1);
}
break;
case LENERR:
case FMTERR:
goto badret;
default:
badret:
return(-1);
case FILEEOF:
/* Is this the right place..(no) .. */
if( !f_perused )
scanl[ UNSEENADDR ] = '>';
if ( f_replied )
scanl[REPLYADDR] = '-';
return(0);
}
}
}
trim(str)
char *str;
{
register char *cp;
cp = str;
while(*cp) cp++;
while(*--cp == ' ') ;
cp++;
*cp++ = '\n';
*cp++ = 0;
}
sfill(str, cnt)
char *str;
{
register char *cp;
register int i;
cp = str; i = cnt;
do
*cp++ = ' ';
while(--i);
}
/*
* copy up to cnt characters, skipping initial blanks, and
* collapsing multiple blanks to a single blank. Non-printing
* characters turned to blanks.
*/
cpy(from, to, cnt)
register char *from, *to;
register int cnt;
{
register int c;
int needsp = 0; /* Non-zero if could use a space */
char *savto = to; /* Save for length calculation */
while(cnt && (c = *from++)) {
if (isprint(c) && !isspace(c)) {
*to++ = c;
cnt--;
needsp = 1;
}
else if (needsp) {
*to++ = ' ';
cnt--;
needsp = 0;
}
}
return(to - savto); /*Includes 1 char trailing white space, if any*/
}
struct tm *localtime();
long time();
char *findmonth();
struct date {
char *day;
char *month;
char *year;
char *timestr;
char *zone;
char zoneadd;
};
cpydat(sfrom, sto, cnt, how)
char *sfrom, *sto;
{
register char *cp;
register char *to;
static struct tm *locvec;
char frombuf[100];
char buf[30]; /* should be char buf[cnt + 1] */
long now;
struct date dt;
strncpy(frombuf, sfrom, sizeof frombuf);
frombuf[sizeof frombuf -1] = '\0';
if(!locvec) {
now = time((long *)0);
locvec = localtime(&now);
}
/* Collect the various fields of the date */
for(cp = frombuf; *cp < '0' || *cp > '9'; cp++)
if(!*cp)
return;
/* get the day */
dt.day = cp;
while (isdigit(*cp))
cp++;
if (*cp)
*cp++ = '\0';
/* get the month */
while (*cp && !isalpha(*cp))
cp++;
dt.month = cp;
while (isalpha (*cp))
cp++;
if (*cp)
*cp++ = '\0';
/* get the year */
while (*cp && !isdigit(*cp))
cp++;
dt.year = cp;
while (isdigit(*cp))
cp++;
if (*cp)
*cp++ = '\0';
/* Point timestr at the time, and remove colons, if present */
while (*cp && !isdigit(*cp))
cp++;
dt.timestr = to = cp;
for (; isdigit(*cp) || *cp == ':'; cp++)
if (*cp != ':')
*to++ = *cp;
if (*cp)
cp++;
*to = '\0';
/* get the time zone. */
/* Can be alphas as in PST */
/* If plus/minus digits, then set zoneadd to the + or - */
/* point zone at the string of digits or alphas */
dt.zoneadd = '\0';
while (*cp && !isalpha(*cp) && !isdigit(*cp)) {
if (*cp == '+' || *cp == '-')
dt.zoneadd = *cp;
cp++;
}
dt.zone = cp;
if (isdigit(*cp))
while (isdigit (*cp))
cp++;
else {
dt.zoneadd = '\0';
while (isalpha (*cp))
cp++;
}
if (*cp)
*cp++ = '\0';
/* printf ("Yr='%s' Mo='%s' Day='%s' Time='%s' Zone='%s'\n",
dt.year, dt.month, dt.day, dt.timestr, dt.zone);
if(cp = findmonth(dt.month))
printf ("month='%s'\n", cp);
return;
/**/
to = buf;
if(cp = findmonth(dt.month)) {
{
if(!cp[1])
*to++ = ' ';
while(*cp)
*to++ = *cp++;
*to++ = '/';
cp = dt.day;
if(!cp[1])
*to++ = ' ';
while(*cp >= '0' && *cp <= '9')
*to++ = *cp++;
Block {
register int yr;
if( ( (yr = atoi(dt.year)) > 1970
&& yr - 1900 < locvec->tm_year
)
|| yr < locvec->tm_year
) {
*to++ = '/';
*to++ = (yr - (yr < 100 ? 70 : 1970))
% 10 + '0';
}
else {
*to++ = ' ';
*to++ = ' ';
}
}
*to = '\0';
}
}
else {
cp = dt.day;
if(!cp[1])
*to++ = ' ';
while(*cp)
*to++ = *cp++;
}
Block {
register int tmp;
if (cnt < (tmp = strlen(buf)))
tmp = cnt;
strncpy(sto, buf, tmp);
}
return;
}
char *fromp, fromdlm, pfromdlm;
extern char *hostname();
cpyfrm(sfrom, sto, cnt, fromcall)
char *sfrom, *sto;
{
register char *to, *cp;
register int c;
fromdlm = ' ';
fromp = sfrom; to = sto;
cp = frmtok();
do
if(c = *cp++)
*to++ = c;
else
break;
while(--cnt);
for(;;) {
if(cnt < 3) break;
if(*(cp = frmtok()) == 0) break;
if(*cp == '@' || uleq(cp, "at")) {
cp = frmtok();
if(uleq(cp, hostname())) {
/* if the first "From:" host is local */
if(fromcall != _NOTFROM && !hostseen++)
local++;
} else {
*to++ = '@';
cnt--;
do
if(c = *cp++)
*to++ = c;
else
break;
while(--cnt);
}
} else if(cnt > 4) {
cnt--; *to++ = pfromdlm;
do
if(c = *cp++)
*to++ = c;
else
break;
while(--cnt);
}
}
if(fromcall != _NOTFROM)
hostseen++;
return(to - sto);
}
char *frmtok()
{
static char tokbuf[64];
register char *cp;
register int c;
pfromdlm = fromdlm;
cp = tokbuf; *cp = 0;
while(c = *fromp++) {
if(c == '\t')
c = ' ';
if(c == ' ' && cp == tokbuf)
continue;
if(c == ' ' || c == '\n' || c == ',')
break;
*cp++ = c;
*cp = 0;
if(c == '@' || *fromp == '@' || cp == &tokbuf[63])
break;
}
fromdlm = c;
return(tokbuf);
}
/* num specific! */
/* copy msgnam to addr, right justified */
cpymsgn(msgnam, addr, len)
char *msgnam, *addr;
{
register char *cp, *sp;
sp = msgnam;
cp = &addr[len - strlen(sp)];
if (cp < addr)
cp = addr;
while(*sp)
*cp++ = *sp++;
}
char *monthtab[] = {
"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec",
};
char *findmonth(str)
char *str;
{
register char *cp, *sp;
register int i;
static char buf[4];
for(cp=str, sp=buf; (*sp++ = *cp++) && sp < &buf[3] && *cp != ' '; )
continue;
*sp = 0;
for(i = 0; i < 12; i++)
if(uleq(buf, monthtab[i])) {
sprintf(buf, "%d", i+1);
return buf;
}
return(0);
}
struct tzone {
char *z_nam;
int z_hour;
int z_min;
};
struct tzone zonetab[] = {
{ "GMT", 0, 0, },
{ "NST", -3, -30, },
{ "AST", -4, 0, },
{ "ADT", -3, 0, },
{ "EST", -5, 0, },
{ "EDT", -4, 0, },
{ "CST", -6, 0, },
{ "CDT", -5, 0, },
{ "MST", -7, 0, },
{ "MDT", -6, 0, },
{ "PST", -8, 0, },
{ "PDT", -7, 0, },
{ "YST", -9, 0, },
{ "YDT", -8, 0, },
{ "HST", -10, 0, },
{ "HDT", -9, 0, },
{ "BST", -11, 0, },
{ "BDT", -10, 0, },
{ "Z", 0, 0, },
{ "A", -1, 0, },
{ "M", -12, 0, },
{ "N", 1, 0, },
{ "Y", 12, 0, },
{ 0 }
};
/* adjust for timezone */
adjtime(dt)
register struct date *dt;
{
/* what we should do here is adjust all other timezones to our own */
return;
/* if (isdigit (dt->zone[0])) {
atoi ...
if (dt->zoneadd == '+')
;
}
else {
}
return;
/**/
}