/** * Synchronize invite, ban, except, and G-Line lists between servers. * * @param Client New server. * @return CONNECTED or DISCONNECTED. */ static bool Synchronize_Lists(CLIENT * Client) { CHANNEL *c; struct list_head *head; struct list_elem *elem; time_t t; assert(Client != NULL); /* g-lines */ head = Class_GetList(CLASS_GLINE); elem = Lists_GetFirst(head); while (elem) { t = Lists_GetValidity(elem) - time(NULL); if (!IRC_WriteStrClient(Client, "GLINE %s %ld :%s", Lists_GetMask(elem), t > 0 ? (long)t : 0, Lists_GetReason(elem))) return DISCONNECTED; elem = Lists_GetNext(elem); } c = Channel_First(); while (c) { if (!Send_List(Client, c, Channel_GetListExcepts(c), 'e')) return DISCONNECTED; if (!Send_List(Client, c, Channel_GetListBans(c), 'b')) return DISCONNECTED; if (!Send_List(Client, c, Channel_GetListInvites(c), 'I')) return DISCONNECTED; c = Channel_Next(c); } return CONNECTED; }
/** * Send a specific list to a remote server. */ static bool Send_List(CLIENT *Client, CHANNEL *Chan, struct list_head *Head, char Type) { struct list_elem *elem; elem = Lists_GetFirst(Head); while (elem) { if (!IRC_WriteStrClient(Client, "MODE %s +%c %s", Channel_Name(Chan), Type, Lists_GetMask(elem))) { return DISCONNECTED; } elem = Lists_GetNext(elem); } return CONNECTED; }
/** * Add a new mask to a list. * * @param h List head. * @param Mask The IRC mask to add to the list. * @param ValidUntil 0: unlimited, 1: only once, t>1: until given time_t. * @param Reason Reason string or NULL, if no reason should be saved. * @return true on success, false otherwise. */ bool Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil, const char *Reason, bool OnlyOnce) { struct list_elem *e, *newelem; assert(h != NULL); assert(Mask != NULL); e = Lists_CheckDupeMask(h, Mask); if (e) { e->valid_until = ValidUntil; if (Reason) { if (e->reason) free(e->reason); e->reason = strdup(Reason); } return true; } e = Lists_GetFirst(h); newelem = malloc(sizeof(struct list_elem)); if (!newelem) { Log(LOG_EMERG, "Can't allocate memory for new list entry!"); return false; } strlcpy(newelem->mask, Mask, sizeof(newelem->mask)); if (Reason) { newelem->reason = strdup(Reason); if (!newelem->reason) Log(LOG_EMERG, "Can't allocate memory for new list reason text!"); } else newelem->reason = NULL; newelem->valid_until = ValidUntil; newelem->onlyonce = OnlyOnce; newelem->next = e; h->first = newelem; return true; }
static bool ShowChannelList(struct list_head *head, CLIENT *Client, CHANNEL *Channel, char *msg, char *msg_end) { struct list_elem *e; assert (Client != NULL); assert (Channel != NULL); e = Lists_GetFirst(head); while (e) { if (!IRC_WriteStrClient(Client, msg, Client_ID(Client), Channel_Name(Channel), Lists_GetMask(e))) return DISCONNECTED; e = Lists_GetNext(e); } return IRC_WriteStrClient(Client, msg_end, Client_ID(Client), Channel_Name(Channel)); }
/** * Delete a given IRC mask from a list. * * @param h List head. * @param Mask IRC mask to delete from the list. */ GLOBAL void Lists_Del(struct list_head *h, const char *Mask) { struct list_elem *e, *last, *victim; assert(h != NULL); assert(Mask != NULL); last = NULL; e = Lists_GetFirst(h); while (e) { if (strcasecmp(e->mask, Mask) == 0) { LogDebug("Deleted \"%s\" from list", e->mask); victim = e; e = victim->next; Lists_Unlink(h, last, victim); continue; } last = e; e = e->next; } }