00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 typedef struct uff_list_struct {
00063 struct uff_list_struct *next;
00064 struct uff_list_struct *prev;
00065 uff_table_t *entry;
00066
00067
00068 } uff_list_t;
00069
00070 typedef struct {
00071 uff_list_t *start;
00072 uff_list_t *end;
00073 } uff_head_t;
00074
00075 static uff_head_t uff_list;
00076 static char uff_sbuf[512];
00077
00078
00079
00080
00081
00082
00083 static void uff_init(void)
00084 {
00085 egg_bzero(&uff_list, sizeof(uff_head_t));
00086 }
00087
00088
00089
00090 static int uff_expmem(void)
00091 {
00092 uff_list_t *ul;
00093 int tot = 0;
00094
00095 for (ul = uff_list.start; ul; ul = ul->next)
00096 tot += sizeof(uff_list_t);
00097 return tot;
00098 }
00099
00100
00101
00102
00103
00104 static uff_list_t *uff_findentry_byflag(int flag)
00105 {
00106 uff_list_t *ul;
00107
00108 for (ul = uff_list.start; ul; ul = ul->next)
00109 if (ul->entry->flag & flag)
00110 return ul;
00111 return NULL;
00112 }
00113
00114
00115
00116
00117 static uff_list_t *uff_findentry_byname(char *feature)
00118 {
00119 uff_list_t *ul;
00120
00121 for (ul = uff_list.start; ul; ul = ul->next)
00122 if (!strcmp(ul->entry->feature, feature))
00123 return ul;
00124 return NULL;
00125 }
00126
00127
00128
00129 static void uff_insert_entry(uff_list_t *nul)
00130 {
00131 uff_list_t *ul, *lul = NULL;
00132
00133 ul = uff_list.start;
00134 while (ul && ul->entry->priority < nul->entry->priority) {
00135 lul = ul;
00136 ul = ul->next;
00137 }
00138
00139 nul->prev = NULL;
00140 nul->next = NULL;
00141 if (lul) {
00142 if (lul->next)
00143 lul->next->prev = nul;
00144 nul->next = lul->next;
00145 nul->prev = lul;
00146 lul->next = nul;
00147 } else if (ul) {
00148 uff_list.start->prev = nul;
00149 nul->next = uff_list.start;
00150 uff_list.start = nul;
00151 } else
00152 uff_list.start = nul;
00153 if (!nul->next)
00154 uff_list.end = nul;
00155 }
00156
00157
00158
00159 static void uff_remove_entry(uff_list_t *ul)
00160 {
00161 if (!ul->next)
00162 uff_list.end = ul->prev;
00163 else
00164 ul->next->prev = ul->prev;
00165 if (!ul->prev)
00166 uff_list.start = ul->next;
00167 else
00168 ul->prev->next = ul->next;
00169 }
00170
00171
00172
00173 static void uff_addfeature(uff_table_t *ut)
00174 {
00175 uff_list_t *ul;
00176
00177 if (uff_findentry_byname(ut->feature)) {
00178 putlog(LOG_MISC, "*", "(!) share: same feature name used twice: %s",
00179 ut->feature);
00180 return;
00181 }
00182 ul = uff_findentry_byflag(ut->flag);
00183 if (ul) {
00184 putlog(LOG_MISC, "*", "(!) share: feature flag %d used twice by %s and %s",
00185 ut->flag, ut->feature, ul->entry->feature);
00186 return;
00187 }
00188 ul = nmalloc(sizeof(uff_list_t));
00189 ul->entry = ut;
00190 uff_insert_entry(ul);
00191 }
00192
00193
00194
00195 static void uff_addtable(uff_table_t *ut)
00196 {
00197 if (!ut)
00198 return;
00199 for (; ut->feature; ++ut)
00200 uff_addfeature(ut);
00201 }
00202
00203
00204
00205 static int uff_delfeature(uff_table_t *ut)
00206 {
00207 uff_list_t *ul;
00208
00209 for (ul = uff_list.start; ul; ul = ul->next)
00210 if (!strcmp(ul->entry->feature, ut->feature)) {
00211 uff_remove_entry(ul);
00212 nfree(ul);
00213 return 1;
00214 }
00215 return 0;
00216 }
00217
00218
00219
00220 static void uff_deltable(uff_table_t *ut)
00221 {
00222 if (!ut)
00223 return;
00224 for (; ut->feature; ++ut)
00225 (int) uff_delfeature(ut);
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 static void uf_features_parse(int idx, char *par)
00237 {
00238 char *buf, *s, *p;
00239 uff_list_t *ul;
00240
00241 uff_sbuf[0] = 0;
00242 p = s = buf = nmalloc(strlen(par) + 1);
00243 strcpy(buf, par);
00244
00245
00246 dcc[idx].u.bot->uff_flags = 0;
00247
00248
00249 while ((s = strchr(s, ' ')) != NULL) {
00250 *s = '\0';
00251
00252
00253 ul = uff_findentry_byname(p);
00254 if (ul && (ul->entry->ask_func == NULL || ul->entry->ask_func(idx))) {
00255 dcc[idx].u.bot->uff_flags |= ul->entry->flag;
00256 strcat(uff_sbuf, ul->entry->feature);
00257 strcat(uff_sbuf, " ");
00258 }
00259 p = ++s;
00260 }
00261 nfree(buf);
00262
00263
00264 if (uff_sbuf[0])
00265 dprintf(idx, "s feats %s\n", uff_sbuf);
00266 }
00267
00268
00269
00270 static char *uf_features_dump(int idx)
00271 {
00272 uff_list_t *ul;
00273
00274 uff_sbuf[0] = 0;
00275 for (ul = uff_list.start; ul; ul = ul->next)
00276 if (ul->entry->ask_func == NULL || ul->entry->ask_func(idx)) {
00277 strcat(uff_sbuf, ul->entry->feature);
00278 strcat(uff_sbuf, " ");
00279 }
00280 return uff_sbuf;
00281 }
00282
00283 static int uf_features_check(int idx, char *par)
00284 {
00285 char *buf, *s, *p;
00286 uff_list_t *ul;
00287
00288 uff_sbuf[0] = 0;
00289 p = s = buf = nmalloc(strlen(par) + 1);
00290 strcpy(buf, par);
00291
00292
00293 dcc[idx].u.bot->uff_flags = 0;
00294
00295
00296 while ((s = strchr(s, ' ')) != NULL) {
00297 *s = '\0';
00298
00299
00300 ul = uff_findentry_byname(p);
00301 if (ul && (ul->entry->ask_func == NULL || ul->entry->ask_func(idx)))
00302 dcc[idx].u.bot->uff_flags |= ul->entry->flag;
00303 else {
00304
00305
00306
00307
00308
00309
00310
00311 putlog(LOG_BOTS, "*", "Bot %s tried unsupported feature!", dcc[idx].nick);
00312 dprintf(idx, "s e Attempt to use an unsupported feature\n");
00313 zapfbot(idx);
00314
00315 nfree(buf);
00316 return 0;
00317 }
00318 p = ++s;
00319 }
00320 nfree(buf);
00321 return 1;
00322 }
00323
00324
00325
00326
00327 static int uff_call_sending(int idx, char *user_file)
00328 {
00329 uff_list_t *ul;
00330
00331 for (ul = uff_list.start; ul; ul = ul->next)
00332 if (ul->entry && ul->entry->snd &&
00333 (dcc[idx].u.bot->uff_flags & ul->entry->flag))
00334 if (!(ul->entry->snd(idx, user_file)))
00335 return 0;
00336 return 1;
00337 }
00338
00339
00340
00341
00342
00343 static int uff_call_receiving(int idx, char *user_file)
00344 {
00345 uff_list_t *ul;
00346
00347 for (ul = uff_list.end; ul; ul = ul->prev)
00348 if (ul->entry && ul->entry->rcv &&
00349 (dcc[idx].u.bot->uff_flags & ul->entry->flag))
00350 if (!(ul->entry->rcv(idx, user_file)))
00351 return 0;
00352 return 1;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 static int uff_ask_override_bots(int idx)
00365 {
00366 if (overr_local_bots)
00367 return 1;
00368 else
00369 return 0;
00370 }
00371
00372
00373
00374
00375
00376
00377 static uff_table_t internal_uff_table[] = {
00378 {"overbots", UFF_OVERRIDE, uff_ask_override_bots, 0, NULL, NULL},
00379 {"invites", UFF_INVITE, NULL, 0, NULL, NULL},
00380 {"exempts", UFF_EXEMPT, NULL, 0, NULL, NULL},
00381 {NULL, 0, NULL, 0, NULL, NULL}
00382 };