00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: ircmasks.c,v 1.15 2005-05-15 17:34:23 stdarg Exp $";
00022 #endif
00023
00024 #include <eggdrop/eggdrop.h>
00025
00026 static int compute_hash(const char *str, int *hash1, int *hash2);
00027
00028 int ircmask_list_clear(ircmask_list_t *list)
00029 {
00030 ircmask_list_entry_t *entry, *next;
00031
00032 if (list == NULL) return -1;
00033
00034 for (entry = list->head; entry; ) {
00035 next = entry->next;
00036
00037 free(entry->ircmask);
00038 free(entry);
00039
00040 entry = next;
00041 }
00042
00043 return (0);
00044 }
00045
00046 int ircmask_list_add(ircmask_list_t *list, const char *ircmask, void *data)
00047 {
00048 int i, stars, len;
00049 ircmask_list_entry_t *entry, *prev;
00050
00051 stars = 0;
00052 len = strlen(ircmask);
00053 for (i = 0; i < len; i++) {
00054 if (ircmask[i] == '*') stars++;
00055 }
00056 len -= stars;
00057 prev = NULL;
00058 for (entry = list->head; entry; entry = entry->next) {
00059 if (len >= entry->len) break;
00060 prev = entry;
00061 }
00062 entry = malloc(sizeof(*entry));
00063 entry->ircmask = strdup(ircmask);
00064 entry->len = len;
00065 entry->data = data;
00066 compute_hash(ircmask, &entry->hash1, &entry->hash2);
00067 if (prev) {
00068 entry->next = prev->next;
00069 prev->next = entry;
00070 }
00071 else {
00072 entry->next = list->head;
00073 list->head = entry;
00074 }
00075 return(0);
00076 }
00077
00078 int ircmask_list_del(ircmask_list_t *list, const char *ircmask, void *data)
00079 {
00080 ircmask_list_entry_t *entry, *prev;
00081
00082 prev = NULL;
00083 for (entry = list->head; entry; entry = entry->next) {
00084 if (!strcasecmp(ircmask, entry->ircmask)) break;
00085 prev = entry;
00086 }
00087 if (entry) {
00088 if (prev) prev->next = entry->next;
00089 else list->head = entry->next;
00090 free(entry->ircmask);
00091 free(entry);
00092 }
00093 return(0);
00094 }
00095
00096 int ircmask_list_find(ircmask_list_t *list, const char *irchost, void *dataptr)
00097 {
00098 ircmask_list_entry_t *entry;
00099 int hash1, hash2;
00100
00101 compute_hash(irchost, &hash1, &hash2);
00102 for (entry = list->head; entry; entry = entry->next) {
00103 if ((entry->hash1 & hash1) != entry->hash1 || (entry->hash2 & hash2) != entry->hash2) {
00104 continue;
00105 }
00106 if (wild_match(entry->ircmask, irchost) > 0) {
00107 *(void **)dataptr = entry->data;
00108 return(0);
00109 }
00110 }
00111 *(void **)dataptr = NULL;
00112 return(-1);
00113 }
00114
00115
00116 char *ircmask_create_separate(int type, const char *nick, const char *user, const char *host)
00117 {
00118 char *mask;
00119 char ustar[2] = {0, 0};
00120 char *domain;
00121
00122
00123
00124
00125
00126
00127
00128
00129 if (type < 5) nick = "*";
00130 if (type == 2 || type == 4 || type == 7 || type == 9) user = "*";
00131 else if (type == 1 || type == 3 || type == 6 || type == 8) {
00132 while (*user && !isalnum(*user)) user++;
00133 ustar[0] = '*';
00134 }
00135 else {
00136 user = "";
00137 ustar[0] = '*';
00138 }
00139
00140 domain = strdup(host);
00141 if (type == 3 || type == 4 || type == 8 || type == 9) {
00142 char *dot = strrchr(host, '.');
00143 char *colon = strrchr(host, ':');
00144 if (colon || (dot && isdigit(*(dot+1)))) {
00145
00146 if (dot < colon) dot = colon;
00147 domain[host-dot+1] = '*';
00148 domain[host-dot+2] = 0;
00149 }
00150 else if (dot) {
00151 char *dot2;
00152 dot = strchr(host, '.');
00153 if ((dot2 = strchr(dot+1, '.'))) {
00154 if (strlen(dot2+1) > 2) {
00155 free(domain);
00156 domain = egg_mprintf("*%s", dot);
00157 }
00158 }
00159 }
00160 }
00161 mask = egg_mprintf("%s!%s%s@%s", nick, ustar, user, domain);
00162 free(domain);
00163
00164
00165
00166
00167
00168
00169
00170
00171 return(mask);
00172 }
00173
00174 char *ircmask_create(int type, const char *nick, const char *uhost)
00175 {
00176 char *user = strdup(uhost);
00177 char *at = strchr(uhost, '@');
00178 char *mask;
00179
00180 if (at) {
00181 user[at-uhost] = 0;
00182 uhost = at+1;
00183 }
00184 else user[0] = 0;
00185 mask = ircmask_create_separate(type, nick, user, uhost);
00186 free(user);
00187 return(mask);
00188 }
00189
00190 char *ircmask_create_full(int type, const char *nuhost)
00191 {
00192 char *nick, *user, *host, *buf, *mask;
00193
00194 buf = strdup(nuhost);
00195 nick = buf;
00196 user = strchr(nick, '!');
00197 if (user) *user++ = 0;
00198 else user = "";
00199 host = strchr(user, '@');
00200 if (host) *host++ = 0;
00201 else host = "";
00202 mask = ircmask_create_separate(type, nick, user, host);
00203 free(buf);
00204 return(mask);
00205 }
00206
00207 static int compute_hash(const char *str, int *hash1, int *hash2)
00208 {
00209 unsigned int pair;
00210 int last = 0;
00211
00212 *hash1 = *hash2 = 0;
00213 for (; *str; str++) {
00214 if (*str == '*' || *str == '?') {
00215 last = -1;
00216 continue;
00217 }
00218 if (last != -1) {
00219 pair = (last * 71317 + ((unsigned)tolower(*str)) * 1937) % 64;
00220 if (pair > 31) *hash2 |= 1 << (pair-32);
00221 else *hash1 |= 1 << pair;
00222 }
00223 last = (unsigned) tolower(*str);
00224 }
00225 if (last > 0) {
00226 pair = (last * 3133719) % 64;
00227 if (pair > 31) *hash2 |= 1 << (pair-32);
00228 else *hash1 |= 1 << pair;
00229 }
00230 return(0);
00231 }