unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
sinfo.c (4923B)
1 /* 2 * cmd_sinfo - Server information 3 * (C) Copyright 2019 Bram Matthys (Syzop) and the UnrealIRCd team. 4 * License: GPLv2 or later 5 */ 6 7 #include "unrealircd.h" 8 9 ModuleHeader MOD_HEADER 10 = { 11 "sinfo", 12 "5.0", 13 "Server information", 14 "UnrealIRCd Team", 15 "unrealircd-6", 16 }; 17 18 /* Forward declarations */ 19 CMD_FUNC(cmd_sinfo); 20 21 MOD_INIT() 22 { 23 MARK_AS_OFFICIAL_MODULE(modinfo); 24 CommandAdd(modinfo->handle, "SINFO", cmd_sinfo, MAXPARA, CMD_USER|CMD_SERVER); 25 26 return MOD_SUCCESS; 27 } 28 29 MOD_LOAD() 30 { 31 return MOD_SUCCESS; 32 } 33 34 MOD_UNLOAD() 35 { 36 return MOD_SUCCESS; 37 } 38 39 /** SINFO server-to-server command. 40 * Technical documentation is available at: 41 * https://www.unrealircd.org/docs/Server_protocol:SINFO_command 42 * ^ contains important remarks regarding when to send it and when not. 43 */ 44 CMD_FUNC(sinfo_server) 45 { 46 char buf[512]; 47 48 if (MyConnect(client)) 49 { 50 /* It is a protocol violation to send an SINFO for yourself, 51 * eg if you are server 001, then you cannot send :001 SINFO .... 52 * Exiting the client may seem harsh, but this way we force users 53 * to use the correct protocol. If we would not do this then some 54 * services coders may think they should use only SINFO while in 55 * fact for directly connected servers they should use things like 56 * PROTOCTL CHANMODES=... USERMODES=... NICKCHARS=.... etc, and 57 * failure to do so will lead to potential desyncs or other major 58 * issues. 59 */ 60 exit_client(client, NULL, "Protocol error: you cannot send SINFO about yourself"); 61 return; 62 } 63 64 /* :SID SINFO up_since protocol umodes chanmodes nickchars :software name 65 * 1 2 3 4 5 6 (last one) 66 * If we extend it then 'software name' will still be the last one, so 67 * it may become 7, 8 or 9. New elements are inserted right before it. 68 */ 69 70 if ((parc < 6) || BadPtr(parv[6])) 71 { 72 sendnumeric(client, ERR_NEEDMOREPARAMS, "SINFO"); 73 return; 74 } 75 76 client->server->boottime = atol(parv[1]); 77 client->server->features.protocol = atoi(parv[2]); 78 79 if (!strcmp(parv[3], "*")) 80 safe_free(client->server->features.usermodes); 81 else 82 safe_strdup(client->server->features.usermodes, parv[3]); 83 84 if (!strcmp(parv[4], "*")) 85 { 86 safe_free(client->server->features.chanmodes[0]); 87 safe_free(client->server->features.chanmodes[1]); 88 safe_free(client->server->features.chanmodes[2]); 89 safe_free(client->server->features.chanmodes[3]); 90 } else { 91 parse_chanmodes_protoctl(client, parv[4]); 92 } 93 94 if (!strcmp(parv[5], "*")) 95 safe_free(client->server->features.nickchars); 96 else 97 safe_strdup(client->server->features.nickchars, parv[5]); 98 99 /* Software is always the last parameter. It is currently parv[6] 100 * but may change later. So always use parv[parc-1]. 101 */ 102 if (!strcmp(parv[parc-1], "*")) 103 safe_free(client->server->features.software); 104 else 105 safe_strdup(client->server->features.software, parv[parc-1]); 106 107 if (is_services_but_not_ulined(client)) 108 { 109 char buf[512]; 110 snprintf(buf, sizeof(buf), "Services detected but no ulines { } for server name %s", client->name); 111 exit_client_ex(client, &me, NULL, buf); 112 return; 113 } 114 115 /* Broadcast to 'the other side' of the net */ 116 concat_params(buf, sizeof(buf), parc, parv); 117 sendto_server(client, 0, 0, NULL, ":%s SINFO %s", client->id, buf); 118 } 119 120 #define SafeDisplayStr(x) ((x && *(x)) ? (x) : "-") 121 CMD_FUNC(sinfo_user) 122 { 123 Client *acptr; 124 125 if (!IsOper(client)) 126 { 127 sendnumeric(client, ERR_NOPRIVILEGES); 128 return; 129 } 130 131 list_for_each_entry(acptr, &global_server_list, client_node) 132 { 133 sendtxtnumeric(client, "*** Server %s:", acptr->name); 134 sendtxtnumeric(client, "Protocol: %d", 135 acptr->server->features.protocol); 136 sendtxtnumeric(client, "Software: %s", 137 SafeDisplayStr(acptr->server->features.software)); 138 if (!acptr->server->boottime) 139 { 140 sendtxtnumeric(client, "Up since: -"); 141 sendtxtnumeric(client, "Uptime: -"); 142 } else { 143 sendtxtnumeric(client, "Up since: %s", 144 pretty_date(acptr->server->boottime)); 145 sendtxtnumeric(client, "Uptime: %s", 146 pretty_time_val(TStime() - acptr->server->boottime)); 147 } 148 sendtxtnumeric(client, "User modes: %s", 149 SafeDisplayStr(acptr->server->features.usermodes)); 150 if (!acptr->server->features.chanmodes[0]) 151 { 152 sendtxtnumeric(client, "Channel modes: -"); 153 } else { 154 sendtxtnumeric(client, "Channel modes: %s,%s,%s,%s", 155 SafeDisplayStr(acptr->server->features.chanmodes[0]), 156 SafeDisplayStr(acptr->server->features.chanmodes[1]), 157 SafeDisplayStr(acptr->server->features.chanmodes[2]), 158 SafeDisplayStr(acptr->server->features.chanmodes[3])); 159 } 160 sendtxtnumeric(client, "Allowed nick characters: %s", 161 SafeDisplayStr(acptr->server->features.nickchars)); 162 } 163 } 164 165 CMD_FUNC(cmd_sinfo) 166 { 167 if (IsServer(client)) 168 CALL_CMD_FUNC(sinfo_server); 169 else if (MyUser(client)) 170 CALL_CMD_FUNC(sinfo_user); 171 }