001    // This file is part of the program FRYSK.
002    //
003    // Copyright 2008, Red Hat Inc.
004    //
005    // FRYSK is free software; you can redistribute it and/or modify it
006    // under the terms of the GNU General Public License as published by
007    // the Free Software Foundation; version 2 of the License.
008    //
009    // FRYSK is distributed in the hope that it will be useful, but
010    // WITHOUT ANY WARRANTY; without even the implied warranty of
011    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012    // General Public License for more details.
013    // 
014    // You should have received a copy of the GNU General Public License
015    // along with FRYSK; if not, write to the Free Software Foundation,
016    // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
017    // 
018    // In addition, as a special exception, Red Hat, Inc. gives You the
019    // additional right to link the code of FRYSK with code not covered
020    // under the GNU General Public License ("Non-GPL Code") and to
021    // distribute linked combinations including the two, subject to the
022    // limitations in this paragraph. Non-GPL Code permitted under this
023    // exception must only link to the code of FRYSK through those well
024    // defined interfaces identified in the file named EXCEPTION found in
025    // the source code files (the "Approved Interfaces"). The files of
026    // Non-GPL Code may instantiate templates or use macros or inline
027    // functions from the Approved Interfaces without causing the
028    // resulting work to be covered by the GNU General Public
029    // License. Only Red Hat, Inc. may make changes or additions to the
030    // list of Approved Interfaces. You must obey the GNU General Public
031    // License in all respects for all of the FRYSK code and other code
032    // used in conjunction with FRYSK except the Non-GPL Code covered by
033    // this exception. If you modify this file, you may extend this
034    // exception to your version of the file, but you are not obligated to
035    // do so. If you do not wish to provide this exception without
036    // modification, you must delete this exception statement from your
037    // version and license this file solely under the GPL without
038    // exception.
039    
040    package frysk.sysroot;
041    
042    import java.io.File;
043    
044    /**
045     * Map from a Task's executable to its special root directory.
046     */  
047    
048    public class SysRoot {
049        private File sysRoot;
050    
051        public SysRoot (File path) {
052            sysRoot = path;
053        }
054    
055        public SysRoot (String string) {
056            sysRoot = new File(string);
057        }
058        
059        /**
060         * return a pathname of an executable.
061         * 
062         * @param pathname
063         *          is the executable.
064         * @return this executable's pathname, searched for on $PATH in the special 
065         *          root directory.
066         */
067        public SysRootFile getPathViaSysRoot (String pathname) {
068            String pathVar = System.getenv("PATH");
069            return new SysRootFile(sysRoot, findExe(pathVar, pathname));
070        }
071        
072        /**
073         * return a pathname of an executable in a system root.  Used only for testing.
074         */
075        SysRootFile getPathViaSysRoot (String pathname, String pathVar) {
076            return new SysRootFile(sysRoot, findExe(pathVar, pathname));
077        }
078    
079        /**
080         * return a pathname of an executable's source.
081         * 
082         * @param pathname
083         *          is the executable's compilation directory.
084         * @param file
085         *          this executable's source name.
086         * @return the pathname of the executable's source searched for in the
087         *          special root directory.
088         */
089        public SysRootFile getSourcePathViaSysRoot (File compilationDir, File f) {
090            if (! f.isAbsolute())
091                // The file refers to a path relative to the
092                // compilation directory, so prepend that directory path.
093                return new SysRootFile(sysRoot, new File(compilationDir, f.getPath()));
094            else
095                return new SysRootFile(sysRoot, f);
096        }
097        
098        /**
099         * return a pathname of an executable.
100         * 
101         * @return this executable's library pathname, in the special 
102         *          root directory.
103         */
104        public String getLibPathViaSysRoot () {
105            String libraryPath = "";
106            if (! sysRoot.equals("/")) {
107                if (new File(sysRoot, "/lib").exists())
108                    libraryPath += sysRoot + "/lib:";
109                if (new File(sysRoot, "/usr/lib").exists())
110                    libraryPath += sysRoot + "/usr/lib";
111            }
112            
113            return libraryPath;
114        }
115    
116    
117        private File findExe(String pathVar, String arg0) {
118            File exeFile = new File(arg0);
119            if (pathVar == null) {
120                return exeFile;
121            }
122    
123            if (arg0.startsWith(File.separator)) {
124                return exeFile;
125            }
126    
127            String[] path = pathVar.split(":");
128            if (path == null) {
129                return exeFile;
130            }
131            
132            // Given "./executable" with sysroot "/"
133            if (sysRoot.getPath().compareTo(File.separator) == 0) { 
134                if (! exeFile.isAbsolute() 
135                        && exeFile.getPath().indexOf(File.separator) != -1
136                        && exeFile.exists()) {
137                    return exeFile;
138                }
139            }
140    
141            // Otherwise search in $PATH
142            for (int i = 0; i < path.length; i++) {
143                File file = new File(new File(sysRoot.getPath(), path[i]), arg0);
144                if (file.exists()) {
145                    return new File(path[i], arg0);
146                }
147            }
148            return new File(arg0);
149        }
150    }