1 /* $Id: channels.c,v 1.15 2005/10/06 13:08:28 sys-op Exp $
2 * -------------------------------------------------------
3 * Copyright (c) 1998-2002 Sebastian Kienzl <zap@riot.org>
4 * (c) 2002 Lee Hardy <lee@leeh.co.uk>
5 * -------------------------------------------------------
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17 #include "muh.h"
18 #include "channels.h"
19 #include "tools.h"
20 #include "dlink.h"
21 #include "table.h"
22 #include "log.h"
23 #include "messages.h"
24
25 dlink_list channel_list;
26
27 /* add_channel()
28 *
29 * adds a channel to muhs internal list
30 */
31 void
add_channel(char * s)32 add_channel(char *s)
33 {
34 dlink_node *ptr;
35 struct channel *chptr;
36 struct logentry *logptr;
37
38 /* check to see we're not trying to add a channel we're already in */
39 for(ptr = channel_list.head; ptr; ptr = ptr->next)
40 {
41 chptr = ptr->data;
42 if(xstrcmp(chptr->name, s) == 0)
43 return;
44 }
45
46 ptr = dlink_create();
47 chptr = (struct channel *) xcalloc(1, sizeof(struct channel));
48 dlink_add_tail(chptr, ptr, &channel_list);
49
50 ptr->data = chptr;
51 chptr->name = strdup(s);
52
53 for(ptr = log_list.head; ptr; ptr = ptr->next)
54 {
55 logptr = ptr->data;
56
57 if(xstrcasecmp(chptr->name, logptr->channel) == 0)
58 {
59 chptr->log = (struct channel_log *) xcalloc(1, sizeof(struct channel_log));
60 chptr->log->logfile = fopen(logptr->filename, "a");
61
62 /* error opening */
63 if(chptr->log->logfile == NULL)
64 return;
65
66 chptr->log->logtype = logptr->logtype;
67 write_logentry(chptr, LOGM_LOGOPEN, get_logtimestamp());
68 return;
69 }
70 }
71
72 if(global_logtype)
73 {
74 char *p;
75
76 chptr->log = (struct channel_log *) xcalloc(1, sizeof(struct channel_log));
77 p = xmalloc(strlen(chptr->name) + 5);
78 sprintf(p, "%s.log", chptr->name);
79 chptr->log->logfile = fopen(p, "a");
80
81 if(chptr->log->logfile == NULL)
82 return;
83
84 chptr->log->logtype = global_logtype;
85 write_logentry(chptr, LOGM_LOGOPEN, get_logtimestamp());
86 }
87 }
88
89 /* rem_channel()
90 *
91 * removes a channel from muhs internal list
92 */
93 void
rem_channel(struct channel * chptr)94 rem_channel(struct channel *chptr)
95 {
96 dlink_node *ptr;
97
98 /* close the logfile if we have one */
99 if(chptr->log != NULL)
100 {
101 if(chptr->log->logfile)
102 {
103 write_logentry(chptr, LOGM_LOGCLOSE, get_logtimestamp());
104 fflush(chptr->log->logfile);
105 fclose(chptr->log->logfile);
106 }
107
108 xfree(chptr->log);
109 }
110
111 if((ptr = dlink_find(chptr, &channel_list)) == NULL)
112 return;
113
114 dlink_delete(ptr, &channel_list);
115 dlink_free(ptr);
116
117 xfree(chptr->name);
118 xfree(chptr->topic);
119 xfree(chptr->topicwho);
120 xfree(chptr->topicwhen);
121 xfree(chptr);
122 }
123
124 /* drop_channels()
125 *
126 * removes all channel_list and topics from muhs internal list
127 */
128 void
drop_channels()129 drop_channels()
130 {
131 dlink_node *ptr;
132 dlink_node *next_ptr;
133
134 for(ptr = channel_list.head; ptr; ptr = next_ptr)
135 {
136 next_ptr = ptr->next;
137
138 rem_channel((struct channel *)ptr->data);
139 }
140 }
141
142 /* find_channel()
143 *
144 * searches for a channel, returning it if found, else NULL
145 */
146 struct channel *
find_channel(char * name)147 find_channel(char *name)
148 {
149 dlink_node *ptr;
150 struct channel *chptr;
151
152 for(ptr = channel_list.head; ptr; ptr = ptr->next)
153 {
154 chptr = ptr->data;
155
156 if(xstrcmp(chptr->name, name) == 0)
157 return chptr;
158 }
159
160 return NULL;
161 }
162
163 /* list_channels()
164 *
165 * returns a comma seperated list of all the channel_list we're in
166 */
167 char *
list_channels()168 list_channels()
169 {
170 dlink_node *ptr;
171 struct channel *chptr;
172 static char temp[512];
173 char *p;
174
175 p = temp;
176
177 for(ptr = channel_list.head; ptr; ptr = ptr->next)
178 {
179 chptr = ptr->data;
180 p += sprintf(p, "%s,", chptr->name);
181 }
182
183 /* remove trailing , */
184 p--;
185 *p = '\0';
186 return temp;
187 }
188
189 /* channel_topic()
190 *
191 * stores a topic for a channel we're in
192 */
193 void
channel_topic(struct channel * chptr,char * topic)194 channel_topic(struct channel *chptr, char *topic)
195 {
196 xfree(chptr->topic);
197 xfree(chptr->topicwho);
198 xfree(chptr->topicwhen);
199 chptr->topic = NULL;
200 chptr->topicwho = NULL;
201 chptr->topicwhen = NULL;
202
203 if(topic != NULL && *topic != '\0')
204 chptr->topic = strdup(topic);
205 }
206
207 /* channel_when()
208 *
209 * stores who set the topic for a channel we're in
210 */
211 void
channel_when(struct channel * chptr,char * topicwho,char * topicwhen)212 channel_when(struct channel *chptr, char *topicwho, char *topicwhen)
213 {
214 if(chptr->topic != NULL)
215 {
216 xfree(chptr->topicwho);
217 xfree(chptr->topicwhen);
218
219 chptr->topicwho = strdup(topicwho);
220 chptr->topicwhen = strdup(topicwhen);
221 }
222 }
223
224 /* hash_channel()
225 *
226 * creates a hash value based on the first 25 chars of a channel name
227 */
228 unsigned int
hash_channel(char * p)229 hash_channel(char *p)
230 {
231 int i = 25;
232 unsigned int hash = 0;
233
234 while(*p && --i)
235 hash = (hash << 4) - (hash + (unsigned char)tolower(*p++));
236
237 return (hash & (MAX_CHANNELS - 1));
238 }
239
240