2 * IRC - Internet Relay Chat, ircd/m_create.c
3 * Copyright (C) 1990 Jarkko Oikarinen and
4 * University of Oulu, Computing Center
6 * See file AUTHORS in IRC package for additional names of
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 1, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * m_functions execute protocol messages on this server:
29 * cptr is always NON-NULL, pointing to a *LOCAL* client
30 * structure (with an open socket connected!). This
31 * identifies the physical socket where the message
32 * originated (or which caused the m_function to be
33 * executed--some m_functions may call others...).
35 * sptr is the source of the message, defined by the
36 * prefix part of the message if present. If not
37 * or prefix not found, then sptr==cptr.
39 * (!IsServer(cptr)) => (cptr == sptr), because
40 * prefixes are taken *only* from servers...
43 * (sptr == cptr) => the message didn't
46 * (sptr != cptr && IsServer(sptr) means
47 * the prefix specified servername. (?)
49 * (sptr != cptr && !IsServer(sptr) means
50 * that message originated from a remote
55 * (!IsServer(sptr)) means that, sptr can safely
56 * taken as defining the target structure of the
57 * message in this server.
59 * *Always* true (if 'parse' and others are working correct):
61 * 1) sptr->from == cptr (note: cptr->from == cptr)
63 * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr
64 * *cannot* be a local connection, unless it's
65 * actually cptr!). [MyConnect(x) should probably
66 * be defined as (x == x->from) --msa ]
68 * parc number of variable parameter strings (if zero,
69 * parv is allowed to be NULL)
71 * parv a NULL terminated list of parameter pointers,
73 * parv[0], sender (prefix string), if not present
74 * this points to an empty string.
75 * parv[1]...parv[parc-1]
76 * pointers to additional parameters
77 * parv[parc] == NULL, *always*
79 * note: it is guaranteed that parv[0]..parv[parc-1] are all
84 * No need to include handlers.h here the signatures must match
85 * and we don't need to force a rebuild of all the handlers everytime
86 * we add a new one to the list. --Bleep
94 #include "ircd_reply.h"
95 #include "ircd_string.h"
106 * m_create - generic message handler
108 int m_create(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
114 * ms_create - server message handler
116 int ms_create(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
118 char cbuf[BUFSIZE]; /* Buffer for list with channels
119 that `sptr' really creates */
120 time_t chanTS; /* Creation time for all channels
121 in the comma seperated list */
124 struct Channel* chptr;
127 if (IsServer(sptr)) {
128 /* PROTOCOL WARNING */
129 /* bail, don't core */
132 /* sanity checks: Only accept CREATE messages from servers */
133 if (!IsServer(cptr) || parc < 3 || *parv[2] == '\0')
136 chanTS = atoi(parv[2]);
138 /* A create that didn't appear during a burst has that servers idea of
139 * the current time. Use it for lag calculations.
141 if (!IsBurstOrBurstAck(sptr) && 0 != chanTS && MAGIC_REMOTE_JOIN_TS != chanTS)
142 sptr->user->server->serv->lag = TStime() - chanTS;
144 *cbuf = '\0'; /* Start with empty buffer */
146 /* For each channel in the comma seperated list: */
147 for (name = ircd_strtok(&p, parv[1], ","); name; name = ircd_strtok(&p, 0, ","))
149 badop = 0; /* Default is to accept the op */
150 if ((chptr = FindChannel(name)))
152 name = chptr->chname;
153 if (TStime() - chanTS > TS_LAG_TIME)
155 /* A bounce would not be accepted anyway - if we get here something
156 is wrong with the TS clock syncing (or we have more then
157 TS_LAG_TIME lag, or an admin is hacking */
159 /* This causes a HACK notice on all upstream servers: */
160 sendto_one(cptr, "%s " TOK_MODE " %s -o %s%s 0", NumServ(&me), name, NumNick(sptr));
161 /* This causes a WALLOPS on all downstream servers and a notice to our
163 parv[1] = name; /* Corrupt parv[1], it is not used anymore anyway */
164 send_hack_notice(cptr, sptr, parc, parv, badop, 2);
166 else if (chptr->creationtime && chanTS > chptr->creationtime &&
167 chptr->creationtime != MAGIC_REMOTE_JOIN_TS)
169 /* We (try) to bounce the mode, because the CREATE is used on an older
170 channel, probably a net.ride */
172 /* Send a deop upstream: */
173 sendto_one(cptr, "%s " TOK_MODE " %s -o %s%s " TIME_T_FMT, NumServ(&me),
174 name, NumNick(sptr), chptr->creationtime);
177 else /* Channel doesn't exist: create it */
178 chptr = get_channel(sptr, name, CGT_CREATE);
180 /* Add and mark ops */
181 add_user_to_channel(chptr, sptr,
182 (badop || IsModelessChannel(name)) ? CHFL_DEOPPED : CHFL_CHANOP);
184 /* Send user join to the local clients (if any) */
185 sendto_channel_butserv(chptr, sptr, ":%s " MSG_JOIN " :%s", parv[0], name);
187 if (badop) /* handle badop: convert CREATE into JOIN */
188 sendto_serv_butone(cptr, "%s%s " TOK_JOIN " %s " TIME_T_FMT,
189 NumNick(sptr), name, chptr->creationtime);
192 /* Send the op to local clients:
193 (if any; extremely unlikely, but it CAN happen) */
194 if (!IsModelessChannel(name))
195 sendto_channel_butserv(chptr, sptr, ":%s MODE %s +o %s",
196 sptr->user->server->name, name, parv[0]);
198 /* Set/correct TS and add the channel to the
199 buffer for accepted channels: */
200 chptr->creationtime = chanTS;
207 if (*cbuf) /* Any channel accepted with ops ? */
209 sendto_serv_butone(cptr, "%s%s " TOK_CREATE " %s " TIME_T_FMT,
210 NumNick(sptr), cbuf, chanTS);
220 * parv[0] = sender prefix
221 * parv[1] = channel names
222 * parv[2] = channel time stamp
224 int m_create(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
226 char cbuf[BUFSIZE]; /* Buffer for list with channels
227 that `sptr' really creates */
228 time_t chanTS; /* Creation time for all channels
229 in the comma seperated list */
232 struct Channel* chptr;
235 /* sanity checks: Only accept CREATE messages from servers */
236 if (!IsServer(cptr) || parc < 3 || *parv[2] == '\0')
239 chanTS = atoi(parv[2]);
241 /* A create that didn't appear during a burst has that servers idea of
242 * the current time. Use it for lag calculations.
244 if (!IsBurstOrBurstAck(sptr) && 0 != chanTS && MAGIC_REMOTE_JOIN_TS != chanTS)
245 sptr->user->server->serv->lag = TStime() - chanTS;
247 *cbuf = '\0'; /* Start with empty buffer */
249 /* For each channel in the comma seperated list: */
250 for (name = ircd_strtok(&p, parv[1], ","); name; name = ircd_strtok(&p, 0, ","))
252 badop = 0; /* Default is to accept the op */
253 if ((chptr = FindChannel(name)))
255 name = chptr->chname;
256 if (TStime() - chanTS > TS_LAG_TIME)
258 /* A bounce would not be accepted anyway - if we get here something
259 is wrong with the TS clock syncing (or we have more then
260 TS_LAG_TIME lag, or an admin is hacking */
262 /* This causes a HACK notice on all upstream servers: */
263 sendto_one(cptr, "%s " TOK_MODE " %s -o %s%s 0", NumServ(&me), name, NumNick(sptr));
264 /* This causes a WALLOPS on all downstream servers and a notice to our
266 parv[1] = name; /* Corrupt parv[1], it is not used anymore anyway */
267 send_hack_notice(cptr, sptr, parc, parv, badop, 2);
269 else if (chptr->creationtime && chanTS > chptr->creationtime &&
270 chptr->creationtime != MAGIC_REMOTE_JOIN_TS)
272 /* We (try) to bounce the mode, because the CREATE is used on an older
273 channel, probably a net.ride */
275 /* Send a deop upstream: */
276 sendto_one(cptr, "%s " TOK_MODE " %s -o %s%s " TIME_T_FMT, NumServ(&me),
277 name, NumNick(sptr), chptr->creationtime);
280 else /* Channel doesn't exist: create it */
281 chptr = get_channel(sptr, name, CGT_CREATE);
283 /* Add and mark ops */
284 add_user_to_channel(chptr, sptr,
285 (badop || IsModelessChannel(name)) ? CHFL_DEOPPED : CHFL_CHANOP);
287 /* Send user join to the local clients (if any) */
288 sendto_channel_butserv(chptr, sptr, ":%s " MSG_JOIN " :%s", parv[0], name);
290 if (badop) /* handle badop: convert CREATE into JOIN */
291 sendto_serv_butone(cptr, "%s%s " TOK_JOIN " %s " TIME_T_FMT,
292 NumNick(sptr), name, chptr->creationtime);
295 /* Send the op to local clients:
296 (if any; extremely unlikely, but it CAN happen) */
297 if (!IsModelessChannel(name))
298 sendto_channel_butserv(chptr, sptr, ":%s MODE %s +o %s",
299 sptr->user->server->name, name, parv[0]);
301 /* Set/correct TS and add the channel to the
302 buffer for accepted channels: */
303 chptr->creationtime = chanTS;
310 if (*cbuf) /* Any channel accepted with ops ? */
312 sendto_serv_butone(cptr, "%s%s " TOK_CREATE " %s " TIME_T_FMT,
313 NumNick(sptr), cbuf, chanTS);