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