|  | /* | 
|  | * Python UUID module that wraps libuuid or Windows rpcrt4.dll. | 
|  | * DCE compatible Universally Unique Identifier library. | 
|  | */ | 
|  |  | 
|  | #define PY_SSIZE_T_CLEAN | 
|  |  | 
|  | #include "Python.h" | 
|  | #ifdef HAVE_UUID_UUID_H | 
|  | #include <uuid/uuid.h> | 
|  | #elif defined(HAVE_UUID_H) | 
|  | #include <uuid.h> | 
|  | #endif | 
|  |  | 
|  | #ifdef MS_WINDOWS | 
|  | #include <rpc.h> | 
|  | #endif | 
|  |  | 
|  | #ifndef MS_WINDOWS | 
|  |  | 
|  | static PyObject * | 
|  | py_uuid_generate_time_safe(PyObject *Py_UNUSED(context), | 
|  | PyObject *Py_UNUSED(ignored)) | 
|  | { | 
|  | uuid_t uuid; | 
|  | #ifdef HAVE_UUID_GENERATE_TIME_SAFE | 
|  | int res; | 
|  |  | 
|  | res = uuid_generate_time_safe(uuid); | 
|  | return Py_BuildValue("y#i", (const char *) uuid, sizeof(uuid), res); | 
|  | #elif defined(HAVE_UUID_CREATE) | 
|  | uint32_t status; | 
|  | uuid_create(&uuid, &status); | 
|  | # if defined(HAVE_UUID_ENC_BE) | 
|  | unsigned char buf[sizeof(uuid)]; | 
|  | uuid_enc_be(buf, &uuid); | 
|  | return Py_BuildValue("y#i", buf, sizeof(uuid), (int) status); | 
|  | # else | 
|  | return Py_BuildValue("y#i", (const char *) &uuid, sizeof(uuid), (int) status); | 
|  | # endif /* HAVE_UUID_CREATE */ | 
|  | #else /* HAVE_UUID_GENERATE_TIME_SAFE */ | 
|  | uuid_generate_time(uuid); | 
|  | return Py_BuildValue("y#O", (const char *) uuid, sizeof(uuid), Py_None); | 
|  | #endif /* HAVE_UUID_GENERATE_TIME_SAFE */ | 
|  | } | 
|  |  | 
|  | #else /* MS_WINDOWS */ | 
|  |  | 
|  | static PyObject * | 
|  | py_UuidCreate(PyObject *Py_UNUSED(context), | 
|  | PyObject *Py_UNUSED(ignored)) | 
|  | { | 
|  | UUID uuid; | 
|  | RPC_STATUS res; | 
|  |  | 
|  | Py_BEGIN_ALLOW_THREADS | 
|  | res = UuidCreateSequential(&uuid); | 
|  | Py_END_ALLOW_THREADS | 
|  |  | 
|  | switch (res) { | 
|  | case RPC_S_OK: | 
|  | case RPC_S_UUID_LOCAL_ONLY: | 
|  | case RPC_S_UUID_NO_ADDRESS: | 
|  | /* | 
|  | All success codes, but the latter two indicate that the UUID is random | 
|  | rather than based on the MAC address. If the OS can't figure this out, | 
|  | neither can we, so we'll take it anyway. | 
|  | */ | 
|  | return Py_BuildValue("y#", (const char *)&uuid, sizeof(uuid)); | 
|  | } | 
|  | PyErr_SetFromWindowsErr(res); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | #endif /* MS_WINDOWS */ | 
|  |  | 
|  |  | 
|  | static int | 
|  | uuid_exec(PyObject *module) { | 
|  | assert(sizeof(uuid_t) == 16); | 
|  | #if defined(MS_WINDOWS) | 
|  | int has_uuid_generate_time_safe = 0; | 
|  | #elif defined(HAVE_UUID_GENERATE_TIME_SAFE) | 
|  | int has_uuid_generate_time_safe = 1; | 
|  | #else | 
|  | int has_uuid_generate_time_safe = 0; | 
|  | #endif | 
|  | if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe", | 
|  | has_uuid_generate_time_safe) < 0) { | 
|  | return -1; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static PyMethodDef uuid_methods[] = { | 
|  | #if defined(HAVE_UUID_UUID_H) || defined(HAVE_UUID_H) | 
|  | {"generate_time_safe", py_uuid_generate_time_safe, METH_NOARGS, NULL}, | 
|  | #endif | 
|  | #if defined(MS_WINDOWS) | 
|  | {"UuidCreate", py_UuidCreate, METH_NOARGS, NULL}, | 
|  | #endif | 
|  | {NULL, NULL, 0, NULL}           /* sentinel */ | 
|  | }; | 
|  |  | 
|  | static PyModuleDef_Slot uuid_slots[] = { | 
|  | {Py_mod_exec, uuid_exec}, | 
|  | {0, NULL} | 
|  | }; | 
|  |  | 
|  | static struct PyModuleDef uuidmodule = { | 
|  | PyModuleDef_HEAD_INIT, | 
|  | .m_name = "_uuid", | 
|  | .m_size = 0, | 
|  | .m_methods = uuid_methods, | 
|  | .m_slots = uuid_slots, | 
|  | }; | 
|  |  | 
|  | PyMODINIT_FUNC | 
|  | PyInit__uuid(void) | 
|  | { | 
|  | return PyModuleDef_Init(&uuidmodule); | 
|  | } |