]>
Commit | Line | Data |
---|---|---|
c7f8876d | 1 | /* $Header$ */ |
bde1652c | 2 | #include "mit_moira_MoiraConnectInternal.h" |
3 | #include <moira.h> | |
4 | #include <mr_et.h> | |
5 | #include <malloc.h> | |
6 | #include <string.h> | |
7 | #include <stdio.h> | |
8 | ||
9 | static void throwMoiraException(JNIEnv *env, int code) | |
10 | { | |
11 | char buffer[1024]; | |
12 | jmethodID mid; | |
13 | jobject tothrow; | |
14 | jclass IOE; | |
15 | jstring jmess; | |
16 | ||
17 | IOE = (*env)->FindClass(env, "mit/moira/MoiraException"); | |
18 | if (IOE == NULL) { | |
19 | fprintf(stderr, "moirai: No Class\n"); | |
20 | goto die; | |
21 | } | |
22 | mid = (*env)->GetMethodID(env, IOE, "<init>", "(Ljava/lang/String;I)V"); | |
23 | if (mid == NULL) { | |
24 | fprintf(stderr, "moirai: No Method\n"); | |
25 | goto die; | |
26 | } | |
27 | sprintf(buffer, "%s", error_message(code)); | |
28 | jmess = (*env)->NewStringUTF(env, buffer); | |
29 | if (jmess == NULL) { | |
30 | fprintf(stderr, "Cannot get new string\n"); | |
31 | goto die; | |
32 | } | |
33 | tothrow = (*env)->NewObject(env, IOE, mid, jmess, (jint) code); | |
34 | if (tothrow == NULL) { | |
35 | fprintf(stderr, "moirai: No Throw\n"); | |
36 | goto die; | |
37 | } | |
38 | (*env)->Throw(env, (jthrowable) tothrow); | |
39 | return; | |
40 | die: | |
41 | abort(); | |
42 | return; | |
43 | } | |
44 | ||
45 | static void throwMoiraExceptionMess(JNIEnv *env, char *mess) | |
46 | { | |
47 | jclass IOE = (*env)->FindClass(env, "mit/moira/MoiraException"); | |
48 | if (IOE == NULL) abort(); | |
49 | (*env)->ThrowNew(env, IOE, mess); | |
50 | return; | |
51 | } | |
52 | ||
53 | JNIEXPORT void JNICALL Java_mit_moira_MoiraConnectInternal_connect(JNIEnv *env, | |
54 | jclass Class, jstring server) { | |
55 | int status; | |
56 | char buffer[1024]; | |
57 | const char *aserver = (*env)->GetStringUTFChars(env, server, 0); | |
58 | if (strlen(aserver) > sizeof(buffer)) abort(); | |
59 | strcpy(buffer, aserver); | |
60 | (*env)->ReleaseStringUTFChars(env, server, aserver); | |
61 | status = mr_connect(buffer); | |
62 | if (status != MR_SUCCESS) throwMoiraException(env, status); | |
63 | status = mr_version(2); | |
64 | if (status != MR_SUCCESS) { | |
65 | if (status == MR_VERSION_LOW) return; /* This is OK */ | |
66 | else { | |
67 | mr_disconnect(); | |
68 | throwMoiraException(env, status); | |
69 | } | |
70 | } | |
71 | return; | |
72 | } | |
73 | ||
74 | JNIEXPORT void JNICALL Java_mit_moira_MoiraConnectInternal_proxy(JNIEnv *env, | |
75 | jclass Class, | |
76 | jstring jUser) { | |
77 | int status; | |
78 | char buffer[1024]; | |
79 | const char *user = (*env)->GetStringUTFChars(env, jUser, 0); | |
80 | if (strlen(user) > sizeof(buffer)) abort(); | |
81 | strcpy(buffer, user); | |
82 | (*env)->ReleaseStringUTFChars(env, jUser, user); | |
83 | status = mr_proxy(buffer, "Java"); | |
84 | if (status != MR_SUCCESS) throwMoiraException(env, status); | |
85 | return; | |
86 | } | |
87 | ||
88 | ||
89 | JNIEXPORT void JNICALL Java_mit_moira_MoiraConnectInternal_auth(JNIEnv *env, | |
90 | jclass Class) { | |
91 | int status; | |
991417e4 | 92 | status = mr_krb5_auth("JavaInterface"); |
bde1652c | 93 | if (status != MR_SUCCESS) throwMoiraException(env, status); |
94 | return; | |
95 | } | |
96 | ||
97 | JNIEXPORT void JNICALL Java_mit_moira_MoiraConnectInternal_disconnect | |
98 | (JNIEnv *env, jclass Class) { | |
99 | mr_disconnect(); | |
100 | return; | |
101 | } | |
102 | ||
103 | typedef struct ArgBlock { | |
104 | int alloccount; | |
105 | int count; | |
106 | char **stringval; | |
107 | } ArgBlock; | |
108 | ||
109 | typedef struct ListBlock { | |
110 | int alloccount; | |
111 | int count; | |
112 | ArgBlock **Args; | |
113 | } ListBlock; | |
114 | ||
115 | static jobjectArray ArgBlockToJavaArray(JNIEnv *env, ArgBlock *argb); | |
116 | static jobjectArray ListBlockToJavaArray(JNIEnv *env, ListBlock *lb); | |
117 | ||
118 | extern int mr_query(char *name, int argc, char **argv, | |
119 | int (*proc)(int, char **, void *), void *hint); | |
120 | static ListBlock *NewListBlock(); | |
121 | static ArgBlock *NewArgBlock(); | |
122 | static void FreeListBlock(ListBlock *); | |
123 | static int StashResults(int argc, char **argv, void *callback); | |
124 | static char **ConvertJavaArgs(JNIEnv *env, jobjectArray jargs); | |
125 | static void FreeArgs(char **args); | |
126 | ||
127 | JNIEXPORT jobjectArray JNICALL Java_mit_moira_MoiraConnectInternal_mr_1query | |
128 | (JNIEnv *env, jclass Class, jstring jcommand, jobjectArray jargs) { | |
129 | ListBlock *listblock = NewListBlock(); | |
130 | jobjectArray retval; | |
131 | int status; | |
132 | const char *command; | |
133 | char icommand[1024]; | |
134 | char **args = ConvertJavaArgs(env, jargs); | |
135 | if (args == NULL) return (NULL); /* It probably thru an exception */ | |
136 | command = (*env)->GetStringUTFChars(env, jcommand, 0); | |
137 | strncpy(icommand, command, sizeof(icommand)); | |
138 | ||
139 | status = mr_query(icommand, (*env)->GetArrayLength(env, jargs), args, | |
140 | StashResults, listblock); | |
141 | FreeArgs(args); /* Don't need them anymore */ | |
142 | if (status != MR_SUCCESS) { | |
143 | FreeListBlock(listblock); | |
144 | throwMoiraException(env, status); | |
145 | return (0); | |
146 | } | |
147 | /* if (listblock->count == 0) { / * No such list or empty list * / | |
148 | FreeListBlock(listblock); | |
149 | throwMoiraExceptionMess(env, "No Such List or Empty List"); | |
150 | return(0); | |
151 | } */ | |
152 | ||
153 | if (listblock->count == 0) return (0); | |
154 | ||
155 | retval = ListBlockToJavaArray(env, listblock); | |
156 | FreeListBlock(listblock); | |
157 | return (retval); | |
158 | ||
159 | } | |
160 | ||
161 | static ArgBlock *NewArgBlock() { | |
162 | ArgBlock *argb = (ArgBlock *)malloc(sizeof(ArgBlock)); | |
163 | argb->alloccount = 10; | |
164 | argb->stringval = (char **) malloc(10 * sizeof(char *)); | |
165 | argb->count = 0; | |
166 | return (argb); | |
167 | } | |
168 | ||
169 | static void AddArg(ArgBlock *argb, char *arg) { | |
170 | int i; | |
171 | if (argb->alloccount <= (argb->count + 1)) { | |
172 | char **st = malloc((2 * argb->alloccount) * sizeof(char *)); | |
173 | argb->alloccount *= 2; | |
174 | for (i = 0; i < argb->count; i++) | |
175 | st[i] = argb->stringval[i]; | |
176 | free(argb->stringval); | |
177 | argb->stringval = st; | |
178 | } | |
179 | argb->stringval[argb->count++] = arg; | |
180 | } | |
181 | ||
182 | static ListBlock *NewListBlock() { | |
183 | ListBlock *list = (ListBlock *)malloc(sizeof(ListBlock)); | |
184 | list->alloccount = 10; | |
185 | list->Args = (ArgBlock **) malloc(10 * sizeof(ArgBlock *)); | |
186 | list->count = 0; | |
187 | return (list); | |
188 | } | |
189 | ||
190 | static void FreeArgBlock(ArgBlock *argb) { | |
191 | int i; | |
192 | for (i = 0; i < argb->count; i++) free(argb->stringval[i]); | |
193 | free(argb->stringval); | |
194 | free(argb); | |
195 | } | |
196 | ||
197 | static void FreeListBlock(ListBlock *list) { | |
198 | int i; | |
199 | for (i = 0; i < list->count; i++) FreeArgBlock(list->Args[i]); | |
200 | free(list->Args); | |
201 | free(list); | |
202 | } | |
203 | ||
204 | static jobjectArray ArgBlockToJavaArray(JNIEnv *env, ArgBlock *argb) { | |
205 | jobjectArray retval; | |
206 | int i; | |
207 | retval = (*env)->NewObjectArray(env, argb->count, | |
208 | (*env)->FindClass(env, "java/lang/String"), | |
209 | NULL); | |
210 | for (i = 0; i < argb->count; i++) { | |
211 | (*env)->SetObjectArrayElement(env, retval, i, | |
212 | (*env)->NewStringUTF(env, argb->stringval[i])); | |
213 | } | |
214 | return (retval); | |
215 | } | |
216 | ||
217 | static jobjectArray ListBlockToJavaArray(JNIEnv *env, ListBlock *lb) { | |
218 | jobjectArray retval; | |
219 | int i; | |
220 | retval = (*env)->NewObjectArray(env, lb->count, | |
221 | (*env)->FindClass(env, "java/lang/Object"), | |
222 | NULL); | |
223 | for (i = 0; i < lb->count; i++) | |
224 | (*env)->SetObjectArrayElement(env, retval, i, | |
225 | ArgBlockToJavaArray(env, lb->Args[i])); | |
226 | return (retval); | |
227 | } | |
228 | ||
229 | static int StashResults(int argc, char **argv, void *callback) { | |
230 | ListBlock *list = (ListBlock *) callback; | |
231 | ArgBlock *argb; | |
232 | char *arg; | |
233 | int i; | |
234 | ||
235 | /* printf("DEBUG: StashResults argc = %d\n", argc); | |
236 | * for (i = 0; i < argc; i++) | |
237 | * printf("DEBUG: StashResults argv[%d] = %s\n", i, argv[i]); | |
238 | */ | |
239 | ||
240 | while (list->alloccount <= (list->count + 1)) { | |
241 | ArgBlock **args = (ArgBlock **) malloc(list->alloccount * 2 * sizeof(char *)); | |
242 | list->alloccount = list->alloccount * 2; | |
243 | for(i = 0; i < list->count; i++) { | |
244 | args[i] = list->Args[i]; | |
245 | } | |
246 | free(list->Args); | |
247 | list->Args = args; | |
248 | } | |
249 | ||
250 | argb = NewArgBlock(); | |
251 | ||
252 | for (i = 0; i < argc; i++) { | |
253 | arg = (char *) malloc(strlen(argv[i]) + 1); | |
254 | strcpy(arg, argv[i]); | |
255 | AddArg(argb, arg); | |
256 | } | |
257 | list->Args[list->count++] = argb; | |
258 | return (0); | |
259 | } | |
260 | ||
261 | static char **ConvertJavaArgs(JNIEnv *env, jobjectArray jargs) { | |
262 | char **retval; | |
263 | int i, j; | |
264 | const char *iarg; | |
265 | int length = (*env)->GetArrayLength(env, jargs); | |
266 | if (length == 0) { /* Does this happen in a non-error situation? */ | |
267 | retval = (char **) malloc(sizeof (char *)); | |
268 | retval[0] = NULL; | |
269 | return(retval); | |
270 | } | |
271 | retval = (char **) malloc((length + 1) * sizeof(char *)); | |
272 | for (i = 0; i < length; i++) { | |
273 | jobject jarg = (*env)->GetObjectArrayElement(env, jargs, i); | |
274 | if ((*env)->ExceptionOccurred(env)) { | |
275 | for (j = 0; j < i; j++) free(retval[j]); | |
276 | free (retval); | |
277 | return (NULL); | |
278 | } | |
279 | iarg = (*env)->GetStringUTFChars(env, jarg, 0); | |
280 | if ((*env)->ExceptionOccurred(env)) { | |
281 | for (j = 0; j < i; j++) free(retval[j]); | |
282 | free (retval); | |
283 | return (NULL); | |
284 | } | |
285 | retval[i] = malloc(strlen(iarg) + 1); | |
286 | strcpy(retval[i], iarg); | |
287 | (*env)->ReleaseStringUTFChars(env, jarg, iarg); | |
288 | } | |
289 | retval[length] = NULL; | |
290 | return (retval); | |
291 | } | |
292 | ||
293 | static void FreeArgs(char **args) { | |
294 | int i; | |
295 | i = 0; | |
296 | while (args[i] != NULL) free(args[i++]); | |
297 | free(args); | |
298 | } | |
299 |