Frank Smit avatar Frank Smit committed 4c86126

_bcrypt.c now compiles for Python too.

Comments (0)

Files changed (1)

cryptacular/bcrypt/_bcrypt.c

 #include <Python.h>
 #include "ow-crypt.h"
 
-static PyObject *_py_crypt_rn(PyObject *self, PyObject *args) {
-	char *rc;
-	const char *key;
-	const char *setting;
-	char output[61];
 
-	memset(output, 0, sizeof(output));
+struct module_state {
+    PyObject *error;
+};
 
-	if (!PyArg_ParseTuple(args, "ss", &key, &setting)) {
-		return NULL;
-	}
 
-	Py_BEGIN_ALLOW_THREADS;
-	
-	/* key, setting, output, size */
-	rc = crypt_rn(key, setting, output, sizeof(output));
+#if PY_MAJOR_VERSION >= 3
+    #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+#else
+    #define GETSTATE(m) (&_state)
+    static struct module_state _state;
+#endif
 
-	Py_END_ALLOW_THREADS;
 
-	if (rc == NULL) {
-		Py_RETURN_NONE;
-	}
+static PyObject *
+_py_crypt_rn(PyObject *self, PyObject *args)
+{
+    char *rc;
+    const char *key;
+    const char *setting;
+    char output[61];
 
-	output[sizeof(output) - 1] = '\0';
+    memset(output, 0, sizeof(output));
 
-	return Py_BuildValue("s", output);
+    if (!PyArg_ParseTuple(args, "ss", &key, &setting)) {
+        return NULL;
+    }
+
+    Py_BEGIN_ALLOW_THREADS;
+
+    /* key, setting, output, size */
+    rc = crypt_rn(key, setting, output, sizeof(output));
+
+    Py_END_ALLOW_THREADS;
+
+    if (rc == NULL) {
+        Py_RETURN_NONE;
+    }
+
+    output[sizeof(output) - 1] = '\0';
+
+    return Py_BuildValue("s", output);
 }
 
-static PyObject *_py_crypt_gensalt_rn(PyObject *self, PyObject *args) {
-	char *rc;
-	const char *prefix;
-	const int count;
-	const char *salt;
-	const Py_ssize_t salt_len;
-	char output[30];
 
-	memset(output, 0, sizeof(output));
-	
-	if (!PyArg_ParseTuple(args, "sis#", &prefix, &count, &salt, &salt_len)) {
-		return NULL;
-	}
+static PyObject *
+_py_crypt_gensalt_rn(PyObject *self, PyObject *args)
+{
+    char *rc;
+    const char *prefix;
+    const int count;
+    const char *salt;
+    const Py_ssize_t salt_len;
+    char output[30];
 
-	/* prefix, count, input, size, output, output_size */
-	rc = crypt_gensalt_rn(prefix, count, salt, salt_len, output, sizeof(output));
+    memset(output, 0, sizeof(output));
 
-	if (rc == NULL) {
-		Py_RETURN_NONE;
-	}
+    if (!PyArg_ParseTuple(args, "sis#", &prefix, &count, &salt, &salt_len)) {
+        return NULL;
+    }
 
-	output[sizeof(output) - 1] = '\0';
+    /* prefix, count, input, size, output, output_size */
+    rc = crypt_gensalt_rn(prefix, count, salt, salt_len, output, sizeof(output));
 
-	return Py_BuildValue("s", output);
+    if (rc == NULL) {
+        Py_RETURN_NONE;
+    }
+
+    output[sizeof(output) - 1] = '\0';
+
+    return Py_BuildValue("s", output);
 }
 
-static PyMethodDef BcryptMethods[] = {
-	{"crypt_rn", _py_crypt_rn, METH_VARARGS, "Encrypt password"},
-	{"crypt_gensalt_rn", _py_crypt_gensalt_rn, METH_VARARGS, "Generate salt"},
-	{NULL, NULL, 0, NULL}
+
+static PyMethodDef _bcrypt_methods[] = {
+    {"crypt_rn", _py_crypt_rn, METH_VARARGS, "Encrypt password"},
+    {"crypt_gensalt_rn", _py_crypt_gensalt_rn, METH_VARARGS, "Generate salt"},
+    {NULL, NULL, 0, NULL} /* Sentinel */
 };
 
-PyMODINIT_FUNC
-init_bcrypt(void)
+
+
+#if PY_MAJOR_VERSION >= 3
+    static int
+    _bcrypt_traverse(PyObject *m, visitproc visit, void *arg)
+    {
+        Py_VISIT(GETSTATE(m)->error);
+        return 0;
+    }
+
+    static int
+    _bcrypt_clear(PyObject *m)
+    {
+        Py_CLEAR(GETSTATE(m)->error);
+        return 0;
+    }
+
+    static struct PyModuleDef moduledef = {
+        PyModuleDef_HEAD_INIT,
+        "_bcrypt",
+        NULL,
+        sizeof(struct module_state),
+        _bcrypt_methods,
+        NULL,
+        _bcrypt_traverse,
+        _bcrypt_clear,
+        NULL
+    };
+
+    #define INITERROR return NULL
+
+    PyObject *
+    PyInit__bcrypt(void)
+#else
+    #define INITERROR return
+
+    PyMODINIT_FUNC
+    init_bcrypt(void)
+#endif
 {
-	(void) Py_InitModule("_bcrypt", BcryptMethods);
+    #if PY_MAJOR_VERSION >= 3
+        PyObject *module = PyModule_Create(&moduledef);
+    #else
+        PyObject *module = Py_InitModule("_bcrypt", _bcrypt_methods);
+    #endif
+
+    if (module == NULL) {
+        INITERROR;
+    }
+    struct module_state *st = GETSTATE(module);
+
+    st->error = PyErr_NewException("_bcrypt.Error", NULL, NULL);
+    if (st->error == NULL) {
+        Py_DECREF(module);
+        INITERROR;
+    }
+
+    #if PY_MAJOR_VERSION >= 3
+        return module;
+    #endif
 }
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.