/*
 * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.security.auth;

import java.io.*;
import java.lang.RuntimePermission;
import java.net.MalformedURLException;
import java.net.SocketPermission;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Vector;
import java.util.StringTokenizer;
import java.security.GeneralSecurityException;
import sun.security.util.PropertyExpander;

/**
 * The policy for a Java runtime (specifying
 * which permissions are available for code from various principals)
 * is represented as a separate
 * persistent configuration.  The configuration may be stored as a
 * flat ASCII file, as a serialized binary file of
 * the Policy class, or as a database. <p>
 *
 * <p>The Java runtime creates one global Policy object, which is used to
 * represent the static policy configuration file.  It is consulted by
 * a ProtectionDomain when the protection domain initializes its set of
 * permissions. <p>
 *
 * <p>The Policy <code>init</code> method parses the policy
 * configuration file, and then
 * populates the Policy object.  The Policy object is agnostic in that
 * it is not involved in making policy decisions.  It is merely the
 * Java runtime representation of the persistent policy configuration
 * file. <p>
 *
 * <p>When a protection domain needs to initialize its set of
 * permissions, it executes code such as the following
 * to ask the global Policy object to populate a
 * Permissions object with the appropriate permissions:
 * <pre>
 *  policy = Policy.getPolicy();
 *  Permissions perms = policy.getPermissions(MyCodeSource)
 * </pre>
 *
 * <p>The protection domain passes in a CodeSource
 * object, which encapsulates its codebase (URL) and public key attributes.
 * The Policy object evaluates the global policy in light of who the
 * principal is and returns an appropriate Permissions object.
 *
 * @deprecated As of JDK&nbsp;1.4, replaced by
 *             {@link sun.security.provider.PolicyParser}.
 *             This class is entirely deprecated.
 *
 * @author Roland Schemers
 *
 * @since 1.2
 */
@Deprecated
class PolicyParser {

    private static final java.util.ResourceBundle rb =
        java.security.AccessController.doPrivileged
        (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
            public java.util.ResourceBundle run() {
                    return (java.util.ResourceBundle.getBundle
                                ("sun.security.util.AuthResources"));
           }
        });

    private Vector<GrantEntry> grantEntries;

    // Convenience variables for parsing
    private static final sun.security.util.Debug debug =
        sun.security.util.Debug.getInstance("parser", "\t[Auth Policy Parser]");
    private StreamTokenizer st;
    private int lookahead;
    private int linenum;
    private boolean expandProp = false;
    private String keyStoreUrlString = null; // unexpanded
    private String keyStoreType = null;

    private String expand(String value)
        throws PropertyExpander.ExpandException
    {
        if (expandProp)
            return PropertyExpander.expand(value);
        else
            return value;
    }
    /**
     * Creates a PolicyParser object.
     */

    public PolicyParser() {
        grantEntries = new Vector<GrantEntry>();
    }


    public PolicyParser(boolean expandProp) {
        this();
        this.expandProp = expandProp;
    }

    /**
     * Reads a policy configuration into the Policy object using a
     * Reader object. <p>
     *
     * @param policy the policy Reader object.
     *
     * @exception ParsingException if the policy configuration contains
     *          a syntax error.
     *
     * @exception IOException if an error occurs while reading the policy
     *          configuration.
     */

    public void read(Reader policy)
        throws ParsingException, IOException
    {
        if (!(policy instanceof BufferedReader)) {
            policy = new BufferedReader(policy);
        }

        /**
         * Configure the stream tokenizer:
         *      Recognize strings between "..."
         *      Don't convert words to lowercase
         *      Recognize both C-style and C++-style comments
         *      Treat end-of-line as white space, not as a token
         */
        st   = new StreamTokenizer(policy);

        st.resetSyntax();
        st.wordChars('a', 'z');
        st.wordChars('A', 'Z');
        st.wordChars('.', '.');
        st.wordChars('0', '9');
        st.wordChars('_', '_');
        st.wordChars('$', '$');
        st.wordChars(128 + 32, 255);
        st.whitespaceChars(0, ' ');
        st.commentChar('/');
        st.quoteChar('\'');
        st.quoteChar('"');
        st.lowerCaseMode(false);
        st.ordinaryChar('/');
        st.slashSlashComments(true);
        st.slashStarComments(true);

        /**
         * The main parsing loop.  The loop is executed once
         * for each entry in the config file.      The entries
         * are delimited by semicolons.   Once we've read in
         * the information for an entry, go ahead and try to
         * add it to the policy vector.
         *
         */

        lookahead = st.nextToken();
        while (lookahead != StreamTokenizer.TT_EOF) {
            if (peek("grant")) {
                GrantEntry ge = parseGrantEntry();
                // could be null if we couldn't expand a property
                if (ge != null)
                    add(ge);
            } else if (peek("keystore") && keyStoreUrlString==null) {
                // only one keystore entry per policy file, others will be
                // ignored
                parseKeyStoreEntry();
            } else {
                // error?
            }
            match(";");
        }
    }

    public void add(GrantEntry ge)
    {
        grantEntries.addElement(ge);
    }

    public void replace(GrantEntry origGe, GrantEntry newGe)
    {
        grantEntries.setElementAt(newGe, grantEntries.indexOf(origGe));
    }

    public boolean remove(GrantEntry ge)
    {
        return grantEntries.removeElement(ge);
    }

    /**
     * Returns the (possibly expanded) keystore location, or null if the
     * expansion fails.
     */
    public String getKeyStoreUrl() {
        try {
            if (keyStoreUrlString!=null && keyStoreUrlString.length()!=0) {
                return expand(keyStoreUrlString).replace(File.separatorChar,
                                                         '/');
            }
        } catch (PropertyExpander.ExpandException peee) {
            return null;
        }
        return null;
    }

    public void setKeyStoreUrl(String url) {
        keyStoreUrlString = url;
    }

    public String getKeyStoreType() {
        return keyStoreType;
    }

    public void setKeyStoreType(String type) {
        keyStoreType = type;
    }

    /**
     * Enumerate all the entries in the global policy object.
     * This method is used by policy admin tools.   The tools
     * should use the Enumeration methods on the returned object
     * to fetch the elements sequentially.
     */
    public Enumeration<GrantEntry> grantElements(){
        return grantEntries.elements();
    }

    /**
     * write out the policy
     */

    public void write(Writer policy)
    {
        PrintWriter out = new PrintWriter(new BufferedWriter(policy));

        Enumeration<GrantEntry> enum_ = grantElements();

        out.println("/* AUTOMATICALLY GENERATED ON "+
                    (new java.util.Date()) + "*/");
        out.println("/* DO NOT EDIT */");
        out.println();

        // write the (unexpanded) keystore entry as the first entry of the
        // policy file
        if (keyStoreUrlString != null) {
            writeKeyStoreEntry(out);
        }

        // write "grant" entries
        while (enum_.hasMoreElements()) {
            GrantEntry ge = enum_.nextElement();
            ge.write(out);
            out.println();
        }
        out.flush();
    }

    /**
     * parses a keystore entry
     */
    private void parseKeyStoreEntry() throws ParsingException, IOException {
        match("keystore");
        keyStoreUrlString = match("quoted string");

        // parse keystore type
        if (!peek(",")) {
            return; // default type
        }
        match(",");

        if (peek("\"")) {
            keyStoreType = match("quoted string");
        } else {
            throw new ParsingException(st.lineno(),
                        rb.getString("expected keystore type"));
        }
    }

    /**
     * writes the (unexpanded) keystore entry
     */
    private void writeKeyStoreEntry(PrintWriter out) {
        out.print("keystore \"");
        out.print(keyStoreUrlString);
        out.print('"');
        if (keyStoreType != null && keyStoreType.length() > 0)
            out.print(", \"" + keyStoreType + "\"");
        out.println(";");
        out.println();
    }

    /**
     * parse a Grant entry
     */
    private GrantEntry parseGrantEntry()
        throws ParsingException, IOException
    {
        GrantEntry e = new GrantEntry();
        LinkedList<PrincipalEntry> principals = null;
        boolean ignoreEntry = false;

        match("grant");

        while(!peek("{")) {

            if (peekAndMatch("Codebase")) {
                e.codeBase = match("quoted string");
                peekAndMatch(",");
            } else if (peekAndMatch("SignedBy")) {
                e.signedBy = match("quoted string");
                peekAndMatch(",");
            } else if (peekAndMatch("Principal")) {
                if (principals == null) {
                    principals = new LinkedList<PrincipalEntry>();
                }

                // check for principalClass wildcard
                String principalClass;
                if (peek("*")) {
                    match("*");
                    principalClass = PrincipalEntry.WILDCARD_CLASS;
                } else {
                    principalClass = match("principal type");
                }

                // check for principalName wildcard
                String principalName;
                if (peek("*")) {
                    match("*");
                    principalName = PrincipalEntry.WILDCARD_NAME;
                } else {
                    principalName = match("quoted string");
                }

                // disallow WILDCARD_CLASS && actual name
                if (principalClass.equals(PrincipalEntry.WILDCARD_CLASS) &&
                    !principalName.equals(PrincipalEntry.WILDCARD_NAME)) {
                    if (debug != null)
                        debug.println("disallowing principal that has " +
                                "WILDCARD class but no WILDCARD name");
                    throw new ParsingException
                        (st.lineno(),
                        rb.getString("can not specify Principal with a ") +
                        rb.getString("wildcard class without a wildcard name"));
                }

                try {
                    principalName = expand(principalName);
                    principals.add
                        (new PrincipalEntry(principalClass, principalName));
                } catch (PropertyExpander.ExpandException peee) {
                    // ignore the entire policy entry
                    // but continue parsing all the info
                    // so we can get to the next entry
                    if (debug != null)
                        debug.println("principal name expansion failed: " +
                                        principalName);
                    ignoreEntry = true;
                }
                peekAndMatch(",");
            } else {
                throw new
                 ParsingException(st.lineno(),
                        rb.getString("expected codeBase or SignedBy"));
            }
        }

        // disallow non principal-based grant entries
        if (principals == null) {
            throw new ParsingException
                (st.lineno(),
                rb.getString("only Principal-based grant entries permitted"));
        }

        e.principals = principals;
        match("{");

        while(!peek("}")) {
            if (peek("Permission")) {
                try {
                    PermissionEntry pe = parsePermissionEntry();
                    e.add(pe);
                } catch (PropertyExpander.ExpandException peee) {
                    // ignore. The add never happened
                    skipEntry();  // BugId 4219343
                }
                match(";");
            } else {
                throw new
                    ParsingException(st.lineno(),
                    rb.getString("expected permission entry"));
            }
        }
        match("}");

        try {
            if (e.codeBase != null)
              e.codeBase = expand(e.codeBase).replace(File.separatorChar, '/');
            e.signedBy = expand(e.signedBy);
        } catch (PropertyExpander.ExpandException peee) {
            return null;
        }

        return (ignoreEntry == true) ? null : e;
    }

    /**
     * parse a Permission entry
     */
    private PermissionEntry parsePermissionEntry()
        throws ParsingException, IOException, PropertyExpander.ExpandException
    {
        PermissionEntry e = new PermissionEntry();

        // Permission
        match("Permission");
        e.permission = match("permission type");

        if (peek("\"")) {
            // Permission name
            e.name = expand(match("quoted string"));
        }

        if (!peek(",")) {
            return e;
        }
        match(",");

        if (peek("\"")) {
                e.action = expand(match("quoted string"));
                if (!peek(",")) {
                    return e;
                }
                match(",");
        }

        if (peekAndMatch("SignedBy")) {
            e.signedBy = expand(match("quoted string"));
        }
        return e;
    }

    private boolean peekAndMatch(String expect)
        throws ParsingException, IOException
    {
        if (peek(expect)) {
            match(expect);
            return true;
        } else {
            return false;
        }
    }

    private boolean peek(String expect) {
        boolean found = false;

        switch (lookahead) {

        case StreamTokenizer.TT_WORD:
            if (expect.equalsIgnoreCase(st.sval))
                found = true;
            break;
        case ',':
            if (expect.equalsIgnoreCase(","))
                found = true;
            break;
        case '{':
            if (expect.equalsIgnoreCase("{"))
                found = true;
            break;
        case '}':
            if (expect.equalsIgnoreCase("}"))
                found = true;
            break;
        case '"':
            if (expect.equalsIgnoreCase("\""))
                found = true;
            break;
        case '*':
            if (expect.equalsIgnoreCase("*"))
                found = true;
            break;
        default:

        }
        return found;
    }

    private String match(String expect)
        throws ParsingException, IOException
    {
        String value = null;

        switch (lookahead) {
        case StreamTokenizer.TT_NUMBER:
            throw new ParsingException(st.lineno(), expect,
                                        rb.getString("number ") +
                                        String.valueOf(st.nval));
        case StreamTokenizer.TT_EOF:
           throw new ParsingException
                (rb.getString("expected ") + expect +
                rb.getString(", read end of file"));
        case StreamTokenizer.TT_WORD:
            if (expect.equalsIgnoreCase(st.sval)) {
                lookahead = st.nextToken();
            } else if (expect.equalsIgnoreCase("permission type")) {
                value = st.sval;
                lookahead = st.nextToken();
            } else if (expect.equalsIgnoreCase("principal type")) {
                value = st.sval;
                lookahead = st.nextToken();
            } else {
                throw new ParsingException(st.lineno(), expect, st.sval);
            }
            break;
        case '"':
            if (expect.equalsIgnoreCase("quoted string")) {
                value = st.sval;
                lookahead = st.nextToken();
            } else if (expect.equalsIgnoreCase("permission type")) {
                value = st.sval;
                lookahead = st.nextToken();
            } else if (expect.equalsIgnoreCase("principal type")) {
                value = st.sval;
                lookahead = st.nextToken();
            } else {
                throw new ParsingException(st.lineno(), expect, st.sval);
            }
            break;
        case ',':
            if (expect.equalsIgnoreCase(","))
                lookahead = st.nextToken();
            else
                throw new ParsingException(st.lineno(), expect, ",");
            break;
        case '{':
            if (expect.equalsIgnoreCase("{"))
                lookahead = st.nextToken();
            else
                throw new ParsingException(st.lineno(), expect, "{");
            break;
        case '}':
            if (expect.equalsIgnoreCase("}"))
                lookahead = st.nextToken();
            else
                throw new ParsingException(st.lineno(), expect, "}");
            break;
        case ';':
            if (expect.equalsIgnoreCase(";"))
                lookahead = st.nextToken();
            else
                throw new ParsingException(st.lineno(), expect, ";");
            break;
        case '*':
            if (expect.equalsIgnoreCase("*"))
                lookahead = st.nextToken();
            else
                throw new ParsingException(st.lineno(), expect, "*");
            break;
        default:
            throw new ParsingException(st.lineno(), expect,
                               new String(new char[] {(char)lookahead}));
        }
        return value;
    }

    /**
     * skip all tokens for this entry leaving the delimiter ";"
     * in the stream.
     */
    private void skipEntry()
        throws ParsingException, IOException
    {
      while(lookahead != ';') {
        switch (lookahead) {
        case StreamTokenizer.TT_NUMBER:
            throw new ParsingException(st.lineno(), ";",
                                       rb.getString("number ") +
                                        String.valueOf(st.nval));
        case StreamTokenizer.TT_EOF:
          throw new ParsingException
                (rb.getString("expected ';', read end of file"));
        default:
          lookahead = st.nextToken();
        }
      }
    }

    /**
     * Each grant entry in the policy configuration file is
     * represented by a
     * GrantEntry object.  <p>
     *
     * <p>
     * For example, the entry
     * <pre>
     *      grant signedBy "Duke" {
     *          permission java.io.FilePermission "/tmp", "read,write";
     *      };
     *
     * </pre>
     * is represented internally
     * <pre>
     *
     * pe = new PermissionEntry("java.io.FilePermission",
     *                           "/tmp", "read,write");
     *
     * ge = new GrantEntry("Duke", null);
     *
     * ge.add(pe);
     *
     * </pre>
     *
     * @author Roland Schemers
     *
     * version 1.19, 05/21/98
     */

    static class GrantEntry {

        public String signedBy;
        public String codeBase;
        public LinkedList<PrincipalEntry> principals;
        public Vector<PermissionEntry> permissionEntries;

        public GrantEntry() {
            permissionEntries = new Vector<PermissionEntry>();
        }

        public GrantEntry(String signedBy, String codeBase) {
            this.codeBase = codeBase;
            this.signedBy = signedBy;
            permissionEntries = new Vector<PermissionEntry>();
        }

        public void add(PermissionEntry pe)
        {
            permissionEntries.addElement(pe);
        }

        public boolean remove(PermissionEntry pe)
        {
            return permissionEntries.removeElement(pe);
        }

        public boolean contains(PermissionEntry pe)
        {
            return permissionEntries.contains(pe);
        }

        /**
         * Enumerate all the permission entries in this GrantEntry.
         */
        public Enumeration<PermissionEntry> permissionElements(){
            return permissionEntries.elements();
        }


        public void write(PrintWriter out) {
            out.print("grant");
            if (signedBy != null) {
                out.print(" signedBy \"");
                out.print(signedBy);
                out.print('"');
                if (codeBase != null)
                    out.print(", ");
            }
            if (codeBase != null) {
                out.print(" codeBase \"");
                out.print(codeBase);
                out.print('"');
                if (principals != null && principals.size() > 0)
                    out.print(",\n");
            }
            if (principals != null && principals.size() > 0) {
                ListIterator<PrincipalEntry> pli = principals.listIterator();
                while (pli.hasNext()) {
                    out.print("\tPrincipal ");
                    PrincipalEntry pe = pli.next();
                    out.print(pe.principalClass +
                                " \"" + pe.principalName + "\"");
                    if (pli.hasNext())
                        out.print(",\n");
                }
            }
            out.println(" {");
            Enumeration<PermissionEntry> enum_ = permissionEntries.elements();
            while (enum_.hasMoreElements()) {
                PermissionEntry pe = enum_.nextElement();
                out.write("  ");
                pe.write(out);
            }
            out.println("};");
        }

    }

    /**
     * Principal info (class and name) in a grant entry
     */
    static class PrincipalEntry {

        static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS";
        static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME";

        String principalClass;
        String principalName;

        /**
         * A PrincipalEntry consists of the <code>Principal</code>
         * class and <code>Principal</code> name.
         *
         * <p>
         *
         * @param principalClass the <code>Principal</code> class. <p>
         *
         * @param principalName the <code>Principal</code> name. <p>
         */
        public PrincipalEntry(String principalClass, String principalName) {
            if (principalClass == null || principalName == null)
                throw new NullPointerException
                        ("null principalClass or principalName");
            this.principalClass = principalClass;
            this.principalName = principalName;
        }

        /**
         * Test for equality between the specified object and this object.
         * Two PrincipalEntries are equal if their PrincipalClass and
         * PrincipalName values are equal.
         *
         * <p>
         *
         * @param obj the object to test for equality with this object.
         *
         * @return true if the objects are equal, false otherwise.
         */
        public boolean equals(Object obj) {
            if (this == obj)
                return true;

            if (!(obj instanceof PrincipalEntry))
                return false;

            PrincipalEntry that = (PrincipalEntry)obj;
            if (this.principalClass.equals(that.principalClass) &&
                this.principalName.equals(that.principalName)) {
                return true;
            }

            return false;
        }

        /**
         * Return a hashcode for this <code>PrincipalEntry</code>.
         *
         * <p>
         *
         * @return a hashcode for this <code>PrincipalEntry</code>.
         */
        public int hashCode() {
            return principalClass.hashCode();
        }
    }

    /**
     * Each permission entry in the policy configuration file is
     * represented by a
     * PermissionEntry object.  <p>
     *
     * <p>
     * For example, the entry
     * <pre>
     *          permission java.io.FilePermission "/tmp", "read,write";
     * </pre>
     * is represented internally
     * <pre>
     *
     * pe = new PermissionEntry("java.io.FilePermission",
     *                           "/tmp", "read,write");
     * </pre>
     *
     * @author Roland Schemers
     *
     * version 1.19, 05/21/98
     */

    static class PermissionEntry {

        public String permission;
        public String name;
        public String action;
        public String signedBy;

        public PermissionEntry() {
        }

        public PermissionEntry(String permission,
                        String name,
                        String action) {
            this.permission = permission;
            this.name = name;
            this.action = action;
        }

        /**
         * Calculates a hash code value for the object.  Objects
         * which are equal will also have the same hashcode.
         */
        public int hashCode() {
            int retval = permission.hashCode();
            if (name != null) retval ^= name.hashCode();
            if (action != null) retval ^= action.hashCode();
            return retval;
        }

        public boolean equals(Object obj) {
            if (obj == this)
                return true;

            if (! (obj instanceof PermissionEntry))
                return false;

            PermissionEntry that = (PermissionEntry) obj;

            if (this.permission == null) {
                if (that.permission != null) return false;
            } else {
                if (!this.permission.equals(that.permission)) return false;
            }

            if (this.name == null) {
                if (that.name != null) return false;
            } else {
                if (!this.name.equals(that.name)) return false;
            }

            if (this.action == null) {
                if (that.action != null) return false;
            } else {
                if (!this.action.equals(that.action)) return false;
            }

            if (this.signedBy == null) {
                if (that.signedBy != null) return false;
            } else {
                if (!this.signedBy.equals(that.signedBy)) return false;
            }

            // everything matched -- the 2 objects are equal
            return true;
        }

        public void write(PrintWriter out) {
            out.print("permission ");
            out.print(permission);
            if (name != null) {
                out.print(" \"");

                // have to add escape chars for quotes
                if (name.indexOf("\"") != -1) {
                    int numQuotes = 0;
                    char[] chars = name.toCharArray();

                    // count the number of quote chars
                    for (int i = 0; i < chars.length; i++) {
                        if (chars[i] == '"')
                            numQuotes++;
                    }

                    // now, add an escape char before each quote
                    char[] newChars = new char[chars.length + numQuotes];
                    for (int i = 0, j = 0; i < chars.length; i++) {
                        if (chars[i] != '"') {
                            newChars[j++] = chars[i];
                        } else {
                            newChars[j++] = '\\';
                            newChars[j++] = chars[i];
                        }
                    }
                    name = new String(newChars);
                }
                out.print(name);
                out.print('"');
            }
            if (action != null) {
                out.print(", \"");
                out.print(action);
                out.print('"');
            }
            if (signedBy != null) {
                out.print(", signedBy \"");
                out.print(signedBy);
                out.print('"');
            }
            out.println(";");
        }
    }

    static class ParsingException extends GeneralSecurityException {

        private static final long serialVersionUID = 8240970523155877400L;

        /**
         * Constructs a ParsingException with the specified
         * detail message. A detail message is a String that describes
         * this particular exception, which may, for example, specify which
         * algorithm is not available.
         *
         * @param msg the detail message.
         */
        public ParsingException(String msg) {
            super(msg);
        }

        public ParsingException(int line, String msg) {
            super(rb.getString("line ") + line + rb.getString(": ") + msg);
        }

        public ParsingException(int line, String expect, String actual) {
            super(rb.getString("line ") + line + rb.getString(": expected '") +
                expect + rb.getString("', found '") + actual +
                rb.getString("'"));
        }
    }

    public static void main(String arg[]) throws Exception {
        PolicyParser pp = new PolicyParser(true);
        pp.read(new FileReader(arg[0]));
        FileWriter fr = new FileWriter(arg[1]);
        pp.write(fr);
        fr.close();
    }
}
