Bez tytułu

z Sloppy Cockroach, 10 miesiące temu, napisane w C, wyświetlone 109 razy. [paste_expire] 3 tygodnie.
URL https://pastebin.k4be.pl/view/fb12fd4b Udostępnij
Pobierz wklejkę lub Pokaż surowy tekst
  1. /* Copyright (C) All Rights Reserved
  2. ** Written by k4be, partially based on src/modules/message.c
  3. ** License: GPLv3 https://www.gnu.org/licenses/gpl-3.0.html
  4. ** A lot of code is copied from message.c, as MSGTAG spec requires same behavior
  5. ** as with PRIVMSG, and functions used inside message.c are not reachable from here.
  6. ** UnrealIRCd distribution does not implement MSGTAG by choice.
  7. */
  8.  
  9. #include "unrealircd.h"
  10.  
  11. int clienttags_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
  12. int clienttags_configposttest(int *errs);
  13. int clienttags_configrun(ConfigFile *cf, ConfigEntry *ce, int type);
  14.  
  15. struct ct *find_ct(char *name);
  16. int client_mtag_is_ok(Client *client, char *name, char *value);
  17. void mtag_inherit(Client *sender, MessageTag *recv_mtags, MessageTag **mtag_list, char *signature);
  18.  
  19. ModuleHeader MOD_HEADER = {
  20.         "third/client-tags",
  21.         "5.0beta2",
  22.         "Selective client tags support",
  23.         "k4be@PIRC",
  24.         "unrealircd-5",
  25. };
  26.  
  27. // config file stuff, based on Gottem's module
  28.  
  29. #define MYCONF "client-tags"
  30.  
  31. /*
  32. client-tags {
  33.         tag-name "+draft/typing";
  34. };
  35. */
  36.  
  37. struct ct {
  38.         char *name;
  39.         struct ct *next;
  40. };
  41.  
  42. struct {
  43.         int tempcount;
  44.         struct ct *cts;
  45. } ctdata;
  46.  
  47. MOD_TEST(){
  48.         // We have our own config block so we need to checkem config obv m9
  49.         // Priorities don't really matter here
  50.         ctdata.tempcount = 0;
  51.  
  52.         HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, clienttags_configtest);
  53.         HookAdd(modinfo->handle, HOOKTYPE_CONFIGPOSTTEST, 0, clienttags_configposttest);
  54.         return MOD_SUCCESS;
  55. }
  56.  
  57. int clienttags_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs) {
  58.         ConfigEntry *cep; // For looping through our bl0cc
  59.         int errors = 0; // Error count
  60.        
  61.         // Since we'll add a new top-level block to unrealircd.conf, need to filter on CONFIG_MAIN lmao
  62.         if(type != CONFIG_MAIN)
  63.                 return 0; // Returning 0 means idgaf bout dis
  64.  
  65.         // Check for valid config entries first
  66.         if(!ce || !ce->ce_varname)
  67.                 return 0;
  68.  
  69.         // If it isn't our bl0ck, idc
  70.         if(strcmp(ce->ce_varname, MYCONF))
  71.                 return 0;
  72.  
  73.         // Loop dat shyte fam
  74.         for(cep = ce->ce_entries; cep; cep = cep->ce_next) {
  75.                 // Do we even have a valid name l0l?
  76.                 if(!cep->ce_varname) {
  77.                         config_error("%s:%i: blank %s item", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF); // Rep0t error
  78.                         errors++; // Increment err0r count fam
  79.                         continue; // Next iteration imo tbh
  80.                 }
  81.        
  82.                 if(!strcmp(cep->ce_varname, "tag-name")) {
  83.                         // Check tag name format
  84.                         if(!cep->ce_vardata || strlen(cep->ce_vardata) < 2 || cep->ce_vardata[0] != '+') {
  85.                                 config_error("%s:%i: %s::%s value must not be empty and must start with \"+\" character", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname);
  86.                                 errors++; // Increment err0r count fam
  87.                                 break;
  88.                         }
  89.                         ctdata.tempcount++;
  90.                         continue;
  91.                 }
  92.  
  93.                 // Anything else is unknown to us =]
  94.                 config_warn("%s:%i: unknown item %s::%s", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, MYCONF, cep->ce_varname); // So display just a warning
  95.         }
  96.        
  97.         *errs = errors;
  98.         return errors ? -1 : 1; // Returning 1 means "all good", -1 means we shat our panties
  99. }
  100.  
  101. int clienttags_configposttest(int *errs) {
  102.         int errors = 0;
  103.         if(ctdata.tempcount == 0){
  104.                 config_error("[%s] No valid %s::tag-name entries found!", MOD_HEADER.name, MYCONF);
  105.                 errors++;
  106.         }
  107.         *errs = errors;
  108.         return errors ? -1 : 1;
  109. }
  110.  
  111.  
  112. // "Run" the config (everything should be valid at this point)
  113. int clienttags_configrun(ConfigFile *cf, ConfigEntry *ce, int type) {
  114.         ConfigEntry *cep; // For looping through our bl0cc
  115.         struct ct *prev_ct = NULL;
  116.         struct ct **ct = &ctdata.cts;
  117.  
  118.         // Since we'll add a new top-level block to unrealircd.conf, need to filter on CONFIG_MAIN lmao
  119.         if(type != CONFIG_MAIN)
  120.                 return 0; // Returning 0 means idgaf bout dis
  121.  
  122.         // Check for valid config entries first
  123.         if(!ce || !ce->ce_varname)
  124.                 return 0;
  125.  
  126.         // If it isn't our bl0cc, idc
  127.         if(strcmp(ce->ce_varname, MYCONF))
  128.                 return 0;
  129.  
  130.         // Loop dat shyte fam
  131.         for(cep = ce->ce_entries; cep; cep = cep->ce_next) {
  132.                 // Do we even have a valid name l0l?
  133.                 if(!cep->ce_varname)
  134.                         continue; // Next iteration imo tbh
  135.  
  136.                 if(!strcmp(cep->ce_varname, "tag-name")) {
  137.                         if(find_ct(cep->ce_vardata)){
  138.                                 config_warn("%s:%i: duplicate tag name \"%s\"", cep->ce_fileptr->cf_filename, cep->ce_varlinenum, cep->ce_vardata);
  139.                                 continue;
  140.                         }
  141.                         *ct = safe_alloc(sizeof(struct ct));
  142.                         (*ct)->name = strdup(cep->ce_vardata);
  143.                         if(prev_ct)
  144.                                 prev_ct->next = *ct;
  145.                         prev_ct = *ct;
  146.                         ct = &(*ct)->next;
  147.                         continue;
  148.                 }
  149.         }
  150.         return 1; // We good
  151. }
  152.  
  153. MOD_INIT(){
  154.         MARK_AS_GLOBAL_MODULE(modinfo);
  155.         HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, clienttags_configrun);
  156.         HookAddVoid(modinfo->handle, HOOKTYPE_NEW_MESSAGE, 0, mtag_inherit);
  157.  
  158.         return MOD_SUCCESS;
  159. }
  160.  
  161. MOD_LOAD(){
  162.         MessageTagHandlerInfo mtag;
  163.         struct ct *ct;
  164.  
  165.         // now request all the client tags configured
  166.         for(ct = ctdata.cts; ct; ct = ct->next){
  167.                 memset(&mtag, 0, sizeof(mtag));
  168.                 mtag.name = ct->name;
  169.                 mtag.is_ok = client_mtag_is_ok;
  170.                 mtag.flags = MTAG_HANDLER_FLAGS_NO_CAP_NEEDED;
  171.                 if(!MessageTagHandlerAdd(modinfo->handle, &mtag)){
  172.                         config_warn("[%s] Failed to request client tag \"%s\": %s. This one will not work.", MOD_HEADER.name, ct->name, ModuleGetErrorStr(modinfo->handle));
  173.                 }
  174.         }
  175.  
  176.         return MOD_SUCCESS;
  177. }
  178.  
  179. MOD_UNLOAD(){
  180.         struct ct *ct, *prev_ct;
  181.  
  182. #ifdef TAGMSG_HACK
  183.         RealCommand *c;
  184.         c = find_command_simple("TAGMSG");
  185.         if(c){
  186.                 c->flags &= ~CMD_SERVER; // revert to the original
  187.         }
  188. #endif
  189.  
  190.         // free the memory
  191.         ct = ctdata.cts;
  192.         prev_ct = ctdata.cts;
  193.         while(ct){
  194.                 safe_free(ct->name);
  195.                 ct = ct->next;
  196.                 safe_free(prev_ct);
  197.                 prev_ct = ct;
  198.         }
  199.         ctdata.cts = NULL;
  200.         return MOD_SUCCESS;
  201. }
  202.  
  203. struct ct *find_ct(char *name){
  204.         struct ct *ct;
  205.         for(ct = ctdata.cts; ct; ct = ct->next){
  206.                 if(!strcmp(name, ct->name))
  207.                         return ct;
  208.         }
  209.         return NULL;
  210. }
  211.  
  212. int client_mtag_is_ok(Client *client, char *name, char *value){ // permit anything
  213.         return 1;
  214. }
  215.  
  216. void mtag_inherit(Client *sender, MessageTag *recv_mtags, MessageTag **mtag_list, char *signature){
  217.         struct ct *ct;
  218.         for(ct = ctdata.cts; ct; ct = ct->next){
  219.                 MessageTag *m = find_mtag(recv_mtags, ct->name);
  220.                 if (m)
  221.                         m = duplicate_mtag(m);
  222.                 else
  223.                         continue;
  224.                 AddListItem(m, *mtag_list);
  225.         }
  226. }
  227.  

odpowiedź "Bez tytułu"

Tutaj możesz odpowiedzieć na wklejkę z góry

captcha