source: trunk/third/moira/webmoira/moirai.c @ 24319

Revision 24319, 8.4 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/webmoira/moirai.c $ $Id: moirai.c 3956 2010-01-05 20:56:56Z zacheiss $ */
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
9static 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
45static 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
53JNIEXPORT 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
74JNIEXPORT 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
89JNIEXPORT void JNICALL Java_mit_moira_MoiraConnectInternal_auth(JNIEnv *env,
90                                                      jclass Class) {
91    int status;
92    status = mr_krb5_auth("JavaInterface");
93    if (status != MR_SUCCESS) throwMoiraException(env, status);
94    return;
95}
96
97JNIEXPORT void JNICALL Java_mit_moira_MoiraConnectInternal_disconnect
98    (JNIEnv *env, jclass Class) {
99    mr_disconnect();
100    return;
101}
102       
103typedef struct ArgBlock {
104    int alloccount;
105    int count;
106    char **stringval;
107} ArgBlock;
108
109typedef struct ListBlock {
110    int alloccount;
111    int count;
112    ArgBlock **Args;
113} ListBlock;
114
115static jobjectArray ArgBlockToJavaArray(JNIEnv *env, ArgBlock *argb);
116static jobjectArray ListBlockToJavaArray(JNIEnv *env, ListBlock *lb);
117
118extern int mr_query(char *name, int argc, char **argv,
119                int (*proc)(int, char **, void *), void *hint);
120static ListBlock *NewListBlock();
121static ArgBlock *NewArgBlock();
122static void FreeListBlock(ListBlock *);
123static int StashResults(int argc, char **argv, void *callback);
124static char **ConvertJavaArgs(JNIEnv *env, jobjectArray jargs);
125static void FreeArgs(char **args);
126
127JNIEXPORT 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
161static 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
169static 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
182static 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
190static 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
197static 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
204static 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
217static 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
229static 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
261static 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
293static void FreeArgs(char **args) {
294    int i;
295    i = 0;
296    while (args[i] != NULL) free(args[i++]);
297    free(args);
298}
299
Note: See TracBrowser for help on using the repository browser.