JAVA: Don't cast returns from malloc()
[openafs.git] / src / JAVA / libjafs / Process.c
1 /*
2  * Copyright (c) 2001-2002 International Business Machines Corp.
3  * All rights reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  * 
9  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
12  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR
13  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
15  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
17  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20  */
21
22 #include "Internal.h"
23 #include "org_openafs_jafs_Process.h"
24
25 #include <afs_bosAdmin.h>
26
27 ///// definitions in Internal.c ////////////////////
28
29 extern jclass processCls;
30 extern jfieldID process_nameField;
31 extern jfieldID process_typeField;
32 extern jfieldID process_stateField;
33 extern jfieldID process_goalField;
34 extern jfieldID process_startTimeField;
35 extern jfieldID process_numberStartsField;
36 extern jfieldID process_exitTimeField;
37 extern jfieldID process_exitErrorTimeField;
38 extern jfieldID process_errorCodeField;
39 extern jfieldID process_errorSignalField;
40 extern jfieldID process_stateOkField;
41 extern jfieldID process_stateTooManyErrorsField;
42 extern jfieldID process_stateBadFileAccessField;
43
44 //////////////////////////////////////////////////////////////////
45
46 /**
47  * Retrieve the information for the specified process and populate the
48  * given object
49  *
50  * env      the Java environment
51  * serverHandle    the bos handle of the server on which the process resides
52  * processName      the name of the process for which to get the info
53  * process      the Process object to populate with the info
54  */
55 void getProcessInfoChar( JNIEnv *env, void *serverHandle, 
56                          const char *processName, jobject process ) {
57
58   afs_status_t ast;
59   bos_ProcessType_t type;
60   bos_ProcessInfo_t infoEntry;
61   bos_ProcessExecutionState_t state;
62   char *auxStatus;
63
64   // get class fields if need be
65   if( processCls == 0 ) {
66     internal_getProcessClass( env, process );
67   }
68
69   if( !bos_ProcessInfoGet( serverHandle, processName, &type, 
70                            &infoEntry, &ast ) ) {
71     throwAFSException( env, ast );
72     return;
73   }
74
75   // set type variable
76   switch( type ) {
77   case BOS_PROCESS_SIMPLE :
78       (*env)->SetIntField(env, process, process_typeField, 
79                           org_openafs_jafs_Process_SIMPLE_PROCESS);
80       break;
81   case BOS_PROCESS_FS :
82       (*env)->SetIntField(env, process, process_typeField, 
83                           org_openafs_jafs_Process_FS_PROCESS);
84       break;
85   case BOS_PROCESS_CRON :
86       (*env)->SetIntField(env, process, process_typeField, 
87                           org_openafs_jafs_Process_CRON_PROCESS);
88       break;
89   default:
90       throwAFSException( env, type );
91       return;
92   }
93
94   // set goal variable
95   switch( infoEntry.processGoal ) {
96   case BOS_PROCESS_STOPPED :
97       (*env)->SetIntField(env, process, process_goalField, 
98                           org_openafs_jafs_Process_STOPPED);
99       break;
100   case BOS_PROCESS_RUNNING :
101       (*env)->SetIntField(env, process, process_goalField, 
102                           org_openafs_jafs_Process_RUNNING);
103       break;
104   case BOS_PROCESS_STOPPING :
105       (*env)->SetIntField(env, process, process_goalField, 
106                           org_openafs_jafs_Process_STOPPING);
107       break;
108   case BOS_PROCESS_STARTING :
109       (*env)->SetIntField(env, process, process_goalField, 
110                           org_openafs_jafs_Process_STARTING);
111       break;
112   default:
113       throwAFSException( env, infoEntry.processGoal );
114       return;
115   }
116
117   // set state variable
118   auxStatus = malloc( sizeof(char)*BOS_MAX_NAME_LEN );
119   if( !auxStatus ) {
120     throwAFSException( env, JAFSADMNOMEM );
121     return;    
122   }
123   if( !bos_ProcessExecutionStateGet( (void *) serverHandle, processName, 
124                                      &state, auxStatus, &ast ) ) {
125       free( auxStatus );
126       throwAFSException( env, ast );
127       return;
128   }
129   free( auxStatus );
130   switch( state ) {
131   case BOS_PROCESS_STOPPED :
132       (*env)->SetIntField(env, process, process_stateField, 
133                           org_openafs_jafs_Process_STOPPED);
134       break;
135   case BOS_PROCESS_RUNNING :
136       (*env)->SetIntField(env, process, process_stateField, 
137                           org_openafs_jafs_Process_RUNNING);
138       break;
139   case BOS_PROCESS_STOPPING :
140       (*env)->SetIntField(env, process, process_stateField, 
141                           org_openafs_jafs_Process_STOPPING);
142       break;
143   case BOS_PROCESS_STARTING :
144       (*env)->SetIntField(env, process, process_stateField, 
145                           org_openafs_jafs_Process_STARTING);
146       break;
147   default:
148       throwAFSException( env, state );
149       return;
150   }
151
152   // set longs
153   (*env)->SetLongField(env, process, process_startTimeField, 
154                        infoEntry.processStartTime );
155   (*env)->SetLongField(env, process, process_numberStartsField, 
156                        infoEntry.numberProcessStarts );
157   (*env)->SetLongField(env, process, process_exitTimeField, 
158                        infoEntry.processExitTime );
159   (*env)->SetLongField(env, process, process_exitErrorTimeField, 
160                        infoEntry.processExitErrorTime );
161   (*env)->SetLongField(env, process, process_errorCodeField, 
162                        infoEntry.processErrorCode );
163   (*env)->SetLongField(env, process, process_errorSignalField, 
164                        infoEntry.processErrorSignal );
165
166   // set stateOk to true if no core dump
167   if( infoEntry.state & BOS_PROCESS_CORE_DUMPED ) {
168     (*env)->SetBooleanField(env, process, process_stateOkField, FALSE );
169   } else {
170     (*env)->SetBooleanField(env, process, process_stateOkField, TRUE );
171   }
172
173   // set stateTooManyErrors
174   if( infoEntry.state & BOS_PROCESS_TOO_MANY_ERRORS ) {
175     (*env)->SetBooleanField(env, process, 
176                             process_stateTooManyErrorsField, TRUE );
177   } else {
178     (*env)->SetBooleanField(env, process, 
179                             process_stateTooManyErrorsField, FALSE );
180   }
181
182   // set stateBadFileAccess
183   if( infoEntry.state & BOS_PROCESS_BAD_FILE_ACCESS ) {
184     (*env)->SetBooleanField(env, process, 
185                             process_stateBadFileAccessField, TRUE );
186   } else {
187     (*env)->SetBooleanField(env, process, 
188                             process_stateBadFileAccessField, FALSE );
189   }
190
191 }
192
193 /**
194  * Fills in the information fields of the provided Process.
195  *
196  * env      the Java environment
197  * cls      the current Java class
198  * cellHandle    the handle of the cell to which the process belongs
199  * jname     the instance name of the process  for which to get
200  *                  the information
201  * process     the Process object in which to fill 
202  *                    in the information
203  */
204 JNIEXPORT void JNICALL 
205 Java_org_openafs_jafs_Process_getProcessInfo (JNIEnv *env, jclass cls, 
206                                                  jlong serverHandle, 
207                                                  jstring jname, 
208                                                  jobject process) {
209
210   const char *name;
211
212   if( jname != NULL ) {
213     name = (*env)->GetStringUTFChars(env, jname, 0);
214     if( !name ) {
215         throwAFSException( env, JAFSADMNOMEM );
216         return;    
217     }
218   } else {
219     name = NULL;
220   }
221
222   getProcessInfoChar( env, (void *) serverHandle, name, process );
223
224   // set name in case blank object
225   if( name != NULL ) {
226     if( processCls == 0 ) {
227       internal_getProcessClass( env, process );
228     }
229     (*env)->SetObjectField(env, process, process_nameField, jname);
230     (*env)->ReleaseStringUTFChars(env, jname, name);
231   }
232
233 }
234
235 /**
236  * Creates a process on a server.
237  *
238  * env      the Java environment
239  * cls      the current Java class
240  * serverHandle  the bos handle of the server to which the key will 
241  *                      belong
242  * jname  the instance name to give the process.  See AFS 
243  *                     documentation for a standard list of instance names
244  * jtype  the type of process this will be. 
245  *                     Acceptable values are:
246  *                     org_openafs_jafs_Process_SIMPLE_PROCESS
247  *                     org_openafs_jafs_Process_FS_PROCESS
248  *                     org_openafs_jafs_Process_CRON_PROCESS
249  * jpath  the execution path process to create
250  * jcronTime   a String representing the time a cron process is to 
251  *                   be run.  Acceptable formats are:
252  *                   for daily restarts: "23:10" or "11:10 pm"
253  *                   for weekly restarts: "sunday 11:10pm" or 
254  *                       "sun 11:10pm"
255  *                   Can be null for non-cron processes.
256  * jnotifier   the execution path to a notifier program that should 
257  *                   be called when the process terminates.  Can be 
258  *                   null
259  */
260 JNIEXPORT void JNICALL 
261 Java_org_openafs_jafs_Process_create (JNIEnv *env, jclass cls, 
262                                          jlong serverHandle, jstring jname, 
263                                          jint jtype, jstring jpath, 
264                                          jstring jcronTime, 
265                                          jstring jnotifier) {
266
267     afs_status_t ast;
268     bos_ProcessType_t type;
269     const char *name;
270     const char *path;
271     const char *cronTime;
272     const char *notifier;
273
274     if( jname != NULL ) {
275       name = (*env)->GetStringUTFChars(env, jname, 0);
276       if( !name ) {
277           throwAFSException( env, JAFSADMNOMEM );
278           return;    
279       }
280     } else {
281       name = NULL;
282     }
283
284     if( jpath != NULL ) {
285       path = (*env)->GetStringUTFChars(env, jpath, 0);
286       if( !path ) {
287         if( name != NULL ) {
288           (*env)->ReleaseStringUTFChars(env, jname, name);
289         }
290         throwAFSException( env, JAFSADMNOMEM );
291         return;    
292       }
293     } else {
294       path = NULL;
295     }
296
297     switch( jtype ) {
298     case org_openafs_jafs_Process_SIMPLE_PROCESS:
299         type = BOS_PROCESS_SIMPLE;
300         break;
301     case org_openafs_jafs_Process_FS_PROCESS:
302         type = BOS_PROCESS_FS;
303         break;
304     case org_openafs_jafs_Process_CRON_PROCESS:
305         type = BOS_PROCESS_CRON;
306         break;
307     default:
308       if( name != NULL ) {
309         (*env)->ReleaseStringUTFChars(env, jname, name);
310       }
311       if( path != NULL ) {
312         (*env)->ReleaseStringUTFChars(env, jpath, path);
313       }
314       throwAFSException( env, jtype );
315       return;
316     }
317
318     if( jcronTime != NULL ) {
319         cronTime = (*env)->GetStringUTFChars(env, jcronTime, 0);
320         if( !cronTime ) {
321           if( name != NULL ) {
322             (*env)->ReleaseStringUTFChars(env, jname, name);
323           }
324           if( path != NULL ) {
325             (*env)->ReleaseStringUTFChars(env, jpath, path);
326           }
327           throwAFSException( env, JAFSADMNOMEM );
328           return;    
329         }
330     } else {
331         cronTime = NULL;
332     }
333
334     if( jnotifier != NULL ) {
335         notifier = (*env)->GetStringUTFChars(env, jnotifier, 0);
336         if( !notifier ) {
337           if( name != NULL ) {
338             (*env)->ReleaseStringUTFChars(env, jname, name);
339           }
340           if( path != NULL ) {
341             (*env)->ReleaseStringUTFChars(env, jpath, path);
342           }
343           if( cronTime != NULL ) {
344             (*env)->ReleaseStringUTFChars(env, jcronTime, cronTime);
345           }
346           throwAFSException( env, JAFSADMNOMEM );
347           return;    
348         }
349     } else {
350         notifier = NULL;
351     }
352
353     if( !bos_ProcessCreate( (void *) serverHandle, name, type, path, 
354                             cronTime, notifier, &ast ) ) {
355         // release strings
356         if( cronTime != NULL ) {
357             (*env)->ReleaseStringUTFChars(env, jcronTime, cronTime);
358         }
359         if( notifier != NULL ) {
360             (*env)->ReleaseStringUTFChars(env, jnotifier, notifier);
361         }
362         if( name != NULL ) {
363           (*env)->ReleaseStringUTFChars(env, jname, name);
364         }
365         if( path != NULL ) {
366           (*env)->ReleaseStringUTFChars(env, jpath, path);
367         }
368         throwAFSException( env, ast );
369         return;
370     }
371
372
373     // release strings
374     if( cronTime != NULL ) {
375         (*env)->ReleaseStringUTFChars(env, jcronTime, cronTime);
376     }
377     if( notifier != NULL ) {
378         (*env)->ReleaseStringUTFChars(env, jnotifier, notifier);
379     }
380     if( name != NULL ) {
381       (*env)->ReleaseStringUTFChars(env, jname, name);
382     }
383     if( path != NULL ) {
384       (*env)->ReleaseStringUTFChars(env, jpath, path);
385     }
386
387 }
388
389 /**
390  * Removes a process from a server.
391  *
392  * env      the Java environment
393  * cls      the current Java class
394  * serverHandle  the bos handle of the server to which the process 
395  *                      belongs
396  * jname   the name of the process to remove
397  */
398 JNIEXPORT void JNICALL 
399 Java_org_openafs_jafs_Process_delete (JNIEnv *env, jclass cls, 
400                                          jlong serverHandle, jstring jname) {
401
402     afs_status_t ast;
403     const char *name;
404
405     if( jname != NULL ) {
406       name = (*env)->GetStringUTFChars(env, jname, 0);
407       if( !name ) {
408           throwAFSException( env, JAFSADMNOMEM );
409           return;    
410       }
411     } else {
412       name = NULL;
413     }
414
415     if( !bos_ProcessDelete( (void *) serverHandle, name, &ast ) ) {
416       if( name != NULL ) {
417         (*env)->ReleaseStringUTFChars(env, jname, name);
418       }
419       throwAFSException( env, ast );
420       return;
421     }
422
423     if( name != NULL ) {
424       (*env)->ReleaseStringUTFChars(env, jname, name);
425     }
426
427 }
428
429 /**
430  * Stop this process.
431  *
432  * env      the Java environment
433  * cls      the current Java class
434  * serverHandle  the bos handle of the server to which the process 
435  *                      belongs
436  * jname   the name of the process to stop
437  */
438 JNIEXPORT void JNICALL 
439 Java_org_openafs_jafs_Process_stop (JNIEnv *env, jclass cls, 
440                                        jlong serverHandle, jstring jname) {
441
442     afs_status_t ast;
443     const char *name;
444
445     if( jname != NULL ) {
446       name = (*env)->GetStringUTFChars(env, jname, 0);
447       if( !name ) {
448           throwAFSException( env, JAFSADMNOMEM );
449           return;    
450       }
451     } else {
452       name = NULL;
453     }
454
455     if( !bos_ProcessExecutionStateSet( (void *) serverHandle, name, 
456                                        BOS_PROCESS_STOPPED, &ast ) ) {
457       if( name != NULL ) {
458         (*env)->ReleaseStringUTFChars(env, jname, name);
459       }
460       throwAFSException( env, ast );
461       return;
462     }
463
464     if( name != NULL ) {
465       (*env)->ReleaseStringUTFChars(env, jname, name);
466     }
467
468 }
469
470 /**
471  * Start this process.
472  *
473  * env      the Java environment
474  * cls      the current Java class
475  * serverHandle  the bos handle of the server to which the process 
476  *                      belongs
477  * jname   the name of the process to start
478  */
479 JNIEXPORT void JNICALL 
480 Java_org_openafs_jafs_Process_start (JNIEnv *env, jclass cls, 
481                                         jlong serverHandle, jstring jname) {
482
483     afs_status_t ast;
484     const char *name;
485
486     if( jname != NULL ) {
487       name = (*env)->GetStringUTFChars(env, jname, 0);
488       if( !name ) {
489           throwAFSException( env, JAFSADMNOMEM );
490           return;    
491       }
492     } else {
493       name = NULL;
494     }
495
496     if( !bos_ProcessExecutionStateSet( (void *) serverHandle, name, 
497                                        BOS_PROCESS_RUNNING, &ast ) ) {
498       if( name != NULL ) {
499         (*env)->ReleaseStringUTFChars(env, jname, name);
500       }
501       throwAFSException( env, ast );
502       return;
503     }
504
505     if( name != NULL ) {
506       (*env)->ReleaseStringUTFChars(env, jname, name);
507     }
508
509 }
510
511 /**
512  * Retart this process.
513  *
514  * env      the Java environment
515  * cls      the current Java class
516  * serverHandle  the bos handle of the server to which the process 
517  *                      belongs
518  * jname   the name of the process to restart
519  */
520 JNIEXPORT void JNICALL 
521 Java_org_openafs_jafs_Process_restart (JNIEnv *env, jclass cls, 
522                                           jlong serverHandle, jstring jname) {
523
524     afs_status_t ast;
525     const char *name;
526
527     if( jname != NULL ) {
528       name = (*env)->GetStringUTFChars(env, jname, 0);
529       if( !name ) {
530           throwAFSException( env, JAFSADMNOMEM );
531           return;    
532       }
533     } else {
534       name = NULL;
535     }
536
537     if( !bos_ProcessRestart( (void *) serverHandle, name, &ast ) ) {
538       if( name != NULL ) {
539         (*env)->ReleaseStringUTFChars(env, jname, name);
540       }
541       throwAFSException( env, ast );
542       return;
543     }
544
545     if( name != NULL ) {
546       (*env)->ReleaseStringUTFChars(env, jname, name);
547     }
548
549 }
550
551 // reclaim global memory being used by this portion
552 JNIEXPORT void JNICALL
553 Java_org_openafs_jafs_Process_reclaimProcessMemory (JNIEnv *env, 
554                                                        jclass cls) {
555
556   if( processCls ) {
557       (*env)->DeleteGlobalRef(env, processCls);
558       processCls = 0;
559   }
560
561 }
562
563
564
565
566
567