xref: /trunk/main/javainstaller2/src/JavaSetup/org/openoffice/setup/Installer/LinuxInstaller.java (revision 515f4036a64467de788f5756d8ebf472d92f9466)
19a1eeea9SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39a1eeea9SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49a1eeea9SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59a1eeea9SAndrew Rist  * distributed with this work for additional information
69a1eeea9SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79a1eeea9SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89a1eeea9SAndrew Rist  * "License"); you may not use this file except in compliance
99a1eeea9SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
119a1eeea9SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
139a1eeea9SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149a1eeea9SAndrew Rist  * software distributed under the License is distributed on an
159a1eeea9SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169a1eeea9SAndrew Rist  * KIND, either express or implied.  See the License for the
179a1eeea9SAndrew Rist  * specific language governing permissions and limitations
189a1eeea9SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
209a1eeea9SAndrew Rist  *************************************************************/
219a1eeea9SAndrew Rist 
229a1eeea9SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir package org.openoffice.setup.Installer;
25cdf0e10cSrcweir 
26cdf0e10cSrcweir import java.io.File;
27cdf0e10cSrcweir import org.openoffice.setup.InstallData;
28cdf0e10cSrcweir import org.openoffice.setup.InstallerHelper.LinuxHelper;
29cdf0e10cSrcweir import org.openoffice.setup.ResourceManager;
30cdf0e10cSrcweir import org.openoffice.setup.SetupData.PackageDescription;
31cdf0e10cSrcweir import org.openoffice.setup.SetupData.ProductDescription;
32cdf0e10cSrcweir import org.openoffice.setup.SetupData.SetupDataProvider;
33cdf0e10cSrcweir import org.openoffice.setup.Util.ExecuteProcess;
34cdf0e10cSrcweir import org.openoffice.setup.Util.Informer;
35cdf0e10cSrcweir import org.openoffice.setup.Util.LogManager;
36cdf0e10cSrcweir import java.util.HashMap;
37cdf0e10cSrcweir import java.util.Iterator;
38cdf0e10cSrcweir import java.util.Map;
39cdf0e10cSrcweir import java.util.Vector;
40cdf0e10cSrcweir 
41cdf0e10cSrcweir public class LinuxInstaller extends Installer {
42cdf0e10cSrcweir 
43cdf0e10cSrcweir     LinuxHelper helper = new LinuxHelper();
44cdf0e10cSrcweir 
LinuxInstaller()45cdf0e10cSrcweir     public LinuxInstaller() {
46cdf0e10cSrcweir         super();
47cdf0e10cSrcweir     }
48cdf0e10cSrcweir 
preInstall(PackageDescription packageData)49cdf0e10cSrcweir     public void preInstall(PackageDescription packageData) {
50cdf0e10cSrcweir         InstallData installData = InstallData.getInstance();
51cdf0e10cSrcweir         // Collecting package names
52cdf0e10cSrcweir         helper.getLinuxPackageNamesFromRpmquery(packageData, installData);
53cdf0e10cSrcweir         helper.getLinuxFileInfo(packageData);
54cdf0e10cSrcweir         // Dumper.dumpAllRpmInfo(packageData);
55cdf0e10cSrcweir     }
56cdf0e10cSrcweir 
postInstall(PackageDescription packageData)57cdf0e10cSrcweir     public void postInstall(PackageDescription packageData) {
58cdf0e10cSrcweir         InstallData data = InstallData.getInstance();
59cdf0e10cSrcweir 
60cdf0e10cSrcweir         if ( ! data.isAbortedInstallation() ) {
61cdf0e10cSrcweir             data.setStillRunning(true);
62cdf0e10cSrcweir             // Collecting information about installed packages
63cdf0e10cSrcweir             // Creating a list containing pairs of package names and rpm file names
64cdf0e10cSrcweir             // that has to be used during uninstallation.
65cdf0e10cSrcweir             helper.createPackageNameFileAtPostinstall(data, packageData);
66cdf0e10cSrcweir             helper.saveModulesLogFile(data);
67cdf0e10cSrcweir             data.setStillRunning(false);
68cdf0e10cSrcweir         }
69cdf0e10cSrcweir     }
70cdf0e10cSrcweir 
preUninstall(PackageDescription packageData)71cdf0e10cSrcweir     public void preUninstall(PackageDescription packageData) {
72cdf0e10cSrcweir         // Collecting information about installed packages
73cdf0e10cSrcweir         HashMap packageNames = helper.readPackageNamesFile();
74cdf0e10cSrcweir         helper.setFullPackageNameAtUninstall(packageData, packageNames);
75cdf0e10cSrcweir         helper.getLinuxFileInfo(packageData);
76cdf0e10cSrcweir         // Dumper.dumpAllRpmInfo(packageData);
77cdf0e10cSrcweir     }
78cdf0e10cSrcweir 
defineDatabasePath()79cdf0e10cSrcweir     public void defineDatabasePath() {
80cdf0e10cSrcweir 
81cdf0e10cSrcweir         InstallData data = InstallData.getInstance();
82cdf0e10cSrcweir         String oldDatabasePath = data.getDatabasePath();
83cdf0e10cSrcweir         data.setDatabasePath(null);
84cdf0e10cSrcweir 
85cdf0e10cSrcweir         // Determining the database path (only for user installation).
86cdf0e10cSrcweir         // Important if a user installation is done into an existing
87cdf0e10cSrcweir         // user installation -> this methode can only be called after
88cdf0e10cSrcweir         // determination of installation directory.
89cdf0e10cSrcweir 
90cdf0e10cSrcweir         if ( data.isUserInstallation() ) {
91cdf0e10cSrcweir             String databasePath = helper.getLinuxDatabasePath(data); // the file does not need to exist!
92cdf0e10cSrcweir             data.setDatabasePath(databasePath);
93cdf0e10cSrcweir 
94cdf0e10cSrcweir             // If this is a new path to the database, then this database was
95cdf0e10cSrcweir             // not analyzed before (when going back in installation wizard)
96cdf0e10cSrcweir             if ( ! databasePath.equals(oldDatabasePath) ) {
97cdf0e10cSrcweir                 data.setDatabaseAnalyzed(false);
98cdf0e10cSrcweir                 data.setDatabaseQueried(false);
99cdf0e10cSrcweir             }
100cdf0e10cSrcweir         }
101cdf0e10cSrcweir     }
102cdf0e10cSrcweir 
getChangeInstallDir(PackageDescription packageData)103cdf0e10cSrcweir     public String getChangeInstallDir(PackageDescription packageData) {
104cdf0e10cSrcweir         String installDir = null;
105cdf0e10cSrcweir         InstallData installData = InstallData.getInstance();
106cdf0e10cSrcweir 
107cdf0e10cSrcweir         String packageName = packageData.getPkgRealName();
108cdf0e10cSrcweir 
109cdf0e10cSrcweir         if ( packageName != null ) {
110cdf0e10cSrcweir             String rpmCommand = "rpm -q --queryformat %{INSTALLPREFIX} " + packageName;
111cdf0e10cSrcweir             String[] rpmCommandArray = new String[5];
112cdf0e10cSrcweir             rpmCommandArray[0] = "rpm";
113cdf0e10cSrcweir             rpmCommandArray[1] = "-q";
114cdf0e10cSrcweir             rpmCommandArray[2] = "--queryformat";
115cdf0e10cSrcweir             rpmCommandArray[3] = "%{INSTALLPREFIX}";
116cdf0e10cSrcweir             rpmCommandArray[4] = packageName;
117cdf0e10cSrcweir 
118cdf0e10cSrcweir             Vector returnVector = new Vector();
119cdf0e10cSrcweir             Vector returnErrorVector = new Vector();
120cdf0e10cSrcweir             int returnValue = ExecuteProcess.executeProcessReturnVector(rpmCommandArray, returnVector, returnErrorVector);
121cdf0e10cSrcweir             String returnString = (String) returnVector.get(0);
122cdf0e10cSrcweir             returnString = returnString.replaceAll("//","/");
123cdf0e10cSrcweir 
124cdf0e10cSrcweir             String log = rpmCommand + "<br><b>Returns: " + returnString + "</b><br>";
125cdf0e10cSrcweir             LogManager.addCommandsLogfileComment(log);
126cdf0e10cSrcweir 
127cdf0e10cSrcweir             installDir = returnString;
128cdf0e10cSrcweir         }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir         return installDir;
131cdf0e10cSrcweir     }
132cdf0e10cSrcweir 
installPackage(PackageDescription packageData)133cdf0e10cSrcweir     public void installPackage(PackageDescription packageData) {
134cdf0e10cSrcweir         // get ProductDescription for logging mechanism
135cdf0e10cSrcweir         ProductDescription productData = SetupDataProvider.getProductDescription();
136cdf0e10cSrcweir         InstallData data = InstallData.getInstance();
137cdf0e10cSrcweir 
138cdf0e10cSrcweir         // String log = "<br><b>Package: " + packageData.getName() + "</b>";
139cdf0e10cSrcweir         // LogManager.addCommandsLogfileComment(log);
140cdf0e10cSrcweir         String log = "";
141cdf0e10cSrcweir 
142cdf0e10cSrcweir         // setting installDir
143cdf0e10cSrcweir         String installDir = data.getInstallDir();
144cdf0e10cSrcweir         String packagePath = data.getPackagePath();
145cdf0e10cSrcweir 
146cdf0e10cSrcweir         if (( packageData.getPkgSubdir() != null ) && ( ! packageData.getPkgSubdir().equals("") )) {
147cdf0e10cSrcweir             File completePackageFile = new File(packagePath, packageData.getPkgSubdir());
148cdf0e10cSrcweir             packagePath = completePackageFile.getPath();
149cdf0e10cSrcweir         }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir         String packageName = packageData.getPackageName();
152cdf0e10cSrcweir 
153cdf0e10cSrcweir         if (( packageName.equals("")) || ( packageName == null )) {
154cdf0e10cSrcweir             log = "<b>No package name specified. Nothing to do</b>";
155cdf0e10cSrcweir             LogManager.addCommandsLogfileComment(log);
156cdf0e10cSrcweir         } else {
157cdf0e10cSrcweir             log = "<b>Package Name: " + packageName + "</b>";
158cdf0e10cSrcweir             LogManager.addCommandsLogfileComment(log);
159cdf0e10cSrcweir 
160cdf0e10cSrcweir             File completePackage = new File(packagePath, packageName);
161cdf0e10cSrcweir             packageName = completePackage.getPath();
1627950f2afSmseidel             packageName = "\"" + packageName + "\""; // Quoting is necessary, if the path to the packages contains white spaces.
163cdf0e10cSrcweir 
164cdf0e10cSrcweir             if ( completePackage.exists() ) {
165cdf0e10cSrcweir                 String relocations = helper.getRelocationString(packageData, packageName);
166cdf0e10cSrcweir                 if ( relocations != null ) {
167cdf0e10cSrcweir                     // Problem: If Prefix = "/" the packages are not relocatable with RPM version 3.x .
168cdf0e10cSrcweir                     // Therefore Prefix has to be "/opt" in spec file, although packages shall not be
169cdf0e10cSrcweir                     // relocatable (except for installations with root privileges). So /opt has to be
170cdf0e10cSrcweir                     // listed left and right of equal sign: --relocate /opt=<installDir>/opt
171cdf0e10cSrcweir                     // -> /opt has to be added to the installDir
172cdf0e10cSrcweir                     File localInstallDir = new File(installDir, relocations);  // "/" -> "/opt"
173cdf0e10cSrcweir                     String localInstallDirString = localInstallDir.getPath();
174cdf0e10cSrcweir 
175cdf0e10cSrcweir                     // Fixing problem with installation directory and RPM version 3.x
176cdf0e10cSrcweir                     String fixedInstallDir = helper.fixInstallationDirectory(localInstallDirString);
177cdf0e10cSrcweir                     relocations = relocations + "=" + fixedInstallDir;
178cdf0e10cSrcweir                     // relocations: "/opt/staroffice8=" + fixedInstallDir;
179cdf0e10cSrcweir                 }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir                 // Some packages have to be installed with parameter "--force", if the link "/usr/bin/soffice"
182*515f4036SJohn Bampton                 // already exists. These packages return true with methode "useForce()".
183cdf0e10cSrcweir                 boolean useForce = false;
184cdf0e10cSrcweir                 if ( packageData.useForce() ) {
185cdf0e10cSrcweir                     File sofficeLink = new File("/usr/bin/soffice");
186cdf0e10cSrcweir                     if ( sofficeLink.exists() ) { useForce = true; }
187cdf0e10cSrcweir                 }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir                 // On Debian based systems, rpms can be installed with the switch --force-debian, if a rpm
190cdf0e10cSrcweir                 // is installed.
191cdf0e10cSrcweir 
192cdf0e10cSrcweir                 String forceDebianString = "";
193cdf0e10cSrcweir                 String nodepsString = "";
194cdf0e10cSrcweir 
195cdf0e10cSrcweir                 if ( ! data.debianInvestigated() ) {
196cdf0e10cSrcweir                     helper.investigateDebian(data);
197cdf0e10cSrcweir                     data.setDebianInvestigated(true);
198cdf0e10cSrcweir                 }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir                 if ( data.isDebianSystem() ) {
201cdf0e10cSrcweir                     nodepsString = "--nodeps";
202cdf0e10cSrcweir 
203cdf0e10cSrcweir                     if ( data.useForceDebian() ) {
204cdf0e10cSrcweir                         forceDebianString = "--force-debian";
205cdf0e10cSrcweir                     }
206cdf0e10cSrcweir                 }
207cdf0e10cSrcweir 
208cdf0e10cSrcweir                 String databasePath = null;
209cdf0e10cSrcweir                 String databaseString = "";
210cdf0e10cSrcweir                 boolean useLocalDatabase = false;
211cdf0e10cSrcweir 
212cdf0e10cSrcweir                 if ( data.isUserInstallation() ) {
213cdf0e10cSrcweir                     databasePath = data.getDatabasePath();
214cdf0e10cSrcweir                     if ( databasePath == null ) {
215cdf0e10cSrcweir                         databasePath = helper.getLinuxDatabasePath(data);
216cdf0e10cSrcweir                         data.setDatabasePath(databasePath);
217cdf0e10cSrcweir                     }
218cdf0e10cSrcweir                 }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir                 if (( databasePath != null ) && (! databasePath.equalsIgnoreCase("null"))) {
221cdf0e10cSrcweir                     databaseString = "--dbpath";
222cdf0e10cSrcweir                     useLocalDatabase = true;
223cdf0e10cSrcweir                 }
224cdf0e10cSrcweir 
225cdf0e10cSrcweir                 // Defining a Vector that contains the full rpm command. Then the string array can be
226cdf0e10cSrcweir                 // created dynamically. Otherwise there would be too many different scenarios.
227cdf0e10cSrcweir 
228cdf0e10cSrcweir                 Vector rpmVector = new Vector();
229cdf0e10cSrcweir 
230cdf0e10cSrcweir                 rpmVector.add("rpm");
231cdf0e10cSrcweir                 rpmVector.add("--upgrade");
232cdf0e10cSrcweir                 rpmVector.add("--ignoresize");
233cdf0e10cSrcweir 
234cdf0e10cSrcweir                 if ( useForce ) {
235cdf0e10cSrcweir                     rpmVector.add("--force");
236cdf0e10cSrcweir                 }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir                 if ( ! forceDebianString.equals("") ) {
239cdf0e10cSrcweir                     rpmVector.add(forceDebianString);
240cdf0e10cSrcweir                 }
241cdf0e10cSrcweir 
242cdf0e10cSrcweir                 if ( ! nodepsString.equals("") ) {
243cdf0e10cSrcweir                     rpmVector.add(nodepsString);
244cdf0e10cSrcweir                 }
245cdf0e10cSrcweir 
246cdf0e10cSrcweir                 rpmVector.add("-vh");
247cdf0e10cSrcweir 
248cdf0e10cSrcweir                 if ( relocations != null ) {
249cdf0e10cSrcweir                     rpmVector.add("--relocate");
250cdf0e10cSrcweir                     rpmVector.add(relocations);
251cdf0e10cSrcweir                 }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir                 if ( useLocalDatabase ) {
254cdf0e10cSrcweir                     rpmVector.add(databaseString);
255cdf0e10cSrcweir                     rpmVector.add(databasePath);
256cdf0e10cSrcweir                 }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir                 rpmVector.add(packageName);
259cdf0e10cSrcweir 
260cdf0e10cSrcweir                 // Creating String and StringArray for rpm command
261cdf0e10cSrcweir 
262cdf0e10cSrcweir                 int capacity = rpmVector.size();
263cdf0e10cSrcweir 
264cdf0e10cSrcweir                 String rpmCommand = "";
265cdf0e10cSrcweir                 String[] rpmCommandArray = new String[capacity];
266cdf0e10cSrcweir 
267cdf0e10cSrcweir                 for (int i = 0; i < rpmVector.size(); i++) {
268cdf0e10cSrcweir                     rpmCommandArray[i] = (String)rpmVector.get(i);
269cdf0e10cSrcweir                     rpmCommand = rpmCommand + " " + (String)rpmVector.get(i);
270cdf0e10cSrcweir                 }
271cdf0e10cSrcweir 
272cdf0e10cSrcweir                 rpmCommand = rpmCommand.trim();
273cdf0e10cSrcweir 
274cdf0e10cSrcweir                 // Staring rpm process
275cdf0e10cSrcweir 
276cdf0e10cSrcweir                 Vector returnVector = new Vector();
277cdf0e10cSrcweir                 Vector returnErrorVector = new Vector();
278cdf0e10cSrcweir                 // int returnValue = SystemManager.executeProcessReturnVector(rpmCommand, returnVector, returnErrorVector);
279cdf0e10cSrcweir                 int returnValue = ExecuteProcess.executeProcessReturnVector(rpmCommandArray, returnVector, returnErrorVector);
280cdf0e10cSrcweir 
281cdf0e10cSrcweir                 if ( returnValue == 0 ) {
282cdf0e10cSrcweir                     log = rpmCommand + "<br><b>Returns: " + returnValue + " Successful installation</b><br>";
283cdf0e10cSrcweir                     LogManager.addCommandsLogfileComment(log);
284a893be29SPedro Giffuni                 } else {    // an error occurred during installation
285cdf0e10cSrcweir                     if ( packageData.installCanFail() ) {
286cdf0e10cSrcweir                         log = rpmCommand + "<br><b>Returns: " + returnValue + " Problem during installation. Can be ignored.</b><br>";
287cdf0e10cSrcweir                         LogManager.addCommandsLogfileComment(log);
288cdf0e10cSrcweir                     } else {
289cdf0e10cSrcweir                         log = rpmCommand + "<br><b>Returns: " + returnValue + " Error during installation</b><br>";
290cdf0e10cSrcweir                         LogManager.addCommandsLogfileComment(log);
291cdf0e10cSrcweir                         for (int i = 0; i < returnErrorVector.size(); i++) {
292cdf0e10cSrcweir                             LogManager.addCommandsLogfileComment((String)returnErrorVector.get(i));
293cdf0e10cSrcweir                         }
294cdf0e10cSrcweir                         data.setIsErrorInstallation(true);
295cdf0e10cSrcweir                     }
296cdf0e10cSrcweir                 }
297cdf0e10cSrcweir 
298cdf0e10cSrcweir                 // saving installation state at package
299cdf0e10cSrcweir                 packageData.setIsNewInstalled(true);
300cdf0e10cSrcweir             } else {
301cdf0e10cSrcweir                 log = "<b>Error: Did not find package " + packageName + "</b><br>";
302cdf0e10cSrcweir                 System.err.println(log);
303cdf0e10cSrcweir                 String message = ResourceManager.getString("String_File_Not_Found") + ": " + packageName;
304cdf0e10cSrcweir                 String title = ResourceManager.getString("String_Error");
305cdf0e10cSrcweir                 Informer.showErrorMessage(message, title);
306cdf0e10cSrcweir                 LogManager.addCommandsLogfileComment(log);
307cdf0e10cSrcweir                 data.setIsErrorInstallation(true);
308cdf0e10cSrcweir             }
309cdf0e10cSrcweir         }
310cdf0e10cSrcweir     }
311cdf0e10cSrcweir 
uninstallPackage(PackageDescription packageData)312cdf0e10cSrcweir     public void uninstallPackage(PackageDescription packageData) {
313cdf0e10cSrcweir         // get ProductDescription for logging mechanism
314cdf0e10cSrcweir         ProductDescription productData = SetupDataProvider.getProductDescription();
315cdf0e10cSrcweir         InstallData data = InstallData.getInstance();
316cdf0e10cSrcweir 
317cdf0e10cSrcweir         String log  = "";
318cdf0e10cSrcweir         // String log = "<br><b>Package: " + packageData.getName() + "</b>";
319cdf0e10cSrcweir         // LogManager.addCommandsLogfileComment(log);
320cdf0e10cSrcweir 
321cdf0e10cSrcweir         String rpmPackageName = packageData.getPackageName();
322cdf0e10cSrcweir 
323cdf0e10cSrcweir         if (( rpmPackageName.equals("")) || ( rpmPackageName == null )) {
324cdf0e10cSrcweir             log = "<b>No package name specified. Nothing to do</b>";
325cdf0e10cSrcweir             LogManager.addCommandsLogfileComment(log);
326cdf0e10cSrcweir         } else {
327cdf0e10cSrcweir             log = "<b>Package Name: " + rpmPackageName + "</b>";
328cdf0e10cSrcweir             LogManager.addCommandsLogfileComment(log);
329cdf0e10cSrcweir 
330cdf0e10cSrcweir             String packageName = packageData.getPkgRealName();
331cdf0e10cSrcweir             String databasePath = data.getDatabasePath();
332cdf0e10cSrcweir             String databaseString = "";
333cdf0e10cSrcweir             boolean useLocalDatabase = false;
334cdf0e10cSrcweir 
335cdf0e10cSrcweir             if (( databasePath != null ) && (! databasePath.equalsIgnoreCase("null"))) {
336cdf0e10cSrcweir                 databaseString = "--dbpath";
337cdf0e10cSrcweir                 useLocalDatabase = true;
338cdf0e10cSrcweir             }
339cdf0e10cSrcweir 
340cdf0e10cSrcweir             // On Debian based systems, rpms can be installed with the switch --force-debian, if a rpm
341cdf0e10cSrcweir             // is installed.
342cdf0e10cSrcweir 
343cdf0e10cSrcweir             String forceDebianString = "";
344cdf0e10cSrcweir             String nodepsString = "";
345cdf0e10cSrcweir             String noscriptsString = "";
346cdf0e10cSrcweir 
347cdf0e10cSrcweir             if ( ! data.debianInvestigated() ) {
348cdf0e10cSrcweir                 helper.investigateDebian(data);
349cdf0e10cSrcweir                 data.setDebianInvestigated(true);
350cdf0e10cSrcweir             }
351cdf0e10cSrcweir 
352cdf0e10cSrcweir             if ( data.isDebianSystem() ) {
353cdf0e10cSrcweir                 nodepsString = "--nodeps";
354cdf0e10cSrcweir 
355cdf0e10cSrcweir                 if ( data.useForceDebian() ) {
356cdf0e10cSrcweir                     forceDebianString = "--force-debian";
357cdf0e10cSrcweir                 }
358cdf0e10cSrcweir             }
359cdf0e10cSrcweir 
360cdf0e10cSrcweir             if (( data.isErrorInstallation() ) && ( data.isFirstPackage() )) {
361cdf0e10cSrcweir                 noscriptsString = "--noscripts";
362cdf0e10cSrcweir             }
363cdf0e10cSrcweir 
364cdf0e10cSrcweir             // Defining a Vector that contains the full rpm command. Then the string array can be
365cdf0e10cSrcweir             // created dynamically. Otherwise there would be too many different scenarios.
366cdf0e10cSrcweir 
367cdf0e10cSrcweir             Vector rpmVector = new Vector();
368cdf0e10cSrcweir 
369cdf0e10cSrcweir             rpmVector.add("rpm");
370cdf0e10cSrcweir 
371cdf0e10cSrcweir             if ( ! forceDebianString.equals("") ) {
372cdf0e10cSrcweir                 rpmVector.add(forceDebianString);
373cdf0e10cSrcweir             }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir             if ( ! nodepsString.equals("") ) {
376cdf0e10cSrcweir                 rpmVector.add(nodepsString);
377cdf0e10cSrcweir             }
378cdf0e10cSrcweir 
379cdf0e10cSrcweir             if ( ! noscriptsString.equals("") ) {
380cdf0e10cSrcweir                 rpmVector.add(noscriptsString);
381cdf0e10cSrcweir             }
382cdf0e10cSrcweir 
383cdf0e10cSrcweir             rpmVector.add("-ev");
384cdf0e10cSrcweir 
385cdf0e10cSrcweir             if ( useLocalDatabase ) {
386cdf0e10cSrcweir                 rpmVector.add(databaseString);
387cdf0e10cSrcweir                 rpmVector.add(databasePath);
388cdf0e10cSrcweir             }
389cdf0e10cSrcweir 
390cdf0e10cSrcweir             rpmVector.add(packageName);
391cdf0e10cSrcweir 
392cdf0e10cSrcweir             // Creating String and StringArray for rpm command
393cdf0e10cSrcweir 
394cdf0e10cSrcweir             int capacity = rpmVector.size();
395cdf0e10cSrcweir 
396cdf0e10cSrcweir             String rpmCommand = "";
397cdf0e10cSrcweir             String[] rpmCommandArray = new String[capacity];
398cdf0e10cSrcweir 
399cdf0e10cSrcweir             for (int i = 0; i < rpmVector.size(); i++) {
400cdf0e10cSrcweir                 rpmCommandArray[i] = (String)rpmVector.get(i);
401cdf0e10cSrcweir                 rpmCommand = rpmCommand + " " + (String)rpmVector.get(i);
402cdf0e10cSrcweir             }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir             rpmCommand = rpmCommand.trim();
405cdf0e10cSrcweir 
406cdf0e10cSrcweir             // Starting rpm process
407cdf0e10cSrcweir 
408cdf0e10cSrcweir             Vector returnVector = new Vector();
409cdf0e10cSrcweir             Vector returnErrorVector = new Vector();
410cdf0e10cSrcweir             int returnValue = ExecuteProcess.executeProcessReturnVector(rpmCommandArray, returnVector, returnErrorVector);
411cdf0e10cSrcweir 
412cdf0e10cSrcweir             if ( returnValue == 0 ) {
413cdf0e10cSrcweir                 log = rpmCommand + "<br><b>Returns: " + returnValue + " Successful uninstallation</b><br>";
414cdf0e10cSrcweir                 LogManager.addCommandsLogfileComment(log);
415a893be29SPedro Giffuni             } else {    // an error occurred during installation
416cdf0e10cSrcweir                 if ( packageData.uninstallCanFail() ) {
417cdf0e10cSrcweir                     log = rpmCommand + "<br><b>Returns: " + returnValue + " Problem during uninstallation. Can be ignored.</b><br>";
418cdf0e10cSrcweir                     LogManager.addCommandsLogfileComment(log);
419cdf0e10cSrcweir                 } else {
420cdf0e10cSrcweir                     log = rpmCommand + "<br><b>Returns: " + returnValue + " Error during uninstallation</b><br>";
421cdf0e10cSrcweir                     LogManager.addCommandsLogfileComment(log);
422cdf0e10cSrcweir                     for (int i = 0; i < returnErrorVector.size(); i++) {
423cdf0e10cSrcweir                         LogManager.addCommandsLogfileComment((String)returnErrorVector.get(i));
424cdf0e10cSrcweir                     }
425cdf0e10cSrcweir                     data.setIsErrorInstallation(true);
426cdf0e10cSrcweir                 }
427cdf0e10cSrcweir             }
428cdf0e10cSrcweir         }
429cdf0e10cSrcweir     }
430cdf0e10cSrcweir 
isPackageInstalledClassic(PackageDescription packageData, InstallData installData)431cdf0e10cSrcweir     public boolean isPackageInstalledClassic(PackageDescription packageData, InstallData installData) {
432cdf0e10cSrcweir 
433cdf0e10cSrcweir         boolean isInstalled = false;
434cdf0e10cSrcweir         boolean doCheck = false;
435cdf0e10cSrcweir 
436cdf0e10cSrcweir         // only checking existing packages (and always at uninstallation)
437cdf0e10cSrcweir         if ( (packageData.pkgExists()) || (installData.isUninstallationMode()) ) {
438cdf0e10cSrcweir             doCheck = true;
439cdf0e10cSrcweir         }
440cdf0e10cSrcweir 
441cdf0e10cSrcweir         String rpmPackageName = packageData.getPackageName();
442cdf0e10cSrcweir 
443cdf0e10cSrcweir         if ( rpmPackageName.equals("") ) {
444cdf0e10cSrcweir             rpmPackageName = null;
445cdf0e10cSrcweir         }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir         if (( rpmPackageName != null ) && ( doCheck )) {
448cdf0e10cSrcweir 
449cdf0e10cSrcweir             String databaseString = "";
450cdf0e10cSrcweir             String databasePath = null;
451cdf0e10cSrcweir             String packageName = packageData.getPkgRealName();
452cdf0e10cSrcweir             Vector allPackages = null;
453cdf0e10cSrcweir             boolean useLocalDatabase = false;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir             if (installData.isUserInstallation()) {
456cdf0e10cSrcweir                 databasePath = installData.getDatabasePath();
457cdf0e10cSrcweir             }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir             if (( databasePath != null ) && (! databasePath.equals("null"))) {
460cdf0e10cSrcweir                 databaseString = "--dbpath";
461cdf0e10cSrcweir                 useLocalDatabase = true;
462cdf0e10cSrcweir             }
463cdf0e10cSrcweir 
464cdf0e10cSrcweir             if (packageName != null) {
465cdf0e10cSrcweir 
466cdf0e10cSrcweir                 String rpmCommand;
467cdf0e10cSrcweir                 String[] rpmCommandArray;
468cdf0e10cSrcweir 
469cdf0e10cSrcweir                 if (useLocalDatabase) {
470cdf0e10cSrcweir                     rpmCommand = "rpm" + " " + databaseString + " " + databasePath + " --query " + packageName;
471cdf0e10cSrcweir                     rpmCommandArray = new String[5];
472cdf0e10cSrcweir                     rpmCommandArray[0] = "rpm";
473cdf0e10cSrcweir                     rpmCommandArray[1] = databaseString;
474cdf0e10cSrcweir                     rpmCommandArray[2] = databasePath;
475cdf0e10cSrcweir                     rpmCommandArray[3] = "--query";
476cdf0e10cSrcweir                     rpmCommandArray[4] = packageName;
477cdf0e10cSrcweir                 } else {
478cdf0e10cSrcweir                     rpmCommand = "rpm" + " --query " + packageName;
479cdf0e10cSrcweir                     rpmCommandArray = new String[3];
480cdf0e10cSrcweir                     rpmCommandArray[0] = "rpm";
481cdf0e10cSrcweir                     rpmCommandArray[1] = "--query";
482cdf0e10cSrcweir                     rpmCommandArray[2] = packageName;
483cdf0e10cSrcweir                 }
484cdf0e10cSrcweir 
485cdf0e10cSrcweir                 int returnValue = ExecuteProcess.executeProcessReturnValue(rpmCommandArray);
486cdf0e10cSrcweir 
487cdf0e10cSrcweir                 if ( returnValue == 0 ) {
488cdf0e10cSrcweir                     isInstalled = true;
489cdf0e10cSrcweir                     packageData.setWasAlreadyInstalled(true); // needed for logging
490cdf0e10cSrcweir                     String log = rpmCommand + "<br><b>Returns: " + returnValue + " Package is installed" + "</b><br>";
491cdf0e10cSrcweir                     LogManager.addCommandsLogfileComment(log);
492cdf0e10cSrcweir                 } else {
493cdf0e10cSrcweir                     String log = rpmCommand + "<br><b>Returns: " + returnValue + " Package is not installed" + "</b><br>";
494cdf0e10cSrcweir                     LogManager.addCommandsLogfileComment(log);
495cdf0e10cSrcweir                 }
496cdf0e10cSrcweir             }
497cdf0e10cSrcweir         }
498cdf0e10cSrcweir 
499cdf0e10cSrcweir         return isInstalled;
500cdf0e10cSrcweir     }
501cdf0e10cSrcweir 
queryAllDatabase(InstallData installData)502cdf0e10cSrcweir     private void queryAllDatabase(InstallData installData) {
503cdf0e10cSrcweir 
504cdf0e10cSrcweir         String databaseString = "";
505cdf0e10cSrcweir         String databasePath = null;
506d05a6787Smseidel         HashMap map = new HashMap();
507cdf0e10cSrcweir         boolean useLocalDatabase = false;
508cdf0e10cSrcweir 
509cdf0e10cSrcweir         if (installData.isUserInstallation()) {
510cdf0e10cSrcweir             databasePath = installData.getDatabasePath();
511cdf0e10cSrcweir         }
512cdf0e10cSrcweir 
513cdf0e10cSrcweir         if (( databasePath != null ) && (! databasePath.equals("null"))) {
514cdf0e10cSrcweir             databaseString = "--dbpath";
515cdf0e10cSrcweir             useLocalDatabase = true;
516cdf0e10cSrcweir         }
517cdf0e10cSrcweir 
518cdf0e10cSrcweir         String rpmCommand;
519cdf0e10cSrcweir         String[] rpmCommandArray;
520cdf0e10cSrcweir 
521cdf0e10cSrcweir         if (useLocalDatabase) {
522cdf0e10cSrcweir             rpmCommand = "rpm" + " " + databaseString + " " + databasePath + " --query" + " -a";
523cdf0e10cSrcweir             rpmCommandArray = new String[5];
524cdf0e10cSrcweir             rpmCommandArray[0] = "rpm";
525cdf0e10cSrcweir             rpmCommandArray[1] = databaseString;
526cdf0e10cSrcweir             rpmCommandArray[2] = databasePath;
527cdf0e10cSrcweir             rpmCommandArray[3] = "--query";
528cdf0e10cSrcweir             rpmCommandArray[4] = "-a";
529cdf0e10cSrcweir         } else {
530cdf0e10cSrcweir             rpmCommand = "rpm" + " --query" + " -a";
531cdf0e10cSrcweir             rpmCommandArray = new String[3];
532cdf0e10cSrcweir             rpmCommandArray[0] = "rpm";
533cdf0e10cSrcweir             rpmCommandArray[1] = "--query";
534cdf0e10cSrcweir             rpmCommandArray[2] = "-a";
535cdf0e10cSrcweir         }
536cdf0e10cSrcweir 
537cdf0e10cSrcweir         Vector returnVector = new Vector();
538cdf0e10cSrcweir         Vector returnErrorVector = new Vector();
539cdf0e10cSrcweir         int returnValue = ExecuteProcess.executeProcessReturnVector(rpmCommandArray, returnVector, returnErrorVector);
540cdf0e10cSrcweir 
541cdf0e10cSrcweir         String log = rpmCommand + "<br><b>Returns: " + returnValue + "</b><br>";
542cdf0e10cSrcweir         LogManager.addCommandsLogfileComment(log);
543cdf0e10cSrcweir         String value = "1";
544cdf0e10cSrcweir 
545cdf0e10cSrcweir         if ( ! returnVector.isEmpty()) {
546cdf0e10cSrcweir             for (int i = 0; i < returnVector.size(); i++) {
547cdf0e10cSrcweir                 String onePackage = (String)returnVector.get(i);
548cdf0e10cSrcweir                 int pos1 = onePackage.lastIndexOf("-");
549cdf0e10cSrcweir                 int pos2 = onePackage.substring(0, pos1).lastIndexOf("-");
550cdf0e10cSrcweir                 String key = onePackage.substring(0, pos2);
551cdf0e10cSrcweir                 map.put(key, value);
552cdf0e10cSrcweir             }
553cdf0e10cSrcweir         }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir         installData.setDatabaseQueried(true);
556cdf0e10cSrcweir         installData.setDatabaseMap(map);
557cdf0e10cSrcweir     }
558cdf0e10cSrcweir 
isPackageInstalled(PackageDescription packageData, InstallData installData)559cdf0e10cSrcweir     public boolean isPackageInstalled(PackageDescription packageData, InstallData installData) {
560cdf0e10cSrcweir 
561cdf0e10cSrcweir         boolean isInstalled = false;
562cdf0e10cSrcweir         boolean doCheck = false;
563cdf0e10cSrcweir 
564cdf0e10cSrcweir         // only checking existing packages (and always at uninstallation)
565cdf0e10cSrcweir         if ( (packageData.pkgExists()) || (installData.isUninstallationMode()) ) {
566cdf0e10cSrcweir             doCheck = true;
567cdf0e10cSrcweir         }
568cdf0e10cSrcweir 
569cdf0e10cSrcweir         String rpmPackageName = packageData.getPackageName();
570cdf0e10cSrcweir 
571cdf0e10cSrcweir         if ( rpmPackageName.equals("") ) {
572cdf0e10cSrcweir             rpmPackageName = null;
573cdf0e10cSrcweir         }
574cdf0e10cSrcweir 
575cdf0e10cSrcweir         if (( rpmPackageName != null ) && ( doCheck )) {
576cdf0e10cSrcweir             String packageName = packageData.getPkgRealName();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir             if (packageName != null) {
579cdf0e10cSrcweir 
580cdf0e10cSrcweir                 HashMap map = null;
581cdf0e10cSrcweir                 if ( ! installData.databaseQueried() ) {
582cdf0e10cSrcweir                     queryAllDatabase(installData);
583cdf0e10cSrcweir                 }
584cdf0e10cSrcweir 
585cdf0e10cSrcweir                 map = installData.getDatabaseMap();
586cdf0e10cSrcweir 
587cdf0e10cSrcweir                 if ( map.containsKey(packageName)) {
588cdf0e10cSrcweir                     isInstalled = true;
589cdf0e10cSrcweir                 }
590cdf0e10cSrcweir             } else {
591cdf0e10cSrcweir                 System.err.println("Error: No packageName defined for package: " + packageData.getPackageName());
592cdf0e10cSrcweir             }
593cdf0e10cSrcweir         }
594cdf0e10cSrcweir 
595cdf0e10cSrcweir         return isInstalled;
596cdf0e10cSrcweir     }
597cdf0e10cSrcweir 
isInstallSetPackageOlder(PackageDescription packageData, InstallData installData)598cdf0e10cSrcweir     public boolean isInstallSetPackageOlder(PackageDescription packageData, InstallData installData) {
599cdf0e10cSrcweir         boolean installSetPackageIsOlder = false;
600cdf0e10cSrcweir         boolean checkIfInstalledIsOlder = false;
601cdf0e10cSrcweir         installSetPackageIsOlder = findOlderPackage(packageData, installData, checkIfInstalledIsOlder);
602cdf0e10cSrcweir         return installSetPackageIsOlder;
603cdf0e10cSrcweir     }
604cdf0e10cSrcweir 
isInstalledPackageOlder(PackageDescription packageData, InstallData installData)605cdf0e10cSrcweir     public boolean isInstalledPackageOlder(PackageDescription packageData, InstallData installData) {
606cdf0e10cSrcweir         boolean installedPackageIsOlder = false;
607cdf0e10cSrcweir         boolean checkIfInstalledIsOlder = true;
608cdf0e10cSrcweir         installedPackageIsOlder = findOlderPackage(packageData, installData, checkIfInstalledIsOlder);
609cdf0e10cSrcweir         return installedPackageIsOlder;
610cdf0e10cSrcweir     }
611cdf0e10cSrcweir 
findOlderPackage(PackageDescription packageData, InstallData installData, boolean checkIfInstalledIsOlder)612cdf0e10cSrcweir     private boolean findOlderPackage(PackageDescription packageData, InstallData installData, boolean checkIfInstalledIsOlder) {
613cdf0e10cSrcweir 
614cdf0e10cSrcweir         // The information about the new package is stored in packageData (the version and the release).
615cdf0e10cSrcweir         // This information can be stored in xpd files. If it is not stored in xpd files, it is determined
616cdf0e10cSrcweir         // during installation process by querying the rpm file. This process costs much time and should
617cdf0e10cSrcweir         // therefore be done by the process, that creates the xpd files. On the other hand this requires,
618cdf0e10cSrcweir         // that the xpd files contain the correct information.
619cdf0e10cSrcweir 
620cdf0e10cSrcweir         boolean isOlder = false;
621cdf0e10cSrcweir 
622cdf0e10cSrcweir         // get the version of the installed package
623cdf0e10cSrcweir         String rpmPackageName = packageData.getPackageName();
624cdf0e10cSrcweir         String log;
625cdf0e10cSrcweir 
626cdf0e10cSrcweir         if ( rpmPackageName.equals("")) {
627cdf0e10cSrcweir             rpmPackageName = null;
628cdf0e10cSrcweir         }
629cdf0e10cSrcweir 
630cdf0e10cSrcweir         if ( rpmPackageName != null ) {
631cdf0e10cSrcweir             String databaseString = "";
632cdf0e10cSrcweir             String databasePath = null;
633cdf0e10cSrcweir             String packageName =  packageData.getPkgRealName();
634cdf0e10cSrcweir             Vector allPackages = null;
635cdf0e10cSrcweir             boolean useLocalDatabase = false;
636cdf0e10cSrcweir 
637cdf0e10cSrcweir             if (installData.isUserInstallation()) {
638cdf0e10cSrcweir                 databasePath = installData.getDatabasePath();
639cdf0e10cSrcweir             }
640cdf0e10cSrcweir 
641cdf0e10cSrcweir             if (( databasePath != null ) && (! databasePath.equals("null"))) {
642cdf0e10cSrcweir                 databaseString = "--dbpath";
643cdf0e10cSrcweir                 useLocalDatabase = true;
644cdf0e10cSrcweir             }
645cdf0e10cSrcweir 
646cdf0e10cSrcweir             if (packageName != null) {
647cdf0e10cSrcweir                 // Collect information about the installed package by querying the database.
648cdf0e10cSrcweir                 // Instead of rpm file name, the real package name has to be used.
649cdf0e10cSrcweir 
650cdf0e10cSrcweir                 String rpmCommand;
651cdf0e10cSrcweir                 String[] rpmCommandArray;
652cdf0e10cSrcweir 
653cdf0e10cSrcweir                 if (useLocalDatabase) {
654cdf0e10cSrcweir                     rpmCommand = "rpm" + " " + databaseString + " " + databasePath + " -q --queryformat %{VERSION}\\n " + packageName;
655cdf0e10cSrcweir                     rpmCommandArray = new String[7];
656cdf0e10cSrcweir                     rpmCommandArray[0] = "rpm";
657cdf0e10cSrcweir                     rpmCommandArray[1] = databaseString;
658cdf0e10cSrcweir                     rpmCommandArray[2] = databasePath;
659cdf0e10cSrcweir                     rpmCommandArray[3] = "-q";
660cdf0e10cSrcweir                     rpmCommandArray[4] = "--queryformat";
661cdf0e10cSrcweir                     rpmCommandArray[5] = "%{VERSION}\\n";
662cdf0e10cSrcweir                     rpmCommandArray[6] = packageName;
663cdf0e10cSrcweir                 } else {
664cdf0e10cSrcweir                     rpmCommand = "rpm" + " -q --queryformat %{VERSION}\\n " + packageName;
665cdf0e10cSrcweir                     rpmCommandArray = new String[5];
666cdf0e10cSrcweir                     rpmCommandArray[0] = "rpm";
667cdf0e10cSrcweir                     rpmCommandArray[1] = "-q";
668cdf0e10cSrcweir                     rpmCommandArray[2] = "--queryformat";
669cdf0e10cSrcweir                     rpmCommandArray[3] = "%{VERSION}\\n";
670cdf0e10cSrcweir                     rpmCommandArray[4] = packageName;
671cdf0e10cSrcweir                 }
672cdf0e10cSrcweir 
673cdf0e10cSrcweir                 Vector versionVector = new Vector();
674cdf0e10cSrcweir                 Vector returnErrorVector = new Vector();
675cdf0e10cSrcweir                 int returnValue = ExecuteProcess.executeProcessReturnVector(rpmCommandArray, versionVector, returnErrorVector);
676cdf0e10cSrcweir                 String version = (String) versionVector.lastElement();
677cdf0e10cSrcweir                 log = rpmCommand + "<br><b>Returns: " + version + "</b><br>";
678cdf0e10cSrcweir                 LogManager.addCommandsLogfileComment(log);
679cdf0e10cSrcweir 
680cdf0e10cSrcweir                 if ( ! installData.installedProductMinorSet() ) {
681cdf0e10cSrcweir                     int productMinor = helper.getInstalledMinor(version);
682cdf0e10cSrcweir                     installData.setInstalledProductMinor(productMinor);
683cdf0e10cSrcweir                     installData.setInstalledProductMinorSet(true);
684cdf0e10cSrcweir                 }
685cdf0e10cSrcweir 
686cdf0e10cSrcweir                 if (useLocalDatabase) {
687cdf0e10cSrcweir                     rpmCommand = "rpm" + " " + databaseString + " " + databasePath + " -q --queryformat %{RELEASE}\\n " + packageName;
688cdf0e10cSrcweir                     rpmCommandArray[5] = "%{RELEASE}\\n";
689cdf0e10cSrcweir                 } else {
690cdf0e10cSrcweir                     rpmCommand = "rpm" + " -q --queryformat %{RELEASE}\\n " + packageName;
691cdf0e10cSrcweir                     rpmCommandArray[3] = "%{RELEASE}\\n";
692cdf0e10cSrcweir                 }
693cdf0e10cSrcweir 
694cdf0e10cSrcweir                 Vector releaseVector = new Vector();
695cdf0e10cSrcweir                 returnValue = ExecuteProcess.executeProcessReturnVector(rpmCommandArray, releaseVector, returnErrorVector);
696cdf0e10cSrcweir                 String release = (String) releaseVector.lastElement();
697cdf0e10cSrcweir 
698cdf0e10cSrcweir                 log = rpmCommand + "<br><b>Returns: " + release + "</b><br>";
699cdf0e10cSrcweir                 LogManager.addCommandsLogfileComment(log);
700cdf0e10cSrcweir 
701cdf0e10cSrcweir                 isOlder = helper.compareVersionAndRelease(version, release, packageData, checkIfInstalledIsOlder);
702cdf0e10cSrcweir 
703cdf0e10cSrcweir                 if ( checkIfInstalledIsOlder ) {
704cdf0e10cSrcweir                     if ( isOlder ) {
705cdf0e10cSrcweir                         LogManager.addCommandsLogfileComment("<b>-> Installed package is older</b><br>");
706cdf0e10cSrcweir                     } else {
707cdf0e10cSrcweir                         LogManager.addCommandsLogfileComment("<b>-> Installed package is not older</b><br>");
708cdf0e10cSrcweir                     }
709cdf0e10cSrcweir                 } else {
710cdf0e10cSrcweir                     if ( isOlder ) {
711cdf0e10cSrcweir                         LogManager.addCommandsLogfileComment("<b>-> Package in installation set is older</b><br>");
712cdf0e10cSrcweir                     } else {
713cdf0e10cSrcweir                         LogManager.addCommandsLogfileComment("<b>-> Package in installation set is not older</b><br>");
714cdf0e10cSrcweir                     }
715cdf0e10cSrcweir                 }
716cdf0e10cSrcweir 
717cdf0e10cSrcweir             } else {
718cdf0e10cSrcweir                 System.err.println("Error: No packageName defined for package: " + rpmPackageName);
719cdf0e10cSrcweir             }
720cdf0e10cSrcweir         }
721cdf0e10cSrcweir 
722cdf0e10cSrcweir         return isOlder;
723cdf0e10cSrcweir     }
724cdf0e10cSrcweir 
725cdf0e10cSrcweir }
726