| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /*
- * 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}
- };
|