|
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 - downloadIndex: ┃ T a ┃
Length: 16530 (0x4092) Types: TextFile Names: »addr_utils.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/elm/src/addr_utils.c«
/** addr_utils.c **/ /** This file contains addressing utilities (C) Copyright 1986 Dave Taylor **/ #include "headers.h" #include <sys/types.h> #include <sys/stat.h> #include <ctype.h> #ifdef BSD #undef tolower #endif char *shift_lower(), *get_alias_address(), *get_token(), *strtok(), *strchr(), *strcpy(), *strcat(), *strncpy(); int talk_to(sitename) char *sitename; { /** If we talk to the specified site, return true, else we're going to have to expand this baby out, so return false! **/ struct lsys_rec *sysname; sysname = talk_to_sys; if (sysname == NULL) { dprint0(2, "Warning - talk_to_sys is currently set to NULL! (talk_to)\n"); return(0); } while (sysname != NULL) { if (strcmp(sysname->name, sitename) == 0) return(1); else sysname = sysname->next; } return(0); } remove_domains(host) char *host; { /** Remove all entries following the first '.' to ensure that entries like "MIT.ARPA" will match "MIT" in the database **/ register int loc = 0; while (host[loc] != '.' && host[loc] != '\0') loc++; if (host[loc] == '.') host[loc] = '\0'; } add_site(buffer, site, lastsite) char *buffer, *site, *lastsite; { /** add site to buffer, unless site is 'uucp', current machine, or site is the same as lastsite. If not, set lastsite to site. **/ char local_buffer[LONG_SLEN]; char *strip_parens(); if (strcmp(site, "uucp") != 0) if (strcmp(site, lastsite) != 0) if (strcmp(site, hostname) != 0) { if (buffer[0] == '\0') strcpy(buffer, strip_parens(site)); /* first in list! */ else { sprintf(local_buffer,"%s!%s", buffer, strip_parens(site)); strcpy(buffer, local_buffer); } strcpy(lastsite, strip_parens(site)); /* don't want THIS twice! */ } } #ifdef USE_EMBEDDED_ADDRESSES get_address_from(prefix, line, buffer) char *prefix, *line, *buffer; { /** This routine extracts the address from either a 'From:' line or a 'Reply-To:' line...the algorithm is quite simple, too: increment 'line' past header, then check last character of line. If it's a '>' then the address is contained within '<>' and if it's a ')' then the address is in the 'clear'... **/ register int i, j = 0; no_ret(line); line = (char *) (line + strlen(prefix) + 1); if (line[strlen(line)-1] == '>') { for (i=strlen(line)-2; i > -1 && line[i] != '<'; i--) buffer[j++] = line[i]; buffer[j] = 0; reverse(buffer); } else { /* either ')' or address in the clear... */ for (i=0; i < strlen(line) && line[i] != '('; i++) buffer[j++] = line[i]; if (buffer[j-1] == '(') j--; buffer[j] = 0; } } #endif translate_return(addr, ret_addr) char *addr, *ret_addr; { /** Return ret_addr to be the same as addr, but with the login of the person sending the message replaced by '%s' for future processing... Fixed to make "%xx" "%%xx" (dumb 'C' system!) **/ register int loc, loc2, index = 0; loc2 = chloc(addr,'@'); if ((loc = chloc(addr, '%')) < loc2) loc2 = loc; if (loc2 != -1) { /* ARPA address. */ /* algorithm is to get to '@' sign and move backwards until we've hit the beginning of the word or another metachar. */ for (loc = loc2 - 1; loc > -1 && addr[loc] != '!'; loc--) ; } else { /* usenet address */ /* simple algorithm - find last '!' */ loc2 = strlen(addr); /* need it anyway! */ for (loc = loc2; loc > -1 && addr[loc] != '!'; loc--) ; } /** now copy up to 'loc' into destination... **/ while (index <= loc) { ret_addr[index] = addr[index]; index++; } /** now append the '%s'... **/ ret_addr[index++] = '%'; ret_addr[index++] = 's'; /** and, finally, if anything left, add that **/ while (loc2 < strlen(addr)) { ret_addr[index++] = addr[loc2++]; if (addr[loc2-1] == '%') /* tweak for "printf" */ ret_addr[index++] = '%'; } ret_addr[index] = '\0'; } build_address(to, full_to) char *to, *full_to; { /** loop on all words in 'to' line...append to full_to as we go along, until done or length > len. Modified to know that stuff in parens are comments... **/ register int i, changed = 0, in_parens = 0; char word[SLEN], *ptr, buffer[SLEN]; char new_to_list[LONG_SLEN]; char *strpbrk(), *expand_system(), *strcat(); new_to_list[0] = '\0'; i = get_word(to, 0, word); full_to[0] = '\0'; while (i > 0) { if (word[0] == '(' || in_parens) { in_parens = (word[strlen(word-1)] != ')'); strcat(full_to, " "); strcat(full_to, word); } else if (strpbrk(word,"!@:") != NULL) #ifdef DONT_TOUCH_ADDRESS sprintf(full_to, "%s%s%s", full_to, full_to[0] != '\0'? ", " : "", word); #else sprintf(full_to, "%s%s%s", full_to, full_to[0] != '\0'? ", " : "", expand_system(word, 1)); #endif else if ((ptr = get_alias_address(word, 1, 0)) != NULL) sprintf(full_to, "%s%s%s", full_to, full_to[0] != '\0'? ", " : "", ptr); else if (strlen(word) > 0) { if (valid_name(word)) sprintf(full_to, "%s%s%s", full_to, full_to[0] != '\0'? ", " : "", word); else if (check_only) { printf("(alias \"%s\" is unknown)\n\r", word); changed++; } else if (! isatty(fileno(stdin)) ) { /* batch mode error! */ fprintf(stderr,"Cannot expand alias '%s'!\n\r", word); fprintf(stderr,"Use \"checkalias\" to find valid addresses!\n\r"); dprint1(1, "Can't expand alias %s - bailing out! (build_address)\n", word); emergency_exit(); } else { dprint1(2,"Entered unknown address %s (build_address)\n", word); sprintf(buffer, "'%s' is an unknown address. Replace with: ", word); word[0] = '\0'; if (mail_only) printf(buffer); else PutLine0(LINES, 0, buffer); (void) optionally_enter(word, LINES, strlen(buffer), FALSE); if (strlen(word) > 0) { sprintf(new_to_list, "%s%s%s", new_to_list, strlen(new_to_list) > 0? " ":"", word); dprint1(3,"Replaced with %s (build_address)\n", word); } else dprint0(3,"Address removed from to list (build_address)\n"); if (mail_only) printf("\n\r"); changed++; clear_error(); continue; } } i = get_word(to, i, word); } if (changed) strcpy(to, new_to_list); } int real_from(buffer, entry) char *buffer; struct header_rec *entry; { /***** Returns true iff 's' has the seven 'from' fields, (or 8 - some machines include the TIME ZONE!!!) Initializing the date and from entries in the record and also the message received date/time. *****/ char junk[STRING], timebuff[STRING], holding_from[SLEN]; int eight_fields = 0; entry->year[0] = '\0'; junk[0] = '\0'; /* From <user> <day> <month> <day> <hr:min:sec> <year> */ sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %s", timebuff, junk); if (timebuff[1] != ':' && timebuff[2] != ':') { dprint1(3,"real_from returns FAIL [bad time field] on\n-> %s\n", buffer); return(FALSE); } if (junk[0] != '\0') { /* try for 8 field entry */ junk[0] = '\0'; sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %*s %s", timebuff, junk); if (junk[0] != '\0') { dprint1(3,"real_from returns FAIL [too many fields] on\n-> %s\n", buffer); return(FALSE); } eight_fields++; } /** now get the info out of the record! **/ if (eight_fields) sscanf(buffer, "%s %s %s %s %s %s %*s %s", junk, holding_from, entry->dayname, entry->month, entry->day, entry->time, entry->year); else sscanf(buffer, "%s %s %s %s %s %s %s", junk, holding_from, entry->dayname, entry->month, entry->day, entry->time, entry->year); strncpy(entry->from, holding_from, STRING); resolve_received(entry); return(entry->year[0] != '\0'); } forwarded(buffer, entry) char *buffer; struct header_rec *entry; { /** Change 'from' and date fields to reflect the ORIGINATOR of the message by iteratively parsing the >From fields... Modified to deal with headers that include the time zone of the originating machine... **/ char machine[SLEN], buff[SLEN], holding_from[SLEN]; machine[0] = '\0'; sscanf(buffer, "%*s %s %s %s %s %s %s %*s %*s %s", holding_from, entry->dayname, entry->month, entry->day, entry->time, entry->year, machine); if (isdigit(entry->month[0])) { /* try for veeger address */ sscanf(buffer, "%*s %s %s%*c %s %s %s %s %*s %*s %s", holding_from, entry->dayname, entry->day, entry->month, entry->year, entry->time, machine); } if (isalpha(entry->year[0])) { /* try for address including tz */ sscanf(buffer, "%*s %s %s %s %s %s %*s %s %*s %*s %s", holding_from, entry->dayname, entry->month, entry->day, entry->time, entry->year, machine); } if (machine[0] == '\0') sprintf(buff,"anonymous"); else sprintf(buff,"%s!%s", machine, holding_from); strncpy(entry->from, buff, STRING); } parse_arpa_from(buffer, newfrom) char *buffer, *newfrom; { /** try to parse the 'From:' line given... It can be in one of two formats: From: Dave Taylor <hplabs!dat> or From: hplabs!dat (Dave Taylor) Added: removes quotes if name is quoted (12/12) Added: only copies STRING characters... Added: if no comment part, copy address instead! **/ char temp_buffer[SLEN], *temp; register int i, j = 0; temp = (char *) temp_buffer; temp[0] = '\0'; no_ret(buffer); /* blow away '\n' char! */ if (lastch(buffer) == '>') { for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' && buffer[i] != '('; i++) temp[j++] = buffer[i]; temp[j] = '\0'; } else if (lastch(buffer) == ')') { for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' && buffer[i] != '<'; i--) temp[j++] = buffer[i]; temp[j] = '\0'; reverse(temp); } #ifdef USE_EMBEDDED_ADDRESSES /** if we have a null string at this point, we must just have a From: line that contains an address only. At this point we can have one of a few possibilities... From: address From: <address> From: address () **/ if (strlen(temp) == 0) { if (lastch(buffer) != '>') { for (i=strlen("From:");buffer[i] != '\0' && buffer[i] != '('; i++) temp[j++] = buffer[i]; temp[j] = '\0'; } else { /* get outta '<>' pair, please! */ for (i=strlen(buffer)-2;buffer[i] != '<' && buffer[i] != ':';i--) temp[j++] = buffer[i]; temp[j] = '\0'; reverse(temp); } } #endif if (strlen(temp) > 0) { /* mess with buffer... */ /* remove leading spaces and quotes... */ while (whitespace(temp[0]) || quote(temp[0])) temp = (char *) (temp + 1); /* increment address! */ /* remove trailing spaces and quotes... */ i = strlen(temp) - 1; while (whitespace(temp[i]) || quote(temp[i])) temp[i--] = '\0'; /* if anything is left, let's change 'from' value! */ if (strlen(temp) > 0) strncpy(newfrom, temp, STRING); } } parse_arpa_date(string, entry) char *string; struct header_rec *entry; { /** Parse and figure out the given date format... return the entry fields changed iff it turns out we have a valid parse of the date! **/ char word[15][NLEN], buffer[SLEN], *bufptr; char *aword; int words = 0; strcpy(buffer, string); bufptr = (char *) buffer; /** break the line down into words... **/ while ((aword = strtok(bufptr," \t '\"-/(),.")) != NULL) { strcpy(word[words++], aword); bufptr = NULL; } if (words < 6) { /* strange format. We're outta here! */ dprint1(3,"parse_arpa_date failed [less than six fields] on\n-> %s\n", string); return; } /* There are now five possible combinations that we could have: Date: day_number month_name year_number time timezone Date: day_name day_number month_name year_number ... Date: day_name month_name day_number time year_number Date: day_name month_name day_number year_number time Date: day_number month_name year_number time timezone day_name Note that they are distinguishable by checking the first character of the second, third and fourth words... */ if (isdigit(word[1][0])) { /*** type one! ***/ if (! valid_date(word[1], word[2], word[3])) { dprint4(3,"parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n", word[1], word[2], word[3], string); return; /* strange date! */ } strncpy(entry->day, word[1], 3); strncpy(entry->month, word[2], 3); strncpy(entry->year, word[3], 4); strncpy(entry->time, word[4], 10); } else if (isdigit(word[2][0])) { /*** type two! ***/ if (! valid_date(word[2], word[3], word[4])) { dprint4(3,"parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n", word[2], word[3], word[4], string); return; /* strange date! */ } strncpy(entry->day, word[2], 3); strncpy(entry->month, word[3], 3); strncpy(entry->year, word[4], 4); strncpy(entry->time, word[5], 10); } else if (isdigit(word[3][0])) { if (word[4][1] == ':' || word[4][2] == ':') { /*** type three! ***/ if (! valid_date(word[3], word[2], word[5])) { dprint4(3, "parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n", word[3], word[2], word[5], string); return; /* strange date! */ } strncpy(entry->year, word[5], 4); strncpy(entry->time, word[4], 10); } else { /*** type four! ***/ if (! valid_date(word[3], word[2], word[4])) { dprint4(3,"parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n", word[3], word[2], word[4], string); return; /* strange date! */ } strncpy(entry->year, word[4], 4); strncpy(entry->time, word[5], 10); } strncpy(entry->day, word[3], 3); strncpy(entry->month, word[2], 3); } } fix_arpa_address(address) char *address; { /** Given a pure ARPA address, try to make it reasonable. This means that if you have something of the form a@b@b make it a@b. If you have something like a%b%c%b@x make it a%b@x... **/ register int host_count = 0, i; char hosts[MAX_HOPS][2*NLEN]; /* array of machine names */ char *host, *addrptr; /* break down into a list of machine names, checking as we go along */ addrptr = (char *) address; while ((host = get_token(addrptr, "%@", 2)) != NULL) { for (i = 0; i < host_count && ! equal(hosts[i], host); i++) ; if (i == host_count) { strcpy(hosts[host_count++], host); if (host_count == MAX_HOPS) { dprint0(2, "Can't build return address - hit MAX_HOPS (fix_arpa_address)\n"); error("Can't build return address - hit MAX_HOPS limit!"); return(1); } } else host_count = i + 1; addrptr = NULL; } /** rebuild the address.. **/ address[0] = '\0'; for (i = 0; i < host_count; i++) sprintf(address, "%s%s%s", address, address[0] == '\0'? "" : (i == host_count - 1 ? "@" : "%"), hosts[i]); return(0); } figure_out_addressee(buffer, mail_to) char *buffer; char *mail_to; { /** This routine steps through all the addresses in the "To:" list, initially setting it to the first entry (if mail_to is NULL) or, if the user is found (eg "alternatives") to the current "username". Modified to know how to read quoted names... **/ char *address, *bufptr; register int index = 0, index2 = 0; if (equal(mail_to, username)) return; /* can't be better! */ bufptr = (char *) buffer; /* use the string directly */ if (strchr(buffer,'"') != NULL) { /* we have a quoted string */ while (buffer[index] != '"') index++; index++; /* skip the leading quote */ while (buffer[index] != '"' && index < strlen(buffer)) mail_to[index2++] = buffer[index++]; mail_to[index2] = '\0'; } else while ((address = strtok(bufptr, " ,\t\n\r")) != NULL) { if (! okay_address(address, "don't match me!")) { strcpy(mail_to, username); /* it's to YOU! */ return; } else if (strlen(mail_to) == 0) /* it's SOMEthing! */ get_return_name(address, mail_to, FALSE); bufptr = (char *) NULL; /* set to null */ } return; }