blob: d1347a2367ded8c703d2d38afec3b6e439fb56cd [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*********************************************************************************************************
2* Software License Agreement (BSD License) *
3* Author: Sebastien Decugis <sdecugis@freediameter.net> *
4* *
5* Copyright (c) 2013, WIDE Project and NICT *
6* All rights reserved. *
7* *
8* Redistribution and use of this software in source and binary forms, with or without modification, are *
9* permitted provided that the following conditions are met: *
10* *
11* * Redistributions of source code must retain the above *
12* copyright notice, this list of conditions and the *
13* following disclaimer. *
14* *
15* * Redistributions in binary form must reproduce the above *
16* copyright notice, this list of conditions and the *
17* following disclaimer in the documentation and/or other *
18* materials provided with the distribution. *
19* *
20* * Neither the name of the WIDE Project or NICT nor the *
21* names of its contributors may be used to endorse or *
22* promote products derived from this software without *
23* specific prior written permission of WIDE Project and *
24* NICT. *
25* *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
34*********************************************************************************************************/
35
36#include <Python.h>
37#include <freeDiameter/extension.h>
38#include <unistd.h>
39
40/* wrapper generated by SWIG */
41#if PY_VERSION_HEX >= 0x03000000
42 extern void PyInit__fDpy(void);
43 #define WRAPPER_INIT PyInit__fDpy()
44#else /* PY_VERSION_HEX */
45 extern void init_fDpy(void);
46 #define WRAPPER_INIT init_fDpy()
47#endif /* PY_VERSION_HEX */
48
49/* The string created in the shadow proxy C string file */
50extern unsigned char fDpy_py[];
51extern unsigned int fDpy_py_len;
52
53/* Run an interactive interpreter in a separate thread */
54static pthread_t pyinterp = (pthread_t)NULL;
55static void * myinterp (void * arg)
56{
57 char * dum[3] = { "<dbg_interactive>", arg, NULL };
58
59 TRACE_ENTRY("%p", arg);
60
61 fd_log_threadname ( "fDpy" );
62
63 CHECK_FCT_DO(fd_core_waitstartcomplete(), goto end);
64
65 if (arg) {
66 fd_log_debug("Starting python interpreter with a script file [experimental].");
67 Py_Main(2, dum);
68 } else {
69 if (!isatty(fileno(stdin)) || !isatty(fileno(stdout))) {
70 TRACE_ERROR("[dbg_interactive]: this extension requires freeDiameter to be run from a console terminal!");
71 goto end;
72 }
73 printf("Starting interactive python interpreter [experimental].\n");
74 printf("Please use Ctrl-D to exit.\n");
75 printf("Example syntax:\n");
76 printf(" >>> print cvar.fd_g_config.cnf_diamid\n");
77 printf(" '%s'\n", fd_g_config->cnf_diamid);
78 Py_Main(1, dum);
79 printf("Python interpreter has exited...\n");
80 }
81
82end:
83 /* Upon exit, issue the order of terminating to fD, if the interpreter was started without a file */
84 if (!arg) {
85 (void)fd_core_shutdown();
86 }
87
88 return NULL;
89}
90
91/* Register the callbacks to the daemon */
92static int di_main(char * conffile)
93{
94 char * shadow_hlp = NULL;
95 int mustfree = 0;
96 TRACE_ENTRY("%p", conffile);
97
98 Py_InitializeEx(0);
99
100 WRAPPER_INIT;
101
102 /* Small hack to avoid duplicating the string, we replace the last char by a \0.
103 It works if the python file is terminated with several \n */
104 if ( (fDpy_py[fDpy_py_len - 2] == '\n')
105 && (fDpy_py[fDpy_py_len - 1] == '\n')) {
106 fDpy_py[fDpy_py_len - 1] = '\0';
107 shadow_hlp = (char *)&fDpy_py[0];
108 } else {
109 CHECK_MALLOC(shadow_hlp = malloc(fDpy_py_len + 1));
110 memcpy(shadow_hlp, fDpy_py, fDpy_py_len);
111 shadow_hlp[fDpy_py_len] = '\0';
112 mustfree=1;
113 }
114
115 PyRun_SimpleString("__file__ = \"\"\n");
116 PyRun_SimpleString(shadow_hlp);
117
118 if (mustfree)
119 free(shadow_hlp);
120
121 CHECK_POSIX( pthread_create(&pyinterp, NULL, myinterp, conffile) );
122
123 return 0;
124}
125
126/* Terminate the extension */
127void fd_ext_fini(void)
128{
129 TRACE_ENTRY();
130 void * ret;
131
132 /* Cleanup the python interpreter */
133 Py_Finalize();
134 pthread_join(pyinterp, &ret);
135
136 return ;
137}
138
139/* Define the entry point function */
140EXTENSION_ENTRY("dbg_interactive", di_main);