Initial client library rewrite, connects to remote server already.
[silc.git] / lib / silcclient / client_register.c
1 /*
2
3   client_register.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2006 Pekka Riikonen
8
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.
12
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.
17
18 */
19
20 #include "silc.h"
21 #include "silcclient.h"
22 #include "client_internal.h"
23
24 /************************** Types and definitions ***************************/
25
26
27 /************************ Static utility functions **************************/
28
29
30 /************************ Register to SILC network **************************/
31
32 /* Register to network */
33
34 SILC_FSM_STATE(silc_client_st_register)
35 {
36   SilcClientConnection conn = fsm_context;
37   SilcClient client = conn->client;
38   SilcBufferStruct buf;
39   int ret;
40
41   SILC_LOG_DEBUG(("Register to network"));
42
43   memset(&buf, 0, sizeof(buf));
44   ret = silc_buffer_format(&buf,
45                            SILC_STR_UI_SHORT(strlen(client->username)),
46                            SILC_STR_DATA(client->username,
47                                          strlen(client->username)),
48                            SILC_STR_UI_SHORT(strlen(client->realname)),
49                            SILC_STR_DATA(client->realname,
50                                          strlen(client->realname)),
51                            SILC_STR_END);
52   if (ret < 0) {
53     /** Out of memory */
54     silc_fsm_next(fsm, silc_client_st_register_error);
55     return SILC_FSM_CONTINUE;
56   }
57
58   /* Send the packet */
59   if (!silc_packet_send(conn->stream, SILC_PACKET_NEW_CLIENT, 0,
60                         silc_buffer_data(&buf), silc_buffer_len(&buf))) {
61     /** Error sending packet */
62     silc_buffer_purge(&buf);
63     silc_fsm_next(fsm, silc_client_st_register_error);
64     return SILC_FSM_CONTINUE;
65   }
66
67   silc_buffer_purge(&buf);
68
69   /** Wait for new ID */
70   conn->internal->registering = TRUE;
71   silc_fsm_next_later(fsm, silc_client_st_register_complete, 15, 0);
72   return SILC_FSM_WAIT;
73 }
74
75 /* Wait for NEW_ID packet to arrive */
76
77 SILC_FSM_STATE(silc_client_st_register_complete)
78 {
79   SilcClientConnection conn = fsm_context;
80   SilcClient client = conn->client;
81
82   if (!conn->local_id) {
83     /* Timeout, ID not received */
84     conn->internal->registering = FALSE;
85     silc_fsm_next(fsm, silc_client_st_register_error);
86     return SILC_FSM_CONTINUE;
87   }
88
89   SILC_LOG_DEBUG(("Registered to network"));
90
91   /* Issue IDENTIFY command for itself to get resolved hostname
92      correctly from server. */
93   silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, NULL, NULL,
94                            1, 5, silc_buffer_data(conn->local_idp),
95                            silc_buffer_len(conn->local_idp));
96
97   /* Send NICK command if the nickname was set by the application (and is
98      not same as the username).  Send this with little timeout. */
99   if (client->nickname &&
100       !silc_utf8_strcasecmp(client->nickname, client->username))
101     silc_client_command_send(client, conn, SILC_COMMAND_NICK, NULL, NULL,
102                              1, 1, client->nickname, strlen(client->nickname));
103
104   /* Issue INFO command to fetch the real server name and server
105      information and other stuff. */
106   silc_client_command_send(client, conn, SILC_COMMAND_INFO, NULL, NULL,
107                            1, 2, silc_buffer_data(conn->remote_idp),
108                            silc_buffer_len(conn->remote_idp));
109
110   /* Call connection callback.  We are now inside SILC network. */
111   conn->callback(client, conn, SILC_CLIENT_CONN_SUCCESS, conn->context);
112
113   conn->internal->registering = FALSE;
114   return SILC_FSM_FINISH;
115 }
116
117 SILC_FSM_STATE(silc_client_st_register_error)
118 {
119   SilcClientConnection conn = fsm_context;
120   SilcClient client = conn->client;
121
122   /* XXX */
123   /* Close connection */
124
125   conn->callback(client, conn, SILC_CLIENT_CONN_ERROR, conn->context);
126
127   return SILC_FSM_FINISH;
128 }
129
130
131 /************************* Resume detached session **************************/
132
133 /* Resume detached session */
134
135 SILC_FSM_STATE(silc_client_st_resume)
136 {
137
138   return SILC_FSM_FINISH;
139 }
140
141 SILC_FSM_STATE(silc_client_st_resume_new_id)
142 {
143   SilcClientConnection conn = fsm_context;
144
145   return SILC_FSM_FINISH;
146 }
147
148 SILC_FSM_STATE(silc_client_st_resume_error)
149 {
150   /* XXX */
151   /* Close connection */
152
153   return SILC_FSM_FINISH;
154 }