17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci * Python UUID module that wraps libuuid or Windows rpcrt4.dll. 37db96d56Sopenharmony_ci * DCE compatible Universally Unique Identifier library. 47db96d56Sopenharmony_ci */ 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci#include "Python.h" 97db96d56Sopenharmony_ci#if defined(HAVE_UUID_H) 107db96d56Sopenharmony_ci // AIX, FreeBSD, libuuid with pkgconf 117db96d56Sopenharmony_ci #include <uuid.h> 127db96d56Sopenharmony_ci#elif defined(HAVE_UUID_UUID_H) 137db96d56Sopenharmony_ci // libuuid without pkgconf 147db96d56Sopenharmony_ci #include <uuid/uuid.h> 157db96d56Sopenharmony_ci#endif 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci#ifdef MS_WINDOWS 187db96d56Sopenharmony_ci#include <rpc.h> 197db96d56Sopenharmony_ci#endif 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci#ifndef MS_WINDOWS 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_cistatic PyObject * 247db96d56Sopenharmony_cipy_uuid_generate_time_safe(PyObject *Py_UNUSED(context), 257db96d56Sopenharmony_ci PyObject *Py_UNUSED(ignored)) 267db96d56Sopenharmony_ci{ 277db96d56Sopenharmony_ci uuid_t uuid; 287db96d56Sopenharmony_ci#ifdef HAVE_UUID_GENERATE_TIME_SAFE 297db96d56Sopenharmony_ci int res; 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci res = uuid_generate_time_safe(uuid); 327db96d56Sopenharmony_ci return Py_BuildValue("y#i", (const char *) uuid, sizeof(uuid), res); 337db96d56Sopenharmony_ci#elif defined(HAVE_UUID_CREATE) 347db96d56Sopenharmony_ci uint32_t status; 357db96d56Sopenharmony_ci uuid_create(&uuid, &status); 367db96d56Sopenharmony_ci# if defined(HAVE_UUID_ENC_BE) 377db96d56Sopenharmony_ci unsigned char buf[sizeof(uuid)]; 387db96d56Sopenharmony_ci uuid_enc_be(buf, &uuid); 397db96d56Sopenharmony_ci return Py_BuildValue("y#i", buf, sizeof(uuid), (int) status); 407db96d56Sopenharmony_ci# else 417db96d56Sopenharmony_ci return Py_BuildValue("y#i", (const char *) &uuid, sizeof(uuid), (int) status); 427db96d56Sopenharmony_ci# endif /* HAVE_UUID_CREATE */ 437db96d56Sopenharmony_ci#else /* HAVE_UUID_GENERATE_TIME_SAFE */ 447db96d56Sopenharmony_ci uuid_generate_time(uuid); 457db96d56Sopenharmony_ci return Py_BuildValue("y#O", (const char *) uuid, sizeof(uuid), Py_None); 467db96d56Sopenharmony_ci#endif /* HAVE_UUID_GENERATE_TIME_SAFE */ 477db96d56Sopenharmony_ci} 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci#else /* MS_WINDOWS */ 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_cistatic PyObject * 527db96d56Sopenharmony_cipy_UuidCreate(PyObject *Py_UNUSED(context), 537db96d56Sopenharmony_ci PyObject *Py_UNUSED(ignored)) 547db96d56Sopenharmony_ci{ 557db96d56Sopenharmony_ci UUID uuid; 567db96d56Sopenharmony_ci RPC_STATUS res; 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 597db96d56Sopenharmony_ci res = UuidCreateSequential(&uuid); 607db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci switch (res) { 637db96d56Sopenharmony_ci case RPC_S_OK: 647db96d56Sopenharmony_ci case RPC_S_UUID_LOCAL_ONLY: 657db96d56Sopenharmony_ci case RPC_S_UUID_NO_ADDRESS: 667db96d56Sopenharmony_ci /* 677db96d56Sopenharmony_ci All success codes, but the latter two indicate that the UUID is random 687db96d56Sopenharmony_ci rather than based on the MAC address. If the OS can't figure this out, 697db96d56Sopenharmony_ci neither can we, so we'll take it anyway. 707db96d56Sopenharmony_ci */ 717db96d56Sopenharmony_ci return Py_BuildValue("y#", (const char *)&uuid, sizeof(uuid)); 727db96d56Sopenharmony_ci } 737db96d56Sopenharmony_ci PyErr_SetFromWindowsErr(res); 747db96d56Sopenharmony_ci return NULL; 757db96d56Sopenharmony_ci} 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci#endif /* MS_WINDOWS */ 787db96d56Sopenharmony_ci 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_cistatic int 817db96d56Sopenharmony_ciuuid_exec(PyObject *module) { 827db96d56Sopenharmony_ci assert(sizeof(uuid_t) == 16); 837db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 847db96d56Sopenharmony_ci int has_uuid_generate_time_safe = 0; 857db96d56Sopenharmony_ci#elif defined(HAVE_UUID_GENERATE_TIME_SAFE) 867db96d56Sopenharmony_ci int has_uuid_generate_time_safe = 1; 877db96d56Sopenharmony_ci#else 887db96d56Sopenharmony_ci int has_uuid_generate_time_safe = 0; 897db96d56Sopenharmony_ci#endif 907db96d56Sopenharmony_ci if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe", 917db96d56Sopenharmony_ci has_uuid_generate_time_safe) < 0) { 927db96d56Sopenharmony_ci return -1; 937db96d56Sopenharmony_ci } 947db96d56Sopenharmony_ci return 0; 957db96d56Sopenharmony_ci} 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_cistatic PyMethodDef uuid_methods[] = { 987db96d56Sopenharmony_ci#if defined(HAVE_UUID_UUID_H) || defined(HAVE_UUID_H) 997db96d56Sopenharmony_ci {"generate_time_safe", py_uuid_generate_time_safe, METH_NOARGS, NULL}, 1007db96d56Sopenharmony_ci#endif 1017db96d56Sopenharmony_ci#if defined(MS_WINDOWS) 1027db96d56Sopenharmony_ci {"UuidCreate", py_UuidCreate, METH_NOARGS, NULL}, 1037db96d56Sopenharmony_ci#endif 1047db96d56Sopenharmony_ci {NULL, NULL, 0, NULL} /* sentinel */ 1057db96d56Sopenharmony_ci}; 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_cistatic PyModuleDef_Slot uuid_slots[] = { 1087db96d56Sopenharmony_ci {Py_mod_exec, uuid_exec}, 1097db96d56Sopenharmony_ci {0, NULL} 1107db96d56Sopenharmony_ci}; 1117db96d56Sopenharmony_ci 1127db96d56Sopenharmony_cistatic struct PyModuleDef uuidmodule = { 1137db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 1147db96d56Sopenharmony_ci .m_name = "_uuid", 1157db96d56Sopenharmony_ci .m_size = 0, 1167db96d56Sopenharmony_ci .m_methods = uuid_methods, 1177db96d56Sopenharmony_ci .m_slots = uuid_slots, 1187db96d56Sopenharmony_ci}; 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ciPyMODINIT_FUNC 1217db96d56Sopenharmony_ciPyInit__uuid(void) 1227db96d56Sopenharmony_ci{ 1237db96d56Sopenharmony_ci return PyModuleDef_Init(&uuidmodule); 1247db96d56Sopenharmony_ci} 125