hirc

[archived] IRC client
git clone https://hhvn.uk/hirc
git clone git://hhvn.uk/hirc
Log | Files | Refs

chan.c (3472B)


      1 /*
      2  * src/chan.c from hirc
      3  *
      4  * Copyright (c) 2021 hhvn <dev@hhvn.uk>
      5  *
      6  * Permission to use, copy, modify, and distribute this software for any
      7  * purpose with or without fee is hereby granted, provided that the above
      8  * copyright notice and this permission notice appear in all copies.
      9  *
     10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17  *
     18  */
     19 
     20 #include <stdlib.h>
     21 #include <string.h>
     22 #include "hirc.h"
     23 
     24 void
     25 chan_free(struct Channel *channel) {
     26 	if (channel) {
     27 		pfree(&channel->name);
     28 		pfree(&channel->mode);
     29 		nick_free_list(&channel->nicks);
     30 		pfree(&channel->nicks);
     31 		hist_free_list(channel->history);
     32 		pfree(&channel);
     33 	}
     34 }
     35 
     36 void
     37 chan_free_list(struct Channel **head) {
     38 	struct Channel *p, *prev;
     39 
     40 	if (!head || !*head)
     41 		return;
     42 
     43 	prev = *head;
     44 	p = prev->next;
     45 	while (prev) {
     46 		chan_free(prev);
     47 		prev = p;
     48 		if (p)
     49 			p = p->next;
     50 	}
     51 	*head = NULL;
     52 }
     53 
     54 struct Channel *
     55 chan_create(struct Server *server, char *name, int query) {
     56 	struct Channel *channel;
     57 
     58 	channel = emalloc(sizeof(struct Channel));
     59 	channel->name = name ? estrdup(name) : NULL;
     60 	channel->next = channel->prev = NULL;
     61 	channel->nicks = NULL;
     62 	channel->old = 0;
     63 	channel->mode = channel->topic = NULL;
     64 	channel->query = query;
     65 	channel->server = server;
     66 	channel->history = emalloc(sizeof(struct HistInfo));
     67 	channel->history->activity = Activity_none;
     68 	channel->history->unread = channel->history->ignored = 0;
     69 	channel->history->server = server;
     70 	channel->history->channel = channel;
     71 	if (server)
     72 		channel->history->history = hist_loadlog(channel->history, server->name, name);
     73 	else
     74 		channel->history->history = NULL;
     75 
     76 	return channel;
     77 }
     78 
     79 int
     80 chan_selected(struct Channel *channel) {
     81 	if (selected.channel == channel)
     82 		return 1;
     83 	else
     84 		return 0;
     85 }
     86 
     87 struct Channel *
     88 chan_add(struct Server *server, struct Channel **head, char *name, int query) {
     89 	struct Channel *channel, *p;
     90 
     91 	assert_warn(name, NULL);
     92 
     93 	channel = chan_create(server, name, query);
     94 	assert_warn(channel, NULL);
     95 
     96 	if (!*head) {
     97 		*head = channel;
     98 		return channel;
     99 	}
    100 
    101 	p = *head;
    102 	for (; p && p->next; p = p->next);
    103 	p->next = channel;
    104 	channel->prev = p;
    105 
    106 	return channel;
    107 }
    108 
    109 struct Channel *
    110 chan_get(struct Channel **head, char *name, int old) {
    111 	struct Channel *p;
    112 
    113 	/* if old is negative, match regardless of p->old
    114 	 * else return only when p->old and old match */
    115 
    116 	assert_warn(head && name, NULL);
    117 	if (!*head)
    118 		return NULL;
    119 
    120 	for (p = *head; p; p = p->next) {
    121 		if (strcmp(p->name, name) == 0 && (old < 0 || p->old == old))
    122 			return p;
    123 	}
    124 
    125 	return NULL;
    126 }
    127 
    128 int
    129 chan_isold(struct Channel *channel) {
    130 	if (channel)
    131 		return channel->old;
    132 	else
    133 		return 0;
    134 }
    135 
    136 void
    137 chan_setold(struct Channel *channel, int old) {
    138 	channel->old = old;
    139 }
    140 
    141 int
    142 chan_remove(struct Channel **head, char *name) {
    143 	struct Channel *p;
    144 
    145 	assert_warn(head && name, -1);
    146 
    147 	if ((p = chan_get(head, name, -1)) == NULL)
    148 		return 0;
    149 
    150 	if (*head == p)
    151 		*head = p->next;
    152 	if (p->next)
    153 		p->next->prev = p->prev;
    154 	if (p->prev)
    155 		p->prev->next = p->next;
    156 	chan_free(p);
    157 	return 1;
    158 }