1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright (c) 2001 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <stdlib.h>
30#include <jni.h>
31#include <dhcp_inittab.h>
32#include <dhcp_symbol.h>
33#include <exception.h>
34#include <com_sun_dhcpmgr_bridge_Bridge.h>
35#include <dhcp_svc_private.h>
36
37#include "class_cache.h"
38
39/*
40 * Retrieve a list of DHCP options from the dhcp inittab.
41 */
42/*ARGSUSED*/
43JNIEXPORT jobjectArray JNICALL
44Java_com_sun_dhcpmgr_bridge_Bridge_getInittabOptions(
45    JNIEnv *env,
46    jobject obj,
47    jbyte jcategory) {
48
49	jclass opt_class;
50	jmethodID opt_cons;
51	jobjectArray jlist = NULL;
52	jobject jobj;
53	jstring jname;
54	jshort jcode;
55	jbyte jtype;
56	jint jgran;
57	jint jmax;
58
59	uchar_t category;
60	dhcp_symbol_t *entryptr;
61	dhcp_symbol_t *list;
62	dhcp_symbol_t internal;
63	size_t num;
64	int i;
65
66	/* Make sure we have the classes & methods we need */
67	opt_class = find_class(env, OPT_CLASS);
68	if (opt_class == NULL) {
69		/* exception thrown */
70		return (NULL);
71	}
72	opt_cons = get_methodID(env, opt_class, OPT_CONS);
73	if (opt_cons == NULL) {
74		/* exception thrown */
75		return (NULL);
76	}
77
78	/* Translate the dhcpmgr category to the inittab category */
79	if (jcategory == DSYM_STANDARD) {
80		category = ITAB_CAT_STANDARD | ITAB_CAT_INTERNAL |
81		    ITAB_CAT_FIELD;
82	} else {
83		category = jcategory;
84	}
85
86	/* Get the list of options */
87	list = inittab_load(category, ITAB_CONS_MANAGER, &num);
88	if (list == NULL) {
89		return (NULL);
90	}
91
92	/* Construct the array */
93	jlist = (*env)->NewObjectArray(env, num, opt_class, NULL);
94	if (jlist == NULL) {
95		/* exception thrown */
96		free(list);
97		return (NULL);
98	}
99
100	/* For each option, create an object and add it to the array */
101	for (i = 0; i < num; ++i) {
102
103		/* Verify the entry. Use the internal if necessary. */
104		if (inittab_verify(&list[i], &internal) == ITAB_FAILURE) {
105			entryptr = &internal;
106		} else {
107			entryptr = &list[i];
108		}
109
110		jtype = entryptr->ds_type;
111		jname = (*env)->NewStringUTF(env, entryptr->ds_name);
112		if (jname == NULL) {
113			/* exception thrown */
114			break;
115		}
116
117		/* HACK. Since the codes for fields can overlap the	*/
118		/* codes for STANDARD options, we will just set the	*/
119		/* code to zero and ignore the need for these codes to	*/
120		/* be unique. We do the same for internal but not	*/
121		/* for the same reason. For internal we have no need	*/
122		/* for the actual code and since we expect them to	*/
123		/* change in the future, we'll just go ahead and	*/
124		/* set them to zero too.				*/
125		if (entryptr->ds_category == DSYM_INTERNAL ||
126		    entryptr->ds_category == DSYM_FIELD) {
127			jcode = (jshort)0;
128		} else {
129			jcode = entryptr->ds_code;
130		}
131
132		jmax = entryptr->ds_max;
133		jgran = entryptr->ds_gran;
134
135		/* Create an 'Option' */
136		jobj = (*env)->NewObject(env, opt_class, opt_cons, jname,
137		    jcategory, NULL, jcode, jtype, jgran, jmax, NULL,
138		    JNI_TRUE);
139		if (jobj == NULL) {
140			/* exception thrown */
141			break;
142		}
143
144		(*env)->SetObjectArrayElement(env, jlist, i, jobj);
145		if ((*env)->ExceptionOccurred(env) != NULL) {
146			break;
147		}
148	}
149
150	free(list);
151
152	return (jlist);
153}
154