Kod:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define CLIENTS_WAITING 10
#define BUFSIZE 20
#define LOGIN "login"
#define PASS "password"
void server_run() ;
void login_user() ;
void exec_commands() ;
void send_com_req() ;
int check_login_pass_user(const char *login, const char *pass) ;
int accepted ;
int main(int argc, char *argv[])
{
int port = atoi(argv[1]) ;
int sockfd = socket(PF_INET, SOCK_STREAM, 0) ;
struct sockaddr_in my_addr ;
struct sockaddr_in their_addr ;
my_addr.sin_family = PF_INET ;
my_addr.sin_port = htons(port) ;
my_addr.sin_addr.s_addr = INADDR_ANY ;
memset(&(my_addr.sin_zero), '\0', 8) ;
if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind") ;
exit(1) ;
}
int yes = 1 ;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt") ;
exit(1) ;
}
if(listen(sockfd, CLIENTS_WAITING) == -1)
{
perror("listen") ;
exit(1) ;
}
int size = sizeof(struct sockaddr) ;
while(1)
{
if((accepted = accept(sockfd, (struct sockaddr *)&their_addr, &size)) == -1)
{
perror("accept") ;
continue ;
}
if(!fork())
{
server_run() ;
close(accepted) ;
exit(0) ;
}
close(accepted) ; //na koniec while'a zamykamy gniazdko
}
exit(0) ; //koniec programu :)
}
void server_run()
{
login_user() ;
exec_commands() ;
}
void exec_commands()
{
char command[BUFSIZE] ;
long bytes = -10 ;
while(1)
{
send_com_req() ;
while(bytes < 1)
{
if((bytes = recv(accepted, &command, BUFSIZE, 0)) == -1) perror("recv") ;
}
/* Te dwie linijki po to, żeby wywalić dwa niepotrzebne znaki, które pojawiają się na końcu tekstu w tablicy */
bytes -= 2 ;
memset(&(command[bytes]), 0, BUFSIZE - bytes) ;
if(strcmp(command, "exitshell") == 0) break ;
FILE *fd = popen(command, "r") ;
/* Tu jeszcze będą potem różne rzeczy, ale na razie to nieważne */
close( (int) fd) ;
}
}
void send_com_req()
{
send(accepted, "$", strlen("$"), 0) ;
}
void login_user()
{
char login[BUFSIZE] ;
memset(login, 0, strlen(login)) ;
char password[BUFSIZE] ;
memset(password, 0, strlen(password)) ;
long bytes = -10 ;
send(accepted, "Login: ", strlen("Login: "), 0) ;
while(bytes < 1)
{
if((bytes = recv(accepted, &login, BUFSIZE, 0)) == -1) perror("recv") ;
}
/* Te dwie linijki po to, żeby wywalić dwa niepotrzebne znaki, które pojawiają się na końcu tekstu w tablicy */
bytes -= 2 ;
memset(&(login[bytes]), 0, BUFSIZE - bytes) ;
bytes = -10 ;
//printf("Received: %s\n", login) ;
send(accepted, "Password: ", strlen("Password: "), 0) ;
while(bytes < 1)
{
if((bytes = recv(accepted, &password, BUFSIZE, 0)) == -1) perror("recv") ;
}
/* Te dwie linijki po to, żeby wywalić dwa niepotrzebne znaki, które pojawiają się na końcu tekstu w tablicy */
bytes -= 2 ;
memset(&(password[bytes]), 0, BUFSIZE - bytes) ;
bytes = -10 ;
//printf("Received: %s\n", password) ;
int logged = check_login_pass_user(login, password) ;
if(logged == 0)
{
send(accepted, "Wrong login or password\n", strlen("Wrong login or password\n"), 0) ;
close(accepted) ;
exit(0) ;
}
send(accepted, "You are logged in!\n", strlen("You are logged in!\n"), 0) ;
}
int check_login_pass_user(const char *login, const char *pass)
{
if(strcmp(login, LOGIN) == 0 && strcmp(pass, PASS) == 0) return 1 ;
return 0 ;
}
Program ma najpierw sprawdzić czy zostało podane odpowiednie dane do logowania, a następnie wykonywać komendy, które zostaną podane.