home *** CD-ROM | disk | FTP | other *** search
- /*
- * anne.jones - anne.jones.c - 11/03/90 - Brendan Kehoe
- * An implementation of Cnews' anne.jones program to parse down articles
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <pwd.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/utsname.h>
- #include "anne.h"
- #include <signal.h>
-
- struct passwd *getpwuid(); /* Not included in pwd.h -- a3@rivm.nl */
-
- #ifdef DEBUG
- FILE *debug = stderr;
- #endif
-
- char *get_a_line(), *safemalloc(), *saferealloc();
-
- int
- main(argc, argv)
- int argc;
- char **argv;
- /*ARGSUSED*/
- {
- char *user, *name, *home, *newsctl, *mailname, *colon, *org, *line,
- **header, from[100], head[MAXHEAD], path[200], fullname[50];
- static char *dayname[8] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
- "Sat", "Sun",
- }, *mon[12] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
- "Aug", "Sep", "Oct", "Nov", "Dec",
- };
- int tmp, i, headcnt = 0, *found, *pme;
- FILE *fp;
- time_t t;
- struct stat statbuf;
- struct tm *tm;
- struct utsname ut;
- struct passwd *pent;
-
- extern char *getenv();
- char *squeeze(), *getmname(), **buildbook();
- FILE *trypath();
- void termin(), squeeze2();
-
- signal(SIGSEGV, termin);
- signal(SIGINT, termin);
- signal(SIGQUIT, termin);
- signal(SIGHUP, termin);
- signal(SIGBUS, termin);
-
- if ((newsctl = getenv("NEWSCTL")) == (char *) NULL) {
- perror("NEWSCTL");
- exit(1);
- }
- found = (int *) calloc(NUMKNOWN + KNOWSTART, sizeof(int));
- for (i = KNOWSTART; i < NUMKNOWN + KNOWSTART; i++)
- found[i] = NOTFOUND;
- header = (char **) buildbook(NUMHEADERS);
-
- /* mailname & host set */
- mailname = safemalloc(301);
- if ((fp = trypath(newsctl, "mailname")) != (FILE *) NULL) {
- mailname = squeeze(getmname(fp));
- } else if ((fp = trypath(newsctl, "whoami")) != (FILE *) NULL) {
- mailname = getmname(fp);
- #ifdef HAVEGETHOSTNAME
- } else if ((gethostname(mailname, 100)) < 0) {
- perror("ghostname");
- exit(1);
- #endif /* HAVEGETHOSTNAME */
- } else if ((fp = fopen("/etc/whoami", "r")) != (FILE *) NULL) {
- mailname = getmname(fp);
- /* skipped the uuname -l one, since it does gethostname(2) */
- } else if (uname(&ut) >= 0) {
- strcpy(mailname, ut.sysname);
- } else {
- strcpy(mailname, "the_unknown_host");
- }
-
- /* if it doesn't have a ., it's probably a uucp host */
- if (strchr(mailname, '.') == (char *) NULL)
- strcat(mailname, ".uucp");
-
- /* user's name set */
- pent = getpwuid(geteuid()); /* make it so su'ing someone works */
- if ((user = getenv("LOGNAME")) == NULL)
- user = pent->pw_name;
-
- /* name set & cleaned up */
- if (((name = getenv("NAME")) == NULL) &&
- ((home = getenv("HOME")) != (char *) NULL)) {
- strcpy(path, home);
- strcat(path, "/.name");
- stat(path, &statbuf);
- if (statbuf.st_size > 0) {
- if ((fp = fopen(path, "r")) != (FILE *) NULL) {
- name = safemalloc(101);
- if ((get_a_line(name, 100, fp)) == (char *) NULL) {
- perror("get_a_line .name");
- exit(1);
- }
- if (*(colon = (name + strlen(name) - 1)) == '\n')
- *colon = '\0';
- fclose(fp);
- }
- } else {
-
- /*
- if gecos has '&', use capitalized login name
- */
- if ((strchr(pent->pw_gecos, '&') != (char *) NULL)) {
- name = safemalloc(strlen(pent->pw_name) + 1);
- strcpy(name, pent->pw_name);
- *name = toupper(*name);
- } else {
- name = pent->pw_gecos;
- }
- }
- }
-
- /* fullname test */
- if (name != NULL) { /* if no real name, leave it off */
- strtok(name, ","); /* preserve only the name field -- ns@iddth.id.dk */
- sprintf(fullname, " (%s)", name);
- }
-
- /* setup the from field */
- sprintf(from, "%s@%s", user, mailname);
- if (name != NULL)
- strcat(from, fullname);
-
- /* set up the date */
- time(&t);
- tm = gmtime(&t);
-
- /* set up the org */
- if ((org = getenv("ORGANIZATION")) == (char *) NULL) {
- if (((fp = trypath(newsctl, "organization")) == (FILE *) NULL) &&
- ((fp = trypath(newsctl, "organisation")) == (FILE *) NULL)) {
- org = "Total lack of organization.";
- } else {
- org = safemalloc(ORGLEN + 1);
- get_a_line(org, ORGLEN, fp);
- if (*(colon = (org + strlen(org) - 1)) == '\n')
- *(org + strlen(org) - 1) = '\0';
- fclose(fp);
- }
- }
-
- /* now pump out a nice clean header */
- line = safemalloc(MAXLINE + 1);
-
- while (get_a_line(line, MAXLINE, stdin) != (char *) NULL) {
- /* squeeze out (tr) the bad chars */
- #ifdef DEBUG
- fprintf(debug, "getline got ->%s<-\n", line);
- #endif
- if (*line != '\n') {
- if (*(colon = (line + strlen(line) - 1)) == '\n')
- *colon = '\0';
- /* clean out the garbage */
- squeeze2(line);
- /* replace :tab with :spc */
- if (colon = strchr(line, ':'))
- if (*(colon + 1) == '\t')
- *(colon + 1) = ' ';
- }
- header[headcnt] = safemalloc(strlen(line) + 1);
- strcpy(header[headcnt++], line);
- #ifdef DEBUG
- fprintf(debug, "getline put ->%s<-\n", line);
- #endif
- }
-
- /* thus begins the defheaders.awk hack */
-
- /* nullify all headers with empty contents */
- for (i = 0; i < headcnt; i++) {
- if ((header[i][0]) && (colon = strchr(header[i], ':'))) {
- colon++; /* move to the chr past the colon */
-
- /*
- strspn -> the last position (the NULL) if there was
- nothing but tabs & spaces .. in that case, it's an
- empty header and discard it
- */
- if (strspn(colon, " \011") == strlen(colon)) {
- header[i][0] = '\0';
- continue;
- }
- strncpy(head, header[i], colon - header[i]);
- *(head + (colon - header[i])) = '\0';
-
- /* fix Message-Id to read Message-ID */
- if (strcmp(head, TYPONAME) == 0)
- header[i][9] = 'D';
-
- /* mark off the ones we're expecting */
- if ((tmp = know_head(head)) != NOTKNOWN)
- found[tmp] = i;
- }
- }
-
- for (i = KNOWSTART; i < (NUMKNOWN + KNOWSTART); i++) {
-
- /*
- If no header was given for something, then fill it in with
- what we've come up with above
- */
- if (found[i] == NOTFOUND) {
- switch (i) {
- case PATHNAMEPOS:
- header[headcnt] = safemalloc(strlen(user) + 8);
- sprintf(header[headcnt], "Path: %s", user);
- found[i] = headcnt++;
- break;
- case MSGIDPOS:
- header[headcnt] = safemalloc(MSGIDLEN + 13);
- sprintf(header[headcnt],
- "Message-ID: <19%02d%s%02d.%02d%02d%02d.%i@%s>",
- tm->tm_year, *(mon + tm->tm_mon),
- tm->tm_mday, tm->tm_hour,
- tm->tm_min, tm->tm_sec, getpid(),
- mailname);
- found[i] = headcnt++;
- break;
- case DATEPOS:
-
- /*
- * put it in the form Day, DD Mon Yr hh:mm:ss GMT
- */
- header[headcnt] = safemalloc(DATELEN + 5);
- sprintf(header[headcnt],
- "Date: %s, %02d %s %02d %02d:%02d:%02d GMT",
- *(dayname + tm->tm_wday), tm->tm_mday,
- *(mon + tm->tm_mon), tm->tm_year,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
- found[i] = headcnt++;
- break;
- case ORGPOS:
- header[headcnt] = safemalloc(strlen(org) + 16);
- sprintf(header[headcnt], "Organization: %s",
- org);
- found[i] = headcnt++;
- break;
- case FROMPOS:
- header[headcnt] = safemalloc(strlen(from) + 8);
- sprintf(header[headcnt], "From: %s", from);
- found[i] = headcnt++;
- break;
- }
- }
- }
-
- /* kill the dist header if it's to 'world' */
- if (found[DISTPOS] != NOTFOUND)
- if (strcmp("Distribution: world", header[found[DISTPOS]]) == 0) {
- header[found[DISTPOS]][0] = '\0';
- found[DISTPOS] = NOTFOUND;
- }
-
- /*
- * if chars 1-14 of Subject header is 'Subject: cmesg ', then create
- * the Control line to read 'Control: 15th_on'
- *
- * if newsgroup line contains '.ctl', build Control: line so it reads
- * 'Control: 8th_on'
- */
- if ((found[SUBJECTPOS] != NOTFOUND) && (found[CTLNAMEPOS] == NOTFOUND)) {
- if (strncmp(header[found[SUBJECTPOS]],
- "Subject: cmesg ", 15) == 0) {
-
- /*
- get 'Control: ' (10) plus rest of Subject (-14)
- */
- header[headcnt] = safemalloc(strlen(header[found[SUBJECTPOS]]) - 3);
- sprintf(header[headcnt], "Control: %s",
- header[found[SUBJECTPOS]] + 15);
- found[CTLNAMEPOS] = headcnt;
- headcnt++;
- } else if ((found[NGNAMEPOS] != NOTFOUND) &&
- (strstr(header[found[NGNAMEPOS]], ".ctl") != (char *) NULL)) {
-
- /*
- * get 'Control: ' (10) plus rest of Subject (-8)
- */
- header[headcnt] = safemalloc(strlen(header[found[SUBJECTPOS]]) + 3);
- sprintf(header[headcnt],
- "Control: %s", header[found[SUBJECTPOS]] + 9);
- found[CTLNAMEPOS] = headcnt;
- headcnt++;
- }
- }
-
- /* warn to stderr if there are no newsgroups listed */
- if (found[NGNAMEPOS] == NOTFOUND)
- fputs("no newsgroups header!\n", stderr);
-
- /* reorder & emit headers */
- pme = (int *) calloc(headcnt, sizeof(int));
-
- for (i = KNOWSTART; i < ORDER + 1; i++) {
- if ((found[i] != NOTFOUND) && (header[found[i]][0])) {
- fprintf(stdout, "%s\n", header[found[i]]);
- pme[found[i]] = 1;
- }
- }
-
- for (i = 0; i < headcnt; i++) {
- if ((pme[i] != 1) && (header[i][0]))
- fprintf(stdout, "%s\n", header[i]);
- }
- fflush(stdout);
- return(0); /* shut UP lint */
- }
-