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 }