Committer : klmitch
CVSROOT : /cvsroot/undernet-ircu
Module : ircu2.10
Commit time: 2004-12-18 16:26:38 UTC
Modified files:
ChangeLog include/client.h include/handlers.h include/msg.h
include/numeric.h ircd/Makefile.in ircd/ircd_string.c ircd/list.c
ircd/m_pong.c ircd/m_user.c ircd/parse.c ircd/s_err.c
ircd/s_user.c
Added files:
include/capab.h ircd/m_cap.c
Log message:
Author: Kev <[EMAIL PROTECTED]>
Log message:
* Simplify logic for determining when to run register_user(); before, we
explicitly checked to see if the username, hostname, and cookie were all
set, and now we can just test to see if a bit flag is 0.
* Fix a minor bug in ircd_strn?cmp() that we've never noticed before,
because we've never needed lexicographic ordering for strings differing
in case.
* Implement capabilities system. There are 604 capabilities implemented
for testing purposes, but they don't do anything. (This is just the
negotiation mechanism. The 604 were needed to test LS & LSL semantics.)
---------------------- diff included ----------------------
Index: ircu2.10/ChangeLog
diff -u ircu2.10/ChangeLog:1.521 ircu2.10/ChangeLog:1.522
--- ircu2.10/ChangeLog:1.521 Sat Dec 18 07:09:12 2004
+++ ircu2.10/ChangeLog Sat Dec 18 08:26:25 2004
@@ -9,6 +9,49 @@
socket's FD is the same after processing as it was before; local
clients apparently have s_fd() == -1 after close.
+2004-12-18 Kevin L Mitchell <[EMAIL PROTECTED]>
+
+ * ircd/s_user.c: make absolutely certain register_user() is never
+ called with cli_unreg non-zero; transition set_nick_name() over to
+ the new way of determining whether client is ready for
+ register_user()
+
+ * ircd/s_err.c: add ERR_UNKNOWNCAPCMD for reporting failure to
+ understand a given CAP subcommand
+
+ * ircd/parse.c: add "CAP" command
+
+ * ircd/m_user.c (m_user): transition over to new way of
+ determining whether client is ready for register_user()
+
+ * ircd/m_pong.c (mr_pong): transition over to new way of
+ determining whether client is ready for register_user()
+
+ * ircd/m_cap.c: implementation of the IRC capabilities draft
+
+ * ircd/list.c (make_client): initialize cli_unreg element of
+ client structure
+
+ * ircd/ircd_string.c: correct old bugs in ircd_strn?cmp()
+ functions that were never found because cross-case ordering has
+ not been needed until now
+
+ * ircd/Makefile.in: add m_cap.c to list of .c files
+
+ * include/numeric.h (ERR_UNKNOWNCAPCMD): define new error reply to
+ indicate an unknown CAP subcommand
+
+ * include/msg.h: add "CAP" command
+
+ * include/handlers.h: add m_cap() to list of handlers
+
+ * include/client.h: add support for client capabilities; rototill
+ the registration mechanism to dovetail well with the capability
+ system--i.e., allow the capability system to suspend registration
+ if the user issues one of the CAP commands
+
+ * include/capab.h: header file to define client capabilities
+
2004-12-17 Michael Poole <[EMAIL PROTECTED]>
* ircd/channel.h (apply_ban): Add new flag to indicate whether
Index: ircu2.10/include/capab.h
diff -u /dev/null ircu2.10/include/capab.h:1.1
--- /dev/null Sat Dec 18 08:26:38 2004
+++ ircu2.10/include/capab.h Sat Dec 18 08:26:26 2004
@@ -0,0 +1,657 @@
+#ifndef INCLUDED_capab_h
+#define INCLUDED_capab_h
+/*
+ * IRC - Internet Relay Chat, include/capab.h
+ * Copyright (C) 2004 Kevin L. Mitchell <[EMAIL PROTECTED]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/** @file
+ * @brief Interface and public definitions for capabilities extension
+ * @version $Id: capab.h,v 1.1 2004/12/18 16:26:26 klmitch Exp $
+ */
+
+#ifndef INCLUDED_client_h
+#include "client.h"
+#endif
+
+#define CAPFL_HIDDEN 0x0001 /**< Do not advertize this capability */
+#define CAPFL_PROHIBIT 0x0002 /**< Client may not set this capability */
+#define CAPFL_PROTO 0x0004 /**< Cap must be acknowledged by client */
+
+/* XXX You can safely ignore all of these; they're only for testing purposes,
+ * XXX and don't result in any behavioral change.
+ */
+#define CAPLIST
\
+ _CAP(USERPFX, 0, "undernet.org/userpfx"), \
+ _CAP(FOO, CAPFL_HIDDEN, "x-foo"), \
+ _CAP(BAR, CAPFL_PROHIBIT, "x-bar"), \
+ _CAP(BINK, CAPFL_PROTO, "x-bink"), \
+ _CAP(CAP000, 0, "x-cap000"), \
+ _CAP(CAP001, 0, "x-cap001"), \
+ _CAP(CAP002, 0, "x-cap002"), \
+ _CAP(CAP003, 0, "x-cap003"), \
+ _CAP(CAP004, 0, "x-cap004"), \
+ _CAP(CAP005, 0, "x-cap005"), \
+ _CAP(CAP006, 0, "x-cap006"), \
+ _CAP(CAP007, 0, "x-cap007"), \
+ _CAP(CAP008, 0, "x-cap008"), \
+ _CAP(CAP009, 0, "x-cap009"), \
+ _CAP(CAP010, 0, "x-cap010"), \
+ _CAP(CAP011, 0, "x-cap011"), \
+ _CAP(CAP012, 0, "x-cap012"), \
+ _CAP(CAP013, 0, "x-cap013"), \
+ _CAP(CAP014, 0, "x-cap014"), \
+ _CAP(CAP015, 0, "x-cap015"), \
+ _CAP(CAP016, 0, "x-cap016"), \
+ _CAP(CAP017, 0, "x-cap017"), \
+ _CAP(CAP018, 0, "x-cap018"), \
+ _CAP(CAP019, 0, "x-cap019"), \
+ _CAP(CAP020, 0, "x-cap020"), \
+ _CAP(CAP021, 0, "x-cap021"), \
+ _CAP(CAP022, 0, "x-cap022"), \
+ _CAP(CAP023, 0, "x-cap023"), \
+ _CAP(CAP024, 0, "x-cap024"), \
+ _CAP(CAP025, 0, "x-cap025"), \
+ _CAP(CAP026, 0, "x-cap026"), \
+ _CAP(CAP027, 0, "x-cap027"), \
+ _CAP(CAP028, 0, "x-cap028"), \
+ _CAP(CAP029, 0, "x-cap029"), \
+ _CAP(CAP030, 0, "x-cap030"), \
+ _CAP(CAP031, 0, "x-cap031"), \
+ _CAP(CAP032, 0, "x-cap032"), \
+ _CAP(CAP033, 0, "x-cap033"), \
+ _CAP(CAP034, 0, "x-cap034"), \
+ _CAP(CAP035, 0, "x-cap035"), \
+ _CAP(CAP036, 0, "x-cap036"), \
+ _CAP(CAP037, 0, "x-cap037"), \
+ _CAP(CAP038, 0, "x-cap038"), \
+ _CAP(CAP039, 0, "x-cap039"), \
+ _CAP(CAP040, 0, "x-cap040"), \
+ _CAP(CAP041, 0, "x-cap041"), \
+ _CAP(CAP042, 0, "x-cap042"), \
+ _CAP(CAP043, 0, "x-cap043"), \
+ _CAP(CAP044, 0, "x-cap044"), \
+ _CAP(CAP045, 0, "x-cap045"), \
+ _CAP(CAP046, 0, "x-cap046"), \
+ _CAP(CAP047, 0, "x-cap047"), \
+ _CAP(CAP048, 0, "x-cap048"), \
+ _CAP(CAP049, 0, "x-cap049"), \
+ _CAP(CAP050, 0, "x-cap050"), \
+ _CAP(CAP051, 0, "x-cap051"), \
+ _CAP(CAP052, 0, "x-cap052"), \
+ _CAP(CAP053, 0, "x-cap053"), \
+ _CAP(CAP054, 0, "x-cap054"), \
+ _CAP(CAP055, 0, "x-cap055"), \
+ _CAP(CAP056, 0, "x-cap056"), \
+ _CAP(CAP057, 0, "x-cap057"), \
+ _CAP(CAP058, 0, "x-cap058"), \
+ _CAP(CAP059, 0, "x-cap059"), \
+ _CAP(CAP060, 0, "x-cap060"), \
+ _CAP(CAP061, 0, "x-cap061"), \
+ _CAP(CAP062, 0, "x-cap062"), \
+ _CAP(CAP063, 0, "x-cap063"), \
+ _CAP(CAP064, 0, "x-cap064"), \
+ _CAP(CAP065, 0, "x-cap065"), \
+ _CAP(CAP066, 0, "x-cap066"), \
+ _CAP(CAP067, 0, "x-cap067"), \
+ _CAP(CAP068, 0, "x-cap068"), \
+ _CAP(CAP069, 0, "x-cap069"), \
+ _CAP(CAP070, 0, "x-cap070"), \
+ _CAP(CAP071, 0, "x-cap071"), \
+ _CAP(CAP072, 0, "x-cap072"), \
+ _CAP(CAP073, 0, "x-cap073"), \
+ _CAP(CAP074, 0, "x-cap074"), \
+ _CAP(CAP075, 0, "x-cap075"), \
+ _CAP(CAP076, 0, "x-cap076"), \
+ _CAP(CAP077, 0, "x-cap077"), \
+ _CAP(CAP078, 0, "x-cap078"), \
+ _CAP(CAP079, 0, "x-cap079"), \
+ _CAP(CAP080, 0, "x-cap080"), \
+ _CAP(CAP081, 0, "x-cap081"), \
+ _CAP(CAP082, 0, "x-cap082"), \
+ _CAP(CAP083, 0, "x-cap083"), \
+ _CAP(CAP084, 0, "x-cap084"), \
+ _CAP(CAP085, 0, "x-cap085"), \
+ _CAP(CAP086, 0, "x-cap086"), \
+ _CAP(CAP087, 0, "x-cap087"), \
+ _CAP(CAP088, 0, "x-cap088"), \
+ _CAP(CAP089, 0, "x-cap089"), \
+ _CAP(CAP090, 0, "x-cap090"), \
+ _CAP(CAP091, 0, "x-cap091"), \
+ _CAP(CAP092, 0, "x-cap092"), \
+ _CAP(CAP093, 0, "x-cap093"), \
+ _CAP(CAP094, 0, "x-cap094"), \
+ _CAP(CAP095, 0, "x-cap095"), \
+ _CAP(CAP096, 0, "x-cap096"), \
+ _CAP(CAP097, 0, "x-cap097"), \
+ _CAP(CAP098, 0, "x-cap098"), \
+ _CAP(CAP099, 0, "x-cap099"), \
+ _CAP(CAP100, 0, "x-cap100"), \
+ _CAP(CAP101, 0, "x-cap101"), \
+ _CAP(CAP102, 0, "x-cap102"), \
+ _CAP(CAP103, 0, "x-cap103"), \
+ _CAP(CAP104, 0, "x-cap104"), \
+ _CAP(CAP105, 0, "x-cap105"), \
+ _CAP(CAP106, 0, "x-cap106"), \
+ _CAP(CAP107, 0, "x-cap107"), \
+ _CAP(CAP108, 0, "x-cap108"), \
+ _CAP(CAP109, 0, "x-cap109"), \
+ _CAP(CAP110, 0, "x-cap110"), \
+ _CAP(CAP111, 0, "x-cap111"), \
+ _CAP(CAP112, 0, "x-cap112"), \
+ _CAP(CAP113, 0, "x-cap113"), \
+ _CAP(CAP114, 0, "x-cap114"), \
+ _CAP(CAP115, 0, "x-cap115"), \
+ _CAP(CAP116, 0, "x-cap116"), \
+ _CAP(CAP117, 0, "x-cap117"), \
+ _CAP(CAP118, 0, "x-cap118"), \
+ _CAP(CAP119, 0, "x-cap119"), \
+ _CAP(CAP120, 0, "x-cap120"), \
+ _CAP(CAP121, 0, "x-cap121"), \
+ _CAP(CAP122, 0, "x-cap122"), \
+ _CAP(CAP123, 0, "x-cap123"), \
+ _CAP(CAP124, 0, "x-cap124"), \
+ _CAP(CAP125, 0, "x-cap125"), \
+ _CAP(CAP126, 0, "x-cap126"), \
+ _CAP(CAP127, 0, "x-cap127"), \
+ _CAP(CAP128, 0, "x-cap128"), \
+ _CAP(CAP129, 0, "x-cap129"), \
+ _CAP(CAP130, 0, "x-cap130"), \
+ _CAP(CAP131, 0, "x-cap131"), \
+ _CAP(CAP132, 0, "x-cap132"), \
+ _CAP(CAP133, 0, "x-cap133"), \
+ _CAP(CAP134, 0, "x-cap134"), \
+ _CAP(CAP135, 0, "x-cap135"), \
+ _CAP(CAP136, 0, "x-cap136"), \
+ _CAP(CAP137, 0, "x-cap137"), \
+ _CAP(CAP138, 0, "x-cap138"), \
+ _CAP(CAP139, 0, "x-cap139"), \
+ _CAP(CAP140, 0, "x-cap140"), \
+ _CAP(CAP141, 0, "x-cap141"), \
+ _CAP(CAP142, 0, "x-cap142"), \
+ _CAP(CAP143, 0, "x-cap143"), \
+ _CAP(CAP144, 0, "x-cap144"), \
+ _CAP(CAP145, 0, "x-cap145"), \
+ _CAP(CAP146, 0, "x-cap146"), \
+ _CAP(CAP147, 0, "x-cap147"), \
+ _CAP(CAP148, 0, "x-cap148"), \
+ _CAP(CAP149, 0, "x-cap149"), \
+ _CAP(CAP150, 0, "x-cap150"), \
+ _CAP(CAP151, 0, "x-cap151"), \
+ _CAP(CAP152, 0, "x-cap152"), \
+ _CAP(CAP153, 0, "x-cap153"), \
+ _CAP(CAP154, 0, "x-cap154"), \
+ _CAP(CAP155, 0, "x-cap155"), \
+ _CAP(CAP156, 0, "x-cap156"), \
+ _CAP(CAP157, 0, "x-cap157"), \
+ _CAP(CAP158, 0, "x-cap158"), \
+ _CAP(CAP159, 0, "x-cap159"), \
+ _CAP(CAP160, 0, "x-cap160"), \
+ _CAP(CAP161, 0, "x-cap161"), \
+ _CAP(CAP162, 0, "x-cap162"), \
+ _CAP(CAP163, 0, "x-cap163"), \
+ _CAP(CAP164, 0, "x-cap164"), \
+ _CAP(CAP165, 0, "x-cap165"), \
+ _CAP(CAP166, 0, "x-cap166"), \
+ _CAP(CAP167, 0, "x-cap167"), \
+ _CAP(CAP168, 0, "x-cap168"), \
+ _CAP(CAP169, 0, "x-cap169"), \
+ _CAP(CAP170, 0, "x-cap170"), \
+ _CAP(CAP171, 0, "x-cap171"), \
+ _CAP(CAP172, 0, "x-cap172"), \
+ _CAP(CAP173, 0, "x-cap173"), \
+ _CAP(CAP174, 0, "x-cap174"), \
+ _CAP(CAP175, 0, "x-cap175"), \
+ _CAP(CAP176, 0, "x-cap176"), \
+ _CAP(CAP177, 0, "x-cap177"), \
+ _CAP(CAP178, 0, "x-cap178"), \
+ _CAP(CAP179, 0, "x-cap179"), \
+ _CAP(CAP180, 0, "x-cap180"), \
+ _CAP(CAP181, 0, "x-cap181"), \
+ _CAP(CAP182, 0, "x-cap182"), \
+ _CAP(CAP183, 0, "x-cap183"), \
+ _CAP(CAP184, 0, "x-cap184"), \
+ _CAP(CAP185, 0, "x-cap185"), \
+ _CAP(CAP186, 0, "x-cap186"), \
+ _CAP(CAP187, 0, "x-cap187"), \
+ _CAP(CAP188, 0, "x-cap188"), \
+ _CAP(CAP189, 0, "x-cap189"), \
+ _CAP(CAP190, 0, "x-cap190"), \
+ _CAP(CAP191, 0, "x-cap191"), \
+ _CAP(CAP192, 0, "x-cap192"), \
+ _CAP(CAP193, 0, "x-cap193"), \
+ _CAP(CAP194, 0, "x-cap194"), \
+ _CAP(CAP195, 0, "x-cap195"), \
+ _CAP(CAP196, 0, "x-cap196"), \
+ _CAP(CAP197, 0, "x-cap197"), \
+ _CAP(CAP198, 0, "x-cap198"), \
+ _CAP(CAP199, 0, "x-cap199"), \
+ _CAP(CAP200, 0, "x-cap200"), \
+ _CAP(CAP201, 0, "x-cap201"), \
+ _CAP(CAP202, 0, "x-cap202"), \
+ _CAP(CAP203, 0, "x-cap203"), \
+ _CAP(CAP204, 0, "x-cap204"), \
+ _CAP(CAP205, 0, "x-cap205"), \
+ _CAP(CAP206, 0, "x-cap206"), \
+ _CAP(CAP207, 0, "x-cap207"), \
+ _CAP(CAP208, 0, "x-cap208"), \
+ _CAP(CAP209, 0, "x-cap209"), \
+ _CAP(CAP210, 0, "x-cap210"), \
+ _CAP(CAP211, 0, "x-cap211"), \
+ _CAP(CAP212, 0, "x-cap212"), \
+ _CAP(CAP213, 0, "x-cap213"), \
+ _CAP(CAP214, 0, "x-cap214"), \
+ _CAP(CAP215, 0, "x-cap215"), \
+ _CAP(CAP216, 0, "x-cap216"), \
+ _CAP(CAP217, 0, "x-cap217"), \
+ _CAP(CAP218, 0, "x-cap218"), \
+ _CAP(CAP219, 0, "x-cap219"), \
+ _CAP(CAP220, 0, "x-cap220"), \
+ _CAP(CAP221, 0, "x-cap221"), \
+ _CAP(CAP222, 0, "x-cap222"), \
+ _CAP(CAP223, 0, "x-cap223"), \
+ _CAP(CAP224, 0, "x-cap224"), \
+ _CAP(CAP225, 0, "x-cap225"), \
+ _CAP(CAP226, 0, "x-cap226"), \
+ _CAP(CAP227, 0, "x-cap227"), \
+ _CAP(CAP228, 0, "x-cap228"), \
+ _CAP(CAP229, 0, "x-cap229"), \
+ _CAP(CAP230, 0, "x-cap230"), \
+ _CAP(CAP231, 0, "x-cap231"), \
+ _CAP(CAP232, 0, "x-cap232"), \
+ _CAP(CAP233, 0, "x-cap233"), \
+ _CAP(CAP234, 0, "x-cap234"), \
+ _CAP(CAP235, 0, "x-cap235"), \
+ _CAP(CAP236, 0, "x-cap236"), \
+ _CAP(CAP237, 0, "x-cap237"), \
+ _CAP(CAP238, 0, "x-cap238"), \
+ _CAP(CAP239, 0, "x-cap239"), \
+ _CAP(CAP240, 0, "x-cap240"), \
+ _CAP(CAP241, 0, "x-cap241"), \
+ _CAP(CAP242, 0, "x-cap242"), \
+ _CAP(CAP243, 0, "x-cap243"), \
+ _CAP(CAP244, 0, "x-cap244"), \
+ _CAP(CAP245, 0, "x-cap245"), \
+ _CAP(CAP246, 0, "x-cap246"), \
+ _CAP(CAP247, 0, "x-cap247"), \
+ _CAP(CAP248, 0, "x-cap248"), \
+ _CAP(CAP249, 0, "x-cap249"), \
+ _CAP(CAP250, 0, "x-cap250"), \
+ _CAP(CAP251, 0, "x-cap251"), \
+ _CAP(CAP252, 0, "x-cap252"), \
+ _CAP(CAP253, 0, "x-cap253"), \
+ _CAP(CAP254, 0, "x-cap254"), \
+ _CAP(CAP255, 0, "x-cap255"), \
+ _CAP(CAP256, 0, "x-cap256"), \
+ _CAP(CAP257, 0, "x-cap257"), \
+ _CAP(CAP258, 0, "x-cap258"), \
+ _CAP(CAP259, 0, "x-cap259"), \
+ _CAP(CAP260, 0, "x-cap260"), \
+ _CAP(CAP261, 0, "x-cap261"), \
+ _CAP(CAP262, 0, "x-cap262"), \
+ _CAP(CAP263, 0, "x-cap263"), \
+ _CAP(CAP264, 0, "x-cap264"), \
+ _CAP(CAP265, 0, "x-cap265"), \
+ _CAP(CAP266, 0, "x-cap266"), \
+ _CAP(CAP267, 0, "x-cap267"), \
+ _CAP(CAP268, 0, "x-cap268"), \
+ _CAP(CAP269, 0, "x-cap269"), \
+ _CAP(CAP270, 0, "x-cap270"), \
+ _CAP(CAP271, 0, "x-cap271"), \
+ _CAP(CAP272, 0, "x-cap272"), \
+ _CAP(CAP273, 0, "x-cap273"), \
+ _CAP(CAP274, 0, "x-cap274"), \
+ _CAP(CAP275, 0, "x-cap275"), \
+ _CAP(CAP276, 0, "x-cap276"), \
+ _CAP(CAP277, 0, "x-cap277"), \
+ _CAP(CAP278, 0, "x-cap278"), \
+ _CAP(CAP279, 0, "x-cap279"), \
+ _CAP(CAP280, 0, "x-cap280"), \
+ _CAP(CAP281, 0, "x-cap281"), \
+ _CAP(CAP282, 0, "x-cap282"), \
+ _CAP(CAP283, 0, "x-cap283"), \
+ _CAP(CAP284, 0, "x-cap284"), \
+ _CAP(CAP285, 0, "x-cap285"), \
+ _CAP(CAP286, 0, "x-cap286"), \
+ _CAP(CAP287, 0, "x-cap287"), \
+ _CAP(CAP288, 0, "x-cap288"), \
+ _CAP(CAP289, 0, "x-cap289"), \
+ _CAP(CAP290, 0, "x-cap290"), \
+ _CAP(CAP291, 0, "x-cap291"), \
+ _CAP(CAP292, 0, "x-cap292"), \
+ _CAP(CAP293, 0, "x-cap293"), \
+ _CAP(CAP294, 0, "x-cap294"), \
+ _CAP(CAP295, 0, "x-cap295"), \
+ _CAP(CAP296, 0, "x-cap296"), \
+ _CAP(CAP297, 0, "x-cap297"), \
+ _CAP(CAP298, 0, "x-cap298"), \
+ _CAP(CAP299, 0, "x-cap299"), \
+ _CAP(CAP300, 0, "x-cap300"), \
+ _CAP(CAP301, 0, "x-cap301"), \
+ _CAP(CAP302, 0, "x-cap302"), \
+ _CAP(CAP303, 0, "x-cap303"), \
+ _CAP(CAP304, 0, "x-cap304"), \
+ _CAP(CAP305, 0, "x-cap305"), \
+ _CAP(CAP306, 0, "x-cap306"), \
+ _CAP(CAP307, 0, "x-cap307"), \
+ _CAP(CAP308, 0, "x-cap308"), \
+ _CAP(CAP309, 0, "x-cap309"), \
+ _CAP(CAP310, 0, "x-cap310"), \
+ _CAP(CAP311, 0, "x-cap311"), \
+ _CAP(CAP312, 0, "x-cap312"), \
+ _CAP(CAP313, 0, "x-cap313"), \
+ _CAP(CAP314, 0, "x-cap314"), \
+ _CAP(CAP315, 0, "x-cap315"), \
+ _CAP(CAP316, 0, "x-cap316"), \
+ _CAP(CAP317, 0, "x-cap317"), \
+ _CAP(CAP318, 0, "x-cap318"), \
+ _CAP(CAP319, 0, "x-cap319"), \
+ _CAP(CAP320, 0, "x-cap320"), \
+ _CAP(CAP321, 0, "x-cap321"), \
+ _CAP(CAP322, 0, "x-cap322"), \
+ _CAP(CAP323, 0, "x-cap323"), \
+ _CAP(CAP324, 0, "x-cap324"), \
+ _CAP(CAP325, 0, "x-cap325"), \
+ _CAP(CAP326, 0, "x-cap326"), \
+ _CAP(CAP327, 0, "x-cap327"), \
+ _CAP(CAP328, 0, "x-cap328"), \
+ _CAP(CAP329, 0, "x-cap329"), \
+ _CAP(CAP330, 0, "x-cap330"), \
+ _CAP(CAP331, 0, "x-cap331"), \
+ _CAP(CAP332, 0, "x-cap332"), \
+ _CAP(CAP333, 0, "x-cap333"), \
+ _CAP(CAP334, 0, "x-cap334"), \
+ _CAP(CAP335, 0, "x-cap335"), \
+ _CAP(CAP336, 0, "x-cap336"), \
+ _CAP(CAP337, 0, "x-cap337"), \
+ _CAP(CAP338, 0, "x-cap338"), \
+ _CAP(CAP339, 0, "x-cap339"), \
+ _CAP(CAP340, 0, "x-cap340"), \
+ _CAP(CAP341, 0, "x-cap341"), \
+ _CAP(CAP342, 0, "x-cap342"), \
+ _CAP(CAP343, 0, "x-cap343"), \
+ _CAP(CAP344, 0, "x-cap344"), \
+ _CAP(CAP345, 0, "x-cap345"), \
+ _CAP(CAP346, 0, "x-cap346"), \
+ _CAP(CAP347, 0, "x-cap347"), \
+ _CAP(CAP348, 0, "x-cap348"), \
+ _CAP(CAP349, 0, "x-cap349"), \
+ _CAP(CAP350, 0, "x-cap350"), \
+ _CAP(CAP351, 0, "x-cap351"), \
+ _CAP(CAP352, 0, "x-cap352"), \
+ _CAP(CAP353, 0, "x-cap353"), \
+ _CAP(CAP354, 0, "x-cap354"), \
+ _CAP(CAP355, 0, "x-cap355"), \
+ _CAP(CAP356, 0, "x-cap356"), \
+ _CAP(CAP357, 0, "x-cap357"), \
+ _CAP(CAP358, 0, "x-cap358"), \
+ _CAP(CAP359, 0, "x-cap359"), \
+ _CAP(CAP360, 0, "x-cap360"), \
+ _CAP(CAP361, 0, "x-cap361"), \
+ _CAP(CAP362, 0, "x-cap362"), \
+ _CAP(CAP363, 0, "x-cap363"), \
+ _CAP(CAP364, 0, "x-cap364"), \
+ _CAP(CAP365, 0, "x-cap365"), \
+ _CAP(CAP366, 0, "x-cap366"), \
+ _CAP(CAP367, 0, "x-cap367"), \
+ _CAP(CAP368, 0, "x-cap368"), \
+ _CAP(CAP369, 0, "x-cap369"), \
+ _CAP(CAP370, 0, "x-cap370"), \
+ _CAP(CAP371, 0, "x-cap371"), \
+ _CAP(CAP372, 0, "x-cap372"), \
+ _CAP(CAP373, 0, "x-cap373"), \
+ _CAP(CAP374, 0, "x-cap374"), \
+ _CAP(CAP375, 0, "x-cap375"), \
+ _CAP(CAP376, 0, "x-cap376"), \
+ _CAP(CAP377, 0, "x-cap377"), \
+ _CAP(CAP378, 0, "x-cap378"), \
+ _CAP(CAP379, 0, "x-cap379"), \
+ _CAP(CAP380, 0, "x-cap380"), \
+ _CAP(CAP381, 0, "x-cap381"), \
+ _CAP(CAP382, 0, "x-cap382"), \
+ _CAP(CAP383, 0, "x-cap383"), \
+ _CAP(CAP384, 0, "x-cap384"), \
+ _CAP(CAP385, 0, "x-cap385"), \
+ _CAP(CAP386, 0, "x-cap386"), \
+ _CAP(CAP387, 0, "x-cap387"), \
+ _CAP(CAP388, 0, "x-cap388"), \
+ _CAP(CAP389, 0, "x-cap389"), \
+ _CAP(CAP390, 0, "x-cap390"), \
+ _CAP(CAP391, 0, "x-cap391"), \
+ _CAP(CAP392, 0, "x-cap392"), \
+ _CAP(CAP393, 0, "x-cap393"), \
+ _CAP(CAP394, 0, "x-cap394"), \
+ _CAP(CAP395, 0, "x-cap395"), \
+ _CAP(CAP396, 0, "x-cap396"), \
+ _CAP(CAP397, 0, "x-cap397"), \
+ _CAP(CAP398, 0, "x-cap398"), \
+ _CAP(CAP399, 0, "x-cap399"), \
+ _CAP(CAP400, 0, "x-cap400"), \
+ _CAP(CAP401, 0, "x-cap401"), \
+ _CAP(CAP402, 0, "x-cap402"), \
+ _CAP(CAP403, 0, "x-cap403"), \
+ _CAP(CAP404, 0, "x-cap404"), \
+ _CAP(CAP405, 0, "x-cap405"), \
+ _CAP(CAP406, 0, "x-cap406"), \
+ _CAP(CAP407, 0, "x-cap407"), \
+ _CAP(CAP408, 0, "x-cap408"), \
+ _CAP(CAP409, 0, "x-cap409"), \
+ _CAP(CAP410, 0, "x-cap410"), \
+ _CAP(CAP411, 0, "x-cap411"), \
+ _CAP(CAP412, 0, "x-cap412"), \
+ _CAP(CAP413, 0, "x-cap413"), \
+ _CAP(CAP414, 0, "x-cap414"), \
+ _CAP(CAP415, 0, "x-cap415"), \
+ _CAP(CAP416, 0, "x-cap416"), \
+ _CAP(CAP417, 0, "x-cap417"), \
+ _CAP(CAP418, 0, "x-cap418"), \
+ _CAP(CAP419, 0, "x-cap419"), \
+ _CAP(CAP420, 0, "x-cap420"), \
+ _CAP(CAP421, 0, "x-cap421"), \
+ _CAP(CAP422, 0, "x-cap422"), \
+ _CAP(CAP423, 0, "x-cap423"), \
+ _CAP(CAP424, 0, "x-cap424"), \
+ _CAP(CAP425, 0, "x-cap425"), \
+ _CAP(CAP426, 0, "x-cap426"), \
+ _CAP(CAP427, 0, "x-cap427"), \
+ _CAP(CAP428, 0, "x-cap428"), \
+ _CAP(CAP429, 0, "x-cap429"), \
+ _CAP(CAP430, 0, "x-cap430"), \
+ _CAP(CAP431, 0, "x-cap431"), \
+ _CAP(CAP432, 0, "x-cap432"), \
+ _CAP(CAP433, 0, "x-cap433"), \
+ _CAP(CAP434, 0, "x-cap434"), \
+ _CAP(CAP435, 0, "x-cap435"), \
+ _CAP(CAP436, 0, "x-cap436"), \
+ _CAP(CAP437, 0, "x-cap437"), \
+ _CAP(CAP438, 0, "x-cap438"), \
+ _CAP(CAP439, 0, "x-cap439"), \
+ _CAP(CAP440, 0, "x-cap440"), \
+ _CAP(CAP441, 0, "x-cap441"), \
+ _CAP(CAP442, 0, "x-cap442"), \
+ _CAP(CAP443, 0, "x-cap443"), \
+ _CAP(CAP444, 0, "x-cap444"), \
+ _CAP(CAP445, 0, "x-cap445"), \
+ _CAP(CAP446, 0, "x-cap446"), \
+ _CAP(CAP447, 0, "x-cap447"), \
+ _CAP(CAP448, 0, "x-cap448"), \
+ _CAP(CAP449, 0, "x-cap449"), \
+ _CAP(CAP450, 0, "x-cap450"), \
+ _CAP(CAP451, 0, "x-cap451"), \
+ _CAP(CAP452, 0, "x-cap452"), \
+ _CAP(CAP453, 0, "x-cap453"), \
+ _CAP(CAP454, 0, "x-cap454"), \
+ _CAP(CAP455, 0, "x-cap455"), \
+ _CAP(CAP456, 0, "x-cap456"), \
+ _CAP(CAP457, 0, "x-cap457"), \
+ _CAP(CAP458, 0, "x-cap458"), \
+ _CAP(CAP459, 0, "x-cap459"), \
+ _CAP(CAP460, 0, "x-cap460"), \
+ _CAP(CAP461, 0, "x-cap461"), \
+ _CAP(CAP462, 0, "x-cap462"), \
+ _CAP(CAP463, 0, "x-cap463"), \
+ _CAP(CAP464, 0, "x-cap464"), \
+ _CAP(CAP465, 0, "x-cap465"), \
+ _CAP(CAP466, 0, "x-cap466"), \
+ _CAP(CAP467, 0, "x-cap467"), \
+ _CAP(CAP468, 0, "x-cap468"), \
+ _CAP(CAP469, 0, "x-cap469"), \
+ _CAP(CAP470, 0, "x-cap470"), \
+ _CAP(CAP471, 0, "x-cap471"), \
+ _CAP(CAP472, 0, "x-cap472"), \
+ _CAP(CAP473, 0, "x-cap473"), \
+ _CAP(CAP474, 0, "x-cap474"), \
+ _CAP(CAP475, 0, "x-cap475"), \
+ _CAP(CAP476, 0, "x-cap476"), \
+ _CAP(CAP477, 0, "x-cap477"), \
+ _CAP(CAP478, 0, "x-cap478"), \
+ _CAP(CAP479, 0, "x-cap479"), \
+ _CAP(CAP480, 0, "x-cap480"), \
+ _CAP(CAP481, 0, "x-cap481"), \
+ _CAP(CAP482, 0, "x-cap482"), \
+ _CAP(CAP483, 0, "x-cap483"), \
+ _CAP(CAP484, 0, "x-cap484"), \
+ _CAP(CAP485, 0, "x-cap485"), \
+ _CAP(CAP486, 0, "x-cap486"), \
+ _CAP(CAP487, 0, "x-cap487"), \
+ _CAP(CAP488, 0, "x-cap488"), \
+ _CAP(CAP489, 0, "x-cap489"), \
+ _CAP(CAP490, 0, "x-cap490"), \
+ _CAP(CAP491, 0, "x-cap491"), \
+ _CAP(CAP492, 0, "x-cap492"), \
+ _CAP(CAP493, 0, "x-cap493"), \
+ _CAP(CAP494, 0, "x-cap494"), \
+ _CAP(CAP495, 0, "x-cap495"), \
+ _CAP(CAP496, 0, "x-cap496"), \
+ _CAP(CAP497, 0, "x-cap497"), \
+ _CAP(CAP498, 0, "x-cap498"), \
+ _CAP(CAP499, 0, "x-cap499"), \
+ _CAP(CAP500, 0, "x-cap500"), \
+ _CAP(CAP501, 0, "x-cap501"), \
+ _CAP(CAP502, 0, "x-cap502"), \
+ _CAP(CAP503, 0, "x-cap503"), \
+ _CAP(CAP504, 0, "x-cap504"), \
+ _CAP(CAP505, 0, "x-cap505"), \
+ _CAP(CAP506, 0, "x-cap506"), \
+ _CAP(CAP507, 0, "x-cap507"), \
+ _CAP(CAP508, 0, "x-cap508"), \
+ _CAP(CAP509, 0, "x-cap509"), \
+ _CAP(CAP510, 0, "x-cap510"), \
+ _CAP(CAP511, 0, "x-cap511"), \
+ _CAP(CAP512, 0, "x-cap512"), \
+ _CAP(CAP513, 0, "x-cap513"), \
+ _CAP(CAP514, 0, "x-cap514"), \
+ _CAP(CAP515, 0, "x-cap515"), \
+ _CAP(CAP516, 0, "x-cap516"), \
+ _CAP(CAP517, 0, "x-cap517"), \
+ _CAP(CAP518, 0, "x-cap518"), \
+ _CAP(CAP519, 0, "x-cap519"), \
+ _CAP(CAP520, 0, "x-cap520"), \
+ _CAP(CAP521, 0, "x-cap521"), \
+ _CAP(CAP522, 0, "x-cap522"), \
+ _CAP(CAP523, 0, "x-cap523"), \
+ _CAP(CAP524, 0, "x-cap524"), \
+ _CAP(CAP525, 0, "x-cap525"), \
+ _CAP(CAP526, 0, "x-cap526"), \
+ _CAP(CAP527, 0, "x-cap527"), \
+ _CAP(CAP528, 0, "x-cap528"), \
+ _CAP(CAP529, 0, "x-cap529"), \
+ _CAP(CAP530, 0, "x-cap530"), \
+ _CAP(CAP531, 0, "x-cap531"), \
+ _CAP(CAP532, 0, "x-cap532"), \
+ _CAP(CAP533, 0, "x-cap533"), \
+ _CAP(CAP534, 0, "x-cap534"), \
+ _CAP(CAP535, 0, "x-cap535"), \
+ _CAP(CAP536, 0, "x-cap536"), \
+ _CAP(CAP537, 0, "x-cap537"), \
+ _CAP(CAP538, 0, "x-cap538"), \
+ _CAP(CAP539, 0, "x-cap539"), \
+ _CAP(CAP540, 0, "x-cap540"), \
+ _CAP(CAP541, 0, "x-cap541"), \
+ _CAP(CAP542, 0, "x-cap542"), \
+ _CAP(CAP543, 0, "x-cap543"), \
+ _CAP(CAP544, 0, "x-cap544"), \
+ _CAP(CAP545, 0, "x-cap545"), \
+ _CAP(CAP546, 0, "x-cap546"), \
+ _CAP(CAP547, 0, "x-cap547"), \
+ _CAP(CAP548, 0, "x-cap548"), \
+ _CAP(CAP549, 0, "x-cap549"), \
+ _CAP(CAP550, 0, "x-cap550"), \
+ _CAP(CAP551, 0, "x-cap551"), \
+ _CAP(CAP552, 0, "x-cap552"), \
+ _CAP(CAP553, 0, "x-cap553"), \
+ _CAP(CAP554, 0, "x-cap554"), \
+ _CAP(CAP555, 0, "x-cap555"), \
+ _CAP(CAP556, 0, "x-cap556"), \
+ _CAP(CAP557, 0, "x-cap557"), \
+ _CAP(CAP558, 0, "x-cap558"), \
+ _CAP(CAP559, 0, "x-cap559"), \
+ _CAP(CAP560, 0, "x-cap560"), \
+ _CAP(CAP561, 0, "x-cap561"), \
+ _CAP(CAP562, 0, "x-cap562"), \
+ _CAP(CAP563, 0, "x-cap563"), \
+ _CAP(CAP564, 0, "x-cap564"), \
+ _CAP(CAP565, 0, "x-cap565"), \
+ _CAP(CAP566, 0, "x-cap566"), \
+ _CAP(CAP567, 0, "x-cap567"), \
+ _CAP(CAP568, 0, "x-cap568"), \
+ _CAP(CAP569, 0, "x-cap569"), \
+ _CAP(CAP570, 0, "x-cap570"), \
+ _CAP(CAP571, 0, "x-cap571"), \
+ _CAP(CAP572, 0, "x-cap572"), \
+ _CAP(CAP573, 0, "x-cap573"), \
+ _CAP(CAP574, 0, "x-cap574"), \
+ _CAP(CAP575, 0, "x-cap575"), \
+ _CAP(CAP576, 0, "x-cap576"), \
+ _CAP(CAP577, 0, "x-cap577"), \
+ _CAP(CAP578, 0, "x-cap578"), \
+ _CAP(CAP579, 0, "x-cap579"), \
+ _CAP(CAP580, 0, "x-cap580"), \
+ _CAP(CAP581, 0, "x-cap581"), \
+ _CAP(CAP582, 0, "x-cap582"), \
+ _CAP(CAP583, 0, "x-cap583"), \
+ _CAP(CAP584, 0, "x-cap584"), \
+ _CAP(CAP585, 0, "x-cap585"), \
+ _CAP(CAP586, 0, "x-cap586"), \
+ _CAP(CAP587, 0, "x-cap587"), \
+ _CAP(CAP588, 0, "x-cap588"), \
+ _CAP(CAP589, 0, "x-cap589"), \
+ _CAP(CAP590, 0, "x-cap590"), \
+ _CAP(CAP591, 0, "x-cap591"), \
+ _CAP(CAP592, 0, "x-cap592"), \
+ _CAP(CAP593, 0, "x-cap593"), \
+ _CAP(CAP594, 0, "x-cap594"), \
+ _CAP(CAP595, 0, "x-cap595"), \
+ _CAP(CAP596, 0, "x-cap596"), \
+ _CAP(CAP597, 0, "x-cap597"), \
+ _CAP(CAP598, 0, "x-cap598"), \
+ _CAP(CAP599, 0, "x-cap599")
+
+/** Client capabilities */
+enum Capab {
+#define _CAP(cap, flags, name) CAP_ ## cap
+ CAPLIST,
+#undef _CAP
+ _CAP_LAST_CAP
+};
+
+DECLARE_FLAGSET(CapSet, _CAP_LAST_CAP);
+
+#define CapHas(cs, cap) FlagHas(cs, cap)
+#define CapSet(cs, cap) FlagSet(cs, cap)
+#define CapClr(cs, cap) FlagClr(cs, cap)
+
+#endif /* INCLUDED_capab_h */
Index: ircu2.10/include/client.h
diff -u ircu2.10/include/client.h:1.41 ircu2.10/include/client.h:1.42
--- ircu2.10/include/client.h:1.41 Wed Dec 15 19:28:51 2004
+++ ircu2.10/include/client.h Sat Dec 18 08:26:26 2004
@@ -19,7 +19,7 @@
*/
/** @file
* @brief Structures and functions for handling local clients.
- * @version $Id: client.h,v 1.41 2004/12/16 03:28:51 entrope Exp $
+ * @version $Id: client.h,v 1.42 2004/12/18 16:26:26 klmitch Exp $
*/
#ifndef INCLUDED_client_h
#define INCLUDED_client_h
@@ -176,6 +176,8 @@
/** Declare flagset type for user flags. */
DECLARE_FLAGSET(Flags, FLAG_LAST_FLAG);
+#include "capab.h" /* client capabilities */
+
/** Represents a local connection.
* This contains a lot of stuff irrelevant to server connections, but
* those are so rare as to not be worth special-casing.
@@ -255,11 +257,21 @@
struct irc_in_addr cli_ip; /**< Real IP of client */
short cli_status; /**< Client type */
struct Privs cli_privs; /**< Oper privileges */
+ struct CapSet cli_capab; /**< Client capabilities */
+ struct CapSet cli_active; /**< Active client capabilities */
+ unsigned long cli_unreg; /**< Indicate what still needs to be done */
char cli_name[HOSTLEN + 1]; /**< Unique name of the client, nick or host
*/
char cli_username[USERLEN + 1]; /**< username here now for auth stuff */
char cli_info[REALLEN + 1]; /**< Free form additional client information
*/
};
+#define CLIREG_NICK 0x0001 /**< Client must set nickname */
+#define CLIREG_USER 0x0002 /**< Client must set username */
+#define CLIREG_COOKIE 0x0004 /**< Client must return cookie */
+#define CLIREG_CAP 0x0008 /**< Client in capability negotiation */
+
+#define CLIREG_INIT (CLIREG_NICK | CLIREG_USER | CLIREG_COOKIE)
+
/** Magic constant to identify valid Client structures. */
#define CLIENT_MAGIC 0x4ca08286
@@ -307,6 +319,12 @@
#define cli_local(cli) (cli_from(cli) == cli)
/** Get oper privileges for client. */
#define cli_privs(cli) ((cli)->cli_privs)
+/** Get client capabilities for client */
+#define cli_capab(cli) (&((cli)->cli_capab))
+/** Get active client capabilities for client */
+#define cli_active(cli) (&((cli)->cli_active))
+/** Get flags for remaining registration tasks */
+#define cli_unreg(cli) ((cli)->cli_unreg)
/** Get client name. */
#define cli_name(cli) ((cli)->cli_name)
/** Get client username (ident). */
@@ -718,6 +736,11 @@
/** Test whether a privilege has been granted to a client. */
#define HasPriv(cli, priv) FlagHas(&cli_privs(cli), priv)
+/** Test whether a client has a capability */
+#define HasCap(cli, cap) CapHas(cli_capab(cli), (cap))
+/** Test whether a client has the capability active */
+#define CapActive(cli, cap) CapHas(cli_active(cli), (cap))
+
#define HIDE_IP 0 /**< Do not show IP address in get_client_name() */
#define SHOW_IP 1 /**< Show ident and IP address in get_client_name() */
Index: ircu2.10/include/handlers.h
diff -u ircu2.10/include/handlers.h:1.20 ircu2.10/include/handlers.h:1.21
--- ircu2.10/include/handlers.h:1.20 Mon Oct 4 21:21:37 2004
+++ ircu2.10/include/handlers.h Sat Dec 18 08:26:26 2004
@@ -19,7 +19,7 @@
*/
/** @file
* @brief Declarations for all protocol message handler functions.
- * @version $Id: handlers.h,v 1.20 2004/10/05 04:21:37 entrope Exp $
+ * @version $Id: handlers.h,v 1.21 2004/12/18 16:26:26 klmitch Exp $
*/
#ifndef INCLUDED_handlers_h
#define INCLUDED_handlers_h
@@ -88,6 +88,7 @@
extern int m_admin(struct Client*, struct Client*, int, char*[]);
extern int m_away(struct Client*, struct Client*, int, char*[]);
+extern int m_cap(struct Client*, struct Client*, int, char*[]);
extern int m_cnotice(struct Client*, struct Client*, int, char*[]);
extern int m_cprivmsg(struct Client*, struct Client*, int, char*[]);
extern int m_gline(struct Client*, struct Client*, int, char*[]);
Index: ircu2.10/include/msg.h
diff -u ircu2.10/include/msg.h:1.16 ircu2.10/include/msg.h:1.17
--- ircu2.10/include/msg.h:1.16 Mon Oct 4 21:21:37 2004
+++ ircu2.10/include/msg.h Sat Dec 18 08:26:26 2004
@@ -19,7 +19,7 @@
*/
/** @file
* @brief Command and token declarations and structures.
- * @version $Id: msg.h,v 1.16 2004/10/05 04:21:37 entrope Exp $
+ * @version $Id: msg.h,v 1.17 2004/12/18 16:26:26 klmitch Exp $
*/
#ifndef INCLUDED_msg_h
#define INCLUDED_msg_h
@@ -355,6 +355,10 @@
#define MSG_PRIVS "PRIVS" /* PRIV */
#define TOK_PRIVS "PRIVS"
+#define MSG_CAP "CAP"
+#define TOK_CAP "CAP"
+#define CMD_CAP MSG_CAP, TOK_CAP
+
/*
* Constants
*/
Index: ircu2.10/include/numeric.h
diff -u ircu2.10/include/numeric.h:1.34 ircu2.10/include/numeric.h:1.35
--- ircu2.10/include/numeric.h:1.34 Sat Oct 16 17:54:23 2004
+++ ircu2.10/include/numeric.h Sat Dec 18 08:26:26 2004
@@ -18,7 +18,7 @@
*/
/** @file
* @brief Declarations of numeric replies and supporting functions.
- * @version $Id: numeric.h,v 1.34 2004/10/17 00:54:23 entrope Exp $
+ * @version $Id: numeric.h,v 1.35 2004/12/18 16:26:26 klmitch Exp $
*/
#ifndef INCLUDED_numeric_h
#define INCLUDED_numeric_h
@@ -325,7 +325,7 @@
/* ERR_NOSUCHSERVICE 408 IRCnet */
/* ERR_NOCOLORSONCHAN 408 Dalnet */
#define ERR_NOORIGIN 409
-
+#define ERR_UNKNOWNCAPCMD 410
#define ERR_NORECIPIENT 411
#define ERR_NOTEXTTOSEND 412
#define ERR_NOTOPLEVEL 413
Index: ircu2.10/ircd/Makefile.in
diff -u ircu2.10/ircd/Makefile.in:1.63 ircu2.10/ircd/Makefile.in:1.64
--- ircu2.10/ircd/Makefile.in:1.63 Sun Nov 7 13:13:57 2004
+++ ircu2.10/ircd/Makefile.in Sat Dec 18 08:26:26 2004
@@ -115,6 +115,7 @@
m_asll.c \
m_away.c \
m_burst.c \
+ m_cap.c \
m_clearmode.c \
m_close.c \
m_connect.c \
Index: ircu2.10/ircd/ircd_string.c
diff -u ircu2.10/ircd/ircd_string.c:1.16 ircu2.10/ircd/ircd_string.c:1.17
--- ircu2.10/ircd/ircd_string.c:1.16 Fri Dec 10 21:13:45 2004
+++ ircu2.10/ircd/ircd_string.c Sat Dec 18 08:26:27 2004
@@ -18,7 +18,7 @@
*/
/** @file
* @brief Implementation of string operations.
- * @version $Id: ircd_string.c,v 1.16 2004/12/11 05:13:45 klmitch Exp $
+ * @version $Id: ircd_string.c,v 1.17 2004/12/18 16:26:27 klmitch Exp $
*/
#include "config.h"
@@ -262,7 +262,7 @@
else
++rb;
}
- return (*ra - *rb);
+ return (ToLower(*ra) - ToLower(*rb));
}
/** Case insensitive comparison of the starts of two strings.
@@ -285,7 +285,7 @@
else
++rb;
}
- return (*ra - *rb);
+ return (ToLower(*ra) - ToLower(*rb));
}
/** Fill a vector of distinct names from a delimited input list.
Index: ircu2.10/ircd/list.c
diff -u ircu2.10/ircd/list.c:1.29 ircu2.10/ircd/list.c:1.30
--- ircu2.10/ircd/list.c:1.29 Fri Dec 10 21:13:45 2004
+++ ircu2.10/ircd/list.c Sat Dec 18 08:26:27 2004
@@ -19,7 +19,7 @@
*/
/** @file
* @brief Singly and doubly linked list manipulation implementation.
- * @version $Id: list.c,v 1.29 2004/12/11 05:13:45 klmitch Exp $
+ * @version $Id: list.c,v 1.30 2004/12/18 16:26:27 klmitch Exp $
*/
#include "config.h"
@@ -245,6 +245,7 @@
cli_connect(cptr) = con; /* set the connection and other fields */
cli_since(cptr) = cli_lasttime(cptr) = cli_firsttime(cptr) = CurrentTime;
cli_lastnick(cptr) = TStime();
+ cli_unreg(cptr) = CLIREG_INIT;
} else
cli_connect(cptr) = cli_connect(from); /* use 'from's connection */
Index: ircu2.10/ircd/m_cap.c
diff -u /dev/null ircu2.10/ircd/m_cap.c:1.1
--- /dev/null Sat Dec 18 08:26:39 2004
+++ ircu2.10/ircd/m_cap.c Sat Dec 18 08:26:27 2004
@@ -0,0 +1,370 @@
+/*
+ * IRC - Internet Relay Chat, ircd/m_cap.c
+ * Copyright (C) 2004 Kevin L. Mitchell <[EMAIL PROTECTED]>
+ *
+ * See file AUTHORS in IRC package for additional names of
+ * the programmers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: m_cap.c,v 1.1 2004/12/18 16:26:27 klmitch Exp $
+ */
+
+/*
+ * m_functions execute protocol messages on this server:
+ *
+ * cptr is always NON-NULL, pointing to a *LOCAL* client
+ * structure (with an open socket connected!). This
+ * identifies the physical socket where the message
+ * originated (or which caused the m_function to be
+ * executed--some m_functions may call others...).
+ *
+ * sptr is the source of the message, defined by the
+ * prefix part of the message if present. If not
+ * or prefix not found, then sptr==cptr.
+ *
+ * (!IsServer(cptr)) => (cptr == sptr), because
+ * prefixes are taken *only* from servers...
+ *
+ * (IsServer(cptr))
+ * (sptr == cptr) => the message didn't
+ * have the prefix.
+ *
+ * (sptr != cptr && IsServer(sptr) means
+ * the prefix specified servername. (?)
+ *
+ * (sptr != cptr && !IsServer(sptr) means
+ * that message originated from a remote
+ * user (not local).
+ *
+ * combining
+ *
+ * (!IsServer(sptr)) means that, sptr can safely
+ * taken as defining the target structure of the
+ * message in this server.
+ *
+ * *Always* true (if 'parse' and others are working correct):
+ *
+ * 1) sptr->from == cptr (note: cptr->from == cptr)
+ *
+ * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr
+ * *cannot* be a local connection, unless it's
+ * actually cptr!). [MyConnect(x) should probably
+ * be defined as (x == x->from) --msa ]
+ *
+ * parc number of variable parameter strings (if zero,
+ * parv is allowed to be NULL)
+ *
+ * parv a NULL terminated list of parameter pointers,
+ *
+ * parv[0], sender (prefix string), if not present
+ * this points to an empty string.
+ * parv[1]...parv[parc-1]
+ * pointers to additional parameters
+ * parv[parc] == NULL, *always*
+ *
+ * note: it is guaranteed that parv[0]..parv[parc-1] are all
+ * non-NULL pointers.
+ */
+#include "config.h"
+
+#include "client.h"
+#include "ircd.h"
+#include "ircd_chattr.h"
+#include "ircd_log.h"
+#include "ircd_reply.h"
+#include "ircd_snprintf.h"
+#include "ircd_string.h"
+#include "msg.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_user.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+typedef int (*bqcmp)(const void *, const void *);
+
+static struct capabilities {
+ enum Capab cap;
+ char *capstr;
+ unsigned long flags;
+ char *name;
+ int namelen;
+} capab_list[] = {
+#define _CAP(cap, flags, name) \
+ { CAP_ ## cap, #cap, (flags), (name), sizeof(name) - 1 }
+ CAPLIST
+#undef _CAP
+};
+
+#define CAPAB_LIST_LEN (sizeof(capab_list) / sizeof(struct capabilities))
+
+static struct CapSet clean_set; /* guaranteed to be all zeros (right?) */
+
+static int
+capab_sort(const struct capabilities *cap1, const struct capabilities *cap2)
+{
+ return ircd_strcmp(cap1->name, cap2->name);
+}
+
+static int
+capab_search(const char *key, const struct capabilities *cap)
+{
+ const char *rb = cap->name;
+ while (ToLower(*key) == ToLower(*rb)) /* walk equivalent part of strings */
+ if (!*key++) /* hit the end, all right... */
+ return 0;
+ else /* OK, let's move on... */
+ rb++;
+
+ /* If the character they differ on happens to be a space, and it happens
+ * to be the same length as the capability name, then we've found a
+ * match; otherwise, return the difference of the two.
+ */
+ return (IsSpace(*key) && !*rb) ? 0 : (ToLower(*key) - ToLower(*rb));
+}
+
+static struct capabilities *
+find_cap(const char **caplist_p, int *neg_p)
+{
+ static int inited = 0;
+ const char *caplist = *caplist_p;
+ struct capabilities *cap = 0;
+
+ *neg_p = 0; /* clear negative flag... */
+
+ if (!inited) { /* First, let's sort the array... */
+ qsort(capab_list, CAPAB_LIST_LEN, sizeof(struct capabilities),
+ (bqcmp)capab_sort);
+ inited++; /* remember that we've done this step... */
+ }
+
+ /* Next, find first non-whitespace character... */
+ while (*caplist && IsSpace(*caplist))
+ caplist++;
+
+ /* We are now at the beginning of an element of the list; is it negative? */
+ if (*caplist == '-') {
+ caplist++; /* yes; step past the flag... */
+ *neg_p = 1; /* remember that it is negative... */
+ }
+
+ /* OK, now see if we can look up the capability... */
+ if (*caplist) {
+ if (!(cap = (struct capabilities *)bsearch(caplist, capab_list,
+ CAPAB_LIST_LEN,
+ sizeof(struct capabilities),
+ (bqcmp)capab_search))) {
+ /* Couldn't find the capability; advance to first whitespace character */
+ while (*caplist && !IsSpace(*caplist))
+ caplist++;
+ } else
+ caplist += cap->namelen; /* advance to end of capability name */
+ }
+
+ assert(caplist != *caplist_p || !*caplist); /* we *must* advance */
+
+ /* move ahead in capability list string--or zero pointer if we hit end */
+ *caplist_p = *caplist ? caplist : 0;
+
+ return cap; /* and return the capability (if any) */
+}
+
+static int
+send_caplist(struct Client *sptr, const struct CapSet *cs)
+{
+ char capbuf[BUFSIZE] = "";
+ struct MsgBuf *mb;
+ int i, loc, len;
+
+ /* set up the buffer for the LSL message... */
+ mb = msgq_make(sptr, "%:#C " MSG_CAP " LSL :", &me);
+
+ for (i = 0, loc = 0; i < CAPAB_LIST_LEN; i++) {
+ if (cs ? !CapHas(cs, capab_list[i].cap) :
+ (capab_list[i].flags & CAPFL_HIDDEN))
+ continue; /* not including this capability in the list */
+
+ len = capab_list[i].namelen + (loc != 0); /* how much we'd add... */
+
+ if (msgq_bufleft(mb) < loc + len) { /* would add too much; must flush */
+ sendcmdto_one(&me, CMD_CAP, sptr, "LS :%s", capbuf);
+ capbuf[(loc = 0)] = '\0'; /* re-terminate the buffer... */
+ }
+
+ loc += ircd_snprintf(0, capbuf + loc, sizeof(capbuf) - loc, "%s%s",
+ loc ? " " : "", capab_list[i].name);
+ }
+
+ msgq_append(0, mb, "%s", capbuf); /* append capabilities to the LSL cmd */
+ send_buffer(sptr, mb, 0); /* send them out... */
+ msgq_clean(mb); /* and release the buffer */
+
+ return 0; /* convenience return */
+}
+
+static int
+cap_empty(struct Client *sptr, const char *caplist)
+{
+ if (IsUnknown(sptr)) /* registration hasn't completed; suspend it... */
+ cli_unreg(sptr) |= CLIREG_CAP;
+
+ return send_caplist(sptr, 0); /* send list of capabilities */
+}
+
+static int
+cap_req(struct Client *sptr, const char *caplist)
+{
+ const char *cl = caplist;
+ struct capabilities *cap;
+ struct CapSet cs = *cli_capab(sptr); /* capability set */
+ struct CapSet as = *cli_active(sptr); /* active set */
+ int neg;
+
+ if (IsUnknown(sptr)) /* registration hasn't completed; suspend it... */
+ cli_unreg(sptr) |= CLIREG_CAP;
+
+ while (cl) { /* walk through the capabilities list... */
+ if (!(cap = find_cap(&cl, &neg)) || /* look up capability... */
+ (!neg && (cap->flags & CAPFL_PROHIBIT))) { /* is it prohibited? */
+ sendcmdto_one(&me, CMD_CAP, sptr, "NAK :%s", caplist);
+ return 0; /* can't complete requested op... */
+ }
+
+ if (neg) { /* set or clear the capability... */
+ CapClr(&cs, cap->cap);
+ if (!(cap->flags & CAPFL_PROTO))
+ CapClr(&as, cap->cap);
+ } else {
+ CapSet(&cs, cap->cap);
+ if (!(cap->flags & CAPFL_PROTO))
+ CapSet(&as, cap->cap);
+ }
+ }
+
+ sendcmdto_one(&me, CMD_CAP, sptr, "ACK :%s", caplist);
+
+ *cli_capab(sptr) = cs; /* copy the completed results */
+ *cli_active(sptr) = as;
+
+ return 0;
+}
+
+static int
+cap_ack(struct Client *sptr, const char *caplist)
+{
+ const char *cl = caplist;
+ struct capabilities *cap;
+ int neg;
+
+ while (cl) { /* walk through the capabilities list... */
+ if (!(cap = find_cap(&cl, &neg)) || /* look up capability... */
+ (neg ? HasCap(sptr, cap->cap) : !HasCap(sptr, cap->cap))) /* uh... */
+ continue;
+
+ if (neg) /* set or clear the active capability... */
+ CapClr(cli_active(sptr), cap->cap);
+ else
+ CapSet(cli_active(sptr), cap->cap);
+ }
+
+ return 0;
+}
+
+static int
+cap_clear(struct Client *sptr, const char *caplist)
+{
+ sendcmdto_one(&me, CMD_CAP, sptr, "CLEAR"); /* Reply... */
+
+ *cli_capab(sptr) = clean_set; /* then clear! */
+
+ return 0;
+}
+
+static int
+cap_end(struct Client *sptr, const char *caplist)
+{
+ if (!IsUnknown(sptr)) /* registration has completed... */
+ return 0; /* so just ignore the message... */
+
+ cli_unreg(sptr) &= ~CLIREG_CAP; /* capability negotiation is now done... */
+
+ if (!cli_unreg(sptr)) /* if client is now done... */
+ return register_user(sptr, sptr, cli_name(sptr), cli_user(sptr)->username);
+
+ return 0; /* Can't do registration yet... */
+}
+
+static int
+cap_list(struct Client *sptr, const char *caplist)
+{
+ /* Send the list of the client's capabilities */
+ return send_caplist(sptr, cli_capab(sptr));
+}
+
+static struct subcmd {
+ char *cmd;
+ int (*proc)(struct Client *sptr, const char *caplist);
+} cmdlist[] = {
+ { "", cap_empty },
+ { "ACK", cap_ack },
+ { "CLEAR", cap_clear },
+ { "END", cap_end },
+ { "LIST", cap_list },
+ { "LS", 0 },
+ { "LSL", 0 },
+ { "NAK", 0 },
+ { "REQ", cap_req }
+};
+
+static int
+subcmd_search(const char *cmd, const struct subcmd *elem)
+{
+ return ircd_strcmp(cmd, elem->cmd);
+}
+
+/*
+ * m_cap - user message handler
+ *
+ * parv[0] = Send prefix
+ *
+ * From user:
+ *
+ * parv[1] = [<subcommand>]
+ * parv[2] = [<capab list>]
+ *
+ */
+int
+m_cap(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
+{
+ char *subcmd = "", *caplist = 0;
+ struct subcmd *cmd;
+
+ if (parc > 1 && parv[1]) /* a subcommand was provided */
+ subcmd = parv[1];
+ if (parc > 2) /* a capability list was provided */
+ caplist = parv[2];
+
+ /* find the subcommand handler */
+ if (!(cmd = (struct subcmd *)bsearch(subcmd, cmdlist,
+ sizeof(cmdlist) / sizeof(struct subcmd),
+ sizeof(struct subcmd),
+ (bqcmp)subcmd_search)))
+ return send_reply(sptr, ERR_UNKNOWNCAPCMD, subcmd);
+
+ /* then execute it... */
+ return cmd->proc ? (cmd->proc)(sptr, caplist) : 0;
+}
Index: ircu2.10/ircd/m_pong.c
diff -u ircu2.10/ircd/m_pong.c:1.15 ircu2.10/ircd/m_pong.c:1.16
--- ircu2.10/ircd/m_pong.c:1.15 Fri Dec 10 21:13:48 2004
+++ ircu2.10/ircd/m_pong.c Sat Dec 18 08:26:27 2004
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: m_pong.c,v 1.15 2004/12/11 05:13:48 klmitch Exp $
+ * $Id: m_pong.c,v 1.16 2004/12/18 16:26:27 klmitch Exp $
*/
/*
@@ -170,7 +170,8 @@
if (0 != cli_cookie(sptr) && COOKIE_VERIFIED != cli_cookie(sptr)) {
if (parc > 1 && cli_cookie(sptr) == atol(parv[parc - 1])) {
cli_cookie(sptr) = COOKIE_VERIFIED;
- if (cli_user(sptr) && *(cli_user(sptr))->host && (cli_name(sptr))[0])
+ cli_unreg(sptr) &= ~CLIREG_COOKIE; /* cookie has been returned... */
+ if (!cli_unreg(sptr)) /* no more registration tasks... */
/*
* NICK and USER OK
*/
Index: ircu2.10/ircd/m_user.c
diff -u ircu2.10/ircd/m_user.c:1.8 ircu2.10/ircd/m_user.c:1.9
--- ircu2.10/ircd/m_user.c:1.8 Fri Dec 10 21:14:03 2004
+++ ircu2.10/ircd/m_user.c Sat Dec 18 08:26:27 2004
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: m_user.c,v 1.8 2004/12/11 05:14:03 klmitch Exp $
+ * $Id: m_user.c,v 1.9 2004/12/18 16:26:27 klmitch Exp $
*/
/*
@@ -144,7 +144,9 @@
user->server = &me;
ircd_strncpy(cli_info(cptr), info, REALLEN);
- if ((cli_name(cptr))[0] && cli_cookie(cptr) == COOKIE_VERIFIED) {
+ cli_unreg(sptr) &= ~CLIREG_USER; /* username now set */
+
+ if (!cli_unreg(sptr)) {
/*
* NICK and PONG already received, now we have USER...
*/
Index: ircu2.10/ircd/parse.c
diff -u ircu2.10/ircd/parse.c:1.47 ircu2.10/ircd/parse.c:1.48
--- ircu2.10/ircd/parse.c:1.47 Fri Dec 10 21:14:04 2004
+++ ircu2.10/ircd/parse.c Sat Dec 18 08:26:27 2004
@@ -19,7 +19,7 @@
*/
/** @file
* @brief Parse input from IRC clients and other servers.
- * @version $Id: parse.c,v 1.47 2004/12/11 05:14:04 klmitch Exp $
+ * @version $Id: parse.c,v 1.48 2004/12/18 16:26:27 klmitch Exp $
*/
#include "config.h"
@@ -616,6 +616,13 @@
/* UNREG, CLIENT, SERVER, OPER, SERVICE */
{ m_ignore, m_not_oper, ms_asll, mo_asll, m_ignore }
},
+ {
+ MSG_CAP,
+ TOK_CAP,
+ 0, MAXPARA, 0, 0, NULL,
+ /* UNREG, CLIENT, SERVER, OPER, SERVICE */
+ { m_cap, m_cap, m_ignore, m_cap, m_ignore }
+ },
/* This command is an alias for QUIT during the unregistered part of
* of the server. This is because someone jumping via a broken web
* proxy will send a 'POST' as their first command - which we will
Index: ircu2.10/ircd/s_err.c
diff -u ircu2.10/ircd/s_err.c:1.61 ircu2.10/ircd/s_err.c:1.62
--- ircu2.10/ircd/s_err.c:1.61 Fri Dec 10 21:14:04 2004
+++ ircu2.10/ircd/s_err.c Sat Dec 18 08:26:27 2004
@@ -18,7 +18,7 @@
*/
/** @file
* @brief Error handling support.
- * @version $Id: s_err.c,v 1.61 2004/12/11 05:14:04 klmitch Exp $
+ * @version $Id: s_err.c,v 1.62 2004/12/18 16:26:27 klmitch Exp $
*/
#include "config.h"
@@ -852,7 +852,7 @@
/* 409 */
{ ERR_NOORIGIN, ":No origin specified", "409" },
/* 410 */
- { 0 },
+ { ERR_UNKNOWNCAPCMD, "%s :Unknown CAP subcommand", "410" },
/* 411 */
{ ERR_NORECIPIENT, ":No recipient given (%s)", "411" },
/* 412 */
Index: ircu2.10/ircd/s_user.c
diff -u ircu2.10/ircd/s_user.c:1.85 ircu2.10/ircd/s_user.c:1.86
--- ircu2.10/ircd/s_user.c:1.85 Sat Dec 18 07:09:13 2004
+++ ircu2.10/ircd/s_user.c Sat Dec 18 08:26:27 2004
@@ -22,7 +22,7 @@
*/
/** @file
* @brief Miscellaneous user-related helper functions.
- * @version $Id: s_user.c,v 1.85 2004/12/18 15:09:13 entrope Exp $
+ * @version $Id: s_user.c,v 1.86 2004/12/18 16:26:27 klmitch Exp $
*/
#include "config.h"
@@ -408,6 +408,7 @@
static time_t last_too_many2;
assert(cptr == sptr);
+ assert(cli_unreg(sptr) == 0);
if (!IsIAuthed(sptr)) {
if (iauth_active)
return iauth_start_client(iauth_active, sptr);
@@ -867,6 +868,8 @@
}
hAddClient(sptr);
+ cli_unreg(sptr) &= ~CLIREG_NICK; /* nickname now set */
+
/*
* If the client hasn't gotten a cookie-ping yet,
* choose a cookie and send it. [EMAIL PROTECTED]
@@ -877,7 +880,7 @@
} while (!cli_cookie(sptr));
sendrawto_one(cptr, MSG_PING " :%u", cli_cookie(sptr));
}
- else if (*(cli_user(sptr))->host && cli_cookie(sptr) == COOKIE_VERIFIED) {
+ else if (!cli_unreg(sptr)) {
/*
* USER and PONG already received, now we have NICK.
* register_user may reject the client and call exit_client
----------------------- End of diff -----------------------