| /********************************************************************************************************* |
| * Software License Agreement (BSD License) * |
| * Author: Sebastien Decugis <sdecugis@freediameter.net> * |
| * * |
| * Copyright (c) 2013, WIDE Project and NICT * |
| * All rights reserved. * |
| * * |
| * Redistribution and use of this software in source and binary forms, with or without modification, are * |
| * permitted provided that the following conditions are met: * |
| * * |
| * * Redistributions of source code must retain the above * |
| * copyright notice, this list of conditions and the * |
| * following disclaimer. * |
| * * |
| * * Redistributions in binary form must reproduce the above * |
| * copyright notice, this list of conditions and the * |
| * following disclaimer in the documentation and/or other * |
| * materials provided with the distribution. * |
| * * |
| * * Neither the name of the WIDE Project or NICT nor the * |
| * names of its contributors may be used to endorse or * |
| * promote products derived from this software without * |
| * specific prior written permission of WIDE Project and * |
| * NICT. * |
| * * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * |
| * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * |
| * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * |
| * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * |
| * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * |
| *********************************************************************************************************/ |
| |
| #include <Python.h> |
| #include <freeDiameter/extension.h> |
| #include <unistd.h> |
| |
| /* wrapper generated by SWIG */ |
| #if PY_VERSION_HEX >= 0x03000000 |
| extern void PyInit__fDpy(void); |
| #define WRAPPER_INIT PyInit__fDpy() |
| #else /* PY_VERSION_HEX */ |
| extern void init_fDpy(void); |
| #define WRAPPER_INIT init_fDpy() |
| #endif /* PY_VERSION_HEX */ |
| |
| /* The string created in the shadow proxy C string file */ |
| extern unsigned char fDpy_py[]; |
| extern unsigned int fDpy_py_len; |
| |
| /* Run an interactive interpreter in a separate thread */ |
| static pthread_t pyinterp = (pthread_t)NULL; |
| static void * myinterp (void * arg) |
| { |
| char * dum[3] = { "<dbg_interactive>", arg, NULL }; |
| |
| TRACE_ENTRY("%p", arg); |
| |
| fd_log_threadname ( "fDpy" ); |
| |
| CHECK_FCT_DO(fd_core_waitstartcomplete(), goto end); |
| |
| if (arg) { |
| fd_log_debug("Starting python interpreter with a script file [experimental]."); |
| Py_Main(2, dum); |
| } else { |
| if (!isatty(fileno(stdin)) || !isatty(fileno(stdout))) { |
| TRACE_ERROR("[dbg_interactive]: this extension requires freeDiameter to be run from a console terminal!"); |
| goto end; |
| } |
| printf("Starting interactive python interpreter [experimental].\n"); |
| printf("Please use Ctrl-D to exit.\n"); |
| printf("Example syntax:\n"); |
| printf(" >>> print cvar.fd_g_config.cnf_diamid\n"); |
| printf(" '%s'\n", fd_g_config->cnf_diamid); |
| Py_Main(1, dum); |
| printf("Python interpreter has exited...\n"); |
| } |
| |
| end: |
| /* Upon exit, issue the order of terminating to fD, if the interpreter was started without a file */ |
| if (!arg) { |
| (void)fd_core_shutdown(); |
| } |
| |
| return NULL; |
| } |
| |
| /* Register the callbacks to the daemon */ |
| static int di_main(char * conffile) |
| { |
| char * shadow_hlp = NULL; |
| int mustfree = 0; |
| TRACE_ENTRY("%p", conffile); |
| |
| Py_InitializeEx(0); |
| |
| WRAPPER_INIT; |
| |
| /* Small hack to avoid duplicating the string, we replace the last char by a \0. |
| It works if the python file is terminated with several \n */ |
| if ( (fDpy_py[fDpy_py_len - 2] == '\n') |
| && (fDpy_py[fDpy_py_len - 1] == '\n')) { |
| fDpy_py[fDpy_py_len - 1] = '\0'; |
| shadow_hlp = (char *)&fDpy_py[0]; |
| } else { |
| CHECK_MALLOC(shadow_hlp = malloc(fDpy_py_len + 1)); |
| memcpy(shadow_hlp, fDpy_py, fDpy_py_len); |
| shadow_hlp[fDpy_py_len] = '\0'; |
| mustfree=1; |
| } |
| |
| PyRun_SimpleString("__file__ = \"\"\n"); |
| PyRun_SimpleString(shadow_hlp); |
| |
| if (mustfree) |
| free(shadow_hlp); |
| |
| CHECK_POSIX( pthread_create(&pyinterp, NULL, myinterp, conffile) ); |
| |
| return 0; |
| } |
| |
| /* Terminate the extension */ |
| void fd_ext_fini(void) |
| { |
| TRACE_ENTRY(); |
| void * ret; |
| |
| /* Cleanup the python interpreter */ |
| Py_Finalize(); |
| pthread_join(pyinterp, &ret); |
| |
| return ; |
| } |
| |
| /* Define the entry point function */ |
| EXTENSION_ENTRY("dbg_interactive", di_main); |