|
|
@@ -1,303 +0,0 @@
|
|
|
-/*
|
|
|
- * uf_features.c -- part of share.mod
|
|
|
- *
|
|
|
- */
|
|
|
-/*
|
|
|
- * Userfile feature protocol description:
|
|
|
- *
|
|
|
- *
|
|
|
- * LEAF HUB
|
|
|
- *
|
|
|
- * uf_features_dump():
|
|
|
- * Finds out which features
|
|
|
- * it supports / wants to use
|
|
|
- * and then dumps those. The
|
|
|
- * list is appended to the
|
|
|
- * user file send ack.
|
|
|
- *
|
|
|
- * "s uy <features>" --+
|
|
|
- * |
|
|
|
- * +--> uf_features_parse():
|
|
|
- * Parses the given list of features,
|
|
|
- * given in a string, seperated with
|
|
|
- * spaces. Decides which features to
|
|
|
- * accept/use. Those features are then
|
|
|
- * locally set:
|
|
|
- *
|
|
|
- * dcc[idx].u.bot->uff_flags |= <feature_flag>
|
|
|
- *
|
|
|
- * and sent back to the LEAF:
|
|
|
- *
|
|
|
- * +--- "s feats <accepted_features>"
|
|
|
- * |
|
|
|
- * uf_features_check(): <--+
|
|
|
- * Checks wether the responded
|
|
|
- * features are still accepted
|
|
|
- * by us. If they are, we set
|
|
|
- * the flags locally:
|
|
|
- *
|
|
|
- * dcc[idx].u.bot->uff_flags |= <feature_flag>
|
|
|
- */
|
|
|
-
|
|
|
-
|
|
|
-typedef struct uff_list_struct {
|
|
|
- struct uff_list_struct *next; /* Pointer to next entry */
|
|
|
- struct uff_list_struct *prev; /* Pointer to previous entry */
|
|
|
- uff_table_t *entry; /* Pointer to entry in table. This is
|
|
|
- not copied or anything, we just refer
|
|
|
- to the original table entry. */
|
|
|
-} uff_list_t;
|
|
|
-
|
|
|
-typedef struct {
|
|
|
- uff_list_t *start;
|
|
|
- uff_list_t *end;
|
|
|
-} uff_head_t;
|
|
|
-
|
|
|
-static uff_head_t uff_list;
|
|
|
-static char uff_sbuf[512] = "";
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Userfile features management functions
|
|
|
- */
|
|
|
-
|
|
|
-static void uff_init(void)
|
|
|
-{
|
|
|
- egg_bzero(&uff_list, sizeof(uff_head_t));
|
|
|
-}
|
|
|
-
|
|
|
-/* Search for a feature in the uff feature list that matches a supplied
|
|
|
- * feature flag. Returns a pointer to the entry in the list or NULL if
|
|
|
- * no feature uses the flag.
|
|
|
- */
|
|
|
-static uff_list_t *uff_findentry_byflag(int flag)
|
|
|
-{
|
|
|
- uff_list_t *ul = NULL;
|
|
|
-
|
|
|
- for (ul = uff_list.start; ul; ul = ul->next)
|
|
|
- if (ul->entry->flag & flag)
|
|
|
- return ul;
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-/* Search for a feature in the uff feature list. Returns a pointer to the
|
|
|
- * entry in the list or NULL if no such feature exists.
|
|
|
- */
|
|
|
-static uff_list_t *uff_findentry_byname(char *feature)
|
|
|
-{
|
|
|
- uff_list_t *ul = NULL;
|
|
|
-
|
|
|
- for (ul = uff_list.start; ul; ul = ul->next)
|
|
|
- if (!strcmp(ul->entry->feature, feature))
|
|
|
- return ul;
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-/* Insert entry into sorted list.
|
|
|
- */
|
|
|
-static void uff_insert_entry(uff_list_t *nul)
|
|
|
-{
|
|
|
- uff_list_t *ul = NULL, *lul = NULL;
|
|
|
-
|
|
|
- ul = uff_list.start;
|
|
|
- while (ul && ul->entry->priority < nul->entry->priority) {
|
|
|
- lul = ul;
|
|
|
- ul = ul->next;
|
|
|
- }
|
|
|
-
|
|
|
- nul->prev = NULL;
|
|
|
- nul->next = NULL;
|
|
|
- if (lul) {
|
|
|
- if (lul->next)
|
|
|
- lul->next->prev = nul;
|
|
|
- nul->next = lul->next;
|
|
|
- nul->prev = lul;
|
|
|
- lul->next = nul;
|
|
|
- } else if (ul) {
|
|
|
- uff_list.start->prev = nul;
|
|
|
- nul->next = uff_list.start;
|
|
|
- uff_list.start = nul;
|
|
|
- } else
|
|
|
- uff_list.start = nul;
|
|
|
- if (!nul->next)
|
|
|
- uff_list.end = nul;
|
|
|
-}
|
|
|
-
|
|
|
-/* Add a single feature to the list.
|
|
|
- */
|
|
|
-static void uff_addfeature(uff_table_t *ut)
|
|
|
-{
|
|
|
- uff_list_t *ul = NULL;
|
|
|
-
|
|
|
- if (uff_findentry_byname(ut->feature)) {
|
|
|
- putlog(LOG_MISC, "*", "(!) share: same feature name used twice: %s", ut->feature);
|
|
|
- return;
|
|
|
- }
|
|
|
- ul = uff_findentry_byflag(ut->flag);
|
|
|
- if (ul) {
|
|
|
- putlog(LOG_MISC, "*", "(!) share: feature flag %d used twice by %s and %s", ut->flag, ut->feature, ul->entry->feature);
|
|
|
- return;
|
|
|
- }
|
|
|
- ul = calloc(1, sizeof(uff_list_t));
|
|
|
- ul->entry = ut;
|
|
|
- uff_insert_entry(ul);
|
|
|
-}
|
|
|
-
|
|
|
-/* Add a complete table to the list.
|
|
|
- */
|
|
|
-void uff_addtable(uff_table_t *ut)
|
|
|
-{
|
|
|
- if (!ut)
|
|
|
- return;
|
|
|
- for (; ut->feature; ++ut)
|
|
|
- uff_addfeature(ut);
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Userfile feature parsing functions
|
|
|
- */
|
|
|
-
|
|
|
-#ifdef HUB
|
|
|
-/* Parse the given features string, set internal flags apropriately and
|
|
|
- * eventually respond with all features we will use.
|
|
|
- */
|
|
|
-static void uf_features_parse(int idx, char *par)
|
|
|
-{
|
|
|
- char *buf = NULL, *s = NULL, *p = NULL;
|
|
|
- uff_list_t *ul = NULL;
|
|
|
-
|
|
|
- uff_sbuf[0] = 0; /* Reset static buffer */
|
|
|
- p = s = buf = strdup(par);
|
|
|
-
|
|
|
- /* Clear all currently set features. */
|
|
|
- dcc[idx].u.bot->uff_flags = 0;
|
|
|
-
|
|
|
- /* Parse string */
|
|
|
- while ((s = strchr(s, ' ')) != NULL) {
|
|
|
- *s = '\0';
|
|
|
-
|
|
|
- /* Is the feature available and active? */
|
|
|
- ul = uff_findentry_byname(p);
|
|
|
- if (ul && (ul->entry->ask_func == NULL || ul->entry->ask_func(idx))) {
|
|
|
- dcc[idx].u.bot->uff_flags |= ul->entry->flag; /* Set flag */
|
|
|
- strcat(uff_sbuf, ul->entry->feature); /* Add feature to list */
|
|
|
- strcat(uff_sbuf, " ");
|
|
|
- }
|
|
|
- p = ++s;
|
|
|
- }
|
|
|
- free(buf);
|
|
|
-
|
|
|
- /* Send response string */
|
|
|
- if (uff_sbuf[0])
|
|
|
- dprintf(idx, "s feats %s\n", uff_sbuf);
|
|
|
-}
|
|
|
-#endif /* HUB */
|
|
|
-
|
|
|
-/* Return a list of features we are supporting.
|
|
|
- */
|
|
|
-static char *uf_features_dump(int idx)
|
|
|
-{
|
|
|
- uff_list_t *ul = NULL;
|
|
|
-
|
|
|
- uff_sbuf[0] = 0;
|
|
|
- for (ul = uff_list.start; ul; ul = ul->next)
|
|
|
- if (ul->entry->ask_func == NULL || ul->entry->ask_func(idx)) {
|
|
|
- strcat(uff_sbuf, ul->entry->feature); /* Add feature to list */
|
|
|
- strcat(uff_sbuf, " ");
|
|
|
- }
|
|
|
- return uff_sbuf;
|
|
|
-}
|
|
|
-
|
|
|
-static int uf_features_check(int idx, char *par)
|
|
|
-{
|
|
|
- char *buf = NULL, *s = NULL, *p = NULL;
|
|
|
- uff_list_t *ul = NULL;
|
|
|
-
|
|
|
- uff_sbuf[0] = 0; /* Reset static buffer */
|
|
|
- p = s = buf = strdup(par);
|
|
|
-
|
|
|
- /* Clear all currently set features. */
|
|
|
- dcc[idx].u.bot->uff_flags = 0;
|
|
|
-
|
|
|
- /* Parse string */
|
|
|
- while ((s = strchr(s, ' ')) != NULL) {
|
|
|
- *s = '\0';
|
|
|
-
|
|
|
- /* Is the feature available and active? */
|
|
|
- ul = uff_findentry_byname(p);
|
|
|
- if (ul && (ul->entry->ask_func == NULL || ul->entry->ask_func(idx)))
|
|
|
- dcc[idx].u.bot->uff_flags |= ul->entry->flag; /* Set flag */
|
|
|
- else {
|
|
|
- /* It isn't, and our hub wants to use it! This either happens
|
|
|
- * because the hub doesn't look at the features we suggested to
|
|
|
- * use or because our admin changed the flags, so that formerly
|
|
|
- * active features are now deactivated.
|
|
|
- *
|
|
|
- * In any case, we abort user file sharing.
|
|
|
- */
|
|
|
- putlog(LOG_BOTS, "*", "Bot %s tried unsupported feature!", dcc[idx].nick);
|
|
|
- dprintf(idx, "s e Attempt to use an unsupported feature\n");
|
|
|
- zapfbot(idx);
|
|
|
-
|
|
|
- free(buf);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- p = ++s;
|
|
|
- }
|
|
|
- free(buf);
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-#ifdef HUB
|
|
|
-/* Call all active feature functions, sorted by their priority. This
|
|
|
- * should be called when we're about to send a user file.
|
|
|
- */
|
|
|
-static int uff_call_sending(int idx, char *user_file)
|
|
|
-{
|
|
|
- uff_list_t *ul = NULL;
|
|
|
-
|
|
|
- for (ul = uff_list.start; ul; ul = ul->next)
|
|
|
- if (ul->entry && ul->entry->snd &&
|
|
|
- (dcc[idx].u.bot->uff_flags & ul->entry->flag))
|
|
|
- if (!(ul->entry->snd(idx, user_file)))
|
|
|
- return 0; /* Failed! */
|
|
|
- return 1;
|
|
|
-}
|
|
|
-#endif /* HUB */
|
|
|
-
|
|
|
-/* Call all active feature functions, sorted by their priority. This
|
|
|
- * should be called when we've received a user file and are about to
|
|
|
- * parse it.
|
|
|
- */
|
|
|
-static int uff_call_receiving(int idx, char *user_file)
|
|
|
-{
|
|
|
- uff_list_t *ul = NULL;
|
|
|
-
|
|
|
- for (ul = uff_list.end; ul; ul = ul->prev)
|
|
|
- if (ul->entry && ul->entry->rcv &&
|
|
|
- (dcc[idx].u.bot->uff_flags & ul->entry->flag))
|
|
|
- if (!(ul->entry->rcv(idx, user_file)))
|
|
|
- return 0; /* Failed! */
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Userfile feature handlers
|
|
|
- */
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
- * Internal user file feature table
|
|
|
- */
|
|
|
-
|
|
|
-int
|
|
|
-blah() {
|
|
|
- return 1;
|
|
|
-}
|
|
|
-static uff_table_t internal_uff_table[] = {
|
|
|
- {"overbots", UFF_OVERRIDE, blah, 0, NULL, NULL},
|
|
|
- {"invites", UFF_INVITE, NULL, 0, NULL, NULL},
|
|
|
- {"exempts", UFF_EXEMPT, NULL, 0, NULL, NULL},
|
|
|
- {NULL, 0, NULL, 0, NULL, NULL}
|
|
|
-};
|