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