138 lines
3.6 KiB
C
138 lines
3.6 KiB
C
#include <arpa/inet.h>
|
|
#include <sys/types.h>
|
|
#include <stdint.h>
|
|
#include <sys/socket.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
#include "gamedata.h"
|
|
|
|
#define SERVER_ADDR htonl(INADDR_ANY)
|
|
#define MAX_CLIENTS 100
|
|
#define MAX_COMMAND_LINE_LENGTH 101
|
|
|
|
bool prefix(const char *pre, const char *str) {
|
|
return strncmp(pre, str, strlen(pre)) == 0;
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
|
|
if(argc < 2) {
|
|
fprintf(stderr, "Give port number as $1\n");
|
|
exit(255);
|
|
}
|
|
|
|
int sock_conn_d, sock_data_d;
|
|
struct sockaddr_in server;
|
|
|
|
if((sock_conn_d = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
|
perror("server socket not created");
|
|
exit(1);
|
|
}
|
|
|
|
memset(&server, 0, sizeof(server)); // zero the memory
|
|
|
|
server.sin_family = AF_INET;
|
|
server.sin_addr.s_addr = SERVER_ADDR;
|
|
server.sin_port = htons(atoi(argv[1]));
|
|
|
|
if(bind(sock_conn_d, (struct sockaddr*)&server, sizeof(server)) == -1) {
|
|
perror("server socket not bound");
|
|
exit(2);
|
|
}
|
|
|
|
while(true) {
|
|
if(listen(sock_conn_d, MAX_CLIENTS) != 0) {
|
|
perror("cannot listen on socket");
|
|
close(sock_conn_d);
|
|
exit(3);
|
|
}
|
|
|
|
printf("listening...\n");
|
|
|
|
struct sockaddr_in client;
|
|
socklen_t client_len = sizeof(client);
|
|
sock_data_d = accept(sock_conn_d, (struct sockaddr*)&client, &client_len);
|
|
|
|
if(sock_data_d == -1) {
|
|
perror("cannot accept client");
|
|
close(sock_conn_d);
|
|
exit(4);
|
|
}
|
|
|
|
pid_t pid = fork();
|
|
|
|
if(pid < 0) {
|
|
perror("cannot fork for new client");
|
|
exit(6);
|
|
}
|
|
else if(pid == 0) {
|
|
gamedata_t *curr_data = gamedata_new();
|
|
|
|
unsigned char command[MAX_COMMAND_LINE_LENGTH];
|
|
FILE* in = fdopen(sock_data_d, "r");
|
|
FILE* out = fdopen(dup(sock_data_d), "w");
|
|
|
|
fprintf(out, "OK Connection establshed.\n");
|
|
fflush(out);
|
|
|
|
while(true) {
|
|
fgets(command, MAX_COMMAND_LINE_LENGTH, in);
|
|
|
|
union {
|
|
unsigned int u;
|
|
double d;
|
|
} arg1;
|
|
|
|
if(sscanf(command, "make %u\n", &(arg1.u)) == 1) {
|
|
bool status = gamedata_make_pizzoccheri(curr_data, arg1.u);
|
|
fprintf(out, status ? "OK Made.\n" : "KO 1 Insufficient resources.\n");
|
|
}
|
|
else if(prefix("sell", command)) {
|
|
unsigned int sold = gamedata_sell_pizzoccheri(curr_data);
|
|
fprintf(out, "OK %d sold.\n", sold);
|
|
}
|
|
else if(sscanf(command, "set price %lf\n", &(arg1.d)) == 1) {
|
|
bool status = gamedata_set_unit_price(curr_data, arg1.d);
|
|
fprintf(out, status ? "OK The price of one pizzocchero is now at %.02lf CHF.\n"
|
|
: "KO %.02lf CHF is not a valid price.\n", arg1.d);
|
|
}
|
|
else if(sscanf(command, "buy bitto %u", &(arg1.u)) == 1) {
|
|
bool status = gamedata_buy_bitto(curr_data, arg1.u);
|
|
fprintf(out, status ? "OK Purchased.\n" : "KO 2 Insufficient funds\n");
|
|
}
|
|
else if(sscanf(command, "buy flour %u", &(arg1.u)) == 1) {
|
|
bool status = gamedata_buy_flour(curr_data, arg1.u);
|
|
fprintf(out, status ? "OK Purchased.\n" : "KO 3 Insufficient funds\n");
|
|
}
|
|
else if(prefix("status", command)) {
|
|
gamedata_print_status(curr_data, out);
|
|
}
|
|
else if(prefix("exit", command)) {
|
|
fprintf(out, "OK Closing...\n");
|
|
break;
|
|
}
|
|
else {
|
|
fprintf(out, "KO 255 Syntax error\n");
|
|
}
|
|
|
|
fflush(out);
|
|
}
|
|
|
|
printf("closing data socket...\n");
|
|
|
|
fclose(in);
|
|
fclose(out);
|
|
|
|
gamedata_delete(curr_data);
|
|
|
|
printf("exiting...\n");
|
|
exit(0);
|
|
}
|
|
// if father process just continue
|
|
}
|
|
close(sock_conn_d);
|
|
exit(0);
|
|
}
|