User registering
User registering

--- a/src/config.c
+++ b/src/config.c
@@ -29,6 +29,8 @@
 	srv->allow_colors_dft = ALLOW_COLORS_DFT_CLIENTS;
 
 	srv->config_file = NULL;
+	srv->users_file  = NULL;
+
 	if(!read_opts(srv, argc, argv)) /* if no opts except -f */
 		read_config(srv); /* Read config file */
 
@@ -168,6 +170,9 @@
 			srv->allow_colors_dft = 0;
 		}
 	}
+	else if(!strcmp(opt, "users-file")) {
+		srv->users_file = strdup(arg);
+	}
 	else {
 		fprintf(stderr, "Unknown option: %s (arg: %s, line: %d)\n",
 		        opt, arg, line);

--- a/src/extra_options.c
+++ b/src/extra_options.c
@@ -1,5 +1,6 @@
 #include <string.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #include "server.h"
 #include "chat.h"
@@ -131,6 +132,79 @@
 } /* }}} */
 
 void
+client_opt_login(struct srv_conf *srv, int asker, char *args)
+{ /* {{{ */
+
+	char *nick, *pwd;
+	char *client_nick;
+
+	char message_nocolor[MAX_MSG_SNT_LEN];
+
+	nick = args;
+	pwd = args;
+	while(*pwd != '=' && *pwd != '\0')
+		pwd++;
+	if(*pwd== '=') {
+		*pwd = '\0';
+		pwd++;
+	}
+
+	if(client_auth_passwd(srv, nick, pwd)) {
+		client_nick = srv->client_list[asker].nick;
+
+		srv->client_list[asker].nick = malloc(sizeof(char*) *
+		                                      strlen(nick) + 5);
+		if(!srv->client_list[asker].nick) {
+			fprintf(stderr, "Not enough mem @ %s:%d !\n",
+			        __FILE__, __LINE__);
+			exit(EXIT_FAILURE);
+		}
+
+		strcpy(srv->client_list[asker].nick, nick);
+
+		sprintf(message_nocolor, TNCMSG_OPT_LOGIN_CHANGED_NICK"\n",
+		                      client_nick, nick);
+
+		send_brdcst(srv, message_nocolor, NULL, -1);
+		free(client_nick);
+	}
+	else {
+		send_msg_to_client(srv, TNCMSG_OPT_LOGIN_WRONG"\n", asker);
+	}
+
+} /* }}} */
+
+void
+client_opt_register(struct srv_conf *srv, int asker, char *args)
+{ /* {{{ */
+
+	char msg_buffer[MAX_NICK_LEN + 40];
+	char change_buffer[MAX_NICK_LEN + MAX_NICK_LEN + 50];
+	char nick_buffer[MAX_NICK_LEN];
+	char old_nick[MAX_NICK_LEN + 5];
+
+
+
+
+	sprintf(old_nick, "%s", client_get_nick(srv, asker));
+
+	if(!args) {
+		client_nick_to_display(srv, asker, nick_buffer,
+		                       client_use_color(srv, asker));
+		sprintf(msg_buffer, "Your nick is %s\n", nick_buffer);
+		send_msg_to_client(srv, msg_buffer, asker);
+
+	}
+	else {
+		client_set_nick(srv, asker, args);
+		sprintf(change_buffer, "%s changed his nick to %s",
+		        old_nick, client_get_nick(srv, asker));
+		send_brdcst(srv, change_buffer, NULL, -1);
+		/* TODO: add color */
+	}
+} /* }}} */
+
+void
 client_opt_slap(struct srv_conf *srv, int asker, char *args)
 { /* {{{ */
 

--- a/src/extra_options.h
+++ b/src/extra_options.h
@@ -13,6 +13,12 @@
 client_opt_nick(struct srv_conf *srv, int asker, char *args);
 
 void
+client_opt_login(struct srv_conf *srv, int asker, char *args);
+
+void
+client_opt_register(struct srv_conf *srv, int asker, char *args);
+
+void
 client_opt_slap(struct srv_conf *srv, int asker, char *args);
 
 void

--- a/src/messages.h
+++ b/src/messages.h
@@ -15,7 +15,12 @@
 /* SLAP */
 #define TNCMSG_OPT_SLAP_MSG "%s was slapped by %s"
 #define TNCMSG_OPT_SLAP_UNK_USER "unknown user"
+/* LOGIN */
+#define TNCMSG_OPT_LOGIN_CHANGED_NICK "%s changed his nick to %s"
+#define TNCMSG_OPT_LOGIN_WRONG "Wrong password or nick not registered"
 
+/**** USERS ****/
+#define TNCMSG_NICK_TAKEN_NEED_LOGIN "The nick is taken/registered. If you want to use it, type: /login nick password"
 
 #endif
 

--- a/src/options.c
+++ b/src/options.c
@@ -64,6 +64,12 @@
 	}
 	else if(cmp_arg_is(sent+1, "slap")) {
 		client_opt_slap(srv, client, get_args(sent));
+	}
+	else if(cmp_arg_is(sent+1, "login")) {
+		client_opt_login(srv, client, get_args(sent));
+	}
+	else if(cmp_arg_is(sent+1, "register")) {
+		client_opt_register(srv, client, get_args(sent));
 	}
 	else if(cmp_arg_is(sent+1, "dummy")) {
 		client_opt_dummy(srv, client, get_args(sent));

file:b/src/passwd (new)
--- /dev/null
+++ b/src/passwd
@@ -1,1 +1,2 @@
+foo	bar
 

--- a/src/server.h
+++ b/src/server.h
@@ -46,6 +46,9 @@
 
 #define TNC_CONFIG_FILES "./tnc.conf", "/etc/tnc.conf", NULL
 
+#define TNC_USER_FILE_PWD_SEPARATOR '\t'
+#define TNC_PUBLIC_PWD_SEPARATOR ','
+
 
 struct socket_config6
 {

--- a/src/users.c
+++ b/src/users.c
@@ -38,6 +38,8 @@
 #include "connections.h"
 #include "chat.h"
 #include "utils.h"
+#include "users_file.h"
+#include "messages.h"
 #include "users.h"
 
 /* high level functions: nick change, etc.. */
@@ -117,25 +119,31 @@
 	unique_nick = my_nick;
 
 	if(strcmp(my_nick, TNC_SERVER_NICK) == 0) {
-		unique_nick = malloc(NICK_SPACE_NEEDED *
-		                      sizeof(char));
-		sprintf(unique_nick, "anon_%d", rand()%100000);
-		free(my_nick);
-		return unique_nick;
-	}
+		goto make_anon_nick; /* bouh ! 17 lines below*/
+	}
+
+	if(user_taken(srv, my_nick)) {
+		send_msg_to_client(srv, TNCMSG_NICK_TAKEN_NEED_LOGIN, client);
+		goto make_anon_nick; /* 13 lines below */
+	}
+
 
 	for(i = 1; i <= srv->num_clients; i++) {
 		if((i != client) &&
 		   strcmp(client_get_nick(srv, i), unique_nick) == 0) {
-			unique_nick = malloc(NICK_SPACE_NEEDED *
-			                      sizeof(char));
-			sprintf(unique_nick, "anon_%d", rand()%100000);
-			free(my_nick);
-			return unique_nick;
+			goto make_anon_nick; /* 6 lines below */
 		}
 	}
 
 	return unique_nick;
+
+make_anon_nick:
+	unique_nick = malloc(NICK_SPACE_NEEDED *
+	                      sizeof(char));
+	sprintf(unique_nick, "anon_%d", rand()%100000);
+	free(my_nick);
+	return unique_nick;
+
 } /* }}} */
 
 const char
@@ -240,15 +248,17 @@
 } /* }}} */
 
 int
-client_auth_passwd(struct srv_conf *srv, int sender, char *password)
+client_auth_passwd(struct srv_conf *srv, char *nick, char *password)
 {
-	return 0; /* client could not be authentified */
+	return (auth_user(srv, nick, password) == 1);
 }
 
 int
 client_register(struct srv_conf *srv, int client, char *password)
 {
-
-	return 0; /* could not be registered */
+	char *user_name;
+
+	user_name = client_get_nick(srv, client);
+	return (register_user(srv, user_name, password) == 1);
 }
 

--- a/src/users.h
+++ b/src/users.h
@@ -36,5 +36,11 @@
 int
 get_client_from_nick(struct srv_conf *srv, char *nick);
 
+int
+client_auth_passwd(struct srv_conf *srv, char *nick, char *password);
+
+int
+client_register(struct srv_conf *srv, int client, char *password);
+
 #endif
 

--- a/src/users_file.c
+++ b/src/users_file.c
@@ -32,6 +32,8 @@
 ** Frank Villaro-Dixon - 2013
 */
 #include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
 
 #include "server.h"
 #include "users_file.h"
@@ -39,16 +41,99 @@
 int
 auth_user(struct srv_conf *srv, char *user, char *pwd)
 {
+	FILE *users_file;
+	char buffer[MAX_MSG_RCV_LEN * 2 + 10];
+	char *password;
+	char *pwd_hashed;
 
+	if(srv->users_file == NULL)
+		return 0; /* Server does not support logins */
+
+	if((users_file = fopen(srv->users_file, "r")) == NULL) {
+		fprintf(stderr, "[ERR] Could not open users file (%s) for writing",
+			srv->users_file);
+		return 0; /* Could not be authed */
+	}
+
+	while(fgets(buffer, sizeof(buffer) - 2, users_file) != NULL) {
+		if(*buffer == '\0' || *buffer == '\n')
+			continue;
+
+		password = buffer;
+		while(*password != TNC_USER_FILE_PWD_SEPARATOR && *password != '\0')
+			password++;
+
+		if(*password == TNC_USER_FILE_PWD_SEPARATOR) {
+			*password = '\0';
+			password++;
+		}
+
+		if(!strcmp(buffer, user)) {
+			/* User exists */
+			puts("User exists!");
+			pwd_hashed = hash_pwd(pwd);
+			if(!strcmp(password, pwd_hashed)) {
+				/* Pwd OK ! */
+				free(pwd_hashed);
+				return 1;
+			}
+			free(pwd_hashed);
+			return -1;
+		}
+	}
+	fclose(users_file);
 
 	return 0;
 }
 
 int
-register_user(struct srv_conf *srv, char *user, char pwd)
+register_user(struct srv_conf *srv, char *user, char *pwd)
 {
 
+	char *pwd_hashed;
+	FILE *users_file;
 
-	return 0;
+	if(srv->users_file == NULL)
+		return 0; /* Server does not support logins */
+
+	if(auth_user(srv, user, "!!##!!//(())") == -1) {
+		/* very crappy way to see if user exists */
+		return 0;
+	}
+
+	pwd_hashed = hash_pwd(pwd);
+
+	if((users_file = fopen(srv->users_file, "a")) == NULL) {
+		fprintf(stderr, "[ERR] Could not open users file (%s) for writing",
+			srv->users_file);
+		return 0; /* Could not be authed */
+	}
+
+	fprintf(users_file, "%s%c%s\n", user, TNC_USER_FILE_PWD_SEPARATOR,
+	                                pwd_hashed);
+	fclose(users_file);
+	free(pwd_hashed);
+
+	return 1;
 }
 
+int
+user_taken(struct srv_conf *srv, char *user)
+{
+	if(srv->users_file == NULL)
+		return 0; /* Server does not support logins */
+
+	return (auth_user(srv, user, "!!##!!//(())") == -1);
+}
+
+char *
+hash_pwd(char *pwd_to_hash)
+{
+	char *pwd;
+
+	pwd = malloc(sizeof(char*) * (strlen(pwd_to_hash) + 5));
+	strcpy(pwd, pwd_to_hash);
+	/* TODO: IMPLEMENT A TYPE OF HASH */
+	return pwd; /* TO FREE */
+}
+

--- a/src/users_file.h
+++ b/src/users_file.h
@@ -3,6 +3,17 @@
 
 #include "server.h"
 
+int
+auth_user(struct srv_conf *srv, char *user, char *pwd);
+
+int
+register_user(struct srv_conf *srv, char *user, char *pwd);
+
+int
+user_taken(struct srv_conf *srv, char *user);
+
+char
+*hash_pwd(char *pwd_to_hash);
 
 #endif