|
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; /**/ }