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 * ident "%Z%%M% %I% %E% SMI"
24 *
25 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
27 */
28 package com.sun.dhcpmgr.cli.dhcpconfig;
29
30 import java.util.List;
31 import java.util.ArrayList;
32 import java.util.Iterator;
33 import com.sun.dhcpmgr.cli.common.GetSubOpt;
34 import com.sun.dhcpmgr.cli.common.DhcpCliFunction;
35 import com.sun.dhcpmgr.data.DhcpdOptions;
36 import com.sun.dhcpmgr.data.DhcpResource;
37 import com.sun.dhcpmgr.data.qualifier.*;
38 import com.sun.dhcpmgr.bridge.BridgeException;
39
40 /**
41 * Functions for handling all dhcpconfig options that manage the DHCP server
42 * parameters.
43 */
44 public class ServerParameter extends DhcpCfgFunction {
45
46 /**
47 * Options that this DhcpCfgFunction will accept.
48 */
49 static final int supportedOptions[] = {
50 };
51
52 /**
53 * List of suboptions.
54 */
55 private String subOptions;
56
57 /**
58 * Simple constructor
59 */
60 public ServerParameter(String subOptions) {
61 validOptions = supportedOptions;
62 this.subOptions = subOptions;
63 } // constructor
64
65 /**
66 * Returns the option flag for this function.
67 * @returns
68 * The option flag for this function.
69 */
70 public int getFunctionFlag() {
71 return DhcpCfg.CONFIGURE_SERVER_PARAMETER;
72 } // getFunctionFlag
73
74 /**
75 * Parse and execute the options for this function.
76 * @return
77 * DhcpCfg.SUCCESS for success and DhcpCfg.FAILURE for failure.
78 */
79 public int execute() throws IllegalArgumentException {
80 List actions = new ArrayList();
81
82 if (subOptions == null || subOptions.length() == 0) {
83 actions.add(new ActionGetAll());
84 } else {
85 GetSubOpt getSubOpt = new GetSubOpt(subOptions);
86
87 while (getSubOpt.hasMoreSubOptions()) {
88 String keyword = getSubOpt.getNextSubOption();
89 String value = getSubOpt.getSubOptionArg();
90
91 boolean valueSet = (value != null);
92
93 if (value == null) {
94 actions.add(new ActionGet(keyword));
95 } else {
96 if (value.equals("")) {
97 actions.add(new ActionDelete(keyword));
98 } else {
99 actions.add(new ActionSet(keyword, value));
100 }
101 }
102 }
103 }
104
105 DhcpdOptions dhcpdOptions;
106 boolean atLeastOneActionFailed;
107 Iterator iterator;
108
109 try {
110 dhcpdOptions = getSvcMgr().readDefaults();
111 } catch (BridgeException be) {
112 printErrMessage(
113 getString("server_parameter_failed_read_params_error"));
114 return DhcpCfg.FAILURE;
115 }
116
117 atLeastOneActionFailed = false;
118
119 // Initialise the actions.
120 iterator = actions.iterator();
121 while (iterator.hasNext()) {
122 Action action = (Action) iterator.next();
123
124 if (action.init(dhcpdOptions) != DhcpCfg.SUCCESS) {
125 atLeastOneActionFailed = true;
126 }
127 }
128
129 if (atLeastOneActionFailed) {
130 return DhcpCfg.FAILURE;
131 }
132
133 dhcpdOptions.clearDirty();
134
135 atLeastOneActionFailed = false;
136
137 // Execute the actions.
138 iterator = actions.iterator();
139 while (iterator.hasNext()) {
140 Action action = (Action) iterator.next();
141
142 if (action.execute() != DhcpCfg.SUCCESS) {
143 atLeastOneActionFailed = true;
144 }
145 }
146
147 if (atLeastOneActionFailed) {
148 return DhcpCfg.FAILURE;
149 }
150
151 if (dhcpdOptions.isDirty()) {
152 try {
153 getSvcMgr().writeDefaults(dhcpdOptions);
154 } catch (BridgeException e) {
155 printErrMessage(
156 getString(
157 "server_parameter_failed_write_params_error"));
158 return DhcpCfg.FAILURE;
159 }
160
161 dhcpdOptions.clearDirty();
162 }
163
164 return DhcpCfg.SUCCESS;
165 } // execute
166
167 /**
168 * All functions are carried out through a specific action sub-classed
169 * from this class.
170 */
171 private interface Action {
172 /**
173 * Initialise the action.
174 *
175 * @param dhcpdOptions
176 * The server options that an action manipulates.
177 *
178 * @return
179 * DhcpCfg.SUCCESS for success and DhcpCfg.FAILURE for failure.
180 */
181 public int init(DhcpdOptions dhcpdOptions);
182
183 /**
184 * Execute the action.
185 *
186 * @return
187 * DhcpCfg.SUCCESS for success and DhcpCfg.FAILURE for failure.
188 */
189 public int execute();
190 }
191
192 /**
193 * Shared super class for actions.
194 */
195 private abstract class ActionImpl implements Action {
196
197 /**
198 * The server parameter this action works upon. Could be null.
199 */
200 protected String keyword;
201
202 /**
203 * The value this action works upon. Could be null.
204 */
205 protected String value;
206
207 /**
208 * The qualifier for the server parameter. If the keyword is null
209 * the qualifier will be null. The general rule is that if keyword is
210 * not null, qualifier must not be null. If it is then the keyword
211 * is not a recognised server parameter.
212 */
213 protected Qualifier qualifier;
214
215 /**
216 * Server parameters.
217 */
218 protected DhcpdOptions dhcpdOptions;
219
220 /**
221 * Construct an action for the given server parameter keyword and
222 * value. The constructor will find the appropriate qualifier that
223 * matches the keyword if the keyword is not null. Note that no
224 * checking on the validity of the keyword contents is made at this
225 * point.
226 *
227 * @param keyword
228 * The server parameter this action works upon. Could be null.
229 * @param value
230 * The value this action works upon. Could be null.
231 */
232 protected ActionImpl(String keyword, String value) {
233 this.keyword = keyword;
234 this.value = value;
235 } // constructor
236
237 /**
238 * Get the keyword.
239 *
240 * @return
241 * The keyword this action operates upon.
242 */
243 public String getKeyword() {
244 return keyword;
245 }
246
247 /**
248 * Validate and initialise the action. A sub-classed action is passed
249 * execution control via the doExecute() callback method.
250 *
251 * @return
252 * DhcpCfg.SUCCESS for success and DhcpCfg.FAILURE for failure.
253 */
254 public final int init(DhcpdOptions dhcpdOptions) {
255 if (dhcpdOptions == null) {
256 return DhcpCfg.FAILURE;
257 }
258
259 this.dhcpdOptions = dhcpdOptions;
260
261 if (keyword != null) {
262 qualifier = dhcpdOptions.getQualifier(keyword);
263
264 if (qualifier == null) {
265 Object[] arguments = new Object[1];
266 arguments[0] = keyword;
267 printErrMessage(
268 getString(
269 "server_parameter_keyword_bad_keyword_error"),
270 arguments);
271 return DhcpCfg.FAILURE;
272 }
273 }
274
275 return doInit();
276 } // execute
277
278 /**
279 * Sub-classed action callback method. Once validation has been
280 * performed initialisation is continued in the action sub-class
281 * by calling this method.
282 *
283 * @return
284 * DhcpCfg.SUCCESS for success, otherwise DhcpCfg.FAILURE for failure.
285 */
286 protected abstract int doInit();
287
288 /**
289 * Validate and execute the action. A sub-classed action is passed
290 * execution control via the doExecute() callback method.
291 *
292 * @return
293 * DhcpCfg.SUCCESS for success and DhcpCfg.FAILURE for failure.
294 */
295 public final int execute() {
296 if (dhcpdOptions == null) {
297 return DhcpCfg.FAILURE;
298 }
299
300 return doExecute();
301 } // execute
302
303 /**
304 * Sub-classed action callback method. Once validation has been
305 * performed execution is continued in the action sub-class by calling
306 * this method.
307 *
308 * @return
309 * DhcpCfg.SUCCESS for success, otherwise DhcpCfg.FAILURE for failure.
310 */
311 protected abstract int doExecute();
312 }
313
314 /**
315 * Set a parameter action.
316 */
317 private class ActionSet extends ActionImpl {
318
319 /**
320 * Construct an add action.
321 *
322 * @param keyword
323 * The server parameter this action works upon.
324 * @param value
325 * The value this action works upon.
326 */
327 public ActionSet(String keyword, String value) {
328 super(keyword, value);
329 } // constructor
330
331 protected int doInit() {
332 if (qualifier.isReadOnly()) {
333 Object[] arguments = new Object[1];
334 arguments[0] = keyword;
335 printErrMessage(
336 getString(
337 "server_parameter_keyword_set_read_only_error"),
338 arguments);
339 return DhcpCfg.FAILURE;
340 }
341
342 QualifierType qualifierType = qualifier.getType();
343
344 if (qualifierType.parseValue(value) == null) {
345 Object[] arguments = new Object[2];
346 arguments[0] = keyword;
347 arguments[1] = value;
348 printErrMessage(
349 getString(
350 "server_parameter_keyword_set_bad_value_error"),
351 arguments);
352 return DhcpCfg.FAILURE;
353 }
354
355 return DhcpCfg.SUCCESS;
356 }
357
358 /**
359 * Set the parameters value.
360 *
361 * @return
362 * DhcpCfg.SUCCESS for success, otherwise DhcpCfg.FAILURE for failure.
363 */
364 protected int doExecute() {
365 QualifierType qualifierType = qualifier.getType();
366
367 dhcpdOptions.set(keyword, qualifierType.formatValue(value));
368 dhcpdOptions.set(keyword, qualifierType.formatValue(value));
369
370 return DhcpCfg.SUCCESS;
371 } // doExecute
372
373 }
374
375 /**
376 * Get a parameter action.
377 */
378 private class ActionGet extends ActionImpl {
379
380 /**
381 * This field controls the displaying of the keyword in addition
382 * to the keywords value. The default is to not show the keyword.
383 */
384 protected boolean showKeyword = false;
385
386 /**
387 * Construct a get action
388 *
389 * @param keyword
390 * The server parameter this action works upon.
391 */
392 public ActionGet(String keyword) {
393 super(keyword, null);
394 } // constructor
395
396 protected int doInit() {
397 if (!dhcpdOptions.isSet(keyword)) {
398 Object[] arguments = new Object[1];
399 arguments[0] = keyword;
400 printErrMessage(
401 getString("server_parameter_keyword_not_set_error"),
402 arguments);
403
404 return DhcpCfg.FAILURE;
405 }
406
407 return DhcpCfg.SUCCESS;
408 }
409
410 /**
411 * Get the parameters value.
412 *
413 * @return
414 * DhcpCfg.SUCCESS for success, otherwise DhcpCfg.FAILURE for failure.
415 */
416 protected int doExecute() {
417 Object[] arguments;
418
419 if (showKeyword) {
420 arguments = new Object[2];
421 arguments[0] = keyword;
422 arguments[1] = dhcpdOptions.valueOf(keyword);
423 printMessage(
424 getString("server_parameter_get_keyword_value"),
425 arguments);
426 } else {
427 arguments = new Object[1];
428 arguments[0] = dhcpdOptions.valueOf(keyword);
429 printMessage(getString("server_parameter_get_value"),
430 arguments);
431 }
432
433 return DhcpCfg.SUCCESS;
434
435 } // doExecute
436
437 /**
438 * This method controls the displaying of the keyword in addition
439 * to the keywords value.
440 *
441 * @param showKeyword
442 * If true the keyword is shown with the value, otherwise only the
443 * the value is shown.
444 */
445 public void setShowKeyword(boolean showKeyword) {
446 this.showKeyword = showKeyword;
447 }
448
449 }
450
451 /**
452 * Get all parameters action.
453 */
454 private class ActionGetAll extends ActionImpl {
455
456 protected List subActions;
457
458 /**
459 * Construct a get all action.
460 */
461 public ActionGetAll() {
462 super(null, null);
463 subActions = new ArrayList();
464 } // constructor
465
466 protected int doInit() {
467 Object[] parameters = dhcpdOptions.getAll();
468 boolean atLeastOneSubActionFailed = false;
469
470 for (int index = 0; index < parameters.length; index++) {
471 ActionGet subAction;
472 String parameter = ((DhcpResource) parameters[index]).getKey();
473 qualifier = dhcpdOptions.getQualifier(parameter);
474
475 if (qualifier == null) {
476 Object[] arguments = new Object[1];
477 arguments[0] = keyword;
478 printErrMessage(
479 getString(
480 "server_parameter_keyword_bad_keyword_error"),
481 arguments);
482 continue;
483 }
484
485 if (qualifier.isHidden()) {
486 continue;
487 }
488
489 subAction = new ActionGet(parameter);
490 subAction.setShowKeyword(true);
491 subActions.add(subAction);
492
493 if (subAction.init(dhcpdOptions) == DhcpCfg.FAILURE) {
494 atLeastOneSubActionFailed = true;
495 }
496 }
497
498 if (atLeastOneSubActionFailed) {
499 return DhcpCfg.FAILURE;
500 } else {
501 return DhcpCfg.SUCCESS;
502 }
503 }
504
505 /**
506 * Get all the parameters and their values.
507 *
508 * @return
509 * DhcpCfg.SUCCESS for success, otherwise DhcpCfg.FAILURE for failure.
510 */
511 protected int doExecute() {
512 Iterator iterator = subActions.iterator();
513
514 while (iterator.hasNext()) {
515 ActionGet subAction = (ActionGet) iterator.next();
516 String parameter = subAction.getKeyword();
517 qualifier = dhcpdOptions.getQualifier(parameter);
518
519 if (subAction.execute() == DhcpCfg.FAILURE) {
520 return DhcpCfg.FAILURE;
521 }
522 }
523
524 return DhcpCfg.SUCCESS;
525 } // doExecute
526
527 }
528
529 /**
530 * Delete a parameter action.
531 */
532 private class ActionDelete extends ActionImpl {
533
534 /**
535 * Construct a get delete action
536 *
537 * @param keyword
538 * The server parameter this action works upon.
539 */
540 public ActionDelete(String keyword) {
541 super(keyword, null);
542 } // constructor
543
544 protected int doInit() {
545 if (!dhcpdOptions.isSet(keyword)) {
546 Object[] arguments = new Object[1];
547 arguments[0] = keyword;
548 printErrMessage(
549 getString("server_parameter_keyword_not_set_error"),
550 arguments);
551 return DhcpCfg.FAILURE;
552 }
553
554 if (qualifier.isReadOnly()) {
555 Object[] arguments = new Object[1];
556 arguments[0] = keyword;
557 printErrMessage(
558 getString(
559 "server_parameter_keyword_delete_read_only_error"),
560 arguments);
561 return DhcpCfg.FAILURE;
562 }
563
564 return DhcpCfg.SUCCESS;
565 }
566
567 /**
568 * Delete the parameter and its value.
569 *
570 * @return
571 * DhcpCfg.SUCCESS for success, otherwise DhcpCfg.FAILURE for failure.
572 */
573 protected int doExecute() {
574 dhcpdOptions.clear(keyword);
575
576 return DhcpCfg.SUCCESS;
577 } // doExecute
578
579 }
580
581 } // ServerParameter