/* * case-mapping stuff * * We exploit the fact that we are dealing only with headers here, and * headers are limited to the ASCII characters by RFC822. It is barely * possible that we might be dealing with a translation into another * character set, but in particular it's very unlikely for a header * character to be outside -128..255. * * Life would be a whole lot simpler if tolower() could safely and portably * be applied to any char. */ #include #include "string.h" #include "case.h" /* note that case.h knows the value of OFFSET */ #define OFFSET 128 /* avoid trouble with negative chars */ #define MAPSIZE (256+OFFSET) char casemap[MAPSIZE]; /* relies on init to '\0' */ static int primed = 0; /* has casemap been set up? */ /* - prime - set up case-mapping stuff */ static void prime() { register char *lp; register char *up; register int c; register int i; static char lower[] = "abcdefghijklmnopqrstuvwxyz"; static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for (lp = lower, up = upper; *lp != '\0'; lp++, up++) { c = *lp; casemap[c+OFFSET] = c; casemap[*up+OFFSET] = c; } for (i = 0; i < MAPSIZE; i++) if (casemap[i] == '\0') casemap[i] = (char)(i-OFFSET); primed = 1; } /* - cistrncmp - case-independent strncmp */ int /* < == > 0 */ cistrncmp(s1, s2, len) char *s1; char *s2; int len; { register char *p1; register char *p2; register int n; if (!primed) prime(); p1 = s1; p2 = s2; n = len; while (--n >= 0 && *p1 != '\0' && TOLOW(*p1) == TOLOW(*p2)) { p1++; p2++; } if (n < 0) return(0); /* * The following case analysis is necessary so that characters * which look negative collate low against normal characters but * high against the end-of-string NUL. */ if (*p1 == '\0' && *p2 == '\0') return(0); else if (*p1 == '\0') return(-1); else if (*p2 == '\0') return(1); else return(TOLOW(*p1) - TOLOW(*p2)); } /* - rfc822ize - do the bizarre case conversion needed for rfc822 message-ids * * Actually, this is not quite complete. Absolute, total, full RFC822 * compliance requires a horrible parsing job, because of the arcane * quoting conventions -- abc"def"ghi is not equivalent to abc"DEF"ghi, * for example. There are three or four things that might occur in the * domain part of a message-id that are case-sensitive. They don't seem * to ever occur in real news, thank Cthulhu. (What? You were expecting * a merciful and forgiving deity to be invoked in connection with RFC822? * Forget it; none of them would come near it.) */ char * /* returns the argument */ rfc822ize(s) char *s; { register char *p; static char post[] = "postmaster"; static int postlen = sizeof(post)-1; if (!primed) prime(); p = strrchr(s, '@'); if (p == NULL) /* no local/domain split */ p = ""; /* assume all local */ else if (p - (s+1) == postlen && CISTREQN(s+1, post, postlen)) { /* crazy special case -- "postmaster" is case-insensitive */ p = s; } #ifdef NONSTANDARD #ifdef RFCVIOLATION #ifdef B_2_11_MISTAKE p = s; /* all case-insensitive */ #endif #endif #endif for (; *p != '\0'; p++) *p = TOLOW(*p); return(s); }