cb2c16e7001064bd2b631d8d9770379fe74db594
[Evergreen.git] / OpenSRF / src / libstack / osrf_application.c
1
2 #include "osrf_application.h"
3
4 osrfApplication* __osrfAppList = NULL; 
5
6
7 int osrfAppRegisterApplication( char* appName, char* soFile ) {
8         if(!appName || ! soFile) return -1;
9         char* error;
10
11         info_handler("Registering application %s with file %s", appName, soFile );
12
13         osrfApplication* app = safe_malloc(sizeof(osrfApplication));
14         app->handle = dlopen (soFile, RTLD_NOW);
15
16         if(!app->handle) {
17                 warning_handler("Failed to dlopen library file %s: %s", soFile, dlerror() );
18                 dlerror(); /* clear the error */
19                 free(app);
20                 return -1;
21         }
22
23         app->name = strdup(appName);
24
25         /* this has to be done before initting the application */
26         app->next = __osrfAppList;
27         __osrfAppList = app;
28
29
30         /* see if we can run the initialize method */
31         int (*init) (void);
32         *(void **) (&init) = dlsym(app->handle, "osrfAppInitialize");
33
34         if( (error = dlerror()) != NULL ) {
35                 warning_handler("! Unable to locate method symbol [osrfAppInitialize] for app %s: %s", appName, error );
36
37         } else {
38
39                 /* run the method */
40                 int ret;
41                 if( (ret = (*init)()) ) {
42                         warning_handler("Application %s returned non-zero value from "
43                                         "'osrfAppInitialize', not registering...", appName );
44                         //free(app->name); /* need a method to remove an application from the list */
45                         //free(app);
46                         return ret;
47                 }
48         }
49
50
51         info_handler("Application %s registered successfully", appName );
52
53
54         return 0;
55 }
56
57
58 int osrfAppRegisterMethod( char* appName, 
59                 char* methodName, char* symbolName, char* notes, int argc ) {
60         if( !appName || ! methodName || ! symbolName ) return -1;
61
62         osrfApplication* app = _osrfAppFindApplication(appName);
63         if(!app) return warning_handler("Unable to locate application %s", appName );
64
65         debug_handler("Registering method %s for app %s", appName, methodName );
66
67         osrfMethod* method = safe_malloc(sizeof(osrfMethod));
68         method->name = strdup(methodName);
69         method->symbol = strdup(symbolName);
70         if(notes) method->notes = strdup(notes);
71         method->argc = argc;
72
73         /* plug the method into the list of methods */
74         method->next = app->methods;
75         app->methods = method;
76         return 0;
77 }
78
79 osrfApplication* _osrfAppFindApplication( char* name ) {
80         if(!name) return NULL;
81         osrfApplication* app = __osrfAppList;
82         while(app) {
83                 if(!strcmp(app->name, name))
84                         return app;
85                 app = app->next;
86         }
87         return NULL;
88 }
89
90 osrfMethod* __osrfAppFindMethod( osrfApplication* app, char* methodName ) {
91         if(!app || ! methodName) return NULL;
92         osrfMethod* method = app->methods;
93         while(method) {
94                 if(!strcmp(method->name, methodName))
95                         return method;
96                 method = method->next;
97         }
98         return NULL;
99 }
100
101 osrfMethod* _osrfAppFindMethod( char* appName, char* methodName ) {
102         if(!appName || ! methodName) return NULL;
103         return __osrfAppFindMethod( _osrfAppFindApplication(appName), methodName );
104 }
105
106
107
108
109 int osrfAppRunMethod( char* appName, char* methodName, osrfAppSession* ses, int reqId, jsonObject* params ) {
110         if( !(appName && methodName && ses) ) return -1;
111
112         char* error;
113         osrfApplication* app;
114         osrfMethod* method;
115         osrfMethodContext context;
116
117         /* this is the method we're gonna run */
118         int (*meth) (osrfMethodContext*);       
119
120         info_handler("Running method [%s] for app [%s] with request id %d and "
121                         "thread trace %s", methodName, appName, reqId, ses->session_id );
122
123         if( !(app = _osrfAppFindApplication(appName)) )
124                 return warning_handler( "Application not found: %s", appName );
125
126         if( !(method = __osrfAppFindMethod( app, methodName )) )
127                 return warning_handler( "NOT FOUND: app %s / method %s", appName, methodName );
128
129         /* open the method */
130         *(void **) (&meth) = dlsym(app->handle, method->symbol);
131
132         if( (error = dlerror()) != NULL ) {
133                 return warning_handler("Unable to locate method symbol [%s] "
134                                 "for method %s and app %s", method->symbol, method->name, app->name );
135         }
136
137         context.session = ses;
138         context.method = method;
139         context.params = params;
140         context.request = reqId;
141
142         /* run the method */
143         int ret = (*meth) (&context);
144
145         debug_handler("method returned %d", ret );
146
147
148         if(ret == -1) {
149                 osrfAppSessionStatus( ses, OSRF_STATUS_INTERNALSERVERERROR, 
150                                         reqId, "An unknown server error occurred" );
151                 return -1;
152         }
153
154         return 0;
155 }
156
157
158