This source file includes following definitions.
- print_stack
- dlopen
- dlclose
- load
- unload
- main
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <freetdm.h>
5 #include <ftdm_dso.h>
6 #include <dlfcn.h>
7 #include <execinfo.h>
8
9 #define ARRLEN(obj) (sizeof(obj)/sizeof(obj[0]))
10
11 struct dso_entry {
12 char name[25];
13 ftdm_dso_lib_t lib;
14 };
15
16 struct dso_entry loaded[10];
17
18 static void *(*real_dlopen)(const char *filename, int flag) = NULL;
19 static int (*real_dlclose)(void *handle) = NULL;
20
21 static void print_stack()
22 {
23 void *stacktrace[100];
24 char **symbols;
25 int size;
26 int i;
27 size = backtrace(stacktrace, ARRLEN(stacktrace));
28 symbols = backtrace_symbols(stacktrace, size);
29 if (!symbols) {
30 return;
31 }
32 for (i = 0; i < size; i++) {
33 ftdm_log(FTDM_LOG_DEBUG, "%s\n", symbols[i]);
34 }
35 free(symbols);
36 }
37
38 void *dlopen(const char *filename, int flag)
39 {
40 char *msg = NULL;
41 void *handle = NULL;
42 print_stack();
43 if (real_dlopen == NULL) {
44 dlerror();
45 real_dlopen = dlsym(RTLD_NEXT, "dlopen");
46 if ((msg = dlerror()) != NULL) {
47 fprintf(stderr, "dlsym failed: %s\n", msg);
48 exit(1);
49 }
50 fprintf(stderr, "Real dlopen at addr %p\n", real_dlopen);
51 }
52 handle = real_dlopen(filename, flag);
53 if (!handle) {
54 return NULL;
55 }
56 ftdm_log(FTDM_LOG_NOTICE, "Loaded %s with handle %p\n", filename, handle);
57 return handle;
58 }
59
60 int dlclose(void *handle)
61 {
62 char *msg = NULL;
63 print_stack();
64 if (real_dlclose == NULL) {
65 dlerror();
66 real_dlclose = dlsym(RTLD_NEXT, "dlclose");
67 if ((msg = dlerror()) != NULL) {
68 fprintf(stderr, "dlsym failed: %s\n", msg);
69 exit(1);
70 }
71 fprintf(stderr, "Real dlclose at addr %p\n", real_dlclose);
72 }
73 ftdm_log(FTDM_LOG_NOTICE, "Unloading %p\n", handle);
74 return real_dlclose(handle);
75 }
76
77 int load(char *name)
78 {
79 char path[255];
80 char *err;
81 struct dso_entry *entry = NULL;
82 int i;
83
84 for (i = 0; i < ARRLEN(loaded); i++) {
85 if (!loaded[i].lib) {
86 entry = &loaded[i];
87 break;
88 }
89 }
90
91 if (!entry) {
92 ftdm_log(FTDM_LOG_CRIT, "Cannot load more libraries\n");
93 return -1;
94 }
95
96 ftdm_build_dso_path(name, path, sizeof(path));
97 ftdm_log(FTDM_LOG_DEBUG, "Loading %s!\n", path);
98 entry->lib = ftdm_dso_open(path, &err);
99 if (!entry->lib) {
100 ftdm_log(FTDM_LOG_CRIT, "Cannot load library '%s': %s\n", path, err);
101 return -1;
102 }
103 strncpy(entry->name, name, sizeof(entry->name)-1);
104 entry->name[sizeof(entry->name)-1] = 0;
105 return 0;
106 }
107
108 int unload(char *name)
109 {
110 int i;
111 struct dso_entry *entry = NULL;
112 ftdm_log(FTDM_LOG_DEBUG, "Unloading %s!\n", name);
113 for (i = 0; i < ARRLEN(loaded); i++) {
114 if (loaded[i].lib && !strcasecmp(loaded[i].name, name)) {
115 entry = &loaded[i];
116 break;
117 }
118 }
119
120 if (!entry) {
121 ftdm_log(FTDM_LOG_CRIT, "Library %s not found\n", name);
122 return -1;
123 }
124
125 ftdm_dso_destroy(&entry->lib);
126 entry->lib = NULL;
127 return 0;
128 }
129
130 int main(int argc, char *argv[])
131 {
132 char cmdline[255];
133 char name[255];
134
135 ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG);
136
137 if (ftdm_global_init() != FTDM_SUCCESS) {
138 fprintf(stderr, "Error loading FreeTDM\n");
139 exit(-1);
140 }
141
142 memset(loaded, 0, sizeof(loaded));
143
144 printf("CLI> ");
145 while (fgets(cmdline, sizeof(cmdline), stdin)) {
146 if (sscanf(cmdline, "load=%s\n", name) == 1) {
147 load(name);
148 } else if (sscanf(cmdline, "unload=%s\n", name) == 1) {
149 unload(name);
150 } else if (!strncasecmp(cmdline, "exit", sizeof("exit")-1)) {
151 printf("Quitting ...\n");
152 sleep(1);
153 break;
154 } else {
155 fprintf(stderr, "load=<name> | unload=<name> | exit\n");
156 }
157 printf("\nCLI> ");
158 }
159
160
161 ftdm_global_destroy();
162
163 printf("Done, press any key to die!\n");
164
165 getchar();
166 return 0;
167 }
168