#include "../include/headdef.h"// initialize the server sockets and listen for incomming connectionsstatic void init(void);// establish connection with clients and fork off a child to servestatic 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 cipherstatic void check_client(int *fd, size_t *nbytes, int *cipher, char *key);// use the fd return by analyse and store datastatic 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 disturbeint 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));}