All pastes #451012 Raw Edit

Stuff

public text v1 · immutable
·published 2007-04-21 06:13 UTC
rendered paste body
#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));
}