#include "../include/headdef.h" // initialize the server sockets and listen for incomming connections static void init(void); // establish connection with clients and fork off a child to serve static void run_server(void); // check for clients identity and set fd to and open fd pointing to the // file on disk to sasve, nbytes to number of bytes to receive, cipher to // which cipher algorithm to use for decryption and key to key being used // by cipher static void check_client(int *fd, size_t *nbytes, int *cipher, char *key); // use the fd return by analyse and store data static void store_file(int fd, size_t nbytes, int cipher, char *key); static int sd_me, sd_other; static struct sockaddr_in sa_me, sa_other; // will be set while receiving data from a client to not let others disturbe int main(void) { init(); run_server(); return EXIT_SUCCESS; } static void init(void) { et_neg1(sd_me = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)); // my socket address info memset(&sa_me, sizeof sa_me, '\0'); sa_me.sin_family = AF_INET; sa_me.sin_port = htons(atoi(S_PORT)); sa_me.sin_addr.s_addr = htonl(INADDR_ANY); // check to reuse the port if already in use int yes = 1; et_neg1(setsockopt(sd_me, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes)); // bind my socket address to the socket for receiving et_neg1(bind(sd_me, (const struct sockaddr *)&sa_me, sizeof(struct sockaddr))); // listen for incomming connections et_neg1(listen(sd_me, BACKLOG)); } static void run_server(void) { while (1) { int sd_other; socklen_t othadd_len = sizeof sa_other; ec_neg1(sd_other = accept(sd_me, (struct sockaddr *)&sa_other, &othadd_len)); // fork a child to serve the client pid_t pid; ec_neg1(pid = fork()); // child part if (! pid) { close(sd_me); int fd, cipher; size_t nbytes; char key[MAX_KEY_SIZE]; printf("socket %d", sd_other); check_client(&fd, &nbytes, &cipher, key); // if everything's fine, then save the file if (-1 != fd) { store_file(fd, nbytes, cipher, key); } exit(EXIT_SUCCESS); } // parent part again // child will die until this moment ec_neg1(wait(0)); close(sd_other); } } static void check_client(int *fd, size_t *nbytes, int *cipher, char *key) { struct nego_pack nego; ssize_t nread; ec_neg1(nread = read_all(sd_other, (char *)&nego, sizeof nego)); // if this is true, then the package is a negotiation package if (! strcmp(HELLO, nego.hello)) { ec_neg1(*fd = open(nego.filename, O_WRONLY | O_CREAT | O_EXCL)); ec_neg1(fchmod(*fd, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR)); *nbytes = nego.nbytes; *cipher = nego.cipher; strcpy(key, nego.key); } } static void store_file(int fd, size_t nbytes, int cipher, char *key) { // while not achived nbytes, read from socket and write to file while (nbytes > 0) { char buf[BUFFER_SIZE]; ssize_t nread; ec_neg1(nread = read_all(sd_other, buf, BUFFER_SIZE)); // TODO: decrypt data here ec_neg1(write_all(fd, buf, nread)); nbytes -= nread; } ec_nzero(close(fd)); }