Merge branch 'jc-thread-safe-bcrypt'
diff --git a/c_src/bcrypt.c b/c_src/bcrypt.c
index 13635d0..dbc9571 100644
--- a/c_src/bcrypt.c
+++ b/c_src/bcrypt.c
@@ -63,14 +63,13 @@
 #define BCRYPT_BLOCKS 6		/* Ciphertext blocks */
 #define BCRYPT_MINROUNDS 16	/* we have log2(rounds) in salt */
 
-char *bcrypt(const char *, const char *);
+int bcrypt(char *, const char *, const char *);
 void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
 
 static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t);
 static void decode_base64(u_int8_t *, u_int16_t, u_int8_t *);
 
-static char    encrypted[_PASSWORD_LEN];
-static char    error[] = ":";
+#define ERROR -1
 
 const static u_int8_t Base64Code[] =
 "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
@@ -143,8 +142,8 @@
 /* We handle $Vers$log2(NumRounds)$salt+passwd$
    i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
 
-char   *
-bcrypt(const char *key, const char *salt)
+int
+bcrypt(char * encrypted, const char *key, const char *salt)
 {
 	blf_ctx state;
 	u_int32_t rounds, i, k;
@@ -160,7 +159,7 @@
 
 	if (*salt > BCRYPT_VERSION) {
 		/* How do I handle errors ? Return ':' */
-		return error;
+		return ERROR;
 	}
 
 	/* Check for minor versions */
@@ -172,7 +171,7 @@
 			 salt++;
 			 break;
 		 default:
-			 return error;
+			 return ERROR;
 		 }
 	} else
 		 minor = 0;
@@ -182,21 +181,21 @@
 
 	if (salt[2] != '$')
 		/* Out of sync with passwd entry */
-		return error;
+		return ERROR;
 
 	/* Computer power doesn't increase linear, 2^x should be fine */
 	n = atoi(salt);
 	if (n > 31 || n < 0)
-		return error;
+		return ERROR;
 	logr = (u_int8_t)n;
 	if ((rounds = (u_int32_t) 1 << logr) < BCRYPT_MINROUNDS)
-		return error;
+		return ERROR;
 
 	/* Discard num rounds + "$" identifier */
 	salt += 3;
 
 	if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
-		return error;
+		return ERROR;
 
 	/* We dont want the base64 salt but the raw data */
 	decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
@@ -248,7 +247,7 @@
 	memset(ciphertext, 0, sizeof(ciphertext));
 	memset(csalt, 0, sizeof(csalt));
 	memset(cdata, 0, sizeof(cdata));
-	return encrypted;
+	return 0;
 }
 
 static void
diff --git a/c_src/bcrypt_nif.c b/c_src/bcrypt_nif.c
index b9e636d..b2f8adc 100644
--- a/c_src/bcrypt_nif.c
+++ b/c_src/bcrypt_nif.c
@@ -75,7 +75,7 @@
 {
     char password[1024] = { 0 };
     char salt[1024] = { 0 };
-    char *ret = NULL;
+    char encrypted[1024] = { 0 };
 
     size_t password_sz = 1024;
     if (password_sz > task->data.hash.password.size)
@@ -87,7 +87,7 @@
         salt_sz = task->data.hash.salt.size;
     (void)memcpy(&salt, task->data.hash.salt.data, salt_sz);
 
-    if (NULL == (ret = bcrypt(password, salt)) || 0 == strcmp(ret, ":")) {
+    if (bcrypt(encrypted, password, salt)) {
         return enif_make_tuple3(
             task->env,
             enif_make_atom(task->env, "error"),
@@ -99,7 +99,7 @@
         task->env,
         enif_make_atom(task->env, "ok"),
         task->ref,
-        enif_make_string(task->env, ret, ERL_NIF_LATIN1));
+        enif_make_string(task->env, encrypted, ERL_NIF_LATIN1));
 }
 
 void* async_worker(void* arg)
diff --git a/c_src/bcrypt_nif.h b/c_src/bcrypt_nif.h
index 5d513cb..7326cb5 100644
--- a/c_src/bcrypt_nif.h
+++ b/c_src/bcrypt_nif.h
@@ -5,7 +5,7 @@
 
 typedef unsigned char byte;
 
-char *bcrypt(const char *, const char *);
+int bcrypt(char *, const char *, const char *);
 void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
 
 typedef struct {
diff --git a/c_src/bcrypt_port.c b/c_src/bcrypt_port.c
index 9abc013..d2f7421 100644
--- a/c_src/bcrypt_port.c
+++ b/c_src/bcrypt_port.c
@@ -35,7 +35,7 @@
 
 typedef unsigned char byte;
 
-char *bcrypt(const char *, const char *);
+char *bcrypt(char *, const char *, const char *);
 void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
 
 /* These methods came from the Erlang port command tutorial:
@@ -72,7 +72,7 @@
 static int
 write_buf(int fd, byte *buf, int len)
 {
-    int i, done = 0; 
+    int i, done = 0;
     do {
         if ((i = write(fd, buf+done, len-done)) < 0) {
             if (errno != EINTR)
@@ -150,7 +150,7 @@
     ETERM *pattern, *pwd, *slt, *pwd_bin, *slt_bin;
     char password[1024];
     char salt[1024];
-    char *ret = NULL;
+    char encrypted[1024] = { 0 };
 
     (void)memset(&password, '\0', sizeof(password));
     (void)memset(&salt, '\0', sizeof(salt));
@@ -168,11 +168,10 @@
         } else {
             memcpy(password, ERL_BIN_PTR(pwd_bin), ERL_BIN_SIZE(pwd_bin));
             memcpy(salt, ERL_BIN_PTR(slt_bin), ERL_BIN_SIZE(slt_bin));
-            if (NULL == (ret = bcrypt(password, salt)) ||
-                0 == strcmp(ret, ":")) {
+            if (bcrypt(encrypted, password, salt)) {
                 retval = process_reply(pid, CMD_HASHPW, "Invalid salt");
             } else {
-                retval = process_reply(pid, CMD_HASHPW, ret);
+                retval = process_reply(pid, CMD_HASHPW, encrypted);
             }
         }
         erl_free_term(pwd);