]> jfr.im git - irc/freenode/solanum.git/commitdiff
Add `attainable` client capability callback origin/edk/cap-attainable
authorEd Kellett <redacted>
Sat, 17 Oct 2020 21:54:32 +0000 (22:54 +0100)
committerEd Kellett <redacted>
Sat, 17 Oct 2020 21:54:32 +0000 (22:54 +0100)
include/s_serv.h
modules/m_cap.c

index 6808c37e9aa786befbd9cf94f869258986a5e3ae..09c46d9884d40d76982eac9673359004ac2a1866 100644 (file)
@@ -55,6 +55,7 @@ extern struct CapabilityIndex *cli_capindex;
 
 struct ClientCapability {
        bool (*visible)(struct Client *);               /* whether or not to display the capability.  set to NULL or true return value = displayed */
+       bool (*attainable)(struct Client *);            /* whether or not to give this capability upon request.  set to NULL uses visible() */
        const char *(*data)(struct Client *);           /* any custom data for the capability.  set to NULL or return NULL = no data */
        unsigned int flags;
 };
index 6dc58cbab55d71433ea407f945e132461d3f48e4..4f3242bd067c259f22b58954066301eeaa506bbd 100644 (file)
@@ -81,6 +81,28 @@ clicap_visible(struct Client *client_p, const struct CapabilityEntry *cap)
        return clicap->visible(client_p);
 }
 
+static inline int
+clicap_attainable(struct Client *client_p, const struct CapabilityEntry *cap)
+{
+       struct ClientCapability *clicap;
+
+       if (cap->flags & CAP_ORPHANED)
+               return 0;
+
+       if (cap->ownerdata == NULL)
+               return 1;
+
+       clicap = cap->ownerdata;
+
+       if (clicap->attainable != NULL)
+               return clicap->attainable(client_p);
+
+       if (clicap->visible != NULL)
+               return clicap->visible(client_p);
+
+       return 1;
+}
+
 /* clicap_find()
  *   Used iteratively over a buffer, extracts individual cap tokens.
  *
@@ -341,7 +363,7 @@ cap_req(struct Client *source_p, const char *arg)
                }
                else
                {
-                       if (!clicap_visible(source_p, cap))
+                       if (!clicap_attainable(source_p, cap))
                        {
                                finished = 0;
                                break;