diff options
Diffstat (limited to 'usr.bin/mail/aux.c')
-rw-r--r-- | usr.bin/mail/aux.c | 705 |
1 files changed, 0 insertions, 705 deletions
diff --git a/usr.bin/mail/aux.c b/usr.bin/mail/aux.c deleted file mode 100644 index f4c2acd..0000000 --- a/usr.bin/mail/aux.c +++ /dev/null @@ -1,705 +0,0 @@ -/* - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)aux.c 8.1 (Berkeley) 6/6/93"; -#endif /* not lint */ - -#include "rcv.h" -#include "extern.h" - -/* - * Mail -- a mail program - * - * Auxiliary functions. - */ - -/* - * Return a pointer to a dynamic copy of the argument. - */ -char * -savestr(str) - char *str; -{ - char *new; - int size = strlen(str) + 1; - - if ((new = salloc(size)) != NOSTR) - bcopy(str, new, size); - return new; -} - -/* - * Make a copy of new argument incorporating old one. - */ -char * -save2str(str, old) - char *str, *old; -{ - char *new; - int newsize = strlen(str) + 1; - int oldsize = old ? strlen(old) + 1 : 0; - - if ((new = salloc(newsize + oldsize)) != NOSTR) { - if (oldsize) { - bcopy(old, new, oldsize); - new[oldsize - 1] = ' '; - } - bcopy(str, new + oldsize, newsize); - } - return new; -} - -/* - * Announce a fatal error and die. - */ -#if __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif - -void -#if __STDC__ -panic(const char *fmt, ...) -#else -panic(fmt, va_alist) - char *fmt; - va_dcl -#endif -{ - va_list ap; -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - (void)fprintf(stderr, "panic: "); - vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - fflush(stderr); - abort(); -} - -/* - * Touch the named message by setting its MTOUCH flag. - * Touched messages have the effect of not being sent - * back to the system mailbox on exit. - */ -void -touch(mp) - register struct message *mp; -{ - - mp->m_flag |= MTOUCH; - if ((mp->m_flag & MREAD) == 0) - mp->m_flag |= MREAD|MSTATUS; -} - -/* - * Test to see if the passed file name is a directory. - * Return true if it is. - */ -int -isdir(name) - char name[]; -{ - struct stat sbuf; - - if (stat(name, &sbuf) < 0) - return(0); - return((sbuf.st_mode & S_IFMT) == S_IFDIR); -} - -/* - * Count the number of arguments in the given string raw list. - */ -int -argcount(argv) - char **argv; -{ - register char **ap; - - for (ap = argv; *ap++ != NOSTR;) - ; - return ap - argv - 1; -} - -/* - * Return the desired header line from the passed message - * pointer (or NOSTR if the desired header field is not available). - */ -char * -hfield(field, mp) - char field[]; - struct message *mp; -{ - register FILE *ibuf; - char linebuf[LINESIZE]; - register int lc; - register char *hfield; - char *colon, *oldhfield = NOSTR; - - ibuf = setinput(mp); - if ((lc = mp->m_lines - 1) < 0) - return NOSTR; - if (readline(ibuf, linebuf, LINESIZE) < 0) - return NOSTR; - while (lc > 0) { - if ((lc = gethfield(ibuf, linebuf, lc, &colon)) < 0) - return oldhfield; - if (hfield = ishfield(linebuf, colon, field)) - oldhfield = save2str(hfield, oldhfield); - } - return oldhfield; -} - -/* - * Return the next header field found in the given message. - * Return >= 0 if something found, < 0 elsewise. - * "colon" is set to point to the colon in the header. - * Must deal with \ continuations & other such fraud. - */ -int -gethfield(f, linebuf, rem, colon) - register FILE *f; - char linebuf[]; - register int rem; - char **colon; -{ - char line2[LINESIZE]; - register char *cp, *cp2; - register int c; - - for (;;) { - if (--rem < 0) - return -1; - if ((c = readline(f, linebuf, LINESIZE)) <= 0) - return -1; - for (cp = linebuf; isprint(*cp) && *cp != ' ' && *cp != ':'; - cp++) - ; - if (*cp != ':' || cp == linebuf) - continue; - /* - * I guess we got a headline. - * Handle wraparounding - */ - *colon = cp; - cp = linebuf + c; - for (;;) { - while (--cp >= linebuf && (*cp == ' ' || *cp == '\t')) - ; - cp++; - if (rem <= 0) - break; - ungetc(c = getc(f), f); - if (c != ' ' && c != '\t') - break; - if ((c = readline(f, line2, LINESIZE)) < 0) - break; - rem--; - for (cp2 = line2; *cp2 == ' ' || *cp2 == '\t'; cp2++) - ; - c -= cp2 - line2; - if (cp + c >= linebuf + LINESIZE - 2) - break; - *cp++ = ' '; - bcopy(cp2, cp, c); - cp += c; - } - *cp = 0; - return rem; - } - /* NOTREACHED */ -} - -/* - * Check whether the passed line is a header line of - * the desired breed. Return the field body, or 0. - */ - -char* -ishfield(linebuf, colon, field) - char linebuf[], field[]; - char *colon; -{ - register char *cp = colon; - - *cp = 0; - if (strcasecmp(linebuf, field) != 0) { - *cp = ':'; - return 0; - } - *cp = ':'; - for (cp++; *cp == ' ' || *cp == '\t'; cp++) - ; - return cp; -} - -/* - * Copy a string, lowercasing it as we go. - */ -void -istrcpy(dest, src) - register char *dest, *src; -{ - - do { - if (isupper(*src)) - *dest++ = tolower(*src); - else - *dest++ = *src; - } while (*src++ != 0); -} - -/* - * The following code deals with input stacking to do source - * commands. All but the current file pointer are saved on - * the stack. - */ - -static int ssp; /* Top of file stack */ -struct sstack { - FILE *s_file; /* File we were in. */ - int s_cond; /* Saved state of conditionals */ - int s_loading; /* Loading .mailrc, etc. */ -} sstack[NOFILE]; - -/* - * Pushdown current input file and switch to a new one. - * Set the global flag "sourcing" so that others will realize - * that they are no longer reading from a tty (in all probability). - */ -int -source(arglist) - char **arglist; -{ - FILE *fi; - char *cp; - - if ((cp = expand(*arglist)) == NOSTR) - return(1); - if ((fi = Fopen(cp, "r")) == NULL) { - perror(cp); - return(1); - } - if (ssp >= NOFILE - 1) { - printf("Too much \"sourcing\" going on.\n"); - Fclose(fi); - return(1); - } - sstack[ssp].s_file = input; - sstack[ssp].s_cond = cond; - sstack[ssp].s_loading = loading; - ssp++; - loading = 0; - cond = CANY; - input = fi; - sourcing++; - return(0); -} - -/* - * Pop the current input back to the previous level. - * Update the "sourcing" flag as appropriate. - */ -int -unstack() -{ - if (ssp <= 0) { - printf("\"Source\" stack over-pop.\n"); - sourcing = 0; - return(1); - } - Fclose(input); - if (cond != CANY) - printf("Unmatched \"if\"\n"); - ssp--; - cond = sstack[ssp].s_cond; - loading = sstack[ssp].s_loading; - input = sstack[ssp].s_file; - if (ssp == 0) - sourcing = loading; - return(0); -} - -/* - * Touch the indicated file. - * This is nifty for the shell. - */ -void -alter(name) - char *name; -{ - struct stat sb; - struct timeval tv[2]; - time_t time(); - - if (stat(name, &sb)) - return; - tv[0].tv_sec = time((time_t *)0) + 1; - tv[1].tv_sec = sb.st_mtime; - tv[0].tv_usec = tv[1].tv_usec = 0; - (void)utimes(name, tv); -} - -/* - * Examine the passed line buffer and - * return true if it is all blanks and tabs. - */ -int -blankline(linebuf) - char linebuf[]; -{ - register char *cp; - - for (cp = linebuf; *cp; cp++) - if (*cp != ' ' && *cp != '\t') - return(0); - return(1); -} - -/* - * Get sender's name from this message. If the message has - * a bunch of arpanet stuff in it, we may have to skin the name - * before returning it. - */ -char * -nameof(mp, reptype) - register struct message *mp; - int reptype; -{ - register char *cp, *cp2; - - cp = skin(name1(mp, reptype)); - if (reptype != 0 || charcount(cp, '!') < 2) - return(cp); - cp2 = rindex(cp, '!'); - cp2--; - while (cp2 > cp && *cp2 != '!') - cp2--; - if (*cp2 == '!') - return(cp2 + 1); - return(cp); -} - -/* - * Start of a "comment". - * Ignore it. - */ -char * -skip_comment(cp) - register char *cp; -{ - register nesting = 1; - - for (; nesting > 0 && *cp; cp++) { - switch (*cp) { - case '\\': - if (cp[1]) - cp++; - break; - case '(': - nesting++; - break; - case ')': - nesting--; - break; - } - } - return cp; -} - -/* - * Skin an arpa net address according to the RFC 822 interpretation - * of "host-phrase." - */ -char * -skin(name) - char *name; -{ - register int c; - register char *cp, *cp2; - char *bufend; - int gotlt, lastsp; - char nbuf[BUFSIZ]; - - if (name == NOSTR) - return(NOSTR); - if (index(name, '(') == NOSTR && index(name, '<') == NOSTR - && index(name, ' ') == NOSTR) - return(name); - gotlt = 0; - lastsp = 0; - bufend = nbuf; - for (cp = name, cp2 = bufend; c = *cp++; ) { - switch (c) { - case '(': - cp = skip_comment(cp); - lastsp = 0; - break; - - case '"': - /* - * Start of a "quoted-string". - * Copy it in its entirety. - */ - while (c = *cp) { - cp++; - if (c == '"') - break; - if (c != '\\') - *cp2++ = c; - else if (c = *cp) { - *cp2++ = c; - cp++; - } - } - lastsp = 0; - break; - - case ' ': - if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ') - cp += 3, *cp2++ = '@'; - else - if (cp[0] == '@' && cp[1] == ' ') - cp += 2, *cp2++ = '@'; - else - lastsp = 1; - break; - - case '<': - cp2 = bufend; - gotlt++; - lastsp = 0; - break; - - case '>': - if (gotlt) { - gotlt = 0; - while ((c = *cp) && c != ',') { - cp++; - if (c == '(') - cp = skip_comment(cp); - else if (c == '"') - while (c = *cp) { - cp++; - if (c == '"') - break; - if (c == '\\' && *cp) - cp++; - } - } - lastsp = 0; - break; - } - /* Fall into . . . */ - - default: - if (lastsp) { - lastsp = 0; - *cp2++ = ' '; - } - *cp2++ = c; - if (c == ',' && !gotlt) { - *cp2++ = ' '; - for (; *cp == ' '; cp++) - ; - lastsp = 0; - bufend = cp2; - } - } - } - *cp2 = 0; - - return(savestr(nbuf)); -} - -/* - * Fetch the sender's name from the passed message. - * Reptype can be - * 0 -- get sender's name for display purposes - * 1 -- get sender's name for reply - * 2 -- get sender's name for Reply - */ -char * -name1(mp, reptype) - register struct message *mp; - int reptype; -{ - char namebuf[LINESIZE]; - char linebuf[LINESIZE]; - register char *cp, *cp2; - register FILE *ibuf; - int first = 1; - - if ((cp = hfield("from", mp)) != NOSTR) - return cp; - if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR) - return cp; - ibuf = setinput(mp); - namebuf[0] = 0; - if (readline(ibuf, linebuf, LINESIZE) < 0) - return(savestr(namebuf)); -newname: - for (cp = linebuf; *cp && *cp != ' '; cp++) - ; - for (; *cp == ' ' || *cp == '\t'; cp++) - ; - for (cp2 = &namebuf[strlen(namebuf)]; - *cp && *cp != ' ' && *cp != '\t' && cp2 < namebuf + LINESIZE - 1;) - *cp2++ = *cp++; - *cp2 = '\0'; - if (readline(ibuf, linebuf, LINESIZE) < 0) - return(savestr(namebuf)); - if ((cp = index(linebuf, 'F')) == NULL) - return(savestr(namebuf)); - if (strncmp(cp, "From", 4) != 0) - return(savestr(namebuf)); - while ((cp = index(cp, 'r')) != NULL) { - if (strncmp(cp, "remote", 6) == 0) { - if ((cp = index(cp, 'f')) == NULL) - break; - if (strncmp(cp, "from", 4) != 0) - break; - if ((cp = index(cp, ' ')) == NULL) - break; - cp++; - if (first) { - strcpy(namebuf, cp); - first = 0; - } else - strcpy(rindex(namebuf, '!')+1, cp); - strcat(namebuf, "!"); - goto newname; - } - cp++; - } - return(savestr(namebuf)); -} - -/* - * Count the occurances of c in str - */ -int -charcount(str, c) - char *str; - int c; -{ - register char *cp; - register int i; - - for (i = 0, cp = str; *cp; cp++) - if (*cp == c) - i++; - return(i); -} - -/* - * Are any of the characters in the two strings the same? - */ -int -anyof(s1, s2) - register char *s1, *s2; -{ - - while (*s1) - if (index(s2, *s1++)) - return 1; - return 0; -} - -/* - * Convert c to upper case - */ -int -raise(c) - register int c; -{ - - if (islower(c)) - return toupper(c); - return c; -} - -/* - * Copy s1 to s2, return pointer to null in s2. - */ -char * -copy(s1, s2) - register char *s1, *s2; -{ - - while (*s2++ = *s1++) - ; - return s2 - 1; -} - -/* - * See if the given header field is supposed to be ignored. - */ -int -isign(field, ignore) - char *field; - struct ignoretab ignore[2]; -{ - char realfld[BUFSIZ]; - - if (ignore == ignoreall) - return 1; - /* - * Lower-case the string, so that "Status" and "status" - * will hash to the same place. - */ - istrcpy(realfld, field); - if (ignore[1].i_count > 0) - return (!member(realfld, ignore + 1)); - else - return (member(realfld, ignore)); -} - -int -member(realfield, table) - register char *realfield; - struct ignoretab *table; -{ - register struct ignore *igp; - - for (igp = table->i_head[hash(realfield)]; igp != 0; igp = igp->i_link) - if (*igp->i_field == *realfield && - equal(igp->i_field, realfield)) - return (1); - return (0); -} |