5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2006 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "silcserver.h"
22 #include "server_internal.h"
24 /************************** Types and definitions ***************************/
26 #define SILC_SERVER_COMMAND_CHECK(min, max) \
30 SILC_LOG_DEBUG(("Start")); \
32 _argc = silc_argument_get_arg_num(args); \
34 SILC_LOG_DEBUG(("Not enough parameters in command")); \
35 silc_server_command_status_reply(cmd, \
36 silc_command_get(cmd->payload), \
37 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \
39 silc_server_command_free(cmd); \
40 return SILC_FSM_FINISH; \
43 SILC_LOG_DEBUG(("Too many parameters in command")); \
44 silc_server_command_status_reply(cmd, \
45 silc_command_get(cmd->payload), \
46 SILC_STATUS_ERR_TOO_MANY_PARAMS, \
48 silc_server_command_free(cmd); \
49 return SILC_FSM_FINISH; \
54 /************************ Static utility functions **************************/
56 /* Sends simple status message as command reply packet */
59 silc_server_command_status_reply(SilcServerCommand cmd,
67 cmd->thread->server->stat.commands_sent++;
69 SILC_LOG_DEBUG(("Sending command status %d", status));
71 silc_command_reply_payload_encode_va(command, status, error,
72 silc_command_get_ident(cmd->payload),
74 silc_packet_send(cmd->packet->stream, SILC_PACKET_COMMAND_REPLY, 0,
75 buffer->data, silc_buffer_len(buffer));
76 silc_buffer_free(buffer);
79 /* Sends command status reply with one extra argument. The argument
80 type must be sent as argument. */
83 silc_server_command_status_data(SilcServerCommand cmd,
88 const unsigned char *arg,
94 cmd->thread->server->stat.commands_sent++;
96 SILC_LOG_DEBUG(("Sending command status %d", status));
99 silc_command_reply_payload_encode_va(command, status, 0,
100 silc_command_get_ident(cmd->payload),
101 1, arg_type, arg, arg_len);
102 silc_packet_send(cmd->packet->stream, SILC_PACKET_COMMAND_REPLY, 0,
103 buffer->data, silc_buffer_len(buffer));
104 silc_buffer_free(buffer);
108 silc_server_command_status_data2(SilcServerCommand cmd,
112 SilcUInt32 arg_type1,
113 const unsigned char *arg1,
115 SilcUInt32 arg_type2,
116 const unsigned char *arg2,
122 cmd->thread->server->stat.commands_sent++;
124 SILC_LOG_DEBUG(("Sending command status %d", status));
127 silc_command_reply_payload_encode_va(command, status, 0,
128 silc_command_get_ident(cmd->payload),
129 2, arg_type1, arg1, arg_len1,
130 arg_type2, arg2, arg_len2);
131 silc_packet_send(cmd->packet->stream, SILC_PACKET_COMMAND_REPLY, 0,
132 buffer->data, silc_buffer_len(buffer));
133 silc_buffer_free(buffer);
136 void silc_server_command_pending_free(SilcServerThread thread,
137 SilcServerPending pending);
140 /**************************** Utility functions *****************************/
142 /* Gets command context from freelist or allocates a new one. */
144 SilcServerCommand silc_server_command_alloc(SilcServerThread thread)
146 SilcServerCommand cmd;
148 silc_mutex_lock(thread->server->lock);
150 /* Get command context from freelist or allocate new one. */
151 cmd = silc_list_get(thread->server->command_pool);
153 silc_mutex_unlock(thread->server->lock);
155 cmd = silc_calloc(1, sizeof(*cmd));
159 SILC_LOG_DEBUG(("Allocating command context %p", cmd));
161 cmd->thread = thread;
166 SILC_LOG_DEBUG(("Get command context %p", cmd));
168 /* Delete from freelist */
169 silc_list_del(thread->server->command_pool, cmd);
171 cmd->thread = thread;
173 silc_mutex_unlock(thread->server->lock);
178 /* Puts the command context back to freelist */
180 void silc_server_command_free(SilcServerCommand cmd)
182 SilcServerThread thread = cmd->thread;
184 silc_mutex_lock(thread->server->lock);
186 #if defined(SILC_DEBUG)
187 /* Check for double free */
188 assert(cmd->packet != NULL);
189 #endif /* SILC_DEBUG */
192 silc_packet_free(cmd->packet);
196 silc_server_command_pending_free(thread, cmd->pending);
198 /* Put the packet back to freelist */
199 silc_list_add(thread->server->command_pool, cmd);
201 silc_mutex_unlock(thread->server->lock);
204 /* Returns pending context used to wait for a command reply. */
206 SilcServerPending silc_server_command_pending(SilcServerThread thread,
207 SilcUInt16 cmd_ident)
209 SilcServerPending pending;
211 silc_mutex_lock(thread->server->lock);
213 /* Check if pending already */
214 if (silc_hash_table_find(thread->server->pending_commands,
215 SILC_32_TO_PTR(cmd_ident), NULL,
216 (void **)&pending)) {
218 silc_mutex_unlock(thread->server->lock);
222 pending = silc_calloc(1, sizeof(*pending));
224 silc_mutex_unlock(thread->server->lock);
228 silc_fsm_event_init(&pending->wait_reply, &thread->fsm, 0);
230 pending->cmd_ident = cmd_ident;
232 /* Add to pending commands hash table */
233 if (!silc_hash_table_add(thread->server->pending_commands,
234 SILC_32_TO_PTR(cmd_ident), pending)) {
235 silc_mutex_unlock(thread->server->lock);
240 silc_mutex_unlock(thread->server->lock);
245 /* Free's the pending command context */
247 void silc_server_command_pending_free(SilcServerThread thread,
248 SilcServerPending pending)
250 silc_mutex_lock(thread->server->lock);
253 if (pending->refcnt > 0) {
254 silc_mutex_unlock(thread->server->lock);
258 /* If command reply context set, free it also */
259 if (pending->reply) {
260 pending->reply->pending = NULL;
261 silc_server_command_free(pending->reply);
264 /* Remove from pending commands */
265 silc_hash_table_del_by_context(thread->server->pending_commands,
266 SILC_32_TO_PTR(pending->cmd_ident), pending);
269 silc_mutex_unlock(thread->server->lock);
272 /* Returns pending command context for command identifier */
274 SilcServerPending silc_server_command_pending_get(SilcServerThread thread,
275 SilcUInt16 cmd_ident)
277 SilcServerPending pending = NULL;
279 silc_mutex_lock(thread->server->lock);
280 silc_hash_table_find(thread->server->pending_commands,
281 SILC_32_TO_PTR(cmd_ident), NULL, (void **)&pending);
282 silc_mutex_unlock(thread->server->lock);
287 /* Signals pending command waiters. Used by command reply routines. */
289 void silc_server_command_pending_signal(SilcServerCommand cmd)
291 SilcServerThread thread = cmd->thread;
292 SilcServerPending pending = cmd->pending;
297 silc_mutex_lock(thread->server->lock);
300 pending->reply = cmd;
301 SILC_FSM_EVENT_SIGNAL(&pending->wait_reply);
303 /* Remove from pending */
304 silc_hash_table_del_by_context(thread->server->pending_commands,
305 SILC_32_TO_PTR(pending->cmd_ident), pending);
307 silc_mutex_unlock(thread->server->lock);
311 /**************************** Command received ******************************/
313 /* Received a COMMAND packet. We parse the packet and process the
314 requested command. */
316 SILC_FSM_STATE(silc_server_st_packet_command)
318 SilcServerThread thread = fsm_context;
319 SilcPacket packet = state_context;
320 SilcEntryData data = silc_packet_get_context(packet->stream);
321 SilcServerCommand cmd;
322 SilcUInt32 timeout = 0;
324 /* Allocate command context. */
325 cmd = silc_server_command_alloc(thread);
327 silc_packet_free(packet);
328 return SILC_FSM_FINISH;
331 cmd->packet = packet;
333 /* Parse the command payload in the packet */
334 cmd->payload = silc_command_payload_parse(packet->buffer.data,
335 silc_buffer_len(&packet->buffer));
337 SILC_LOG_ERROR(("Bad command payload"));
338 silc_server_command_free(cmd);
339 return SILC_FSM_FINISH;
342 /* If client executes commands more frequently than once in 2 seconds,
343 apply 0 - 2 seconds of timeout to prevent flooding. */
344 if (data->type == SILC_CONN_CLIENT) {
345 SilcClientEntry client = (SilcClientEntry)data;
347 if (client->last_command && (time(NULL) - client->last_command) < 2) {
348 client->fast_command++;
349 if (client->fast_command > 5)
350 timeout = (client->fast_command < 3 ? 0 :
351 2 - (time(NULL) - client->last_command));
353 if (client->fast_command - 2 <= 0)
354 client->fast_command = 0;
356 client->fast_command -= 2;
359 client->last_command = time(NULL) + timeout;
362 silc_fsm_set_state_context(fsm, cmd);
364 SILC_LOG_DEBUG(("Processing %s command (%d timeout)",
365 silc_get_command_name(silc_command_get(cmd->payload)),
368 /* Process command */
369 switch (silc_command_get(cmd->payload)) {
371 case SILC_COMMAND_WHOIS:
373 silc_fsm_next_later(fsm, silc_server_st_command_whois, timeout, 0);
376 case SILC_COMMAND_WHOWAS:
377 /** Command WHOWAS */
378 silc_fsm_next_later(fsm, silc_server_st_command_whowas, timeout, 0);
381 case SILC_COMMAND_IDENTIFY:
382 /** Command IDENTIFY */
383 silc_fsm_next_later(fsm, silc_server_st_command_identify, timeout, 0);
386 case SILC_COMMAND_NICK:
388 silc_fsm_next_later(fsm, silc_server_st_command_nick, timeout, 0);
391 case SILC_COMMAND_LIST:
393 silc_fsm_next_later(fsm, silc_server_st_command_list, timeout, 0);
396 case SILC_COMMAND_TOPIC:
398 silc_fsm_next_later(fsm, silc_server_st_command_topic, timeout, 0);
401 case SILC_COMMAND_INVITE:
402 /** Command INVITE */
403 silc_fsm_next_later(fsm, silc_server_st_command_invite, timeout, 0);
406 case SILC_COMMAND_QUIT:
408 silc_fsm_next_later(fsm, silc_server_st_command_quit, timeout, 0);
411 case SILC_COMMAND_KILL:
413 silc_fsm_next_later(fsm, silc_server_st_command_kill, timeout, 0);
416 case SILC_COMMAND_INFO:
418 silc_fsm_next_later(fsm, silc_server_st_command_info, timeout, 0);
421 case SILC_COMMAND_STATS:
423 silc_fsm_next_later(fsm, silc_server_st_command_stats, timeout, 0);
426 case SILC_COMMAND_PING:
428 silc_fsm_next_later(fsm, silc_server_st_command_ping, timeout, 0);
431 case SILC_COMMAND_OPER:
433 silc_fsm_next_later(fsm, silc_server_st_command_oper, timeout, 0);
436 case SILC_COMMAND_JOIN:
438 silc_fsm_next_later(fsm, silc_server_st_command_join, timeout, 0);
441 case SILC_COMMAND_MOTD:
443 silc_fsm_next_later(fsm, silc_server_st_command_motd, timeout, 0);
446 case SILC_COMMAND_UMODE:
448 silc_fsm_next_later(fsm, silc_server_st_command_umode, timeout, 0);
451 case SILC_COMMAND_CMODE:
453 silc_fsm_next_later(fsm, silc_server_st_command_cmode, timeout, 0);
456 case SILC_COMMAND_CUMODE:
457 /** Command CUMODE */
458 silc_fsm_next_later(fsm, silc_server_st_command_cumode, timeout, 0);
461 case SILC_COMMAND_KICK:
463 silc_fsm_next_later(fsm, silc_server_st_command_kick, timeout, 0);
466 case SILC_COMMAND_BAN:
468 silc_fsm_next_later(fsm, silc_server_st_command_ban, timeout, 0);
471 case SILC_COMMAND_DETACH:
472 /** Command DETACH */
473 silc_fsm_next_later(fsm, silc_server_st_command_detach, timeout, 0);
476 case SILC_COMMAND_WATCH:
478 silc_fsm_next_later(fsm, silc_server_st_command_watch, timeout, 0);
481 case SILC_COMMAND_SILCOPER:
482 /** Command SILCOPER */
483 silc_fsm_next_later(fsm, silc_server_st_command_silcoper, timeout, 0);
486 case SILC_COMMAND_LEAVE:
488 silc_fsm_next_later(fsm, silc_server_st_command_leave, timeout, 0);
491 case SILC_COMMAND_USERS:
493 silc_fsm_next_later(fsm, silc_server_st_command_users, timeout, 0);
496 case SILC_COMMAND_GETKEY:
497 /** Command GETKEY */
498 silc_fsm_next_later(fsm, silc_server_st_command_getkey, timeout, 0);
501 case SILC_COMMAND_SERVICE:
502 /** Command SERVICE */
503 silc_fsm_next_later(fsm, silc_server_st_command_service, timeout, 0);
507 SILC_LOG_DEBUG(("Unknown command %d", silc_command_get(cmd->payload)));
508 silc_server_command_free(cmd);
509 return SILC_FSM_FINISH;
514 thread->server->stat.commands_received++;
516 return timeout ? SILC_FSM_WAIT : return SILC_FSM_CONTINUE;
519 /********************************* WHOIS ************************************/
521 SILC_FSM_STATE(silc_server_st_command_whois)
523 SilcServerCommand cmd = state_context;
524 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
526 SILC_SERVER_COMMAND_CHECK(1, 256);
529 silc_fsm_next(fsm, silc_server_st_query_whois);
531 return SILC_FSM_CONTINUE;
535 /********************************* WHOWAS ***********************************/
537 SILC_FSM_STATE(silc_server_st_command_whowas)
539 SilcServerCommand cmd = state_context;
540 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
542 SILC_SERVER_COMMAND_CHECK(1, 2);
545 silc_fsm_next(fsm, silc_server_st_query_whowas);
547 return SILC_FSM_CONTINUE;
551 /******************************** IDENTIFY **********************************/
553 SILC_FSM_STATE(silc_server_st_command_identify)
555 SilcServerCommand cmd = state_context;
556 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
558 SILC_SERVER_COMMAND_CHECK(1, 256);
560 /** IDENTIFY query */
561 silc_fsm_next(fsm, silc_server_st_query_identify);
563 return SILC_FSM_CONTINUE;
567 /********************************** NICK ************************************/
569 SILC_FSM_STATE(silc_server_st_command_nick)
571 SilcServerThread thread = fsm_context;
572 SilcServerCommand cmd = state_context;
573 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
574 SilcClientEntry client = silc_packet_get_context(cmd->packet->stream);
575 SilcBuffer nidp, oidp = NULL;
578 unsigned char *nick, *nickc;
579 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
581 SILC_SERVER_COMMAND_CHECK(1, 1);
583 /* This command can come only from client */
584 if (!SILC_IS_CLIENT(client)) {
585 silc_server_command_status_reply(cmd, SILC_COMMAND_NICK,
586 SILC_STATUS_ERR_OPERATION_ALLOWED, 0);
591 nick = silc_argument_get_arg_type(args, 1, &nick_len);
593 silc_server_command_status_reply(cmd, SILC_COMMAND_NICK,
594 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
598 /* Truncate over long nicks */
599 if (nick_len > 128) {
601 nick[nick_len - 1] = '\0';
604 /* Check for same nickname */
605 if (strlen(client->nickname) == nick_len &&
606 !memcmp(client->nickname, nick, nick_len)) {
607 nidp = silc_id_payload_encode(&client->id, SILC_ID_CLIENT);
611 /* Check for valid nickname string. */
612 nickc = silc_identifier_check(nick, nick_len, SILC_STRING_UTF8, 128, NULL);
614 silc_server_command_status_reply(cmd, SILC_COMMAND_NICK,
615 SILC_STATUS_ERR_BAD_NICKNAME, 0);
619 /* Create new Client ID */
620 if (!silc_server_create_client_id(thread->server, nickc, &new_id)) {
621 silc_server_command_status_reply(cmd, SILC_COMMAND_NICK,
622 SILC_STATUS_ERR_OPERATION_ALLOWED, 0);
627 oidp = silc_id_payload_encode(&client->id, SILC_ID_CLIENT);
629 /* Replace the old nickname and ID with new ones. This checks for
630 validity of the nickname too. */
631 if (!silc_server_replace_client_id(thread->server, &client->id, &new_id,
633 silc_server_command_status_reply(cmd, SILC_COMMAND_NICK,
634 SILC_STATUS_ERR_BAD_NICKNAME, 0);
638 nidp = silc_id_payload_encode(&client->id, SILC_ID_CLIENT);
641 /* Send notify about nickname and ID change to network. */
642 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
643 SILC_BROADCAST(server), client->id,
646 /* Send NICK_CHANGE notify to the client's channels */
647 silc_server_send_notify_on_channels(server, NULL, client,
648 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
649 oidp->data, silc_buffer_len(oidp),
650 nidp->data, silc_buffer_len(nidp),
652 strlen(client->nickname));
656 /* Send the new Client ID as reply command back to client */
657 silc_server_send_command_reply(thread->server, cmd->packet->stream,
659 SILC_STATUS_OK, 0, ident, 2,
660 2, nidp->data, silc_buffer_len(nidp),
662 silc_buffer_free(nidp);
663 silc_buffer_free(oidp);
666 silc_server_command_free(cmd);
667 return SILC_FSM_FINISH;
671 /********************************** LIST ************************************/
673 SILC_FSM_STATE(silc_server_st_command_list)
675 SilcServerThread thread = fsm_context;
676 SilcServerCommand cmd = state_context;
677 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
679 return SILC_FSM_FINISH;
683 /********************************** TOPIC ***********************************/
685 SILC_FSM_STATE(silc_server_st_command_topic)
687 SilcServerThread thread = fsm_context;
688 SilcServerCommand cmd = state_context;
689 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
691 return SILC_FSM_FINISH;
695 /********************************* INVITE ***********************************/
697 SILC_FSM_STATE(silc_server_st_command_invite)
699 SilcServerThread thread = fsm_context;
700 SilcServerCommand cmd = state_context;
701 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
703 return SILC_FSM_FINISH;
707 /********************************** QUIT ************************************/
709 SILC_FSM_STATE(silc_server_st_command_quit)
711 SilcServerThread thread = fsm_context;
712 SilcServerCommand cmd = state_context;
713 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
715 return SILC_FSM_FINISH;
719 /********************************** KILL ************************************/
721 SILC_FSM_STATE(silc_server_st_command_kill)
723 SilcServerThread thread = fsm_context;
724 SilcServerCommand cmd = state_context;
725 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
727 return SILC_FSM_FINISH;
731 /********************************** INFO ************************************/
733 SILC_FSM_STATE(silc_server_st_command_info)
735 return SILC_FSM_FINISH;
739 /********************************** STATS ***********************************/
741 SILC_FSM_STATE(silc_server_st_command_stats)
743 SilcServerThread thread = fsm_context;
744 SilcServerCommand cmd = state_context;
745 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
747 return SILC_FSM_FINISH;
751 /********************************** PING ************************************/
753 SILC_FSM_STATE(silc_server_st_command_ping)
755 SilcServerThread thread = fsm_context;
756 SilcServerCommand cmd = state_context;
757 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
762 SILC_SERVER_COMMAND_CHECK(1, 1);
765 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
767 silc_server_command_status_reply(cmd, silc_command_get(cmd->payload),
768 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
771 if (!silc_id_payload_parse_id(tmp, tmp_len, &id)) {
772 silc_server_command_status_data(cmd, silc_command_get(cmd->payload),
773 SILC_STATUS_ERR_BAD_SERVER_ID, 0,
779 if (!SILC_ID_SERVER_COMPARE(&id.u.server_id, &thread->server->id)) {
780 silc_server_command_status_data(cmd, silc_command_get(cmd->payload),
781 SILC_STATUS_ERR_NO_SUCH_SERVER_ID, 0,
787 silc_server_command_status_reply(cmd, silc_command_get(cmd->payload),
791 silc_server_command_free(cmd);
792 return SILC_FSM_FINISH;
796 /*********************************** OPER ***********************************/
798 SILC_FSM_STATE(silc_server_st_command_oper)
800 SilcServerThread thread = fsm_context;
801 SilcServerCommand cmd = state_context;
802 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
804 return SILC_FSM_FINISH;
808 /*********************************** JOIN ***********************************/
810 SILC_FSM_STATE(silc_server_st_command_join)
812 SilcServerThread thread = fsm_context;
813 SilcServerCommand cmd = state_context;
814 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
816 return SILC_FSM_FINISH;
820 /*********************************** MOTD ***********************************/
822 SILC_FSM_STATE(silc_server_st_command_motd)
824 SilcServerThread thread = fsm_context;
825 SilcServerCommand cmd = state_context;
826 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
828 return SILC_FSM_FINISH;
832 /*********************************** UMODE **********************************/
834 SILC_FSM_STATE(silc_server_st_command_umode)
836 SilcServerThread thread = fsm_context;
837 SilcServerCommand cmd = state_context;
838 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
840 return SILC_FSM_FINISH;
844 /*********************************** CMODE **********************************/
846 SILC_FSM_STATE(silc_server_st_command_cmode)
848 SilcServerThread thread = fsm_context;
849 SilcServerCommand cmd = state_context;
850 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
852 return SILC_FSM_FINISH;
856 /********************************** CUMODE **********************************/
858 SILC_FSM_STATE(silc_server_st_command_cumode)
860 SilcServerThread thread = fsm_context;
861 SilcServerCommand cmd = state_context;
862 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
864 return SILC_FSM_FINISH;
868 /*********************************** KICK ***********************************/
870 SILC_FSM_STATE(silc_server_st_command_kick)
872 SilcServerThread thread = fsm_context;
873 SilcServerCommand cmd = state_context;
874 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
876 return SILC_FSM_FINISH;
880 /*********************************** BAN ************************************/
882 SILC_FSM_STATE(silc_server_st_command_ban)
884 SilcServerThread thread = fsm_context;
885 SilcServerCommand cmd = state_context;
886 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
888 return SILC_FSM_FINISH;
892 /********************************** DETACH **********************************/
894 SILC_FSM_STATE(silc_server_st_command_detach)
896 SilcServerThread thread = fsm_context;
897 SilcServerCommand cmd = state_context;
898 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
900 return SILC_FSM_FINISH;
904 /********************************** WATCH ***********************************/
906 SILC_FSM_STATE(silc_server_st_command_watch)
908 SilcServerThread thread = fsm_context;
909 SilcServerCommand cmd = state_context;
910 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
912 return SILC_FSM_FINISH;
916 /********************************* SILCOPER *********************************/
918 SILC_FSM_STATE(silc_server_st_command_silcoper)
920 SilcServerThread thread = fsm_context;
921 SilcServerCommand cmd = state_context;
922 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
924 return SILC_FSM_FINISH;
928 /********************************** LEAVE ***********************************/
930 SILC_FSM_STATE(silc_server_st_command_leave)
932 SilcServerThread thread = fsm_context;
933 SilcServerCommand cmd = state_context;
934 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
936 return SILC_FSM_FINISH;
940 /********************************** USERS ***********************************/
942 SILC_FSM_STATE(silc_server_st_command_users)
944 SilcServerThread thread = fsm_context;
945 SilcServerCommand cmd = state_context;
946 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
948 return SILC_FSM_FINISH;
952 /********************************** GETKEY **********************************/
954 SILC_FSM_STATE(silc_server_st_command_getkey)
956 SilcServerThread thread = fsm_context;
957 SilcServerCommand cmd = state_context;
958 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
960 return SILC_FSM_FINISH;
964 /********************************** SERVICE *********************************/
966 SILC_FSM_STATE(silc_server_st_command_service)
968 SilcServerThread thread = fsm_context;
969 SilcServerCommand cmd = state_context;
970 SilcArgumentPayload args = silc_command_get_args(cmd->payload);
972 return SILC_FSM_FINISH;