|
|
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.