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 2001-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.ArrayList;
  31 import java.util.StringTokenizer;
  32 import java.text.MessageFormat;
  33 
  34 import com.sun.dhcpmgr.cli.common.DhcpCliFunction;
  35 import com.sun.dhcpmgr.cli.common.DhcpCliPrint;
  36 import com.sun.dhcpmgr.data.*;
  37 import com.sun.dhcpmgr.bridge.BridgeException;
  38 import com.sun.dhcpmgr.bridge.ExistsException;
  39 
  40 import com.sun.dhcpmgr.common.ExportController;
  41 import com.sun.dhcpmgr.common.Exporter;
  42 
  43 /**
  44  * The main class for the "export move data" functionality of dhcpconfig.
  45  */
  46 public class ExportData extends DhcpCfgFunction implements Exporter {
  47 
  48     /**
  49      * The valid options associated with exporting data.
  50      */
  51     private static final int supportedOptions[] = {
  52         DhcpCfg.MACRO_LIST,
  53         DhcpCfg.OPTION_LIST,
  54         DhcpCfg.NETWORK_ADDRESSES,
  55         DhcpCfg.DELETE_DATA,
  56         DhcpCfg.FORCE,
  57         DhcpCfg.SIGHUP
  58     };
  59 
  60     /**
  61      * Keyword that may be used to define all options, all macros, or all
  62      * network tables.
  63      */
  64     private static final String ALL = "ALL";
  65 
  66     /**
  67      * The name of the export file.
  68      */
  69     private String exportFile;
  70 
  71     /**
  72      * Simple constructor
  73      */
  74     public ExportData(String exportFile) {
  75 
  76         validOptions = supportedOptions;
  77         this.exportFile = exportFile;
  78 
  79     } // constructor
  80 
  81     /**
  82      * Returns the option flag for this function.
  83      * @returns the option flag for this function.
  84      */
  85     public int getFunctionFlag() {
  86         return (DhcpCfg.EXPORT_DATA);
  87     }
  88 
  89     /**
  90      * Executes the "export move data" functionality.
  91      * @return DhcpCfg.SUCCESS or DhcpCfg.FAILURE
  92      */
  93     public int execute() {
  94 
  95         // Make sure that server is configured as a DHCP server.
  96         //
  97         if (!isServerConfigured()) {
  98             return (DhcpCfg.FAILURE);
  99         }
 100 
 101         // Check the validity of the data store version.
 102         if (!isVersionValid(false)) {
 103             return (DhcpCfg.FAILURE);
 104         }
 105 
 106         // Should export file be overwritten if it exists?
 107         boolean force = options.isSet(DhcpCfg.FORCE);
 108 
 109         // Should exported data be deleted or just copied?
 110         boolean deleteData = options.isSet(DhcpCfg.DELETE_DATA);
 111         
 112         // Create the export controller
 113         ExportController controller = new ExportController(this, getDhcpMgr());
 114         controller.setFile(exportFile);
 115         // Store user name
 116         controller.setUser(System.getProperty("user.name"));
 117 
 118         /*
 119          * Get the macro list. The keyword of "ALL" means that all macros in
 120          * the dhcptab should be exported. 
 121          */
 122         if (options.isSet(DhcpCfg.MACRO_LIST)) {
 123             String macroNames = options.valueOf(DhcpCfg.MACRO_LIST);
 124             if (ALL.equals(macroNames)) {
 125                 controller.setAllMacros();
 126             } else {
 127                 // Parse macro list and give to controller
 128                 controller.setMacros(argsToArray(macroNames));
 129             }
 130         }
 131 
 132         /*
 133          * Get the option list. Keyword of "ALL" means that all options in the
 134          * dhcptab should be exported.
 135          */
 136         if (options.isSet(DhcpCfg.OPTION_LIST)) {
 137             String optionNames = options.valueOf(DhcpCfg.OPTION_LIST);
 138             if (ALL.equals(optionNames)) {
 139                 controller.setAllOptions();
 140             } else {
 141                 controller.setOptions(argsToArray(optionNames));
 142             }
 143         }
 144 
 145         /*
 146          * Get the list of network addresses. If the option is set to the
 147          * keyword "ALL", all network tables should be exported.
 148          */
 149         if (options.isSet(DhcpCfg.NETWORK_ADDRESSES)) {
 150             String addrs = options.valueOf(DhcpCfg.NETWORK_ADDRESSES);
 151             if (ALL.equals(addrs)) {
 152                 controller.setAllNetworks();
 153             } else {
 154                 // Parse network list
 155                 IPAddressList networkAddresses;
 156                 try {
 157                     networkAddresses = new IPAddressList(addrs);
 158                 } catch (ValidationException e) {
 159                     printErrMessage(getMessage(e));
 160                     printErrMessage(getString("export_abort"));
 161                     return (DhcpCfg.FAILURE);
 162                 }
 163 
 164                 // Now ensure all networks specified exist
 165                 ArrayList netList = new ArrayList();
 166                 try {
 167                     Network [] nets = getNetMgr().getNetworks();
 168 
 169                     for (int i = 0;
 170                             !networkAddresses.isEmpty() && i < nets.length;
 171                             ++i) {
 172                         int index = networkAddresses.indexOf(
 173                             nets[i].getNetworkNumber());
 174                         // Found; remove from search list, add to export list
 175                         if (index != -1) {
 176                             netList.add(nets[i]);
 177                             networkAddresses.remove(index);
 178                         }
 179                     }
 180                 } catch (BridgeException e) {
 181                     e.printStackTrace();
 182                 }
 183 
 184                 if (!networkAddresses.isEmpty()) {
 185                     // One of the networks was not valid
 186                     System.err.print(networkAddresses.firstElement());
 187                     System.err.println(" is not a valid network");
 188                     return (DhcpCfg.FAILURE);
 189                 }
 190 
 191                 controller.setNetworks(
 192                     (Network [])netList.toArray(new Network[0]));
 193             }
 194         }
 195 
 196         // Do the export
 197         try {
 198             // result should affect exit status once that's implemented
 199             if (!controller.exportData(deleteData, force)) {
 200                 return (DhcpCfg.FAILURE);
 201             }
 202         } catch (ExistsException e) {
 203             // File already exists, print error and exit
 204             Object [] arguments = new Object[1];
 205             arguments[0] = exportFile;
 206             printErrMessage(getString("export_file_exist_error"), arguments);
 207             printErrMessage(getString("export_abort"));
 208             return (DhcpCfg.FAILURE);
 209         }
 210 
 211         // Signal server if requested by user
 212         try {
 213             if (options.isSet(DhcpCfg.SIGHUP)) {
 214                 getSvcMgr().reload();
 215             }
 216         } catch (Throwable e) {
 217             printErrMessage(getString("sighup_failed"));
 218             return (DhcpCfg.FAILURE);
 219         }
 220 
 221         return (DhcpCfg.SUCCESS);
 222 
 223     } // execute
 224 
 225     /**
 226      * Convert a comma-separated list of arguments to an array of tokens
 227      */
 228     private String [] argsToArray(String arg) {
 229         ArrayList argList = new ArrayList();
 230         StringTokenizer st = new StringTokenizer(arg, ",");
 231         while (st.hasMoreTokens()) {
 232             argList.add(st.nextToken());
 233         }
 234         return (String [])argList.toArray(new String[0]);
 235     }
 236 
 237     /**
 238      * Initialize progress.  A no-op for us.
 239      */
 240     public void initializeProgress(int length) {
 241         // Do nothing
 242     }
 243 
 244     /**
 245      * Display progress.  Just print the message.
 246      */
 247     public void updateProgress(int done, String message) {
 248         printMessage(message);
 249     }
 250 
 251     /**
 252      * Display an error.
 253      */
 254     public void displayError(String message) {
 255         Object [] arguments = new Object[1];
 256         arguments[0] = message;
 257         printErrMessage(getString("export_err_message"), arguments);
 258     }
 259 
 260     /**
 261      * Display a set of errors during export
 262      */
 263     public void displayErrors(String msg, String label, ActionError [] errs) {
 264         printErrMessage(msg);
 265         Object [] args = new Object[3];
 266         args[0] = label;
 267         MessageFormat form =
 268             new MessageFormat(getString("export_action_error"));
 269         for (int i = 0; i < errs.length; ++i) {
 270             args[1] = errs[i].getName();
 271             args[2] = errs[i].getException().getMessage();
 272             printErrMessage(form.format(args));
 273         }
 274     }
 275 
 276 } // ExportData