source: code/cmd.c@ cd7b81d

Last change on this file since cd7b81d was cd7b81d, checked in by Mike Belopuhov <mike.belopuhov@…>, 15 years ago

move it to the github

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2009, 2010 Mike Belopuhov
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef lint
18static const char rcsid[] = "$ABSD: cmd.c,v 1.21 2010/01/03 20:54:18 kmerz Exp $";
19#endif /* not lint */
20
21#include <sys/param.h>
22#include <sys/queue.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <syslog.h>
27#include <unistd.h>
28#include <event.h>
29
30#include "icb.h"
31
32extern int creategroups;
33
34void icb_cmd_boot(struct icb_session *, char *);
35void icb_cmd_change(struct icb_session *, char *);
36void icb_cmd_name(struct icb_session *, char *);
37void icb_cmd_personal(struct icb_session *, char *);
38void icb_cmd_pass(struct icb_session *, char *);
39void icb_cmd_topic(struct icb_session *, char *);
40void icb_cmd_who(struct icb_session *, char *);
41
42void *
43icb_cmd_lookup(char *cmd)
44{
45 struct {
46 const char *cmd;
47 void (*handler)(struct icb_session *, char *);
48 } cmdtab[] = {
49 { "boot", icb_cmd_boot },
50 { "g", icb_cmd_change },
51 { "m", icb_cmd_personal },
52 { "msg", icb_cmd_personal },
53 { "name", icb_cmd_name },
54 { "pass", icb_cmd_pass },
55 { "topic", icb_cmd_topic },
56 { "w", icb_cmd_who },
57 { NULL, NULL }
58 };
59 int i;
60
61 for (i = 0; cmdtab[i].cmd != NULL; i++)
62 if (strcasecmp(cmdtab[i].cmd, cmd) == 0)
63 return (cmdtab[i].handler);
64 return (NULL);
65}
66
67void
68icb_cmd_boot(struct icb_session *is, char *arg)
69{
70 struct icb_group *ig;
71 struct icb_session *s;
72
73 /* to boot or not to boot, that is the question */
74 ig = is->group;
75 if (!icb_ismoder(ig, is)) {
76 icb_status(is, STATUS_NOTIFY, "Sorry, booting is a privilege "
77 "you don't possess");
78 return;
79 }
80
81 /* who would be a target then? */
82 LIST_FOREACH(s, &ig->sess, entry) {
83 if (strcmp(s->nick, arg) == 0)
84 break;
85 }
86 if (s == NULL) {
87 icb_status(is, STATUS_NOTIFY, "No such user");
88 return;
89 }
90
91 /* okay, here we go, but first, be polite and notify a user */
92 icb_status(s, STATUS_BOOT, "%s booted you", is->nick);
93 icb_status_group(s->group, s, STATUS_BOOT, "%s was booted", s->nick);
94 icb_drop(s, "booted");
95}
96
97void
98icb_cmd_change(struct icb_session *is, char *arg)
99{
100 struct icb_group *ig;
101 struct icb_session *s;
102 int changing = 0;
103
104 if (strlen(arg) == 0) {
105 icb_error(is, "Invalid group");
106 return;
107 }
108
109 LIST_FOREACH(ig, &groups, entry) {
110 if (strcmp(ig->name, arg) == 0)
111 break;
112 }
113 if (ig == NULL) {
114 if (!creategroups) {
115 icb_error(is, "Invalid group");
116 return;
117 } else {
118 if ((ig = icb_addgroup(is, arg, NULL)) == NULL) {
119 icb_error(is, "Can't create group");
120 return;
121 }
122 icb_log(NULL, LOG_DEBUG, "%s created group %s",
123 is->nick, arg);
124 }
125 }
126
127 /* changing to the same group is strictly prohibited */
128 if (is->group && is->group == ig) {
129 icb_error(is, "Huh?");
130 return;
131 }
132
133 LIST_FOREACH(s, &ig->sess, entry) {
134 if (strcmp(s->nick, is->nick) == 0) {
135 icb_error(is, "Nick is already in use");
136 return;
137 }
138 }
139
140 if (is->group) {
141 changing = 1;
142 if (icb_ismoder(is->group, is))
143 (void)icb_pass(is->group, is, NULL);
144 LIST_REMOVE(is, entry);
145 icb_status_group(is->group, NULL, STATUS_DEPART,
146 "%s (%s@%s) just left", is->nick, is->client, is->host);
147 }
148
149 is->group = ig;
150 LIST_INSERT_HEAD(&ig->sess, is, entry);
151
152 /* notify group */
153 icb_status_group(ig, is, changing ? STATUS_ARRIVE : STATUS_SIGNON,
154 "%s (%s@%s) entered group", is->nick, is->client, is->host);
155
156 /* acknowledge successful join */
157 icb_status(is, STATUS_STATUS, "You are now in group %s%s", ig->name,
158 icb_ismoder(ig, is) ? " as moderator" : "");
159
160 /* send user a topic name */
161 if (strlen(ig->topic) > 0)
162 icb_status(is, STATUS_TOPIC, "The topic is: %s", ig->topic);
163}
164
165void
166icb_cmd_name(struct icb_session *is, char *arg)
167{
168 struct icb_group *ig = is->group;
169 struct icb_session *s;
170
171 if (strlen(arg) == 0) {
172 icb_status(is, STATUS_NAME, "Your nickname is %s",
173 is->nick);
174 return;
175 }
176 if (strcasecmp(arg, "admin") == 0) {
177 icb_error(is, "Wuff wuff!");
178 return;
179 }
180 /* sanitize user input */
181 if (strlen(arg) > ICB_MAXNICKLEN)
182 arg[ICB_MAXNICKLEN - 1] = '\0';
183 LIST_FOREACH(s, &ig->sess, entry) {
184 if (strcmp(s->nick, arg) == 0) {
185 icb_error(is, "Nick is already in use");
186 return;
187 }
188 }
189 icb_status_group(ig, NULL, STATUS_NAME,
190 "%s changed nickname to %s", is->nick, arg);
191 strlcpy(is->nick, arg, sizeof is->nick);
192}
193
194void
195icb_cmd_personal(struct icb_session *is, char *arg)
196{
197 char *p;
198
199 if ((p = strchr(arg, ' ')) == 0) {
200 icb_error(is, "Empty message");
201 return;
202 }
203 *p = '\0';
204 icb_privmsg(is, arg, ++p);
205}
206
207void
208icb_cmd_pass(struct icb_session *is, char *arg __attribute__((unused)))
209{
210 if (!icb_ismoder(is->group, is))
211 (void)icb_pass(is->group, is->group->moder, is);
212}
213
214void
215icb_cmd_topic(struct icb_session *is, char *arg)
216{
217 struct icb_group *ig = is->group;
218
219 if (strlen(arg) == 0) { /* querying the topic */
220 if (strlen(ig->topic) > 0)
221 icb_status(is, STATUS_TOPIC, "The topic is: %s",
222 ig->topic);
223 else
224 icb_status(is, STATUS_TOPIC, "The topic is not set.");
225 } else { /* setting the topic */
226 strlcpy(ig->topic, arg, sizeof ig->topic);
227 icb_status_group(ig, NULL, STATUS_TOPIC,
228 "%s changed the topic to \"%s\"", is->nick, ig->topic);
229 }
230}
231
232void
233icb_cmd_who(struct icb_session *is, char *arg __attribute__((unused)))
234{
235 icb_who(is, NULL);
236}
Note: See TracBrowser for help on using the repository browser.