#include #include #include #include #include #include #include #include #include #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); }