]> andersk Git - moira.git/blob - webmoira/moirai.c
More permission tweaking.
[moira.git] / webmoira / moirai.c
1 /* $Header$ */
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;
92     status = mr_krb5_auth("JavaInterface");
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
This page took 0.058006 seconds and 5 git commands to generate.