home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i070: ELM mail syste, release 2.3, Part11/26
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: c8a975a5 796eb4a4 9cdfc7a1 37097fb0
-
- Submitted-by: Syd Weinstein <syd@dsinc.dsi.com>
- Posting-number: Volume 22, Issue 70
- Archive-name: elm2.3/part11
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # this is part 11 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file src/addr_util.c continued
- #
- CurArch=11
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file src/addr_util.c"
- sed 's/^X//' << 'SHAR_EOF' >> src/addr_util.c
- X
- X if(can_access(fullnamefile, READ_ACCESS) != 0)
- X return(NULL); /* fullname file not accessible to user */
- X if((fp = fopen(fullnamefile, "r")) == NULL)
- X return(NULL); /* fullname file cannot be opened! */
- X if(fgets(fullname, SLEN, fp) == NULL) {
- X fclose(fp);
- X return(NULL); /* fullname file empty! */
- X }
- X fclose(fp);
- X no_ret(fullname); /* remove trailing '\n' */
- X#endif
- X return(fullname);
- X}
- X
- Xint
- Xtalk_to(sitename)
- Xchar *sitename;
- X{
- X /** If we talk to the specified site, return true, else
- X we're going to have to expand this baby out, so
- X return false! **/
- X
- X struct lsys_rec *sysname;
- X
- X sysname = talk_to_sys;
- X
- X if (sysname == NULL) {
- X dprint(2, (debugfile,
- X "Warning: talk_to_sys is currently set to NULL!\n"));
- X return(0);
- X }
- X
- X while (sysname != NULL) {
- X if (strcmp(sysname->name, sitename) == 0)
- X return(1);
- X else
- X sysname = sysname->next;
- X }
- X
- X return(0);
- X}
- X
- Xadd_site(buffer, site, lastsite)
- Xchar *buffer, *site, *lastsite;
- X{
- X /** add site to buffer, unless site is 'uucp' or site is
- X the same as lastsite. If not, set lastsite to site.
- X **/
- X
- X char local_buffer[SLEN], *stripped;
- X char *strip_parens();
- X
- X stripped = strip_parens(site);
- X
- X if (strcmp(stripped, "uucp") != 0)
- X if (strcmp(stripped, lastsite) != 0) {
- X if (buffer[0] == '\0')
- X strcpy(buffer, stripped); /* first in list! */
- X else {
- X sprintf(local_buffer,"%s!%s", buffer, stripped);
- X strcpy(buffer, local_buffer);
- X }
- X strcpy(lastsite, stripped); /* don't want THIS twice! */
- X }
- X}
- X
- X#ifdef USE_EMBEDDED_ADDRESSES
- X
- Xget_address_from(prefix, line, buffer)
- Xchar *prefix, *line, *buffer;
- X{
- X /** This routine extracts the address from either a 'From:' line
- X or a 'Reply-To:' line. The strategy is as follows: if the
- X line contains a '<', then the stuff enclosed is returned.
- X Otherwise we go through the line and strip out comments
- X and return that. White space will be elided from the result.
- X **/
- X
- X register char *s;
- X
- X /** Skip start of line over prefix, e.g. "From:". **/
- X line += strlen(prefix);
- X
- X /** If there is a '<' then copy from it to '>' into the buffer. **/
- X if ( (s = index(line,'<')) != NULL ) {
- X while ( ++s , *s != '\0' && *s != '>' ) {
- X if ( !isspace(*s) )
- X *buffer++ = *s;
- X }
- X *buffer = '\0';
- X return;
- X }
- X
- X /** Otherwise, strip comments and get address with whitespace elided. **/
- X for ( s = strip_parens(line) ; *s != '\0' ; ++s ) {
- X if ( !isspace(*s) )
- X *buffer++ = *s;
- X }
- X *buffer = '\0';
- X
- X}
- X
- X#endif
- X
- Xtranslate_return(addr, ret_addr)
- Xchar *addr, *ret_addr;
- X{
- X /** Return ret_addr to be the same as addr, but with the login
- X of the person sending the message replaced by '%s' for
- X future processing...
- X Fixed to make "%xx" "%%xx" (dumb 'C' system!)
- X **/
- X
- X register int loc, loc2, iindex = 0;
- X
- X loc2 = chloc(addr,'@');
- X if ((loc = chloc(addr, '%')) < loc2)
- X loc2 = loc;
- X
- X if (loc2 != -1) { /* ARPA address. */
- X /* algorithm is to get to '@' sign and move backwards until
- X we've hit the beginning of the word or another metachar.
- X */
- X for (loc = loc2 - 1; loc > -1 && addr[loc] != '!'; loc--)
- X ;
- X }
- X else { /* usenet address */
- X /* simple algorithm - find last '!' */
- X
- X loc2 = strlen(addr); /* need it anyway! */
- X
- X for (loc = loc2; loc > -1 && addr[loc] != '!'; loc--)
- X ;
- X }
- X
- X /** now copy up to 'loc' into destination... **/
- X
- X while (iindex <= loc) {
- X ret_addr[iindex] = addr[iindex];
- X iindex++;
- X }
- X
- X /** now append the '%s'... **/
- X
- X ret_addr[iindex++] = '%';
- X ret_addr[iindex++] = 's';
- X
- X /** and, finally, if anything left, add that **/
- X
- X loc = strlen(addr);
- X while (loc2 < loc) {
- X ret_addr[iindex++] = addr[loc2++];
- X if (addr[loc2-1] == '%') /* tweak for "printf" */
- X ret_addr[iindex++] = '%';
- X }
- X
- X ret_addr[iindex] = '\0';
- X}
- X
- Xint
- Xbuild_address(to, full_to)
- Xchar *to, *full_to;
- X{
- X /** loop on all words in 'to' line...append to full_to as
- X we go along, until done or length > len. Modified to
- X know that stuff in parens are comments...Returns non-zero
- X if it changed the information as it copied it across...
- X **/
- X
- X register int i, j, changed = 0, in_parens = 0, expanded_information = 0;
- X char word[SLEN], next_word[SLEN], *ptr, buffer[SLEN];
- X char new_to_list[SLEN];
- X char *strpbrk(), *strcat(), *gecos;
- X#ifndef DONT_TOUCH_ADDRESSES
- X char *expand_system();
- X#endif
- X
- X new_to_list[0] = '\0';
- X
- X i = get_word(to, 0, word);
- X
- X full_to[0] = '\0';
- X
- X while (i > 0) {
- X
- X j = get_word(to, i, next_word);
- X
- Xtry_new_word:
- X if(word[0] == '(')
- X in_parens++;
- X
- X if (in_parens) {
- X if(word[strlen(word)-1] == ')')
- X in_parens--;
- X strcat(full_to, " ");
- X strcat(full_to, word);
- X }
- X else if (strpbrk(word,"!@:") != NULL) {
- X#ifdef DONT_TOUCH_ADDRESSES
- X sprintf(full_to, "%s%s%s", full_to,
- X full_to[0] != '\0'? ", " : "", word);
- X#else
- X sprintf(full_to, "%s%s%s", full_to,
- X full_to[0] != '\0'? ", " : "", expand_system(word, 1));
- X#endif
- X }
- X else if ((ptr = get_alias_address(word, TRUE)) != NULL) {
- X sprintf(full_to, "%s%s%s", full_to,
- X full_to[0] != '\0'? ", " : "", ptr);
- X expanded_information++;
- X }
- X else if (strlen(word) > 0) {
- X if (valid_name(word)) {
- X if (j > 0 && next_word[0] == '(') /* already has full name */
- X gecos = NULL;
- X else /* needs a full name */
- X gecos=get_full_name(word);
- X#if defined(INTERNET) & defined(USE_DOMAIN)
- X sprintf(full_to, "%s%s%s@%s%s%s%s",
- X full_to,
- X (full_to[0] != '\0'? ", " : ""),
- X word,
- X hostfullname,
- X (gecos ? " (" : ""),
- X (gecos ? gecos : ""),
- X (gecos ? ")" : ""));
- X#else /* INTERNET and USE_DOMAIN */
- X sprintf(full_to, "%s%s%s%s%s%s",
- X full_to,
- X (full_to[0] != '\0'? ", " : ""),
- X word,
- X (gecos ? " (" : ""),
- X (gecos ? gecos : ""),
- X (gecos ? ")" : ""));
- X#endif /* INTERNET and USE_DOMAIN */
- X } else if (check_only) {
- X printf("(alias \"%s\" is unknown)\n\r", word);
- X changed++;
- X }
- X else if (! isatty(fileno(stdin)) ) { /* batch mode error! */
- X fprintf(stderr,"Cannot expand alias '%s'!\n\r", word);
- X fprintf(stderr,"Use \"checkalias\" to find valid addresses!\n\r");
- X dprint(1, (debugfile,
- X "Can't expand alias %s - bailing out of build_address\n",
- X word));
- X leave(0);
- X }
- X else {
- X dprint(2,(debugfile,"Entered unknown address %s\n", word));
- X sprintf(buffer, "'%s' is an unknown address. Replace with: ",
- X word);
- X word[0] = '\0';
- X changed++;
- X
- X PutLine0(LINES, 0, buffer);
- X
- X (void)optionally_enter(word, LINES, strlen(buffer), FALSE, FALSE);
- X clear_error();
- X if (strlen(word) > 0) {
- X dprint(3,(debugfile, "Replaced with %s in build_address\n",
- X word));
- X goto try_new_word;
- X }
- X else
- X dprint(3,(debugfile,
- X "Address removed from TO list by build_address\n"));
- X continue;
- X }
- X }
- X
- X /* and this word to the new to list */
- X if(*new_to_list != '\0')
- X strcat(new_to_list, " ");
- X strcat(new_to_list, word);
- X
- X if((i = j) > 0)
- X strcpy(word, next_word);
- X }
- X
- X /* if new to list is different from original, update original */
- X if (changed)
- X strcpy(to, new_to_list);
- X
- X return( expanded_information > 0 ? 1 : 0 );
- X}
- X
- Xint
- Xreal_from(buffer, entry)
- Xchar *buffer;
- Xstruct header_rec *entry;
- X{
- X /***** Returns true iff 's' has the seven 'from' fields, (or
- X 8 - some machines include the TIME ZONE!!!)
- X Initialize the date and from entries in the record
- X and also the message received date/time if 'entry'
- X is not NULL. *****/
- X
- X struct header_rec temp_rec, *rec_ptr;
- X char junk[STRING], timebuff[STRING], holding_from[SLEN], hold_tz[12];
- X char mybuf[BUFSIZ], *p, *q;
- X int eight_fields = 0;
- X int mday, month, year, minutes, seconds, tz, i;
- X long gmttime;
- X
- X /* set rec_ptr according to whether the data is to be returned
- X * in the second argument */
- X rec_ptr = (entry == NULL ? &temp_rec : entry);
- X
- X rec_ptr->year[0] = '\0';
- X timebuff[0] = '\0';
- X junk[0] = '\0';
- X hold_tz[0] = '\0';
- X
- X /* From <user> <day> <month> <day> <hr:min:sec> <year> */
- X
- X sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %s", timebuff, junk);
- X
- X if (strlen(timebuff) < 3) {
- X dprint(3,(debugfile,
- X "Real_from returns FAIL [no time field] on\n-> %s\n",
- X buffer));
- X return(FALSE);
- X }
- X
- X if (timebuff[1] != ':' && timebuff[2] != ':') {
- X dprint(3,(debugfile,
- X "Real_from returns FAIL [bad time field] on\n-> %s\n",
- X buffer));
- X return(FALSE);
- X }
- X if (junk[0] != '\0') { /* try for 8 field entry */
- X junk[0] = '\0';
- X sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %*s %s", timebuff, junk);
- X if (junk[0] != '\0') {
- X dprint(3, (debugfile,
- X "Real_from returns FAIL [too many fields] on\n-> %s\n",
- X buffer));
- X return(FALSE);
- X }
- X eight_fields++;
- X }
- X
- X /** now get the info out of the record! **/
- X
- X if (eight_fields)
- X sscanf(buffer, "%s %s %s %s %s %s %s %s",
- X junk, holding_from, rec_ptr->dayname, rec_ptr->month,
- X rec_ptr->day, rec_ptr->time, hold_tz, rec_ptr->year);
- X else
- X sscanf(buffer, "%s %s %s %s %s %s %s",
- X junk, holding_from, rec_ptr->dayname, rec_ptr->month,
- X rec_ptr->day, rec_ptr->time, rec_ptr->year);
- X
- X strncpy(rec_ptr->from, holding_from, STRING-1);
- X rec_ptr->from[STRING-1] = '\0';
- X resolve_received(rec_ptr);
- X
- X /* first get everything into lower case */
- X for (p=mybuf, q=mybuf+sizeof mybuf;
- X *buffer && p<q;
- X p++, buffer++) {
- X *p = isupper(*buffer) ? tolower(*buffer) : *buffer;
- X }
- X *p = 0;
- X p = mybuf;
- X while (!isspace(*p)) p++; /* skip "from" */
- X SKIP_WS(p);
- X while (!isspace(*p)) p++; /* skip from address */
- X SKIP_WS(p);
- X while (!isspace(*p)) p++; /* skip day of week */
- X SKIP_WS(p);
- X month = prefix(month_name, p);
- X get_unix_date(p,&year, &mday, &minutes, &seconds, &tz);
- X month_len[1] = (year%4) ? 28 : 29;
- X if (mday < 0 || mday>month_len[month]) {
- X dprint(5,(debugfile, "ridiculous day %d of month %d\n",mday,month));
- X }
- X
- X minutes -= tz;
- X if (tz > 0) { /* east of Greenwich */
- X if (minutes < 0) {
- X if (--mday < 0) {
- X if (--month < 0) {
- X year--; /* don't worry about 1900! */
- X month = 11;
- X }
- X mday = month_len[month];
- X }
- X minutes += 24*60;
- X }
- X }
- X if (tz < 0) { /* west of Greenwich */
- X if (minutes <= 24*60) {
- X if (++mday > month_len[month]) {
- X if (++month >= 12) {
- X year++; /* don't worry about 1999! yet?? */
- X month = 0;
- X }
- X mday = 0;
- X }
- X minutes -= 24*60;
- X }
- X }
- X gmttime = year - 70; /* make base year */
- X if (gmttime < 0)
- X gmttime += 100;
- X gmttime = gmttime * 365 + (gmttime + 1) / 4; /* now we have days adjusted for leap years */
- X for (i = 0; i < month; i++)
- X gmttime += month_len[i];
- X if (month > 1 && (year % 4) == 0)
- X gmttime++; /* now to month adjusted for leap year if after feb */
- X gmttime += mday - 1; /* and now to the day */
- X gmttime *= 24 * 60; /* convert to minutes */
- X gmttime += minutes;
- X rec_ptr->time_sent = gmttime * 60; /* now unix seconds since 1/1/70 00:00 GMT */
- X
- X return(rec_ptr->year[0] != '\0');
- X}
- X
- Xforwarded(buffer, entry)
- Xchar *buffer;
- Xstruct header_rec *entry;
- X{
- X /** Change 'from' and date fields to reflect the ORIGINATOR of
- X the message by iteratively parsing the >From fields...
- X Modified to deal with headers that include the time zone
- X of the originating machine... **/
- X
- X char machine[SLEN], buff[SLEN], holding_from[SLEN];
- X
- X machine[0] = holding_from[0] = '\0';
- X
- X sscanf(buffer, "%*s %s %s %s %s %s %s %*s %*s %s",
- X holding_from, entry->dayname, entry->month,
- X entry->day, entry->time, entry->year, machine);
- X
- X if (isdigit(entry->month[0])) { /* try for veeger address */
- X sscanf(buffer, "%*s %s %s%*c %s %s %s %s %*s %*s %s",
- X holding_from, entry->dayname, entry->day, entry->month,
- X entry->year, entry->time, machine);
- X }
- X if (isalpha(entry->year[0])) { /* try for address including tz */
- X sscanf(buffer, "%*s %s %s %s %s %s %*s %s %*s %*s %s",
- X holding_from, entry->dayname, entry->month,
- X entry->day, entry->time, entry->year, machine);
- X }
- X
- X /* the following fix is to deal with ">From xyz ... forwarded by xyz"
- X which occasionally shows up within AT&T. Thanks to Bill Carpenter
- X for the fix! */
- X
- X if (strcmp(machine, holding_from) == 0)
- X machine[0] = '\0';
- X
- X if (machine[0] == '\0')
- X strcpy(buff, holding_from[0] ? holding_from : "anonymous");
- X else
- X sprintf(buff,"%s!%s", machine, holding_from);
- X
- X strncpy(entry->from, buff, STRING-1);
- X entry->from[STRING-1] = '\0';
- X}
- X
- Xparse_arpa_who(buffer, newfrom, is_really_a_to)
- Xchar *buffer, *newfrom;
- Xint is_really_a_to;
- X{
- X /** try to parse the 'From:' line given... It can be in one of
- X two formats:
- X From: Dave Taylor <hplabs!dat>
- X or From: hplabs!dat (Dave Taylor)
- X
- X Added: removes quotes if name is quoted (12/12)
- X Added: only copies STRING characters...
- X Added: if no comment part, copy address instead!
- X Added: if is_really_a_to, this is really a 'to' line
- X and treat as if we allow embedded addresses
- X **/
- X
- X int use_embedded_addresses;
- X char temp_buffer[SLEN], *temp;
- X register int i, j = 0, in_parens;
- X
- X temp = (char *) temp_buffer;
- X temp[0] = '\0';
- X
- X no_ret(buffer); /* blow away '\n' char! */
- X
- X if (lastch(buffer) == '>') {
- X for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
- X buffer[i] != '('; i++)
- X temp[j++] = buffer[i];
- X temp[j] = '\0';
- X }
- X else if (lastch(buffer) == ')') {
- X in_parens = 1;
- X for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '<'; i--) {
- X switch(buffer[i]) {
- X case ')': in_parens++;
- X break;
- X case '(': in_parens--;
- X break;
- X }
- X if(!in_parens) break;
- X temp[j++] = buffer[i];
- X }
- X temp[j] = '\0';
- X reverse(temp);
- X }
- X
- X#ifdef USE_EMBEDDED_ADDRESSES
- X use_embedded_addresses = TRUE;
- X#else
- X use_embedded_addresses = FALSE;
- X#endif
- X
- X if(use_embedded_addresses || is_really_a_to) {
- X /** if we have a null string at this point, we must just have a
- X From: line that contains an address only. At this point we
- X can have one of a few possibilities...
- X
- X From: address
- X From: <address>
- X From: address ()
- X **/
- X
- X if (strlen(temp) == 0) {
- X if (lastch(buffer) != '>') {
- X for (i=strlen("From:");buffer[i] != '\0' && buffer[i] != '('; i++)
- X temp[j++] = buffer[i];
- X temp[j] = '\0';
- X }
- X else { /* get outta '<>' pair, please! */
- X for (i=strlen(buffer)-2;buffer[i] != '<' && buffer[i] != ':';i--)
- X temp[j++] = buffer[i];
- X temp[j] = '\0';
- X reverse(temp);
- X }
- X }
- X }
- X
- X if (strlen(temp) > 0) { /* mess with buffer... */
- X
- X /* remove leading spaces and quotes... */
- X
- X while (whitespace(temp[0]) || quote(temp[0]))
- X temp = (char *) (temp + 1); /* increment address! */
- X
- X /* remove trailing spaces and quotes... */
- X
- X i = strlen(temp) - 1;
- X
- X while (whitespace(temp[i]) || quote(temp[i]))
- X temp[i--] = '\0';
- X
- X /* if anything is left, let's change 'from' value! */
- X
- X if (strlen(temp) > 0) {
- X strncpy(newfrom, temp, STRING-1);
- X newfrom[STRING-1] = '\0';
- X }
- X }
- X}
- X
- X/*
- XQuoting from RFC 822:
- X 5. DATE AND TIME SPECIFICATION
- X
- X 5.1. SYNTAX
- X
- X date-time = [ day "," ] date time ; dd mm yy
- X ; hh:mm:ss zzz
- X
- X day = "Mon" / "Tue" / "Wed" / "Thu"
- X / "Fri" / "Sat" / "Sun"
- X
- X date = 1*2DIGIT month 2DIGIT ; day month year
- X ; e.g. 20 Jun 82
- X
- X month = "Jan" / "Feb" / "Mar" / "Apr"
- X / "May" / "Jun" / "Jul" / "Aug"
- X / "Sep" / "Oct" / "Nov" / "Dec"
- X
- X time = hour zone ; ANSI and Military
- X
- X hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT]
- X ; 00:00:00 - 23:59:59
- X
- X zone = "UT" / "GMT" ; Universal Time
- X ; North American : UT
- X / "EST" / "EDT" ; Eastern: - 5/ - 4
- X / "CST" / "CDT" ; Central: - 6/ - 5
- X / "MST" / "MDT" ; Mountain: - 7/ - 6
- X / "PST" / "PDT" ; Pacific: - 8/ - 7
- X / 1ALPHA ; Military: Z = UT;
- X ; A:-1; (J not used)
- X ; M:-12; N:+1; Y:+12
- X / ( ("+" / "-") 4DIGIT ) ; Local differential
- X ; hours+min. (HHMM)
- X*/
- X
- X/* Translate a symbolic timezone name (e.g. EDT or NZST) to a number of
- X * minutes *east* of gmt (if the local time is t, the gmt equivalent is
- X * t - tz_lookup(zone)).
- X * Return 0 if the timezone is not recognized.
- X */
- Xstatic int tz_lookup(str)
- Xchar *str;
- X{
- X struct tzone *p;
- X
- X for (p = tzone_info; p->str; p++) {
- X if (strcmp(p->str,str)==0) return p->offset;
- X }
- X dprint(5,(debugfile,"unknown time zone %s\n",str));
- X return 0;
- X}
- X
- X/* Return smallest i such that table[i] is a prefix of str. Return -1 if not
- X * found.
- X */
- Xstatic int prefix(table, str)
- Xchar **table;
- Xchar *str;
- X{
- X int i;
- X
- X for (i=0;table[i];i++)
- X if (strncmp(table[i],str,strlen(*table))==0)
- X return i;
- X return -1;
- X}
- X
- X/* The following routines, get_XXX(p,...), expect p to point to a string
- X * of the appropriate syntax. They return decoded values in result parameters,
- X * and return p updated to point past the parsed substring (also stripping
- X * trailing whitespace).
- X * Return 0 on syntax errors.
- X */
- X
- X/* Parse a year: ['1' '9'] digit digit WS
- X */
- Xstatic char *
- Xget_year(p, result)
- Xchar *p;
- Xint *result;
- X{
- X int year;
- X
- X if (!isdigit(*p)) {
- X dprint(5,(debugfile,"missing year: %s\n",p));
- X return 0;
- X }
- X year = atoi(p);
- X /* be nice and allow 19xx, althought that's not really kosher */
- X if (year>=1900 && year <=1999) year -= 1900;
- X if (year<0 || year>99) {
- X dprint(5,(debugfile,"ridiculous year %d\n",year));
- X return 0;
- X }
- X SKIP_DIGITS(p);
- X SKIP_WS(p);
- X *result = year;
- X return p;
- X}
- X
- X/* Parse a time: hours ':' minutes [ ':' seconds ] WS
- X * Check that 0<=hours<24, 0<=minutes,seconds<60.
- X * Also allow the syntax "digit digit digit digit" with implied ':' in the
- X * middle.
- X * Convert to minutes and seconds, with results in (*m,*s).
- X */
- Xstatic char *
- Xget_time(p,m,s)
- Xchar *p;
- Xint *m, *s;
- X{
- X int hours, minutes, seconds;
- X
- X /* hour */
- X if (!isdigit(*p)) {
- X dprint(5,(debugfile,"missing time: %s\n",p));
- X return 0;
- X }
- X hours = atoi(p);
- X SKIP_DIGITS(p);
- X if (*p++ != ':') {
- X /* perhaps they just wrote hhmm instead of hh:mm */
- X minutes = hours % 60;
- X hours /= 60;
- X }
- X else {
- X if (hours<0 || hours>23) {
- X dprint(5,(debugfile,"ridiculous hour: %d\n",hours));
- X return 0;
- X }
- X minutes = atoi(p);
- X if (minutes<0 || minutes>59) {
- X dprint(5,(debugfile,"ridiculous minutes: %d\n",minutes));
- X return 0;
- X }
- X }
- X SKIP_DIGITS(p);
- X if (*p == ':') {
- X p++;
- X seconds = atoi(p);
- X if (seconds<0 || seconds>59) {
- X dprint(5,(debugfile,"ridiculous seconds: %d\n",seconds));
- X return 0;
- X }
- X SKIP_DIGITS(p);
- X }
- X else seconds = 0;
- X minutes += hours*60;
- X SKIP_WS(p);
- X *m = minutes;
- X *s = seconds;
- X return p;
- X}
- X
- X/* Parse a Unix date from which the leading week-day has been stripped.
- X * The syntax is "Jun 21 06:45:44 CDT 1989" with timezone optional.
- X * i.e., month day time [ zone ] year
- X * where day::=digit*, year and time are as defined above,
- X * and month and zone are alpha strings starting with a known 3-char prefix.
- X * The month has already been processed by the caller, so we just skip over
- X * a leading alpha* WS.
- X *
- X * Unlike the preceding routines, the result is not an updated pointer, but
- X * simply 1 for success and 0 for failure.
- X */
- Xstatic int
- Xget_unix_date(p,y,d,m,s,t)
- Xchar *p;
- Xint *y, *d, *m, *s, *t;
- X{
- X
- X SKIP_ALPHA(p);
- X SKIP_WS(p);
- X if (!isdigit(*p)) return 0;
- X *d = atoi(p); /* check the value for sanity after we know the month */
- X SKIP_DIGITS(p);
- X SKIP_WS(p);
- X p = get_time(p,m,s);
- X if (!p) return 0;
- X if (isalpha(*p)) {
- X *t = tz_lookup(p);
- X SKIP_ALPHA(p);
- X SKIP_WS(p);
- X }
- X else *t = 0;
- X p = get_year(p,y);
- X if (!p) return 0;
- X return 1;
- X}
- X
- X
- X/* Parse an rfc822 (with extensions) date. Return 1 on success, 0 on failure.
- X */
- Xparse_arpa_date(string, entry)
- Xchar *string;
- Xstruct header_rec *entry;
- X{
- X char buffer[BUFSIZ], *p, *q;
- X int mday, month, year, minutes, seconds, tz, i;
- X long gmttime;
- X
- X /* first get everything into lower case */
- X for (p=buffer, q=buffer+sizeof buffer; *string && p<q; p++, string++) {
- X *p = isupper(*string) ? tolower(*string) : *string;
- X }
- X *p = 0;
- X p = buffer;
- X SKIP_WS(p);
- X
- X if (prefix(day_name,p)>=0) {
- X /* accept anything that *starts* with a valid day name */
- X /* also, don't check whether it's right! */
- X
- X (void)strncpy(entry->dayname, p, 3);
- X entry->dayname[3] = 0;
- X SKIP_ALPHA(p);
- X SKIP_WS(p);
- X
- X if (*p==',') {
- X p++;
- X SKIP_WS(p);
- X }
- X /* A comma is required here, but we'll be nice guys and look the other
- X * way if it's missing.
- X */
- X }
- X
- X /* date */
- X
- X /* day of the month */
- X if (!isdigit(*p)) {
- X /* Missing day. Maybe this is a Unix date?
- X */
- X month = prefix(month_name,p);
- X if (month >= 0 &&
- X get_unix_date(p, &year, &mday, &minutes, &seconds, &tz)) {
- X goto got_date;
- X }
- X dprint(5,(debugfile,"missing day: %s\n",p));
- X return 0;
- X }
- X mday = atoi(p); /* check the value for sanity after we know the month */
- X SKIP_DIGITS(p);
- X SKIP_WS(p);
- X
- X /* month name */
- X month = prefix(month_name,p);
- X if (month < 0) {
- X dprint(5,(debugfile,"missing month: %s\n",p));
- X return 0;
- X }
- X SKIP_ALPHA(p);
- X SKIP_WS(p);
- X
- X /* year */
- X if (!(p = get_year(p,&year))) return 0;
- X
- X /* time */
- X if (!(p = get_time(p,&minutes,&seconds))) return 0;
- X
- X /* zone */
- X for (q=p; *q && !isspace(*q); q++) continue;
- X *q = 0;
- X if (*p=='-' || *p=='+') {
- X char sign = *p++;
- X
- X if (isdigit(*p)) {
- X for (i=0; i<4; i++) {
- X if (!isdigit(p[i])) {
- X dprint(5,(debugfile,"ridiculous numeric timezone: %s\n",p));
- X return 0;
- X }
- X p[i] -= '0';
- X }
- X tz = (p[0]*10 + p[1])*60 + p[2]*10 + p[3];
- X if (sign=='-') tz = -tz;
- X sprintf(entry->time_zone, "%d", tz);
- X }
- X else {
- X /* some brain-damaged dates use a '-' before a symbolic time zone */
- X SKIP_WS(p);
- X strncpy(entry->time_zone, p, sizeof(entry->time_zone) - 1);
- X tz = tz_lookup(p);
- X }
- X }
- X else {
- X tz = tz_lookup(p);
- X strncpy(entry->time_zone, p, sizeof(entry->time_zone) - 1);
- X }
- X
- Xgot_date:
- X month_len[1] = (year%4) ? 28 : 29;
- X if (mday<0 || mday>month_len[month]) {
- X dprint(5,(debugfile,"ridiculous day %d of month %d\n",mday,month));
- X return 0;
- X }
- X
- X /* convert back to symbolic form (silly, but the rest of the program
- X * expects it and I'm not about to change all that!)
- X */
- X sprintf(entry->year, "%02d", year);
- X sprintf(entry->month, "%s", month_name[month]);
- X entry->month[0] = toupper(entry->month[0]);
- X sprintf(entry->day, "%d", mday);
- X sprintf(entry->time, "%02d:%02d:%02d",minutes/60,minutes%60,seconds);
- X
- X /* shift everything to UTC (aka GMT) before making long time for sorting */
- X minutes -= tz;
- X if (tz > 0) { /* east of Greenwich */
- X if (minutes < 0) {
- X if (--mday < 0) {
- X if (--month < 0) {
- X year--; /* don't worry about 1900! */
- X month = 11;
- X }
- X mday = month_len[month];
- X }
- X minutes += 24*60;
- X }
- X }
- X if (tz < 0) { /* west of Greenwich */
- X if (minutes >= 24*60) {
- X if (++mday > month_len[month]) {
- X if (++month >= 12) {
- X year++; /* don't worry about 1999! */
- X month = 0;
- X }
- X mday = 0;
- X }
- X minutes -= 24*60;
- X }
- X }
- X gmttime = year - 70; /* make base year */
- X if (gmttime < 0)
- X gmttime += 100;
- X gmttime = gmttime * 365 + (gmttime + 1) / 4; /* now we have days adjusted for leap years */
- X for (i = 0; i < month; i++)
- X gmttime += month_len[i];
- X if (month > 1 && (year % 4) == 0)
- X gmttime++; /* now to month adjusted for leap year if after feb */
- X gmttime += mday - 1; /* and now to the day */
- X gmttime *= 24 * 60; /* convert to minutes */
- X gmttime += minutes;
- X entry->time_sent = gmttime * 60; /* now unix seconds since 1/1/70 00:00 GMT */
- X
- X return 1;
- X}
- X
- Xfix_arpa_address(address)
- Xchar *address;
- X{
- X /** Given a pure ARPA address, try to make it reasonable.
- X
- X This means that if you have something of the form a@b@b make
- X it a@b. If you have something like a%b%c%b@x make it a%b@x...
- X **/
- X
- X register int host_count = 0, i;
- X char hosts[MAX_HOPS][NLEN]; /* array of machine names */
- X char *host, *addrptr;
- X
- X /* break down into a list of machine names, checking as we go along */
- X
- X addrptr = (char *) address;
- X
- X while ((host = get_token(addrptr, "%@", 2)) != NULL) {
- X for (i = 0; i < host_count && ! equal(hosts[i], host); i++)
- X ;
- X
- X if (i == host_count) {
- X strcpy(hosts[host_count++], host);
- X if (host_count == MAX_HOPS) {
- X dprint(2, (debugfile,
- X "Can't build return address - hit MAX_HOPS in fix_arpa_address\n"));
- X error("Can't build return address - hit MAX_HOPS limit!");
- X return(1);
- X }
- X }
- X else
- X host_count = i + 1;
- X addrptr = NULL;
- X }
- X
- X /** rebuild the address.. **/
- X
- X address[0] = '\0';
- X
- X for (i = 0; i < host_count; i++)
- X sprintf(address, "%s%s%s", address,
- X address[0] == '\0'? "" :
- X (i == host_count - 1 ? "@" : "%"),
- X hosts[i]);
- X
- X return(0);
- X}
- X
- Xfigure_out_addressee(buffer, mail_to)
- Xchar *buffer;
- Xchar *mail_to;
- X{
- X /** This routine steps through all the addresses in the "To:"
- X list, initially setting it to the first entry (if mail_to
- X is NULL) or, if the user is found (eg "alternatives") to
- X the current "username".
- X
- X Modified to know how to read quoted names...
- X also modified to look for a comma or eol token and then
- X try to give the maximal useful information when giving the
- X default "to" entry (e.g. "Dave Taylor <taylor@hpldat>"
- X will now give "Dave Taylor" rather than just "Dave")
- X **/
- X
- X char *address, *bufptr, mybuf[SLEN];
- X register int index2 = 0;
- X
- X if (equal(mail_to, username)) return; /* can't be better! */
- X
- X bufptr = (char *) buffer; /* use the string directly */
- X
- X if (index(buffer,'"') != NULL) { /* we have a quoted string */
- X while (*bufptr != '"')
- X bufptr++;
- X bufptr++; /* skip the leading quote */
- X while (*bufptr != '"' && *bufptr)
- X mail_to[index2++] = *bufptr++;
- X mail_to[index2] = '\0';
- X }
- X
- X else {
- X
- X while ((address = strtok(bufptr, ",\t\n\r")) != NULL) {
- X
- X if (! okay_address(address, "don't match me!")) {
- X strcpy(mail_to, username); /* it's to YOU! */
- X return;
- X }
- X else if (strlen(mail_to) == 0) { /* it's SOMEthing! */
- X
- X /** this next bit is kinda gory, but allows us to use the
- X existing routines to parse the address - by pretending
- X it's a From: line and going from there...
- X Ah well - you get what you pay for, right?
- X **/
- X
- X if (strlen(address) > (sizeof mybuf) - 7) /* ensure it ain't */
- X address[(sizeof mybuf)-7] = '\0'; /* too long mon! */
- X
- X sprintf(mybuf, "From: %s", address);
- X parse_arpa_who(mybuf, mail_to, TRUE);
- X/**
- X get_return_name(address, mail_to, FALSE);
- X**/
- X }
- X
- X bufptr = (char *) NULL; /* set to null */
- X }
- X }
- X
- X return;
- X}
- SHAR_EOF
- echo "File src/addr_util.c is complete"
- chmod 0444 src/addr_util.c || echo "restore of src/addr_util.c fails"
- echo "x - extracting src/alias.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/alias.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: alias.c,v 4.1 90/04/28 22:42:25 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: alias.c,v $
- X * Revision 4.1 90/04/28 22:42:25 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** This file contains alias stuff
- X
- X**/
- X
- X#include "headers.h"
- X#include <errno.h>
- X#include <ctype.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#ifdef BSD
- X#undef tolower
- X#endif
- X
- X#define ECHOIT 1 /* echo on for prompting */
- X
- Xchar *get_alias_address();
- Xchar *error_name(), *error_description(), *strip_parens(), *index();
- X
- Xextern int errno;
- X
- X#ifndef DONT_TOUCH_ADDRESSES
- Xchar *expand_system();
- X
- Xextern int findnode_has_been_initialized;
- X#endif
- X
- Xint
- Xok_alias_name(name)
- Xchar *name;
- X{
- X while ( *name != '\0' && ok_alias_char(*name) )
- X ++name;
- X return ( *name == '\0' );
- X}
- X
- X
- Xread_alias_files()
- X{
- X /** read the system and user alias files, if present, and if they
- X have changed since last we read them.
- X **/
- X
- X read_system_aliases();
- X read_user_aliases();
- X}
- X
- Xread_system_aliases()
- X{
- X /** read the system alias file, if present,
- X and if it has changed since last we read it.
- X **/
- X
- X struct stat hst;
- X static time_t system_ctime, system_mtime;
- X
- X /* If hash file hasn't changed, don't bother re-reading. */
- X
- X if (system_data != -1
- X && stat(system_hash_file, &hst) == 0
- X && hst.st_ctime == system_ctime
- X && hst.st_mtime == system_mtime)
- X return;
- X
- X /* Close system data file if it was open. */
- X
- X if (system_data != -1) {
- X close(system_data);
- X system_data = -1;
- X }
- X
- X /* Read system hash table. If we can't, just return. */
- X
- X if (read_hash_file(system_hash_file, (char *) system_hash_table,
- X sizeof system_hash_table) < 0)
- X return;
- X
- X /* Open system data table. */
- X
- X if ((system_data = open(system_data_file, O_RDONLY)) == -1) {
- X dprint(1, (debugfile,
- X "Warning: Can't open system alias data file %s\n",
- X system_data_file));
- X return;
- X }
- X
- X /* Remember hash file times. */
- X
- X system_ctime = hst.st_ctime;
- X system_mtime = hst.st_mtime;
- X}
- X
- Xread_user_aliases()
- X{
- X /** read the system alias file, if present,
- X and if it has changed since last we read it.
- X **/
- X
- X struct stat hst;
- X char fname[SLEN];
- X static time_t user_ctime, user_mtime;
- X
- X /* If hash file hasn't changed, don't bother re-reading. */
- X
- X sprintf(fname, "%s/%s", home, ALIAS_HASH);
- X
- X if (user_data != -1
- X && stat(fname, &hst) == 0
- X && hst.st_ctime == user_ctime
- X && hst.st_mtime == user_mtime)
- X return;
- X
- X /* Close user data file if it was open. */
- X
- X if (user_data != -1) {
- X close(user_data);
- X user_data = -1;
- X }
- X
- X /* Read user hash table. If we can't, just return. */
- X
- X if (read_hash_file(fname, (char *) user_hash_table,
- X sizeof user_hash_table) < 0)
- X return;
- X
- X /* Open user data table. */
- X
- X sprintf(fname, "%s/%s", home, ALIAS_DATA);
- X if ((user_data = open(fname, O_RDONLY)) == -1) {
- X dprint(1, (debugfile,
- X "Warning: Can't open user alias data file %s\n", fname));
- X return;
- X }
- X
- X /* Remember hash file times. */
- X
- X user_ctime = hst.st_ctime;
- X user_mtime = hst.st_mtime;
- X}
- X
- Xint
- Xread_hash_file(file, table, table_size)
- Xchar *file, *table;
- Xint table_size;
- X{
- X /** read the specified alias hash file into the specified table.
- X it must be _exactly_ the right size or forget it.
- X **/
- X
- X struct stat st;
- X int hash;
- X
- X /* Open the hash file. */
- X
- X if ((hash = open(file, O_RDONLY)) == -1) {
- X dprint(2, (debugfile,
- X "Warning: Can't open alias hash file %s\n", file));
- X return -1;
- X }
- X
- X /* Be sure the hash file is the correct size. */
- X
- X if (fstat(hash, &st) == 0 && st.st_size != table_size) {
- X dprint(2, (debugfile,
- X "Warning: Alias hash file %s is wrong size (%ld/%d)\n",
- X file, st.st_size, table_size));
- X close(hash);
- X return -1;
- X }
- X
- X /* Read the hash file into memory. */
- X
- X if (read(hash, (char *) table, table_size) != table_size) {
- X dprint(2, (debugfile,
- X "Warning: Can't read alias hash file %s\n", file));
- X close(hash);
- X return -1;
- X }
- X
- X /* Close the hash file; return success. */
- X
- X close(hash);
- X return 0;
- X}
- X
- Xint
- Xadd_alias()
- X{
- X /** add an alias to the user alias text file. Return zero
- X if alias not added in actuality **/
- X
- X char name[SLEN], *address, address1[LONG_STRING], buffer[LONG_STRING];
- X char comment[SLEN], ch;
- X char *strcpy();
- X
- X strcpy(buffer, "Enter alias name: ");
- X PutLine0(LINES-2,0, buffer);
- X CleartoEOLN();
- X *name = '\0';
- X optionally_enter(name, LINES-2, strlen(buffer), FALSE, FALSE);
- X if (strlen(name) == 0)
- X return(0);
- X if ( !ok_alias_name(name) ) {
- X error1("Bad character(s) in alias name %s.", name);
- X return(0);
- X }
- X if ((address = get_alias_address(name, FALSE)) != NULL) {
- X dprint(3, (debugfile,
- X "Attempt to add a duplicate alias [%s] in add_alias\n",
- X address));
- X if (address[0] == '!') {
- X address[0] = ' ';
- X error1("Already a group with name %s.", address);
- X }
- X else
- X error1("Already an alias for %s.", address);
- X return(0);
- X }
- X
- X sprintf(buffer, "Enter full name for %s: ", name);
- X PutLine0(LINES-2,0, buffer);
- X CleartoEOLN();
- X *comment = '\0';
- X optionally_enter(comment, LINES-2, strlen(buffer), FALSE, FALSE);
- X if (strlen(comment) == 0) strcpy(comment, name);
- X
- X sprintf(buffer, "Enter address for %s: ", name);
- X PutLine0(LINES-2,0, buffer);
- X CleartoEOLN();
- X *address1 = '\0';
- X optionally_enter(address1, LINES-2, strlen(buffer), FALSE, FALSE);
- X Raw(ON);
- X if (strlen(address1) == 0) {
- X error("No address specified!");
- X return(0);
- X }
- X PutLine3(LINES-2,0,"%s (%s) = %s", comment, name, address1);
- X CleartoEOLN();
- X if((ch = want_to("Accept new alias? (y/n) ",'y')) == 'y')
- X add_to_alias_text(name, comment, address1);
- X ClearLine(LINES-2);
- X return(ch == 'y' ? 1 : 0);
- X}
- X
- Xint
- Xdelete_alias()
- X{
- X /** delete an alias from the user alias text file. Return zero
- X if alias not deleted in actuality **/
- X
- X char name[SLEN], *address, buffer[LONG_STRING];
- X char *strcpy();
- X
- X strcpy(buffer, "Enter alias name for deletion: ");
- X PutLine0(LINES-2,0, buffer);
- X CleartoEOLN();
- X *name = '\0';
- X optionally_enter(name, LINES-2, strlen(buffer), FALSE, FALSE);
- X if (strlen(name) == 0)
- X return(0);
- X if ((address = get_alias_address(name, FALSE))!=NULL)
- X {
- X if (address[0] == '!')
- X {
- X address[0] = ' ';
- X PutLine1(LINES-1,0,"Group alias: %-60.60s", address);
- X CleartoEOLN();
- X }
- X else
- X PutLine1(LINES-1,0,"Aliased address: %-60.60s", address);
- X }
- X else
- X {
- X dprint(3, (debugfile,
- X "Attempt to delete a non-existent alias [%s] in delete_alias\n",
- X name));
- X error1("No alias for %s.", name);
- X return(0);
- X }
- X if (want_to("Delete this alias? (y/n) ", 'y') == 'y')
- X {
- X if (!delete_from_alias_text(name))
- X {
- X CleartoEOS();
- X return(1);
- X }
- X }
- X CleartoEOS();
- X return(0);
- X}
- X
- Xint
- Xadd_current_alias()
- X{
- X /** alias the current message to the specified name and
- X add it to the alias text file, for processing as
- X the user leaves the program. Returns non-zero iff
- X alias actually added to file **/
- X
- X char name[SLEN], address1[LONG_STRING], buffer[LONG_STRING], *address;
- X char comment[SLEN], ch;
- X struct header_rec *current_header;
- X
- X if (current == 0) {
- X dprint(4, (debugfile,
- X "Add current alias called without any current message!\n"));
- X error("No message to alias to!");
- X return(0);
- X }
- X current_header = headers[current - 1];
- X
- X strcpy(buffer, "Current message address aliased to: ");
- X PutLine0(LINES-2,0, buffer);
- X CleartoEOLN();
- X *name = '\0';
- X optionally_enter(name, LINES-2, strlen(buffer), FALSE, FALSE);
- X if (strlen(name) == 0) /* cancelled... */
- X return(0);
- X if ( !ok_alias_name(name) ) {
- X error1("Bad character(s) in alias name %s.", name);
- X return(0);
- X }
- X if ((address = get_alias_address(name, FALSE)) != NULL) {
- X dprint(3, (debugfile,
- X "Attempt to add a duplicate alias [%s] in add_current_alias\n",
- X address));
- X if (address[1] == '!') {
- X address[0] = ' ';
- X error1("Already a group with name %s.", address);
- X }
- X else
- X error1("Already an alias for %s.", address);
- X return(0);
- X }
- X
- X sprintf(buffer, "Enter full name for %s: ", name);
- X PutLine0(LINES-2,0, buffer);
- X CleartoEOLN();
- X
- X /* use full name in current message for default comment */
- X tail_of(current_header->from, comment, current_header->to);
- X if(index(comment, '!') || index(comment, '@'))
- X /* never mind - it's an address not a full name */
- X *comment = '\0';
- X
- X optionally_enter(comment, LINES-2, strlen(buffer), FALSE, FALSE);
- X
- X /* grab the return address of this message */
- X get_return(address1, current-1);
- X
- X strcpy(address1, strip_parens(address1)); /* remove parens! */
- X#ifdef OPTIMIZE_RETURN
- X optimize_return(address1);
- X#endif
- X PutLine3(LINES-2,0,"%s (%s) = %s", comment, name, address1);
- X CleartoEOLN();
- X if((ch = want_to("Accept new alias? (y/n) ",'y')) == 'y')
- X add_to_alias_text(name, comment, address1);
- X ClearLine(LINES-2);
- X return(ch == 'y' ? 1 : 0);
- X}
- X
- Xadd_to_alias_text(name, comment, address)
- Xchar *name, *comment, *address;
- X{
- X /** Add the data to the user alias text file. Return zero if we
- X succeeded, 1 if not **/
- X
- X FILE *file;
- X char fname[SLEN];
- X
- X sprintf(fname,"%s/%s", home, ALIAS_TEXT);
- X
- X save_file_stats(fname);
- X if ((file = fopen(fname, "a")) == NULL) {
- X dprint(2, (debugfile,
- X "Failure attempting to add alias to file %s within %s",
- X fname, "add_to_alias_text"));
- X dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
- X error_description(errno)));
- X error1("Couldn't open %s to add new alias!", fname);
- X return(1);
- X }
- X
- X if (fprintf(file,"%s = %s = %s\n", name, comment, address) == EOF) {
- X dprint(2, (debugfile,
- X "Failure attempting to write alias to file within %s",
- X fname, "add_to_alias_text"));
- X dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
- X error_description(errno)));
- X error1("Couldn't write alias to file %s!", fname);
- X fclose(file);
- X return(1);
- X }
- X
- X fclose(file);
- X
- X restore_file_stats(fname);
- X
- X return(0);
- X}
- X
- Xdelete_from_alias_text(name)
- Xchar *name;
- X{
- X /** Delete the data from the user alias text file. Return zero if we
- X succeeded, 1 if not **/
- X
- X FILE *file, *tmp_file;
- X char fname[SLEN], tmpfname[SLEN];
- X char line_in_file[SLEN+3+SLEN+3+LONG_STRING]; /* name = comment = address */
- X char name_with_equals[SLEN+2];
- X
- X strcpy(name_with_equals, name);
- X strcat(name_with_equals, " =");
- X
- X sprintf(fname,"%s/%s", home, ALIAS_TEXT);
- X sprintf(tmpfname,"%s/%s.tmp", home, ALIAS_TEXT);
- X
- X save_file_stats(fname);
- X
- X if ((file = fopen(fname, "r")) == NULL) {
- X dprint(2, (debugfile,
- X "Failure attempting to delete alias from file %s within %s",
- X fname, "delete_from_alias_text"));
- X dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
- X error_description(errno)));
- X error1("Couldn't open %s to delete alias!", fname);
- X return(1);
- X }
- X
- X if ((tmp_file = fopen(tmpfname, "w")) == NULL) {
- X dprint(2, (debugfile,
- X "Failure attempting to open temp file %s within %s",
- X tmpfname, "delete_from_alias_text"));
- X dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
- X error_description(errno)));
- X error1("Couldn't open tempfile %s to delete alias!", tmpfname);
- X return(1);
- X }
- X
- X while (fgets(line_in_file, sizeof(line_in_file), file) != (char *)NULL)
- X {
- X if (strncmp(name_with_equals, line_in_file,
- X strlen(name_with_equals)) != 0)
- X if (fprintf(tmp_file,"%s", line_in_file) == EOF) {
- X dprint(2, (debugfile,
- X "Failure attempting to write to temp file %s within %s",
- X tmpfname, "delete_from_alias_text"));
- X dprint(2, (debugfile, "** %s - %s **\n", error_name(errno),
- X error_description(errno)));
- X error1("Couldn't write to tempfile %s!", tmpfname);
- X fclose(file);
- X fclose(tmp_file);
- X unlink(tmpfname);
- X return(1);
- X }
- X }
- X fclose(file);
- X fclose(tmp_file);
- X if (rename(tmpfname, fname) != 0)
- X {
- X error1("Couldn't rename tempfile %s after deleting alias!", tmpfname);
- X return(1);
- X }
- X
- X restore_file_stats(fname);
- X
- X return(0);
- X}
- X
- Xshow_alias_menu()
- X{
- X MoveCursor(LINES-7,0); CleartoEOS();
- X
- X PutLine0(LINES-7,COLUMNS-45, "Alias commands");
- X Centerline(LINES-6,
- X "a)lias current message, d)elete an alias, check a p)erson or s)ystem,");
- X Centerline(LINES-5,
- X "l)ist existing aliases, m)ake new alias, or r)eturn");
- X}
- X
- Xalias()
- X{
- X /** work with alias commands... **/
- X /** return non-0 if main part of screen overwritten, else 0 **/
- X
- X char name[NLEN], *address, ch, buffer[SLEN];
- X int newaliases = 0, redraw = 0;
- X
- X if (mini_menu)
- X show_alias_menu();
- X
- X /** now let's ensure that we've initialized everything! **/
- X
- X#ifndef DONT_TOUCH_ADDRESSES
- X
- X if (! findnode_has_been_initialized) {
- X if (warnings)
- X error("Initializing internal tables...");
- X#ifndef USE_DBM
- X get_connections();
- X open_domain_file();
- X#endif
- X init_findnode();
- X clear_error();
- X findnode_has_been_initialized = TRUE;
- X }
- X
- X#endif
- X
- X define_softkeys(ALIAS);
- X
- X while (1) {
- X prompt("Alias: ");
- X CleartoEOLN();
- X ch = ReadCh();
- X MoveCursor(LINES-1,0); CleartoEOS();
- X
- X dprint(3, (debugfile, "\n-- Alias command: %c\n\n", ch));
- X
- X switch (tolower(ch)) {
- X case '?': redraw += alias_help(); break;
- X
- X case 'a': newaliases += add_current_alias(); break;
- X case 'd': if (delete_alias()) install_aliases(); break;
- X case 'l': display_aliases();
- X redraw++;
- X if (mini_menu) show_alias_menu();
- X break;
- X case 'm': newaliases += add_alias(); break;
- X
- X case RETURN:
- X case LINE_FEED:
- X case 'q':
- X case 'x':
- X case 'r': if (newaliases) install_aliases();
- X clear_error();
- X return(redraw);
- X case 'p': if (newaliases)
- X error("Warning: new aliases not installed yet!");
- X
- X strcpy(buffer, "Check for person: ");
- X PutLine0(LINES-2,0, buffer);
- X CleartoEOLN();
- X *name = '\0';
- X optionally_enter(name, LINES-2, strlen(buffer),
- X FALSE, FALSE);
- X
- X if ((address = get_alias_address(name, FALSE))!=NULL) {
- X if (address[0] == '!') {
- X address[0] = ' ';
- X PutLine1(LINES-1,0,"Group alias:%-60.60s", address);
- X CleartoEOLN();
- X }
- X else
- X PutLine1(LINES-1,0,"Aliased address: %-60.60s",
- X address);
- X }
- X else
- X error("Not found.");
- X break;
- X
- X case 's': strcpy(buffer, "Check for system: ");
- X PutLine0(LINES-2,0, buffer);
- X CleartoEOLN();
- X *name = '\0';
- X optionally_enter(name, LINES-2, strlen(buffer),
- X FALSE, FALSE);
- X if (talk_to(name))
- X#ifdef INTERNET
- X PutLine1(LINES-1,0,
- X "You have a direct connection. The address is USER@%s.",
- X name);
- X#else
- X PutLine1(LINES-1,0,
- X "You have a direct connection. The address is %s!USER.",
- X name);
- X#endif
- X else {
- X sprintf(buffer, "USER@%s", name);
- X#ifdef DONT_TOUCH_ADDRESSES
- X address = buffer;
- X#else
- X address = expand_system(buffer, FALSE);
- X#endif
- X if (strlen(address) > strlen(name) + 7)
- X PutLine1(LINES-1,0,"Address is: %.65s", address);
- X else
- X error1("Couldn't expand system %s.", name);
- X }
- X break;
- X
- X case '@': strcpy(buffer, "Fully expand alias: ");
- X PutLine0(LINES-2,0, buffer);
- X CleartoEOS();
- X *name = '\0';
- X optionally_enter(name, LINES-2, strlen(buffer),
- X FALSE, FALSE);
- X if ((address = get_alias_address(name, TRUE)) != NULL) {
- X ClearScreen();
- X PutLine1(3,0,"Aliased address:\n\r%s", address);
- X PutLine0(LINES-1,0,"Press <return> to continue.");
- X (void) getchar();
- X redraw++;
- X }
- X else
- X error("Not found.");
- X if (mini_menu) show_alias_menu();
- X break;
- X default : error("Invalid input!");
- X }
- X }
- X}
- X
- Xinstall_aliases()
- X{
- X /** run the 'newalias' program and update the
- X aliases before going back to the main program!
- X **/
- X
- X
- X error("Updating aliases...");
- X sleep(2);
- X
- X if (system_call(newalias, SH, FALSE, FALSE) == 0) {
- X error("Re-reading the database in...");
- X sleep(2);
- X read_alias_files();
- X set_error("Aliases updated successfully.");
- X }
- X else
- X set_error("'Newalias' failed. Please check alias_text.");
- X}
- X
- Xalias_help()
- X{
- X /** help section for the alias menu... **/
- X /** return non-0 if main part of screen overwritten, else 0 */
- X
- X char ch;
- X int redraw=0;
- X char *alias_prompt = mini_menu ? "Key: " : "Key you want help for: ";
- X
- X MoveCursor(LINES-3, 0); CleartoEOS();
- X
- X if (mini_menu) {
- X Centerline(LINES-3,
- X "Press the key you want help for, '?' for a key list, or '.' to exit help");
- X }
- X
- X lower_prompt(alias_prompt);
- X
- X while ((ch = ReadCh()) != '.') {
- X ch = tolower(ch);
- X switch(ch) {
- X case '?' : display_helpfile(ALIAS_HELP);
- X redraw++;
- X if (mini_menu) show_alias_menu();
- X return(redraw);
- X case 'a': error(
- X "a = Add (return) address of current message to alias database.");
- X break;
- X case 'd': error("d = Delete a user alias from alias database.");
- X break;
- X case 'l': error("l = List all aliases in database.");
- X break;
- X case 'm': error(
- X "m = Make a new user alias, adding to alias database when done.");
- X break;
- X
- X case RETURN:
- X case LINE_FEED:
- X case 'q':
- X case 'x':
- X case 'r': error("Return from alias menu.");
- X break;
- X
- X case 'p': error("p = Check for a person in the alias database.");
- X break;
- X
- X case 's': error(
- X "s = Check for a system in the host routing/domain database.");
- X break;
- X
- X default : error("That key isn't used in this section.");
- X break;
- X }
- X lower_prompt(alias_prompt);
- X }
- X return(redraw);
- X}
- X
- Xdisplay_aliases()
- X{
- X char fname[SLEN];
- X
- X sprintf(fname,"%s/%s", home, ALIAS_TEXT);
- X display_file(fname);
- X ClearScreen();
- X return;
- X}
- SHAR_EOF
- chmod 0444 src/alias.c || echo "restore of src/alias.c fails"
- echo "x - extracting src/aliasdb.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > src/aliasdb.c &&
- X
- Xstatic char rcsid[] = "@(#)$Id: aliasdb.c,v 4.1 90/04/28 22:42:28 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: aliasdb.c,v $
- X * Revision 4.1 90/04/28 22:42:28 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** Alias database files...
- X
- X**/
- X
- X
- X#include "headers.h"
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <errno.h>
- X
- Xextern int errno;
- X
- X#ifdef USE_DBM
- X# include <dbm.h>
- X#endif
- X
- X#define absolute(x) ((x) > 0 ? x : -(x))
- X
- Xchar *find_path_to(), *strcat(), *strcpy();
- Xunsigned long sleep();
- X
- X#ifndef DONT_TOUCH_ADDRESSES
- Xint findnode_has_been_initialized = FALSE;
- X#endif
- X
- Xfindnode(name, display_error)
- Xchar *name;
- Xint display_error;
- X{
- X /** break 'name' into machine!user or user@machine and then
- X see if you can find 'machine' in the path database..
- X If so, return name as the expanded address. If not,
- X return what was given to us! If display_error, then
- X do so...
- X **/
- X
- X#ifndef DONT_TOUCH_ADDRESSES
- X
- X char old_name[SLEN];
- X char address[SLEN];
- X
- X if (strlen(name) == 0)
- X return;
- X
- X if (! findnode_has_been_initialized) {
- X if (warnings)
- X error("Initializing internal tables...");
- SHAR_EOF
- echo "End of part 11"
- echo "File src/aliasdb.c is continued in part 12"
- echo "12" > s2_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
-