home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff319.lzh
/
CNewsSrc
/
cnews.orig.lzh
/
rna
/
header.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-06-27
|
10KB
|
479 lines
/*
* extract/output headers
*/
#include "defs.h"
#if AUSAM
extern struct pwent pe;
#else
extern struct passwd *pp;
#endif
extern char systemid[];
extern long now;
char tzone[] = TIMEZONE;
char hform[] = "%s: %s\n";
/* Mandatory Headers */
char t_relayversion[] = "Relay-Version";
char t_postversion[] = "Posting-Version";
char t_from[] = "From";
char t_date[] = "Date";
char t_newsgroups[] = "Newsgroups";
char t_subject[] = "Subject";
char t_messageid[] = "Message-ID";
char t_path[] = "Path";
/* Optional Headers */
char t_replyto[] = "Reply-To";
char t_sender[] = "Sender";
char t_followupto[] = "Followup-To";
char t_datereceived[] = "Date-Received";
char t_expires[] = "Expires";
char t_references[] = "References";
char t_control[] = "Control";
char t_distribution[] = "Distribution";
char t_organization[] = "Organization";
char t_lines[] = "Lines";
typedef enum ft
{
f_control, f_date, f_datereceived, f_distribution,
f_expires, f_followupto, f_from, f_lines, f_messageid,
f_newsgroups, f_organization, f_path, f_postversion,
f_references, f_relayversion, f_replyto, f_sender,
f_subject
}
ftype;
typedef struct field {
char *f_name;
ftype f_type;
} field;
static field fields[] =
{
{ t_control, f_control },
{ t_date, f_date },
{ t_datereceived, f_datereceived },
{ t_distribution, f_distribution },
{ t_expires, f_expires },
{ t_followupto, f_followupto },
{ t_from, f_from },
{ t_lines, f_lines },
{ t_messageid, f_messageid },
{ t_newsgroups, f_newsgroups },
{ t_organization, f_organization },
{ t_path, f_path },
{ t_postversion, f_postversion },
{ t_references, f_references },
{ t_relayversion, f_relayversion },
{ t_replyto, f_replyto },
{ t_sender, f_sender },
{ t_subject, f_subject }
};
char *weekdays[7] =
{
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
char *months[12] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static
fieldcmp(a, b)
field *a, *b;
{
return CMP(a->f_name, b->f_name);
}
/*
* extract headers from file,
* position file to start of body
*/
gethead(f, hp)
FILE *f;
header *hp;
{
register char *colon, *space, *s;
register field *fp;
field af;
char buf[BUFLEN*2];
char *hfgets();
memset((char *) hp, 0, sizeof(header));
while (hfgets(buf, sizeof(buf), f)) {
if (buf[0] == '\n')
return;
if (isupper(buf[0]) && (colon = strchr(buf, ':')) && (space =
strchr(buf, ' ')) && (colon + 1 == space)) {
*colon = '\0';
af.f_name = buf;
fp = (field * ) bsearch((char *) & af, (char *) fields,
sizeof(fields) / sizeof(fields[0]), sizeof(fields[0]),
fieldcmp);
*colon = ':';
} else
fp = NIL(field);
if (!fp)
if (hp->h_others)
hp->h_others = catstr(hp->h_others, buf);
else
hp->h_others = newstr(buf);
else
{
if (colon = strchr(space + 1, '\n'))
*colon = '\0';
s = newstr(space + 1);
switch (fp->f_type) {
case f_control:
hp->h_control = s;
break;
case f_date:
hp->h_date = s;
break;
case f_datereceived:
hp->h_datereceived = s;
break;
case f_distribution:
hp->h_distribution = s;
break;
case f_expires:
hp->h_expires = s;
break;
case f_followupto:
hp->h_followupto = s;
break;
case f_from:
hp->h_from = s;
break;
case f_lines:
hp->h_lines = s;
break;
case f_messageid:
hp->h_messageid = s;
break;
case f_newsgroups:
hp->h_newsgroups = s;
break;
case f_organization:
hp->h_organisation = s;
break;
case f_path:
hp->h_path = s;
break;
case f_postversion:
hp->h_postversion = s;
break;
case f_references:
hp->h_references = s;
break;
case f_relayversion:
hp->h_relayversion = s;
break;
case f_replyto:
hp->h_replyto = s;
break;
case f_sender:
hp->h_sender = s;
break;
case f_subject:
hp->h_subject = s;
break;
}
}
}
}
/*
* put headers to file
*/
puthead(hp, f, com)
header *hp;
FILE *f;
pheadcom com;
{
register char *s;
char *getunique();
extern char *getenv();
if (hp->h_relayversion && com == printing)
(void) fprintf(f, hform, t_relayversion, hp->h_relayversion);
else if (com != printing)
(void) fprintf(f, "%s: version %s; site %s.%s\n", t_relayversion, NEWSVERSION
systemid, MYDOMAIN);
if (hp->h_postversion)
(void) fprintf(f, hform, t_postversion, hp->h_postversion);
else if (com == making)
(void) fprintf(f, "%s: version %s; site %s.%s\n", t_postversion, NEWSVERSION,
systemid, MYDOMAIN);
if (hp->h_from)
(void) fprintf(f, hform, t_from, hp->h_from);
else if(com == making) {
if(s = getenv("NAME"))
(void) fprintf(f, "%s: %s@%s.%s (%s)\n", t_from,
#if AUSAM
pe.pw_strings[LNAME],
#else
pp->pw_name,
#endif
systemid, MYDOMAIN, s);
else
(void) fprintf(f,
#if AUSAM
"%s: %s@%s.%s (%s %s)\n",
#else
"%s: %s@%s.%s\n",
#endif
t_from,
#if AUSAM
pe.pw_strings[LNAME],
#else
pp->pw_name,
#endif
systemid, MYDOMAIN
#if AUSAM
,
pe.pw_strings[FIRSTNAME],
pe.pw_strings[LASTNAME]
#endif
);
}
if (hp->h_date)
(void) fprintf(f, hform, t_date, hp->h_date);
else if (com == making)
(void) fprintf(f, hform, t_date, ttoa(now));
if (hp->h_newsgroups)
(void) fprintf(f, hform, t_newsgroups, hp->h_newsgroups);
else if (com == making)
(void) fprintf(f, hform, t_newsgroups, DFLTGRP);
if (hp->h_subject)
(void) fprintf(f, hform, t_subject, hp->h_subject);
else if (com == making)
error("No subject field.");
if (hp->h_messageid)
(void) fprintf(f, hform, t_messageid, hp->h_messageid);
else if (com == making)
error("No messageid.");
if (hp->h_path && com == passing)
(void) fprintf(f, "%s: %s!%s\n", t_path, systemid, hp->h_path);
else if (hp->h_path)
(void) fprintf(f, hform, t_path, hp->h_path);
else if(com == making)
(void) fprintf(f, "%s: %s!%s\n", t_path, systemid,
#if AUSAM
pe.pw_strings[LNAME]
#else
pp->pw_name
#endif
);
/* optional */
if (hp->h_replyto)
(void) fprintf(f, hform, t_replyto, hp->h_replyto);
if (hp->h_sender)
(void) fprintf(f, hform, t_sender, hp->h_sender);
if (hp->h_followupto)
(void) fprintf(f, hform, t_followupto, hp->h_followupto);
if (hp->h_datereceived && com == printing)
(void) fprintf(f, hform, t_datereceived, hp->h_datereceived);
else if (com != printing)
(void) fprintf(f, hform, t_datereceived, ttoa(now));
if (hp->h_expires)
(void) fprintf(f, hform, t_expires, hp->h_expires);
if (hp->h_references)
(void) fprintf(f, hform, t_references, hp->h_references);
if (hp->h_control)
(void) fprintf(f, hform, t_control, hp->h_control);
if (hp->h_distribution)
(void) fprintf(f, hform, t_distribution, hp->h_distribution);
if (hp->h_organisation)
(void) fprintf(f, hform, t_organization, hp->h_organisation);
else if (com == making)
(void) fprintf(f, hform, t_organization, (s = getenv("ORGANIZATION")) ?
s : MYORG);
if (hp->h_lines)
(void) fprintf(f, hform, t_lines, hp->h_lines);
if (hp->h_others)
fputs(hp->h_others, f);
}
/*
* free all strings allocated to header
*/
freehead(hp)
register header *hp;
{
if (hp->h_relayversion)
free(hp->h_relayversion);
if (hp->h_postversion)
free(hp->h_postversion);
if (hp->h_from)
free(hp->h_from);
if (hp->h_date)
free(hp->h_date);
if (hp->h_newsgroups)
free(hp->h_newsgroups);
if (hp->h_subject)
free(hp->h_subject);
if (hp->h_messageid)
free(hp->h_messageid);
if (hp->h_path)
free(hp->h_path);
if (hp->h_replyto)
free(hp->h_replyto);
if (hp->h_sender)
free(hp->h_sender);
if (hp->h_followupto)
free(hp->h_followupto);
if (hp->h_datereceived)
free(hp->h_datereceived);
if (hp->h_expires)
free(hp->h_expires);
if (hp->h_references)
free(hp->h_references);
if (hp->h_control)
free(hp->h_control);
if (hp->h_distribution)
free(hp->h_distribution);
if (hp->h_organisation)
free(hp->h_organisation);
if (hp->h_lines)
free(hp->h_lines);
if (hp->h_others)
free(hp->h_others);
}
/*
* hfgets is like fgets, but deals with continuation lines.
* It also ensures that even if a line that is too long is
* received, the remainder of the line is thrown away
* instead of treated like a second line.
*/
char *
hfgets(buf, len, fp)
char *buf;
int len;
FILE *fp;
{
register int c;
register char *cp, *tp;
if ((cp = fgets(buf, len, fp)) == NIL(char))
return NIL(char);
if (*cp == '\n')
return cp;
tp = cp + strlen(cp);
if (tp[-1] != '\n') {
/* Line too long - part read didn't fit into a newline */
while ((c = getc(fp)) != '\n' && c != EOF)
;
} else
*--tp = '\0'; /* clobber newline */
while ((c = getc(fp)) == ' ' || c == '\t') {
/* Continuation line. */
while ((c = getc(fp)) == ' ' || c == '\t')
;
if (tp - cp < len) {
*tp++ = ' ';
*tp++ = c;
}
while ((c = getc(fp)) != '\n' && c != EOF)
if (tp - cp < len)
*tp++ = c;
}
*tp++ = '\n';
*tp++ = '\0';
if (c != EOF)
ungetc(c, fp); /* push back first char of next header */
return cp;
}
/*
* time to ascii
* leave time in static var
*/
char *
ttoa(t)
long t;
{
static char buf[40];
struct tm *tp;
extern struct tm *localtime();
tp = localtime(&t);
sprintf(buf, "%s, %d %s %d %02d:%02d:%02d %s", weekdays[tp->tm_wday],
tp->tm_mday, months[tp->tm_mon], tp->tm_year, tp->tm_hour, tp->tm_min,
tp->tm_sec, tzone);
return buf;
}
/*
* ascii to time
* return 0L on error
*/
long
atot(s)
char *s;
{
char *argv[4];
int day, year, hour, min, sec;
char month[10], sday[10], stime[10], syear[10];
extern long maketime();
if (sscanf(s, "%*s %d %*[ -] %9[^ -] %*[ -] %d %2d:%2d:%2d", &day, month,
&year, &hour, &min, &sec) != 6)
return 0L;
sprintf(sday, "%d", day);
sprintf(stime, "%d:%d:%d", hour, min, sec);
sprintf(syear, "%d", 1900 + year);
argv[0] = sday;
argv[1] = month;
argv[2] = stime;
argv[3] = syear;
return maketime(4, argv, STIMES);
}