|
|
1.1 ! root 1: /* ! 2: * case-mapping stuff ! 3: * ! 4: * We exploit the fact that we are dealing only with headers here, and ! 5: * headers are limited to the ASCII characters by RFC822. It is barely ! 6: * possible that we might be dealing with a translation into another ! 7: * character set, but in particular it's very unlikely for a header ! 8: * character to be outside -128..255. ! 9: * ! 10: * Life would be a whole lot simpler if tolower() could safely and portably ! 11: * be applied to any char. ! 12: */ ! 13: #include <stdio.h> ! 14: #include "string.h" ! 15: #include "case.h" ! 16: ! 17: /* note that case.h knows the value of OFFSET */ ! 18: #define OFFSET 128 /* avoid trouble with negative chars */ ! 19: #define MAPSIZE (256+OFFSET) ! 20: char casemap[MAPSIZE]; /* relies on init to '\0' */ ! 21: static int primed = 0; /* has casemap been set up? */ ! 22: ! 23: /* ! 24: - prime - set up case-mapping stuff ! 25: */ ! 26: static void ! 27: prime() ! 28: { ! 29: register char *lp; ! 30: register char *up; ! 31: register int c; ! 32: register int i; ! 33: static char lower[] = "abcdefghijklmnopqrstuvwxyz"; ! 34: static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; ! 35: ! 36: for (lp = lower, up = upper; *lp != '\0'; lp++, up++) { ! 37: c = *lp; ! 38: casemap[c+OFFSET] = c; ! 39: casemap[*up+OFFSET] = c; ! 40: } ! 41: for (i = 0; i < MAPSIZE; i++) ! 42: if (casemap[i] == '\0') ! 43: casemap[i] = (char)(i-OFFSET); ! 44: primed = 1; ! 45: } ! 46: ! 47: /* ! 48: - cistrncmp - case-independent strncmp ! 49: */ ! 50: int /* < == > 0 */ ! 51: cistrncmp(s1, s2, len) ! 52: char *s1; ! 53: char *s2; ! 54: int len; ! 55: { ! 56: register char *p1; ! 57: register char *p2; ! 58: register int n; ! 59: ! 60: if (!primed) ! 61: prime(); ! 62: ! 63: p1 = s1; ! 64: p2 = s2; ! 65: n = len; ! 66: while (--n >= 0 && *p1 != '\0' && TOLOW(*p1) == TOLOW(*p2)) { ! 67: p1++; ! 68: p2++; ! 69: } ! 70: if (n < 0) ! 71: return(0); ! 72: ! 73: /* ! 74: * The following case analysis is necessary so that characters ! 75: * which look negative collate low against normal characters but ! 76: * high against the end-of-string NUL. ! 77: */ ! 78: if (*p1 == '\0' && *p2 == '\0') ! 79: return(0); ! 80: else if (*p1 == '\0') ! 81: return(-1); ! 82: else if (*p2 == '\0') ! 83: return(1); ! 84: else ! 85: return(TOLOW(*p1) - TOLOW(*p2)); ! 86: } ! 87: ! 88: /* ! 89: - rfc822ize - do the bizarre case conversion needed for rfc822 message-ids ! 90: * ! 91: * Actually, this is not quite complete. Absolute, total, full RFC822 ! 92: * compliance requires a horrible parsing job, because of the arcane ! 93: * quoting conventions -- abc"def"ghi is not equivalent to abc"DEF"ghi, ! 94: * for example. There are three or four things that might occur in the ! 95: * domain part of a message-id that are case-sensitive. They don't seem ! 96: * to ever occur in real news, thank Cthulhu. (What? You were expecting ! 97: * a merciful and forgiving deity to be invoked in connection with RFC822? ! 98: * Forget it; none of them would come near it.) ! 99: */ ! 100: char * /* returns the argument */ ! 101: rfc822ize(s) ! 102: char *s; ! 103: { ! 104: register char *p; ! 105: static char post[] = "postmaster"; ! 106: static int postlen = sizeof(post)-1; ! 107: ! 108: if (!primed) ! 109: prime(); ! 110: ! 111: p = strrchr(s, '@'); ! 112: if (p == NULL) /* no local/domain split */ ! 113: p = ""; /* assume all local */ ! 114: else if (p - (s+1) == postlen && CISTREQN(s+1, post, postlen)) { ! 115: /* crazy special case -- "postmaster" is case-insensitive */ ! 116: p = s; ! 117: } ! 118: #ifdef NONSTANDARD ! 119: #ifdef RFCVIOLATION ! 120: #ifdef B_2_11_MISTAKE ! 121: p = s; /* all case-insensitive */ ! 122: #endif ! 123: #endif ! 124: #endif ! 125: for (; *p != '\0'; p++) ! 126: *p = TOLOW(*p); ! 127: ! 128: return(s); ! 129: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.