00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026 #include "tools.h"
00027 #include "handlers.h"
00028 #include "channel.h"
00029 #include "channel_mode.h"
00030 #include "client.h"
00031 #include "common.h"
00032 #include "hash.h"
00033 #include "irc_string.h"
00034 #include "sprintf_irc.h"
00035 #include "ircd.h"
00036 #include "list.h"
00037 #include "numeric.h"
00038 #include "send.h"
00039 #include "s_serv.h"
00040 #include "s_conf.h"
00041 #include "msg.h"
00042 #include "parse.h"
00043 #include "modules.h"
00044
00045
00046 static void names_all_visible_channels(struct Client *);
00047 static void names_non_public_non_secret(struct Client *);
00048
00049 static void m_names(struct Client *, struct Client *, int, char *[]);
00050 static void ms_names(struct Client *, struct Client *, int, char *[]);
00051
00052 struct Message names_msgtab = {
00053 "NAMES", 0, 0, 0, 0, MFLG_SLOW, 0,
00054 {m_unregistered, m_names, ms_names, m_ignore, m_names, m_ignore}
00055 };
00056
00057 #ifndef STATIC_MODULES
00058 void
00059 _modinit(void)
00060 {
00061 mod_add_cmd(&names_msgtab);
00062 }
00063
00064 void
00065 _moddeinit(void)
00066 {
00067 mod_del_cmd(&names_msgtab);
00068 }
00069
00070 const char *_version = "$Revision: 632 $";
00071 #endif
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 static void
00083 m_names(struct Client *client_p, struct Client *source_p,
00084 int parc, char *parv[])
00085 {
00086 struct Channel *chptr = NULL;
00087 char *s;
00088 char *para = parc > 1 ? parv[1] : NULL;
00089
00090 if (!EmptyString(para))
00091 {
00092 while (*para == ',')
00093 ++para;
00094
00095 if ((s = strchr(para, ',')) != NULL)
00096 *s = '\0';
00097
00098 if (*para == '\0')
00099 return;
00100
00101 if ((chptr = hash_find_channel(para)) != NULL)
00102 channel_member_names(source_p, chptr, 1);
00103 else
00104 sendto_one(source_p, form_str(RPL_ENDOFNAMES),
00105 me.name, source_p->name, para);
00106 }
00107 else
00108 {
00109 names_all_visible_channels(source_p);
00110 names_non_public_non_secret(source_p);
00111 sendto_one(source_p, form_str(RPL_ENDOFNAMES),
00112 me.name, source_p->name, "*");
00113 }
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 static void
00123 names_all_visible_channels(struct Client *source_p)
00124 {
00125 dlink_node *ptr;
00126 struct Channel *chptr;
00127
00128
00129
00130
00131 DLINK_FOREACH(ptr, global_channel_list.head)
00132 {
00133 chptr = ptr->data;
00134
00135
00136 channel_member_names(source_p, chptr, 0);
00137 }
00138 }
00139
00140
00141
00142
00143
00144
00145
00146 static void
00147 names_non_public_non_secret(struct Client *source_p)
00148 {
00149 int mlen, tlen, cur_len;
00150 int reply_to_send = NO;
00151 int shown_already;
00152 dlink_node *gc2ptr, *lp;
00153 struct Client *c2ptr;
00154 struct Channel *ch3ptr = NULL;
00155 char buf[IRCD_BUFSIZE];
00156 char *t;
00157
00158 mlen = ircsprintf(buf,form_str(RPL_NAMREPLY),
00159 me.name, source_p->name, "*", "*");
00160 cur_len = mlen;
00161 t = buf + mlen;
00162
00163
00164 DLINK_FOREACH(gc2ptr, global_client_list.head)
00165 {
00166 c2ptr = gc2ptr->data;
00167
00168 if (!IsClient(c2ptr) || IsInvisible(c2ptr))
00169 continue;
00170
00171 shown_already = NO;
00172
00173
00174
00175 DLINK_FOREACH(lp, c2ptr->channel.head)
00176 {
00177 ch3ptr = ((struct Membership *) lp->data)->chptr;
00178
00179 if (IsMember(source_p, ch3ptr))
00180 {
00181 shown_already = YES;
00182 break;
00183 }
00184 }
00185
00186 if (shown_already)
00187 continue;
00188
00189 tlen = strlen(c2ptr->name);
00190 if (cur_len + tlen + 1 > IRCD_BUFSIZE - 2)
00191 {
00192 sendto_one(source_p, "%s", buf);
00193 cur_len = mlen;
00194 t = buf + mlen;
00195 }
00196
00197 strcpy(t, c2ptr->name);
00198 t += tlen;
00199
00200 *t++ = ' ';
00201 *t = 0;
00202
00203 cur_len += tlen + 1;
00204
00205 reply_to_send = YES;
00206 }
00207
00208 if (reply_to_send)
00209 sendto_one(source_p, "%s", buf);
00210 }
00211
00212 static void
00213 ms_names(struct Client *client_p, struct Client *source_p,
00214 int parc, char *parv[])
00215 {
00216
00217
00218
00219
00220 if (ServerInfo.hub)
00221 {
00222 if (!IsCapable(client_p->from, CAP_LL))
00223 return;
00224 }
00225
00226 if (IsClient(source_p))
00227 m_names(client_p, source_p, parc, parv);
00228 }