3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>
34 struct sockaddr_in sockName
; // "Jmeno" portu
35 struct sockaddr_in clientInfo
; // Klient, ktere se pripojil
36 int mainSocket
; // Soket
37 socklen_t addrlen
; // Velikost adresy vzdaleneho pocitace
38 char *buffer
; // Buffer
39 int client_count
; // Pocet pripojenych clientu
44 int client_send (client_t
*c
, char *data
, unsigned len
)
47 if ((ret
= send (c
->fd
, data
, len
, 0)) == -1) {
48 printf ("ERROR -> send () = -1\n");
55 int clients_send (char *data
, unsigned len
)
58 for (c
= client_list
.next
; c
!= &client_list
; c
= c
->next
)
59 client_send (c
, data
, len
);
64 int client_recv (client_t
*c
, char *data
, unsigned len
)
66 memset (data
, 0, len
);
68 int ret
= recv (c
->fd
, data
, len
, 0);
76 client_t
*client_connected (int fd
)
79 for (c
= client_list
.next
; c
!= &client_list
; c
= c
->next
)
83 // alloc and init context
84 client_t
*ctx
= (client_t
*) malloc (sizeof (client_t
));
90 ctx
->state
= CLIENT_STATE_CONNECTED
;
93 ctx
->next
= &client_list
;
94 ctx
->prev
= client_list
.prev
;
95 ctx
->prev
->next
= ctx
;
96 ctx
->next
->prev
= ctx
;
101 int client_handle (client_t
*c
)
103 if (c
->state
== CLIENT_STATE_CONNECTED
)
104 return console_motd (c
);
105 if (c
->state
== CLIENT_STATE_LOGIN
)
106 return console_login (c
);
107 if (c
->state
== CLIENT_STATE_READY
)
108 return console_handler (c
);
109 if (c
->state
== CLIENT_STATE_DONE
) {
110 /* disconnect socket */
113 /* delete client_t * struct from list */
114 c
->next
->prev
= c
->prev
;
115 c
->prev
->next
= c
->next
;
126 if ((mainSocket
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) == -1) {
127 printf ("Cant create socket\n");
131 // set mainSocket to non-blocking mode
132 int oldFlag
= fcntl (mainSocket
, F_GETFL
, 0);
133 if (fcntl (mainSocket
, F_SETFL
, oldFlag
| O_NONBLOCK
) == -1) {
134 printf ("Cant set socket to nonblocking mode\n");
138 // 1) Family of protocols
139 sockName
.sin_family
= AF_INET
;
140 // 2) Set number of listen port
141 sockName
.sin_port
= htons (port
);
142 // 3) Listen IP address
143 sockName
.sin_addr
.s_addr
= INADDR_ANY
;
145 // Bind on our socket
146 if (bind (mainSocket
, (struct sockaddr
*) &sockName
, sizeof (sockName
)) == -1) {
147 printf ("bind () - port is used\n");
151 // Create queue for accept
152 if (listen (mainSocket
, 10) == -1) {
153 printf ("ERROR -> listen () == -1\n");
157 addrlen
= sizeof (clientInfo
);
159 printf ("> telnetd is running !\n> listen on port: %d\n", port
);
161 client_list
.next
= &client_list
;
162 client_list
.prev
= &client_list
;
166 return console_init ();
171 // "client" is new socket;
172 int client
= accept (mainSocket
, (struct sockaddr
*) &clientInfo
, &addrlen
);
175 printf ("> New client connected !\n");
177 // socket client will be in non-blocking mode
178 int oldFlag
= fcntl (client
, F_GETFL
, 0);
179 if (fcntl (client
, F_SETFL
, oldFlag
| O_NONBLOCK
) == -1) {
180 printf ("Cant set socket to nonblocking mode\n");
184 client_t
*c
= client_connected (client
);
195 for (c
= client_list
.next
; c
!= &client_list
; c
= c
->next
) {
200 if (!client_handle (c
))