Maven Optimizations + Fixes

This commit is contained in:
Gabriele C 2015-06-17 18:54:32 +02:00
parent 17e81aada3
commit b91ca908ec
232 changed files with 157 additions and 82601 deletions

129
.gitignore vendored
View File

@ -1,6 +1,125 @@
/target/
/bin/
/.settings/
.classpath
# Created by https://www.gitignore.io
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
#*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.project
/target/
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml
.nb-gradle/

33
pom.xml
View File

@ -120,6 +120,13 @@
</repository>
<!-- End of Spout Repo -->
<!-- Attribute Repo
<repository>
<id>comphenix-snapshots</id>
<name>Comphenix Maven Snapshots</name>
<url>http://repo.comphenix.net/content/repositories/snapshots/</url>
</repository> -->
</repositories>
<dependencies>
@ -147,6 +154,32 @@
<version>1.4.187</version>
</dependency>
<!-- Java Email API -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
</dependency>
<!-- Attribute, THIS DOESN?T WORK BECAUSE XEPHI USED A MODIFIED VERSION
<dependency>
<groupId>com.comphenix.attribute</groupId>
<artifactId>AttributeStorage</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency> -->
<!-- Maxmind GeoIp API -->
<dependency>
<groupId>com.maxmind.geoip</groupId>
<artifactId>geoip-api</artifactId>
<version>1.2.14</version>
</dependency>
<!-- Spigot-Api, http://www.spigotmc.org/
Based on the Bukkit project, http://bukkit.org/ -->
<dependency>

Binary file not shown.

View File

@ -1,61 +0,0 @@
/**
* Country.java
*
* Copyright (C) 2003 MaxMind LLC. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.maxmind.geoip;
/**
* Represents a country.
*
* @author Matt Tucker
*/
public class Country {
private String code;
private String name;
/**
* Creates a new Country.
*
* @param code the country code.
* @param name the country name.
*/
public Country(String code, String name) {
this.code = code;
this.name = name;
}
/**
* Returns the ISO two-letter country code of this country.
*
* @return the country code.
*/
public String getCode() {
return code;
}
/**
* Returns the name of this country.
*
* @return the country name.
*/
public String getName() {
return name;
}
}

View File

@ -1,117 +0,0 @@
/**
* DatabaseInfo.java
*
* Copyright (C) 2003 MaxMind LLC. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.maxmind.geoip;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Encapsulates metadata about the GeoIP database. The database has a date, is a premium or
* standard version, and is one of the following types:
*
* <ul>
* <li>Country edition -- this is the most common version of the database. It includes
* the name of the country and it's ISO country code given an IP address.
* <li>Region edition -- includes the country information as well as
* what U.S. state or Canadian province the IP address is from if the IP address
* is from the U.S. or Canada.
* <li>City edition -- includes country, region, city, postal code, latitude, and
* longitude information.
* <li>Org edition -- includes netblock owner.
* <li>ISP edition -- ISP information.
* </ul>
*
* @see com.maxmind.geoip.LookupService#getDatabaseInfo()
* @author Matt Tucker
*/
public class DatabaseInfo {
public final static int COUNTRY_EDITION = 1;
public final static int REGION_EDITION_REV0 = 7;
public final static int REGION_EDITION_REV1 = 3;
public final static int CITY_EDITION_REV0 = 6;
public final static int CITY_EDITION_REV1 = 2;
public final static int ORG_EDITION = 5;
public final static int ISP_EDITION = 4;
public final static int PROXY_EDITION = 8;
public final static int ASNUM_EDITION = 9;
public final static int NETSPEED_EDITION = 10;
public final static int COUNTRY_EDITION_V6 = 12;
private static SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
private String info;
/**
* Creates a new DatabaseInfo object given the database info String.
* @param info
*/
public DatabaseInfo(String info) {
this.info = info;
}
public int getType() {
if (info == null || info.equals("")) {
return COUNTRY_EDITION;
}
else {
// Get the type code from the database info string and then
// subtract 105 from the value to preserve compatability with
// databases from April 2003 and earlier.
return Integer.parseInt(info.substring(4, 7)) - 105;
}
}
/**
* Returns true if the database is the premium version.
*
* @return true if the premium version of the database.
*/
public boolean isPremium() {
return info.indexOf("FREE") < 0;
}
/**
* Returns the date of the database.
*
* @return the date of the database.
*/
public Date getDate() {
for (int i=0; i<info.length()-9; i++) {
if (Character.isWhitespace(info.charAt(i))) {
String dateString = info.substring(i+1, i+9);
try {
synchronized (formatter) {
return formatter.parse(dateString);
}
}
catch (ParseException pe) { }
break;
}
}
return null;
}
public String toString() {
return info;
}
}

View File

@ -1,504 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -1,60 +0,0 @@
/**
* Location.java
*
* Copyright (C) 2004 MaxMind LLC. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Lesser Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.maxmind.geoip;
public class Location {
public String countryCode;
public String countryName;
public String region;
public String city;
public String postalCode;
public float latitude;
public float longitude;
public int dma_code;
public int area_code;
public int metro_code;
private final static double EARTH_DIAMETER = 2 * 6378.2;
private final static double PI = 3.14159265;
private final static double RAD_CONVERT = PI / 180;
public double distance (Location loc) {
double delta_lat, delta_lon;
double temp;
float lat1 = latitude;
float lon1 = longitude;
float lat2 = loc.latitude;
float lon2 = loc.longitude;
// convert degrees to radians
lat1 *= RAD_CONVERT;
lat2 *= RAD_CONVERT;
// find the deltas
delta_lat = lat2 - lat1;
delta_lon = (lon2 - lon1) * RAD_CONVERT;
// Find the great circle distance
temp = Math.pow(Math.sin(delta_lat/2),2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(delta_lon/2),2);
return EARTH_DIAMETER * Math.atan2(Math.sqrt(temp),Math.sqrt(1-temp));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
package com.maxmind.geoip;
public class Region{
public String countryCode;
public String countryName;
public String region;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,295 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2005-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* Copied from OpenJDK with permission.
*/
package com.sun.mail.auth;
import java.security.*;
//import static sun.security.provider.ByteArrayAccess.*;
/**
* The MD4 class is used to compute an MD4 message digest over a given
* buffer of bytes. It is an implementation of the RSA Data Security Inc
* MD4 algorithim as described in internet RFC 1320.
*
* @author Andreas Sterbenz
* @author Bill Shannon (adapted for JavaMail)
*/
public final class MD4 {
// state of this object
private final int[] state;
// temporary buffer, used by implCompress()
private final int[] x;
// size of the input to the compression function in bytes
private static final int blockSize = 64;
// buffer to store partial blocks, blockSize bytes large
private final byte[] buffer = new byte[blockSize];
// offset into buffer
private int bufOfs;
// number of bytes processed so far.
// also used as a flag to indicate reset status
// -1: need to call engineReset() before next call to update()
// 0: is already reset
private long bytesProcessed;
// rotation constants
private static final int S11 = 3;
private static final int S12 = 7;
private static final int S13 = 11;
private static final int S14 = 19;
private static final int S21 = 3;
private static final int S22 = 5;
private static final int S23 = 9;
private static final int S24 = 13;
private static final int S31 = 3;
private static final int S32 = 9;
private static final int S33 = 11;
private static final int S34 = 15;
private static final byte[] padding;
static {
padding = new byte[136];
padding[0] = (byte)0x80;
}
// Standard constructor, creates a new MD4 instance.
public MD4() {
state = new int[4];
x = new int[16];
implReset();
}
/**
* Compute and return the message digest of the input byte array.
*/
public byte[] digest(byte[] in) {
implReset();
engineUpdate(in, 0, in.length);
byte[] out = new byte[16];
implDigest(out, 0);
return out;
}
/**
* Reset the state of this object.
*/
private void implReset() {
// Load magic initialization constants.
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
bufOfs = 0;
bytesProcessed = 0;
}
/**
* Perform the final computations, any buffered bytes are added
* to the digest, the count is added to the digest, and the resulting
* digest is stored.
*/
private void implDigest(byte[] out, int ofs) {
long bitsProcessed = bytesProcessed << 3;
int index = (int)bytesProcessed & 0x3f;
int padLen = (index < 56) ? (56 - index) : (120 - index);
engineUpdate(padding, 0, padLen);
//i2bLittle4((int)bitsProcessed, buffer, 56);
//i2bLittle4((int)(bitsProcessed >>> 32), buffer, 60);
buffer[56] = (byte)bitsProcessed;
buffer[57] = (byte)(bitsProcessed>>8);
buffer[58] = (byte)(bitsProcessed>>16);
buffer[59] = (byte)(bitsProcessed>>24);
buffer[60] = (byte)(bitsProcessed>>32);
buffer[61] = (byte)(bitsProcessed>>40);
buffer[62] = (byte)(bitsProcessed>>48);
buffer[63] = (byte)(bitsProcessed>>56);
implCompress(buffer, 0);
//i2bLittle(state, 0, out, ofs, 16);
for (int i = 0; i < state.length; i++) {
int x = state[i];
out[ofs++] = (byte)x;
out[ofs++] = (byte)(x>>8);
out[ofs++] = (byte)(x>>16);
out[ofs++] = (byte)(x>>24);
}
}
private void engineUpdate(byte[] b, int ofs, int len) {
if (len == 0) {
return;
}
if ((ofs < 0) || (len < 0) || (ofs > b.length - len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (bytesProcessed < 0) {
implReset();
}
bytesProcessed += len;
// if buffer is not empty, we need to fill it before proceeding
if (bufOfs != 0) {
int n = Math.min(len, blockSize - bufOfs);
System.arraycopy(b, ofs, buffer, bufOfs, n);
bufOfs += n;
ofs += n;
len -= n;
if (bufOfs >= blockSize) {
// compress completed block now
implCompress(buffer, 0);
bufOfs = 0;
}
}
// compress complete blocks
while (len >= blockSize) {
implCompress(b, ofs);
len -= blockSize;
ofs += blockSize;
}
// copy remainder to buffer
if (len > 0) {
System.arraycopy(b, ofs, buffer, 0, len);
bufOfs = len;
}
}
private static int FF(int a, int b, int c, int d, int x, int s) {
a += ((b & c) | ((~b) & d)) + x;
return ((a << s) | (a >>> (32 - s)));
}
private static int GG(int a, int b, int c, int d, int x, int s) {
a += ((b & c) | (b & d) | (c & d)) + x + 0x5a827999;
return ((a << s) | (a >>> (32 - s)));
}
private static int HH(int a, int b, int c, int d, int x, int s) {
a += ((b ^ c) ^ d) + x + 0x6ed9eba1;
return ((a << s) | (a >>> (32 - s)));
}
/**
* This is where the functions come together as the generic MD4
* transformation operation. It consumes 64
* bytes from the buffer, beginning at the specified offset.
*/
private void implCompress(byte[] buf, int ofs) {
//b2iLittle64(buf, ofs, x);
for (int xfs = 0; xfs < x.length; xfs++) {
x[xfs] = (buf[ofs] & 0xff) | ((buf[ofs+1] & 0xff) << 8) |
((buf[ofs+2] & 0xff) << 16) | ((buf[ofs+3] & 0xff) << 24);
ofs += 4;
}
int a = state[0];
int b = state[1];
int c = state[2];
int d = state[3];
/* Round 1 */
a = FF (a, b, c, d, x[ 0], S11); /* 1 */
d = FF (d, a, b, c, x[ 1], S12); /* 2 */
c = FF (c, d, a, b, x[ 2], S13); /* 3 */
b = FF (b, c, d, a, x[ 3], S14); /* 4 */
a = FF (a, b, c, d, x[ 4], S11); /* 5 */
d = FF (d, a, b, c, x[ 5], S12); /* 6 */
c = FF (c, d, a, b, x[ 6], S13); /* 7 */
b = FF (b, c, d, a, x[ 7], S14); /* 8 */
a = FF (a, b, c, d, x[ 8], S11); /* 9 */
d = FF (d, a, b, c, x[ 9], S12); /* 10 */
c = FF (c, d, a, b, x[10], S13); /* 11 */
b = FF (b, c, d, a, x[11], S14); /* 12 */
a = FF (a, b, c, d, x[12], S11); /* 13 */
d = FF (d, a, b, c, x[13], S12); /* 14 */
c = FF (c, d, a, b, x[14], S13); /* 15 */
b = FF (b, c, d, a, x[15], S14); /* 16 */
/* Round 2 */
a = GG (a, b, c, d, x[ 0], S21); /* 17 */
d = GG (d, a, b, c, x[ 4], S22); /* 18 */
c = GG (c, d, a, b, x[ 8], S23); /* 19 */
b = GG (b, c, d, a, x[12], S24); /* 20 */
a = GG (a, b, c, d, x[ 1], S21); /* 21 */
d = GG (d, a, b, c, x[ 5], S22); /* 22 */
c = GG (c, d, a, b, x[ 9], S23); /* 23 */
b = GG (b, c, d, a, x[13], S24); /* 24 */
a = GG (a, b, c, d, x[ 2], S21); /* 25 */
d = GG (d, a, b, c, x[ 6], S22); /* 26 */
c = GG (c, d, a, b, x[10], S23); /* 27 */
b = GG (b, c, d, a, x[14], S24); /* 28 */
a = GG (a, b, c, d, x[ 3], S21); /* 29 */
d = GG (d, a, b, c, x[ 7], S22); /* 30 */
c = GG (c, d, a, b, x[11], S23); /* 31 */
b = GG (b, c, d, a, x[15], S24); /* 32 */
/* Round 3 */
a = HH (a, b, c, d, x[ 0], S31); /* 33 */
d = HH (d, a, b, c, x[ 8], S32); /* 34 */
c = HH (c, d, a, b, x[ 4], S33); /* 35 */
b = HH (b, c, d, a, x[12], S34); /* 36 */
a = HH (a, b, c, d, x[ 2], S31); /* 37 */
d = HH (d, a, b, c, x[10], S32); /* 38 */
c = HH (c, d, a, b, x[ 6], S33); /* 39 */
b = HH (b, c, d, a, x[14], S34); /* 40 */
a = HH (a, b, c, d, x[ 1], S31); /* 41 */
d = HH (d, a, b, c, x[ 9], S32); /* 42 */
c = HH (c, d, a, b, x[ 5], S33); /* 43 */
b = HH (b, c, d, a, x[13], S34); /* 44 */
a = HH (a, b, c, d, x[ 3], S31); /* 45 */
d = HH (d, a, b, c, x[11], S32); /* 46 */
c = HH (c, d, a, b, x[ 7], S33); /* 47 */
b = HH (b, c, d, a, x[15], S34); /* 48 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
}

View File

@ -1,361 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2005-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* Copied from OpenJDK with permission.
*/
package com.sun.mail.auth;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.PrintStream;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;
import java.util.logging.Level;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import com.sun.mail.util.BASE64DecoderStream;
import com.sun.mail.util.BASE64EncoderStream;
import com.sun.mail.util.MailLogger;
/**
* NTLMAuthentication:
*
* @author Michael McMahon
* @author Bill Shannon (adapted for JavaMail)
*/
public class Ntlm {
private byte[] type1;
private byte[] type3;
private SecretKeyFactory fac;
private Cipher cipher;
private MD4 md4;
private String hostname;
private String ntdomain;
private String username;
private String password;
private MailLogger logger;
private void init0() {
type1 = new byte[256];
type3 = new byte[256];
System.arraycopy(new byte[] {'N','T','L','M','S','S','P',0,1}, 0,
type1, 0, 9);
type1[12] = (byte) 3;
type1[13] = (byte) 0xb2;
type1[28] = (byte) 0x20;
System.arraycopy(new byte[] {'N','T','L','M','S','S','P',0,3}, 0,
type3, 0, 9);
type3[12] = (byte) 0x18;
type3[14] = (byte) 0x18;
type3[20] = (byte) 0x18;
type3[22] = (byte) 0x18;
type3[32] = (byte) 0x40;
type3[60] = (byte) 1;
type3[61] = (byte) 0x82;
try {
fac = SecretKeyFactory.getInstance("DES");
cipher = Cipher.getInstance("DES/ECB/NoPadding");
md4 = new MD4();
} catch (NoSuchPaddingException e) {
assert false;
} catch (NoSuchAlgorithmException e) {
assert false;
}
};
/**
* Create an NTLM authenticator.
* Username may be specified as domain\\username in the Authenticator.
* If this notation is not used, then the domain will be taken
* from the ntdomain parameter.
*/
public Ntlm(String ntdomain, String hostname, String username,
String password, MailLogger logger) {
int i = hostname.indexOf('.');
if (i != -1) {
hostname = hostname.substring(0, i);
}
i = username.indexOf('\\');
if (i != -1) {
ntdomain = username.substring(0, i).toUpperCase();
username = username.substring(i+1);
} else if (ntdomain == null) {
ntdomain = "";
}
this.ntdomain = ntdomain;
this.hostname = hostname;
this.username = username;
this.password = password;
this.logger = logger.getLogger(this.getClass(), "DEBUG NTLM");
init0();
}
private void copybytes(byte[] dest, int destpos, String src, String enc) {
try {
byte[] x = src.getBytes(enc);
System.arraycopy(x, 0, dest, destpos, x.length);
} catch (UnsupportedEncodingException e) {
assert false;
}
}
public String generateType1Msg(int flags) {
// XXX - should set "flags" in generated message
int dlen = ntdomain.length();
type1[16]= (byte) (dlen % 256);
type1[17]= (byte) (dlen / 256);
type1[18] = type1[16];
type1[19] = type1[17];
if (dlen == 0)
type1[13] &= ~0x10;
int hlen = hostname.length();
type1[24]= (byte) (hlen % 256);
type1[25]= (byte) (hlen / 256);
type1[26] = type1[24];
type1[27] = type1[25];
copybytes(type1, 32, hostname, "iso-8859-1");
copybytes(type1, hlen+32, ntdomain, "iso-8859-1");
type1[20] = (byte) ((hlen+32) % 256);
type1[21] = (byte) ((hlen+32) / 256);
byte[] msg = new byte[32 + hlen + dlen];
System.arraycopy(type1, 0, msg, 0, 32 + hlen + dlen);
if (logger.isLoggable(Level.FINE))
logger.fine("type 1 message: " + toHex(msg));
String result = null;
try {
result = new String(BASE64EncoderStream.encode(msg), "iso-8859-1");
} catch (UnsupportedEncodingException e) {
assert false;
}
return result;
}
/**
* Convert a 7 byte array to an 8 byte array (for a des key with parity).
* Input starts at offset off.
*/
private byte[] makeDesKey(byte[] input, int off) {
int[] in = new int[input.length];
for (int i = 0; i < in.length; i++) {
in[i] = input[i] < 0 ? input[i] + 256: input[i];
}
byte[] out = new byte[8];
out[0] = (byte)in[off+0];
out[1] = (byte)(((in[off+0] << 7) & 0xFF) | (in[off+1] >> 1));
out[2] = (byte)(((in[off+1] << 6) & 0xFF) | (in[off+2] >> 2));
out[3] = (byte)(((in[off+2] << 5) & 0xFF) | (in[off+3] >> 3));
out[4] = (byte)(((in[off+3] << 4) & 0xFF) | (in[off+4] >> 4));
out[5] = (byte)(((in[off+4] << 3) & 0xFF) | (in[off+5] >> 5));
out[6] = (byte)(((in[off+5] << 2) & 0xFF) | (in[off+6] >> 6));
out[7] = (byte)((in[off+6] << 1) & 0xFF);
return out;
}
private byte[] calcLMHash() throws GeneralSecurityException {
byte[] magic = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
byte[] pwb = null;
try {
pwb = password.toUpperCase(Locale.ENGLISH).getBytes("iso-8859-1");
} catch (UnsupportedEncodingException ex) {
// should never happen
assert false;
}
byte[] pwb1 = new byte[14];
int len = password.length();
if (len > 14)
len = 14;
System.arraycopy(pwb, 0, pwb1, 0, len); /* Zero padded */
DESKeySpec dks1 = new DESKeySpec(makeDesKey(pwb1, 0));
DESKeySpec dks2 = new DESKeySpec(makeDesKey(pwb1, 7));
SecretKey key1 = fac.generateSecret(dks1);
SecretKey key2 = fac.generateSecret(dks2);
cipher.init(Cipher.ENCRYPT_MODE, key1);
byte[] out1 = cipher.doFinal(magic, 0, 8);
cipher.init(Cipher.ENCRYPT_MODE, key2);
byte[] out2 = cipher.doFinal(magic, 0, 8);
byte[] result = new byte [21];
System.arraycopy(out1, 0, result, 0, 8);
System.arraycopy(out2, 0, result, 8, 8);
return result;
}
private byte[] calcNTHash() throws GeneralSecurityException {
byte[] pw = null;
try {
pw = password.getBytes("UnicodeLittleUnmarked");
} catch (UnsupportedEncodingException e) {
assert false;
}
byte[] out = md4.digest(pw);
byte[] result = new byte[21];
System.arraycopy(out, 0, result, 0, 16);
return result;
}
/*
* Key is a 21 byte array. Split it into 3 7 byte chunks,
* convert each to 8 byte DES keys, encrypt the text arg with
* each key and return the three results in a sequential [].
*/
private byte[] calcResponse(byte[] key, byte[] text)
throws GeneralSecurityException {
assert key.length == 21;
DESKeySpec dks1 = new DESKeySpec(makeDesKey(key, 0));
DESKeySpec dks2 = new DESKeySpec(makeDesKey(key, 7));
DESKeySpec dks3 = new DESKeySpec(makeDesKey(key, 14));
SecretKey key1 = fac.generateSecret(dks1);
SecretKey key2 = fac.generateSecret(dks2);
SecretKey key3 = fac.generateSecret(dks3);
cipher.init(Cipher.ENCRYPT_MODE, key1);
byte[] out1 = cipher.doFinal(text, 0, 8);
cipher.init(Cipher.ENCRYPT_MODE, key2);
byte[] out2 = cipher.doFinal(text, 0, 8);
cipher.init(Cipher.ENCRYPT_MODE, key3);
byte[] out3 = cipher.doFinal(text, 0, 8);
byte[] result = new byte[24];
System.arraycopy(out1, 0, result, 0, 8);
System.arraycopy(out2, 0, result, 8, 8);
System.arraycopy(out3, 0, result, 16, 8);
return result;
}
public String generateType3Msg(String challenge) {
try {
/* First decode the type2 message to get the server nonce */
/* nonce is located at type2[24] for 8 bytes */
byte[] type2 = null;
try {
type2 = BASE64DecoderStream.decode(challenge.getBytes("us-ascii"));
} catch (UnsupportedEncodingException ex) {
// should never happen
assert false;
}
byte[] nonce = new byte[8];
System.arraycopy(type2, 24, nonce, 0, 8);
int ulen = username.length()*2;
type3[36] = type3[38] = (byte) (ulen % 256);
type3[37] = type3[39] = (byte) (ulen / 256);
int dlen = ntdomain.length()*2;
type3[28] = type3[30] = (byte) (dlen % 256);
type3[29] = type3[31] = (byte) (dlen / 256);
int hlen = hostname.length()*2;
type3[44] = type3[46] = (byte) (hlen % 256);
type3[45] = type3[47] = (byte) (hlen / 256);
int l = 64;
copybytes(type3, l, ntdomain, "UnicodeLittleUnmarked");
type3[32] = (byte) (l % 256);
type3[33] = (byte) (l / 256);
l += dlen;
copybytes(type3, l, username, "UnicodeLittleUnmarked");
type3[40] = (byte) (l % 256);
type3[41] = (byte) (l / 256);
l += ulen;
copybytes(type3, l, hostname, "UnicodeLittleUnmarked");
type3[48] = (byte) (l % 256);
type3[49] = (byte) (l / 256);
l += hlen;
byte[] lmhash = calcLMHash();
byte[] lmresponse = calcResponse(lmhash, nonce);
byte[] nthash = calcNTHash();
byte[] ntresponse = calcResponse(nthash, nonce);
System.arraycopy(lmresponse, 0, type3, l, 24);
type3[16] = (byte) (l % 256);
type3[17] = (byte) (l / 256);
l += 24;
System.arraycopy(ntresponse, 0, type3, l, 24);
type3[24] = (byte) (l % 256);
type3[25] = (byte) (l / 256);
l += 24;
type3[56] = (byte) (l % 256);
type3[57] = (byte) (l / 256);
byte[] msg = new byte[l];
System.arraycopy(type3, 0, msg, 0, l);
if (logger.isLoggable(Level.FINE))
logger.fine("type 3 message: " + toHex(msg));
String result = null;
try {
result = new String(BASE64EncoderStream.encode(msg), "iso-8859-1");
} catch (UnsupportedEncodingException e) {
assert false;
}
return result;
} catch (GeneralSecurityException ex) {
// should never happen
logger.log(Level.FINE, "GeneralSecurityException", ex);
return ""; // will fail later
}
}
private static char[] hex =
{ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
private static String toHex(byte[] b) {
StringBuffer sb = new StringBuffer(b.length * 3);
for (int i = 0; i < b.length; i++)
sb.append(hex[(b[i]>>4)&0xF]).append(hex[b[i]&0xF]).append(' ');
return sb.toString();
}
}

View File

@ -1,123 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.handlers;
import java.io.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import javax.activation.*;
import javax.mail.internet.*;
/**
* DataContentHandler for image/gif.
*/
public class image_gif implements DataContentHandler {
private static ActivationDataFlavor myDF = new ActivationDataFlavor(
java.awt.Image.class,
"image/gif",
"GIF Image");
protected ActivationDataFlavor getDF() {
return myDF;
}
/**
* Return the DataFlavors for this <code>DataContentHandler</code>.
*
* @return The DataFlavors
*/
public DataFlavor[] getTransferDataFlavors() { // throws Exception;
return new DataFlavor[] { getDF() };
}
/**
* Return the Transfer Data of type DataFlavor from InputStream.
*
* @param df The DataFlavor
* @param ds The DataSource corresponding to the data
* @return String object
*/
public Object getTransferData(DataFlavor df, DataSource ds)
throws IOException {
// use myDF.equals to be sure to get ActivationDataFlavor.equals,
// which properly ignores Content-Type parameters in comparison
if (getDF().equals(df))
return getContent(ds);
else
return null;
}
public Object getContent(DataSource ds) throws IOException {
InputStream is = ds.getInputStream();
int pos = 0;
int count;
byte buf[] = new byte[1024];
while ((count = is.read(buf, pos, buf.length - pos)) != -1) {
pos += count;
if (pos >= buf.length) {
int size = buf.length;
if (size < 256*1024)
size += size;
else
size += 256*1024;
byte tbuf[] = new byte[size];
System.arraycopy(buf, 0, tbuf, 0, pos);
buf = tbuf;
}
}
Toolkit tk = Toolkit.getDefaultToolkit();
return tk.createImage(buf, 0, pos);
}
/**
* Write the object to the output stream, using the specified MIME type.
*/
public void writeTo(Object obj, String type, OutputStream os)
throws IOException {
if (!(obj instanceof Image))
throw new IOException("\"" + getDF().getMimeType() +
"\" DataContentHandler requires Image object, " +
"was given object of type " + obj.getClass().toString());
throw new IOException(getDF().getMimeType() + " encoding not supported");
}
}

View File

@ -1,58 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.handlers;
import java.awt.datatransfer.DataFlavor;
import javax.activation.*;
/**
* DataContentHandler for image/jpeg.
*/
public class image_jpeg extends image_gif {
private static ActivationDataFlavor myDF = new ActivationDataFlavor(
java.awt.Image.class,
"image/jpeg",
"JPEG Image");
protected ActivationDataFlavor getDF() {
return myDF;
}
}

View File

@ -1,130 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.handlers;
import java.io.*;
import java.util.Properties;
import java.awt.datatransfer.DataFlavor;
import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
/**
* @author Christopher Cotton
*/
public class message_rfc822 implements DataContentHandler {
ActivationDataFlavor ourDataFlavor = new ActivationDataFlavor(
javax.mail.Message.class,
"message/rfc822",
"Message");
/**
* return the DataFlavors for this <code>DataContentHandler</code>
* @return The DataFlavors.
*/
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { ourDataFlavor };
}
/**
* return the Transfer Data of type DataFlavor from InputStream
* @param df The DataFlavor.
* @param ds The DataSource corresponding to the data
* @return a Message object
*/
public Object getTransferData(DataFlavor df, DataSource ds)
throws IOException {
// make sure we can handle this DataFlavor
if (ourDataFlavor.equals(df))
return getContent(ds);
else
return null;
}
/**
* Return the content.
*/
public Object getContent(DataSource ds) throws IOException {
// create a new MimeMessage
try {
Session session;
if (ds instanceof MessageAware) {
MessageContext mc = ((MessageAware)ds).getMessageContext();
session = mc.getSession();
} else {
// Hopefully a rare case. Also hopefully the application
// has created a default Session that can just be returned
// here. If not, the one we create here is better than
// nothing, but overall not a really good answer.
session = Session.getDefaultInstance(new Properties(), null);
}
return new MimeMessage(session, ds.getInputStream());
} catch (MessagingException me) {
throw new IOException("Exception creating MimeMessage in " +
"message/rfc822 DataContentHandler: " + me.toString());
}
}
/**
* construct an object from a byte stream
* (similar semantically to previous method, we are deciding
* which one to support)
*/
public void writeTo(Object obj, String mimeType, OutputStream os)
throws IOException {
// if the object is a message, we know how to write that out
if (obj instanceof Message) {
Message m = (Message)obj;
try {
m.writeTo(os);
} catch (MessagingException me) {
throw new IOException(me.toString());
}
} else {
throw new IOException("unsupported object");
}
}
}

View File

@ -1,109 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.handlers;
import java.io.*;
import java.awt.datatransfer.DataFlavor;
import javax.activation.*;
import javax.mail.MessagingException;
import javax.mail.internet.*;
public class multipart_mixed implements DataContentHandler {
private ActivationDataFlavor myDF = new ActivationDataFlavor(
javax.mail.internet.MimeMultipart.class,
"multipart/mixed",
"Multipart");
/**
* Return the DataFlavors for this <code>DataContentHandler</code>.
*
* @return The DataFlavors
*/
public DataFlavor[] getTransferDataFlavors() { // throws Exception;
return new DataFlavor[] { myDF };
}
/**
* Return the Transfer Data of type DataFlavor from InputStream.
*
* @param df The DataFlavor
* @param ds The DataSource corresponding to the data
* @return String object
*/
public Object getTransferData(DataFlavor df, DataSource ds)
throws IOException {
// use myDF.equals to be sure to get ActivationDataFlavor.equals,
// which properly ignores Content-Type parameters in comparison
if (myDF.equals(df))
return getContent(ds);
else
return null;
}
/**
* Return the content.
*/
public Object getContent(DataSource ds) throws IOException {
try {
return new MimeMultipart(ds);
} catch (MessagingException e) {
IOException ioex =
new IOException("Exception while constructing MimeMultipart");
ioex.initCause(e);
throw ioex;
}
}
/**
* Write the object to the output stream, using the specific MIME type.
*/
public void writeTo(Object obj, String mimeType, OutputStream os)
throws IOException {
if (obj instanceof MimeMultipart) {
try {
((MimeMultipart)obj).writeTo(os);
} catch (MessagingException e) {
throw new IOException(e.toString());
}
}
}
}

View File

@ -1,58 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.handlers;
import javax.activation.ActivationDataFlavor;
/**
* DataContentHandler for text/html.
*
*/
public class text_html extends text_plain {
private static ActivationDataFlavor myDF = new ActivationDataFlavor(
java.lang.String.class,
"text/html",
"HTML String");
protected ActivationDataFlavor getDF() {
return myDF;
}
}

View File

@ -1,198 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.handlers;
import java.io.*;
import java.awt.datatransfer.DataFlavor;
import javax.activation.*;
import javax.mail.internet.*;
/**
* DataContentHandler for text/plain.
*
*/
public class text_plain implements DataContentHandler {
private static ActivationDataFlavor myDF = new ActivationDataFlavor(
java.lang.String.class,
"text/plain",
"Text String");
/**
* An OuputStream wrapper that doesn't close the underlying stream.
*/
private static class NoCloseOutputStream extends FilterOutputStream {
public NoCloseOutputStream(OutputStream os) {
super(os);
}
public void close() {
// do nothing
}
}
protected ActivationDataFlavor getDF() {
return myDF;
}
/**
* Return the DataFlavors for this <code>DataContentHandler</code>.
*
* @return The DataFlavors
*/
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { getDF() };
}
/**
* Return the Transfer Data of type DataFlavor from InputStream.
*
* @param df The DataFlavor
* @param ds The DataSource corresponding to the data
* @return String object
*/
public Object getTransferData(DataFlavor df, DataSource ds)
throws IOException {
// use myDF.equals to be sure to get ActivationDataFlavor.equals,
// which properly ignores Content-Type parameters in comparison
if (getDF().equals(df))
return getContent(ds);
else
return null;
}
public Object getContent(DataSource ds) throws IOException {
String enc = null;
InputStreamReader is = null;
try {
enc = getCharset(ds.getContentType());
is = new InputStreamReader(ds.getInputStream(), enc);
} catch (IllegalArgumentException iex) {
/*
* An unknown charset of the form ISO-XXX-XXX will cause
* the JDK to throw an IllegalArgumentException. The
* JDK will attempt to create a classname using this string,
* but valid classnames must not contain the character '-',
* and this results in an IllegalArgumentException, rather than
* the expected UnsupportedEncodingException. Yikes.
*/
throw new UnsupportedEncodingException(enc);
}
try {
int pos = 0;
int count;
char buf[] = new char[1024];
while ((count = is.read(buf, pos, buf.length - pos)) != -1) {
pos += count;
if (pos >= buf.length) {
int size = buf.length;
if (size < 256*1024)
size += size;
else
size += 256*1024;
char tbuf[] = new char[size];
System.arraycopy(buf, 0, tbuf, 0, pos);
buf = tbuf;
}
}
return new String(buf, 0, pos);
} finally {
try {
is.close();
} catch (IOException ex) { }
}
}
/**
* Write the object to the output stream, using the specified MIME type.
*/
public void writeTo(Object obj, String type, OutputStream os)
throws IOException {
if (!(obj instanceof String))
throw new IOException("\"" + getDF().getMimeType() +
"\" DataContentHandler requires String object, " +
"was given object of type " + obj.getClass().toString());
String enc = null;
OutputStreamWriter osw = null;
try {
enc = getCharset(type);
osw = new OutputStreamWriter(new NoCloseOutputStream(os), enc);
} catch (IllegalArgumentException iex) {
/*
* An unknown charset of the form ISO-XXX-XXX will cause
* the JDK to throw an IllegalArgumentException. The
* JDK will attempt to create a classname using this string,
* but valid classnames must not contain the character '-',
* and this results in an IllegalArgumentException, rather than
* the expected UnsupportedEncodingException. Yikes.
*/
throw new UnsupportedEncodingException(enc);
}
String s = (String)obj;
osw.write(s, 0, s.length());
/*
* Have to call osw.close() instead of osw.flush() because
* some charset converts, such as the iso-2022-jp converter,
* don't output the "shift out" sequence unless they're closed.
* The NoCloseOutputStream wrapper prevents the underlying
* stream from being closed.
*/
osw.close();
}
private String getCharset(String type) {
try {
ContentType ct = new ContentType(type);
String charset = ct.getParameter("charset");
if (charset == null)
// If the charset parameter is absent, use US-ASCII.
charset = "us-ascii";
return MimeUtility.javaCharset(charset);
} catch (Exception ex) {
return null;
}
}
}

View File

@ -1,157 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.handlers;
import java.awt.datatransfer.DataFlavor;
import java.io.IOException;
import java.io.OutputStream;
import javax.activation.ActivationDataFlavor;
import javax.activation.DataContentHandler;
import javax.activation.DataSource;
import javax.mail.internet.ContentType;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
/**
* DataContentHandler for text/xml.
*
* @author Anil Vijendran
* @author Bill Shannon
*/
public class text_xml extends text_plain {
private final DataFlavor[] flavors;
public text_xml() {
flavors = new DataFlavor[] {
new ActivationDataFlavor(String.class, "text/xml", "XML String"),
new ActivationDataFlavor(String.class, "application/xml",
"XML String"),
new ActivationDataFlavor(StreamSource.class, "text/xml", "XML"),
new ActivationDataFlavor(StreamSource.class, "application/xml",
"XML")
};
}
/**
* Return the DataFlavors for this <code>DataContentHandler</code>.
*
* @return the DataFlavors
*/
public DataFlavor[] getTransferDataFlavors() { // throws Exception;
return (DataFlavor[])flavors.clone();
}
/**
* Return the Transfer Data of type DataFlavor from InputStream.
*
* @param df the DataFlavor
* @param ds the InputStream corresponding to the data
* @return the constructed Object
*/
public Object getTransferData(DataFlavor df, DataSource ds)
throws IOException {
for (int i = 0; i < flavors.length; i++) {
DataFlavor aFlavor = flavors[i];
if (aFlavor.equals(df)) {
if (aFlavor.getRepresentationClass() == String.class)
return super.getContent(ds);
else if (aFlavor.getRepresentationClass() == StreamSource.class)
return new StreamSource(ds.getInputStream());
else
return null; // XXX - should never happen
}
}
return null;
}
/**
*/
public void writeTo(Object obj, String mimeType, OutputStream os)
throws IOException {
if (!isXmlType(mimeType))
throw new IOException(
"Invalid content type \"" + mimeType + "\" for text/xml DCH");
if (obj instanceof String) {
super.writeTo(obj, mimeType, os);
return;
}
if (!(obj instanceof DataSource || obj instanceof Source)) {
throw new IOException("Invalid Object type = "+obj.getClass()+
". XmlDCH can only convert DataSource or Source to XML.");
}
try {
Transformer transformer =
TransformerFactory.newInstance().newTransformer();
StreamResult result = new StreamResult(os);
if (obj instanceof DataSource) {
// Streaming transform applies only to
// javax.xml.transform.StreamSource
transformer.transform(
new StreamSource(((DataSource)obj).getInputStream()),
result);
} else {
transformer.transform((Source)obj, result);
}
} catch (Exception ex) {
throw new IOException(
"Unable to run the JAXP transformer on a stream "
+ ex.getMessage());
}
}
private boolean isXmlType(String type) {
try {
ContentType ct = new ContentType(type);
return ct.getSubType().equals("xml") &&
(ct.getPrimaryType().equals("text") ||
ct.getPrimaryType().equals("application"));
} catch (Exception ex) {
return false;
}
}
}

View File

@ -1,308 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
import java.util.Vector;
import java.io.*;
import com.sun.mail.util.*;
/**
* @author John Mani
*/
public class Argument {
protected Vector items;
/**
* Constructor
*/
public Argument() {
items = new Vector(1);
}
/**
* append the given Argument to this Argument. All items
* from the source argument are copied into this destination
* argument.
*/
public void append(Argument arg) {
items.ensureCapacity(items.size() + arg.items.size());
for (int i=0; i < arg.items.size(); i++)
items.addElement(arg.items.elementAt(i));
}
/**
* Write out given string as an ASTRING, depending on the type
* of the characters inside the string. The string should
* contain only ASCII characters. <p>
*
* XXX: Hmm .. this should really be called writeASCII()
*
* @param s String to write out
*/
public void writeString(String s) {
items.addElement(new AString(ASCIIUtility.getBytes(s)));
}
/**
* Convert the given string into bytes in the specified
* charset, and write the bytes out as an ASTRING
*/
public void writeString(String s, String charset)
throws UnsupportedEncodingException {
if (charset == null) // convenience
writeString(s);
else
items.addElement(new AString(s.getBytes(charset)));
}
/**
* Write out given byte[] as a Literal.
* @param b byte[] to write out
*/
public void writeBytes(byte[] b) {
items.addElement(b);
}
/**
* Write out given ByteArrayOutputStream as a Literal.
* @param b ByteArrayOutputStream to be written out.
*/
public void writeBytes(ByteArrayOutputStream b) {
items.addElement(b);
}
/**
* Write out given data as a literal.
* @param b Literal representing data to be written out.
*/
public void writeBytes(Literal b) {
items.addElement(b);
}
/**
* Write out given string as an Atom. Note that an Atom can contain only
* certain US-ASCII characters. No validation is done on the characters
* in the string.
* @param s String
*/
public void writeAtom(String s) {
items.addElement(new Atom(s));
}
/**
* Write out number.
* @param i number
*/
public void writeNumber(int i) {
items.addElement(new Integer(i));
}
/**
* Write out number.
* @param i number
*/
public void writeNumber(long i) {
items.addElement(new Long(i));
}
/**
* Write out as parenthesised list.
*/
public void writeArgument(Argument c) {
items.addElement(c);
}
/*
* Write out all the buffered items into the output stream.
*/
public void write(Protocol protocol)
throws IOException, ProtocolException {
int size = items != null ? items.size() : 0;
DataOutputStream os = (DataOutputStream)protocol.getOutputStream();
for (int i=0; i < size; i++) {
if (i > 0) // write delimiter if not the first item
os.write(' ');
Object o = items.elementAt(i);
if (o instanceof Atom) {
os.writeBytes(((Atom)o).string);
} else if (o instanceof Number) {
os.writeBytes(((Number)o).toString());
} else if (o instanceof AString) {
astring(((AString)o).bytes, protocol);
} else if (o instanceof byte[]) {
literal((byte[])o, protocol);
} else if (o instanceof ByteArrayOutputStream) {
literal((ByteArrayOutputStream)o, protocol);
} else if (o instanceof Literal) {
literal((Literal)o, protocol);
} else if (o instanceof Argument) {
os.write('('); // open parans
((Argument)o).write(protocol);
os.write(')'); // close parans
}
}
}
/**
* Write out given String as either an Atom, QuotedString or Literal
*/
private void astring(byte[] bytes, Protocol protocol)
throws IOException, ProtocolException {
DataOutputStream os = (DataOutputStream)protocol.getOutputStream();
int len = bytes.length;
// If length is greater than 1024 bytes, send as literal
if (len > 1024) {
literal(bytes, protocol);
return;
}
// if 0 length, send as quoted-string
boolean quote = len == 0 ? true: false;
boolean escape = false;
byte b;
for (int i = 0; i < len; i++) {
b = bytes[i];
if (b == '\0' || b == '\r' || b == '\n' || ((b & 0xff) > 0177)) {
// NUL, CR or LF means the bytes need to be sent as literals
literal(bytes, protocol);
return;
}
if (b == '*' || b == '%' || b == '(' || b == ')' || b == '{' ||
b == '"' || b == '\\' || ((b & 0xff) <= ' ')) {
quote = true;
if (b == '"' || b == '\\') // need to escape these characters
escape = true;
}
}
if (quote) // start quote
os.write('"');
if (escape) {
// already quoted
for (int i = 0; i < len; i++) {
b = bytes[i];
if (b == '"' || b == '\\')
os.write('\\');
os.write(b);
}
} else
os.write(bytes);
if (quote) // end quote
os.write('"');
}
/**
* Write out given byte[] as a literal
*/
private void literal(byte[] b, Protocol protocol)
throws IOException, ProtocolException {
startLiteral(protocol, b.length).write(b);
}
/**
* Write out given ByteArrayOutputStream as a literal.
*/
private void literal(ByteArrayOutputStream b, Protocol protocol)
throws IOException, ProtocolException {
b.writeTo(startLiteral(protocol, b.size()));
}
/**
* Write out given Literal as a literal.
*/
private void literal(Literal b, Protocol protocol)
throws IOException, ProtocolException {
b.writeTo(startLiteral(protocol, b.size()));
}
private OutputStream startLiteral(Protocol protocol, int size)
throws IOException, ProtocolException {
DataOutputStream os = (DataOutputStream)protocol.getOutputStream();
boolean nonSync = protocol.supportsNonSyncLiterals();
os.write('{');
os.writeBytes(Integer.toString(size));
if (nonSync) // server supports non-sync literals
os.writeBytes("+}\r\n");
else
os.writeBytes("}\r\n");
os.flush();
// If we are using synchronized literals, wait for the server's
// continuation signal
if (!nonSync) {
for (; ;) {
Response r = protocol.readResponse();
if (r.isContinuation())
break;
if (r.isTagged())
throw new LiteralException(r);
// XXX - throw away untagged responses;
// violates IMAP spec, hope no servers do this
}
}
return os;
}
}
class Atom {
String string;
Atom(String s) {
string = s;
}
}
class AString {
byte[] bytes;
AString(byte[] b) {
bytes = b;
}
}

View File

@ -1,73 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
/**
* @author John Mani
*/
public class BadCommandException extends ProtocolException {
private static final long serialVersionUID = 5769722539397237515L;
/**
* Constructs an BadCommandException with no detail message.
*/
public BadCommandException() {
super();
}
/**
* Constructs an BadCommandException with the specified detail message.
* @param s the detail message
*/
public BadCommandException(String s) {
super(s);
}
/**
* Constructs an BadCommandException with the specified Response.
* @param r the Response
*/
public BadCommandException(Response r) {
super(r);
}
}

View File

@ -1,132 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
import java.io.ByteArrayInputStream;
/**
* A simple wrapper around a byte array, with a start position and
* count of bytes.
*
* @author John Mani
*/
public class ByteArray {
private byte[] bytes; // the byte array
private int start; // start position
private int count; // count of bytes
/**
* Constructor
*/
public ByteArray(byte[] b, int start, int count) {
bytes = b;
this.start = start;
this.count = count;
}
/**
* Constructor that creates a byte array of the specified size.
*
* @since JavaMail 1.4.1
*/
public ByteArray(int size) {
this(new byte[size], 0, size);
}
/**
* Returns the internal byte array. Note that this is a live
* reference to the actual data, not a copy.
*/
public byte[] getBytes() {
return bytes;
}
/**
* Returns a new byte array that is a copy of the data.
*/
public byte[] getNewBytes() {
byte[] b = new byte[count];
System.arraycopy(bytes, start, b, 0, count);
return b;
}
/**
* Returns the start position
*/
public int getStart() {
return start;
}
/**
* Returns the count of bytes
*/
public int getCount() {
return count;
}
/**
* Set the count of bytes.
*
* @since JavaMail 1.4.1
*/
public void setCount(int count) {
this.count = count;
}
/**
* Returns a ByteArrayInputStream.
*/
public ByteArrayInputStream toByteArrayInputStream() {
return new ByteArrayInputStream(bytes, start, count);
}
/**
* Grow the byte array by incr bytes.
*
* @since JavaMail 1.4.1
*/
public void grow(int incr) {
byte[] nbuf = new byte[bytes.length + incr];
System.arraycopy(bytes, 0, nbuf, 0, bytes.length);
bytes = nbuf;
}
}

View File

@ -1,73 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
/**
* @author John Mani
*/
public class CommandFailedException extends ProtocolException {
private static final long serialVersionUID = 793932807880443631L;
/**
* Constructs an CommandFailedException with no detail message.
*/
public CommandFailedException() {
super();
}
/**
* Constructs an CommandFailedException with the specified detail message.
* @param s the detail message
*/
public CommandFailedException(String s) {
super(s);
}
/**
* Constructs an CommandFailedException with the specified Response.
* @param r the Response.
*/
public CommandFailedException(Response r) {
super(r);
}
}

View File

@ -1,79 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
/**
* @author John Mani
*/
public class ConnectionException extends ProtocolException {
private transient Protocol p;
private static final long serialVersionUID = 5749739604257464727L;
/**
* Constructs an ConnectionException with no detail message.
*/
public ConnectionException() {
super();
}
/**
* Constructs an ConnectionException with the specified detail message.
* @param s the detail message
*/
public ConnectionException(String s) {
super(s);
}
/**
* Constructs an ConnectionException with the specified Response.
* @param r the Response
*/
public ConnectionException(Protocol p, Response r) {
super(r);
this.p = p;
}
public Protocol getProtocol() {
return p;
}
}

View File

@ -1,62 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
import java.io.*;
/**
* An interface for objects that provide data dynamically for use in
* a literal protocol element.
*
* @author Bill Shannon
*/
public interface Literal {
/**
* Return the size of the data.
*/
public int size();
/**
* Write the data to the OutputStream.
*/
public void writeTo(OutputStream os) throws IOException;
}

View File

@ -1,58 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
/**
* @author Bill Shannon
*/
public class LiteralException extends ProtocolException {
private static final long serialVersionUID = -6919179828339609913L;
/**
* Constructs a LiteralException with the specified Response object.
*/
public LiteralException(Response r) {
super(r.toString());
response = r;
}
}

View File

@ -1,73 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
/**
* @author John Mani
*/
public class ParsingException extends ProtocolException {
private static final long serialVersionUID = 7756119840142724839L;
/**
* Constructs an ParsingException with no detail message.
*/
public ParsingException() {
super();
}
/**
* Constructs an ParsingException with the specified detail message.
* @param s the detail message
*/
public ParsingException(String s) {
super(s);
}
/**
* Constructs an ParsingException with the specified Response.
* @param r the Response
*/
public ParsingException(Response r) {
super(r);
}
}

View File

@ -1,496 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
import java.util.Vector;
import java.util.Properties;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import javax.net.ssl.SSLSocket;
import com.sun.mail.util.*;
/**
* General protocol handling code for IMAP-like protocols. <p>
*
* The Protocol object is multithread safe.
*
* @author John Mani
* @author Max Spivak
* @author Bill Shannon
*/
public class Protocol {
protected String host;
private Socket socket;
// in case we turn on TLS, we'll need these later
protected boolean quote;
protected MailLogger logger;
protected MailLogger traceLogger;
protected Properties props;
protected String prefix;
private boolean connected = false; // did constructor succeed?
private TraceInputStream traceInput; // the Tracer
private volatile ResponseInputStream input;
private TraceOutputStream traceOutput; // the Tracer
private volatile DataOutputStream output;
private int tagCounter = 0;
private String localHostName;
/*
* handlers is a Vector, initialized here,
* because we depend on it always existing and depend
* on the synchronization that Vector provides.
*/
private final Vector handlers = new Vector(); // response handlers
private volatile long timestamp;
private static final byte[] CRLF = { (byte)'\r', (byte)'\n'};
/**
* Constructor. <p>
*
* Opens a connection to the given host at given port.
*
* @param host host to connect to
* @param port portnumber to connect to
* @param props Properties object used by this protocol
* @param prefix Prefix to prepend to property keys
* @param isSSL use SSL?
* @param logger log messages here
*/
public Protocol(String host, int port,
Properties props, String prefix,
boolean isSSL, MailLogger logger)
throws IOException, ProtocolException {
try {
this.host = host;
this.props = props;
this.prefix = prefix;
this.logger = logger;
traceLogger = logger.getSubLogger("protocol", null);
socket = SocketFetcher.getSocket(host, port, props, prefix, isSSL);
quote = PropUtil.getBooleanProperty(props,
"mail.debug.quote", false);
initStreams();
// Read server greeting
processGreeting(readResponse());
timestamp = System.currentTimeMillis();
connected = true; // must be last statement in constructor
} finally {
/*
* If we get here because an exception was thrown, we need
* to disconnect to avoid leaving a connected socket that
* no one will be able to use because this object was never
* completely constructed.
*/
if (!connected)
disconnect();
}
}
private void initStreams() throws IOException {
traceInput = new TraceInputStream(socket.getInputStream(), traceLogger);
traceInput.setQuote(quote);
input = new ResponseInputStream(traceInput);
traceOutput =
new TraceOutputStream(socket.getOutputStream(), traceLogger);
traceOutput.setQuote(quote);
output = new DataOutputStream(new BufferedOutputStream(traceOutput));
}
/**
* Constructor for debugging.
*/
public Protocol(InputStream in, PrintStream out, boolean debug)
throws IOException {
this.host = "localhost";
this.quote = false;
logger = new MailLogger(this.getClass(), "DEBUG", debug, out);
traceLogger = logger.getSubLogger("protocol", null);
// XXX - inlined initStreams, won't allow later startTLS
traceInput = new TraceInputStream(in, traceLogger);
traceInput.setQuote(quote);
input = new ResponseInputStream(traceInput);
traceOutput = new TraceOutputStream(out, traceLogger);
traceOutput.setQuote(quote);
output = new DataOutputStream(new BufferedOutputStream(traceOutput));
timestamp = System.currentTimeMillis();
}
/**
* Returns the timestamp.
*/
public long getTimestamp() {
return timestamp;
}
/**
* Adds a response handler.
*/
public void addResponseHandler(ResponseHandler h) {
handlers.addElement(h);
}
/**
* Removed the specified response handler.
*/
public void removeResponseHandler(ResponseHandler h) {
handlers.removeElement(h);
}
/**
* Notify response handlers
*/
public void notifyResponseHandlers(Response[] responses) {
if (handlers.size() == 0)
return;
for (int i = 0; i < responses.length; i++) { // go thru responses
Response r = responses[i];
// skip responses that have already been handled
if (r == null)
continue;
// Need to copy handlers list because handlers can be removed
// when handling a response.
Object[] h = handlers.toArray();
// dispatch 'em
for (int j = 0; j < h.length; j++) {
if (h[j] != null)
((ResponseHandler)h[j]).handleResponse(r);
}
}
}
protected void processGreeting(Response r) throws ProtocolException {
if (r.isBYE())
throw new ConnectionException(this, r);
}
/**
* Return the Protocol's InputStream.
*/
protected ResponseInputStream getInputStream() {
return input;
}
/**
* Return the Protocol's OutputStream
*/
protected OutputStream getOutputStream() {
return output;
}
/**
* Returns whether this Protocol supports non-synchronizing literals
* Default is false. Subclasses should override this if required
*/
protected synchronized boolean supportsNonSyncLiterals() {
return false;
}
public Response readResponse()
throws IOException, ProtocolException {
return new Response(this);
}
/**
* Return a buffer to be used to read a response.
* The default implementation returns null, which causes
* a new buffer to be allocated for every response.
*
* @since JavaMail 1.4.1
*/
protected ByteArray getResponseBuffer() {
return null;
}
public String writeCommand(String command, Argument args)
throws IOException, ProtocolException {
// assert Thread.holdsLock(this);
// can't assert because it's called from constructor
String tag = "A" + Integer.toString(tagCounter++, 10); // unique tag
output.writeBytes(tag + " " + command);
if (args != null) {
output.write(' ');
args.write(this);
}
output.write(CRLF);
output.flush();
return tag;
}
/**
* Send a command to the server. Collect all responses until either
* the corresponding command completion response or a BYE response
* (indicating server failure). Return all the collected responses.
*
* @param command the command
* @param args the arguments
* @return array of Response objects returned by the server
*/
public synchronized Response[] command(String command, Argument args) {
commandStart(command);
Vector v = new Vector();
boolean done = false;
String tag = null;
Response r = null;
// write the command
try {
tag = writeCommand(command, args);
} catch (LiteralException lex) {
v.addElement(lex.getResponse());
done = true;
} catch (Exception ex) {
// Convert this into a BYE response
v.addElement(Response.byeResponse(ex));
done = true;
}
Response byeResp = null;
while (!done) {
try {
r = readResponse();
} catch (IOException ioex) {
if (byeResp != null) // connection closed after BYE was sent
break;
// convert this into a BYE response
r = Response.byeResponse(ioex);
} catch (ProtocolException pex) {
continue; // skip this response
}
if (r.isBYE()) {
byeResp = r;
continue;
}
v.addElement(r);
// If this is a matching command completion response, we are done
if (r.isTagged() && r.getTag().equals(tag))
done = true;
}
if (byeResp != null)
v.addElement(byeResp); // must be last
Response[] responses = new Response[v.size()];
v.copyInto(responses);
timestamp = System.currentTimeMillis();
commandEnd();
return responses;
}
/**
* Convenience routine to handle OK, NO, BAD and BYE responses.
*/
public void handleResult(Response response) throws ProtocolException {
if (response.isOK())
return;
else if (response.isNO())
throw new CommandFailedException(response);
else if (response.isBAD())
throw new BadCommandException(response);
else if (response.isBYE()) {
disconnect();
throw new ConnectionException(this, response);
}
}
/**
* Convenience routine to handle simple IAP commands
* that do not have responses specific to that command.
*/
public void simpleCommand(String cmd, Argument args)
throws ProtocolException {
// Issue command
Response[] r = command(cmd, args);
// dispatch untagged responses
notifyResponseHandlers(r);
// Handle result of this command
handleResult(r[r.length-1]);
}
/**
* Start TLS on the current connection.
* <code>cmd</code> is the command to issue to start TLS negotiation.
* If the command succeeds, we begin TLS negotiation.
* If the socket is already an SSLSocket this is a nop and the command
* is not issued.
*/
public synchronized void startTLS(String cmd)
throws IOException, ProtocolException {
if (socket instanceof SSLSocket)
return; // nothing to do
simpleCommand(cmd, null);
socket = SocketFetcher.startTLS(socket, host, props, prefix);
initStreams();
}
/**
* Is this connection using an SSL socket?
*
* @return true if using SSL
* @since JavaMail 1.4.6
*/
public boolean isSSL() {
return socket instanceof SSLSocket;
}
/**
* Disconnect.
*/
protected synchronized void disconnect() {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// ignore it
}
socket = null;
}
}
/**
* Get the name of the local host.
* The property <prefix>.localhost overrides <prefix>.localaddress,
* which overrides what InetAddress would tell us.
*/
protected synchronized String getLocalHost() {
// get our hostname and cache it for future use
if (localHostName == null || localHostName.length() <= 0)
localHostName =
props.getProperty(prefix + ".localhost");
if (localHostName == null || localHostName.length() <= 0)
localHostName =
props.getProperty(prefix + ".localaddress");
try {
if (localHostName == null || localHostName.length() <= 0) {
InetAddress localHost = InetAddress.getLocalHost();
localHostName = localHost.getCanonicalHostName();
// if we can't get our name, use local address literal
if (localHostName == null)
// XXX - not correct for IPv6
localHostName = "[" + localHost.getHostAddress() + "]";
}
} catch (UnknownHostException uhex) {
}
// last chance, try to get our address from our socket
if (localHostName == null || localHostName.length() <= 0) {
if (socket != null && socket.isBound()) {
InetAddress localHost = socket.getLocalAddress();
localHostName = localHost.getCanonicalHostName();
// if we can't get our name, use local address literal
if (localHostName == null)
// XXX - not correct for IPv6
localHostName = "[" + localHost.getHostAddress() + "]";
}
}
return localHostName;
}
/**
* Is protocol tracing enabled?
*/
protected boolean isTracing() {
return traceLogger.isLoggable(Level.FINEST);
}
/**
* Temporarily turn off protocol tracing, e.g., to prevent
* tracing the authentication sequence, including the password.
*/
protected void suspendTracing() {
if (traceLogger.isLoggable(Level.FINEST)) {
traceInput.setTrace(false);
traceOutput.setTrace(false);
}
}
/**
* Resume protocol tracing, if it was enabled to begin with.
*/
protected void resumeTracing() {
if (traceLogger.isLoggable(Level.FINEST)) {
traceInput.setTrace(true);
traceOutput.setTrace(true);
}
}
/**
* Finalizer.
*/
protected void finalize() throws Throwable {
super.finalize();
disconnect();
}
/*
* Probe points for GlassFish monitoring.
*/
private void commandStart(String command) { }
private void commandEnd() { }
}

View File

@ -1,91 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
/**
* @author John Mani
*/
public class ProtocolException extends Exception {
protected transient Response response = null;
private static final long serialVersionUID = -4360500807971797439L;
/**
* Constructs a ProtocolException with no detail message.
*/
public ProtocolException() {
super();
}
/**
* Constructs a ProtocolException with the specified detail message.
* @param message the detail message
*/
public ProtocolException(String message) {
super(message);
}
/**
* Constructs a ProtocolException with the specified detail message
* and cause.
* @param message the detail message
* @param cause the cause
*/
public ProtocolException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a ProtocolException with the specified Response object.
*/
public ProtocolException(Response r) {
super(r.toString());
response = r;
}
/**
* Return the offending Response object.
*/
public Response getResponse() {
return response;
}
}

View File

@ -1,530 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
import java.io.*;
import java.util.*;
import com.sun.mail.util.*;
/**
* This class represents a response obtained from the input stream
* of an IMAP server.
*
* @author John Mani
*/
public class Response {
protected int index; // internal index (updated during the parse)
protected int pindex; // index after parse, for reset
protected int size; // number of valid bytes in our buffer
protected byte[] buffer = null;
protected int type = 0;
protected String tag = null;
private static final int increment = 100;
// The first and second bits indicate whether this response
// is a Continuation, Tagged or Untagged
public final static int TAG_MASK = 0x03;
public final static int CONTINUATION = 0x01;
public final static int TAGGED = 0x02;
public final static int UNTAGGED = 0x03;
// The third, fourth and fifth bits indicate whether this response
// is an OK, NO, BAD or BYE response
public final static int TYPE_MASK = 0x1C;
public final static int OK = 0x04;
public final static int NO = 0x08;
public final static int BAD = 0x0C;
public final static int BYE = 0x10;
// The sixth bit indicates whether a BYE response is synthetic or real
public final static int SYNTHETIC = 0x20;
public Response(String s) {
buffer = ASCIIUtility.getBytes(s);
size = buffer.length;
parse();
}
/**
* Read a new Response from the given Protocol
* @param p the Protocol object
*/
public Response(Protocol p) throws IOException, ProtocolException {
// read one response into 'buffer'
ByteArray ba = p.getResponseBuffer();
ByteArray response = p.getInputStream().readResponse(ba);
buffer = response.getBytes();
size = response.getCount() - 2; // Skip the terminating CRLF
parse();
}
/**
* Copy constructor.
*/
public Response(Response r) {
index = r.index;
size = r.size;
buffer = r.buffer;
type = r.type;
tag = r.tag;
}
/**
* Return a Response object that looks like a BYE protocol response.
* Include the details of the exception in the response string.
*/
public static Response byeResponse(Exception ex) {
String err = "* BYE JavaMail Exception: " + ex.toString();
err = err.replace('\r', ' ').replace('\n', ' ');
Response r = new Response(err);
r.type |= SYNTHETIC;
return r;
}
private void parse() {
index = 0; // position internal index at start
if (size == 0) // empty line
return;
if (buffer[index] == '+') { // Continuation statement
type |= CONTINUATION;
index += 1; // Position beyond the '+'
return; // return
} else if (buffer[index] == '*') { // Untagged statement
type |= UNTAGGED;
index += 1; // Position beyond the '*'
} else { // Tagged statement
type |= TAGGED;
tag = readAtom(); // read the TAG, index positioned beyond tag
if (tag == null)
tag = ""; // avoid possible NPE
}
int mark = index; // mark
String s = readAtom(); // updates index
if (s == null)
s = ""; // avoid possible NPE
if (s.equalsIgnoreCase("OK"))
type |= OK;
else if (s.equalsIgnoreCase("NO"))
type |= NO;
else if (s.equalsIgnoreCase("BAD"))
type |= BAD;
else if (s.equalsIgnoreCase("BYE"))
type |= BYE;
else
index = mark; // reset
pindex = index;
return;
}
public void skipSpaces() {
while (index < size && buffer[index] == ' ')
index++;
}
/**
* Skip to the next space, for use in error recovery while parsing.
*/
public void skipToken() {
while (index < size && buffer[index] != ' ')
index++;
}
public void skip(int count) {
index += count;
}
public byte peekByte() {
if (index < size)
return buffer[index];
else
return 0; // XXX - how else to signal error?
}
/**
* Return the next byte from this Statement.
* @return the next byte.
*/
public byte readByte() {
if (index < size)
return buffer[index++];
else
return 0; // XXX - how else to signal error?
}
/**
* Extract an ATOM, starting at the current position. Updates
* the internal index to beyond the Atom.
* @return an Atom
*/
public String readAtom() {
return readAtom('\0');
}
/**
* Extract an ATOM, but stop at the additional delimiter
* (if not NUL). Used to parse a response code inside [].
*/
public String readAtom(char delim) {
skipSpaces();
if (index >= size) // already at end of response
return null;
/*
* An ATOM is any CHAR delimited by :
* SPACE | CTL | '(' | ')' | '{' | '%' | '*' | '"' | '\'
*/
byte b;
int start = index;
while (index < size && ((b = buffer[index]) > ' ') &&
b != '(' && b != ')' && b != '%' && b != '*' &&
b != '"' && b != '\\' && b != 0x7f &&
(delim == '\0' || b != delim))
index++;
return ASCIIUtility.toString(buffer, start, index);
}
/**
* Read a string as an arbitrary sequence of characters,
* stopping at the delimiter Used to read part of a
* response code inside [].
*/
public String readString(char delim) {
skipSpaces();
if (index >= size) // already at end of response
return null;
int start = index;
while (index < size && buffer[index] != delim)
index++;
return ASCIIUtility.toString(buffer, start, index);
}
public String[] readStringList() {
return readStringList(false);
}
public String[] readAtomStringList() {
return readStringList(true);
}
private String[] readStringList(boolean atom) {
skipSpaces();
if (buffer[index] != '(') // not what we expected
return null;
index++; // skip '('
Vector v = new Vector();
do {
v.addElement(atom ? readAtomString() : readString());
} while (buffer[index++] != ')');
int size = v.size();
if (size > 0) {
String[] s = new String[size];
v.copyInto(s);
return s;
} else // empty list
return null;
}
/**
* Extract an integer, starting at the current position. Updates the
* internal index to beyond the number. Returns -1 if a number was
* not found.
*
* @return a number
*/
public int readNumber() {
// Skip leading spaces
skipSpaces();
int start = index;
while (index < size && Character.isDigit((char)buffer[index]))
index++;
if (index > start) {
try {
return ASCIIUtility.parseInt(buffer, start, index);
} catch (NumberFormatException nex) { }
}
return -1;
}
/**
* Extract a long number, starting at the current position. Updates the
* internal index to beyond the number. Returns -1 if a long number
* was not found.
*
* @return a long
*/
public long readLong() {
// Skip leading spaces
skipSpaces();
int start = index;
while (index < size && Character.isDigit((char)buffer[index]))
index++;
if (index > start) {
try {
return ASCIIUtility.parseLong(buffer, start, index);
} catch (NumberFormatException nex) { }
}
return -1;
}
/**
* Extract a NSTRING, starting at the current position. Return it as
* a String. The sequence 'NIL' is returned as null
*
* NSTRING := QuotedString | Literal | "NIL"
*
* @return a String
*/
public String readString() {
return (String)parseString(false, true);
}
/**
* Extract a NSTRING, starting at the current position. Return it as
* a ByteArrayInputStream. The sequence 'NIL' is returned as null
*
* NSTRING := QuotedString | Literal | "NIL"
*
* @return a ByteArrayInputStream
*/
public ByteArrayInputStream readBytes() {
ByteArray ba = readByteArray();
if (ba != null)
return ba.toByteArrayInputStream();
else
return null;
}
/**
* Extract a NSTRING, starting at the current position. Return it as
* a ByteArray. The sequence 'NIL' is returned as null
*
* NSTRING := QuotedString | Literal | "NIL"
*
* @return a ByteArray
*/
public ByteArray readByteArray() {
/*
* Special case, return the data after the continuation uninterpreted.
* It's usually a challenge for an AUTHENTICATE command.
*/
if (isContinuation()) {
skipSpaces();
return new ByteArray(buffer, index, size - index);
}
return (ByteArray)parseString(false, false);
}
/**
* Extract an ASTRING, starting at the current position
* and return as a String. An ASTRING can be a QuotedString, a
* Literal or an Atom
*
* Any errors in parsing returns null
*
* ASTRING := QuotedString | Literal | Atom
*
* @return a String
*/
public String readAtomString() {
return (String)parseString(true, true);
}
/**
* Generic parsing routine that can parse out a Quoted-String,
* Literal or Atom and return the parsed token as a String
* or a ByteArray. Errors or NIL data will return null.
*/
private Object parseString(boolean parseAtoms, boolean returnString) {
byte b;
// Skip leading spaces
skipSpaces();
b = buffer[index];
if (b == '"') { // QuotedString
index++; // skip the quote
int start = index;
int copyto = index;
while (index < size && (b = buffer[index]) != '"') {
if (b == '\\') // skip escaped byte
index++;
if (index != copyto) { // only copy if we need to
// Beware: this is a destructive copy. I'm
// pretty sure this is OK, but ... ;>
buffer[copyto] = buffer[index];
}
copyto++;
index++;
}
if (index >= size) {
// didn't find terminating quote, something is seriously wrong
//throw new ArrayIndexOutOfBoundsException(
// "index = " + index + ", size = " + size);
return null;
} else
index++; // skip past the terminating quote
if (returnString)
return ASCIIUtility.toString(buffer, start, copyto);
else
return new ByteArray(buffer, start, copyto-start);
} else if (b == '{') { // Literal
int start = ++index; // note the start position
while (buffer[index] != '}')
index++;
int count = 0;
try {
count = ASCIIUtility.parseInt(buffer, start, index);
} catch (NumberFormatException nex) {
// throw new ParsingException();
return null;
}
start = index + 3; // skip "}\r\n"
index = start + count; // position index to beyond the literal
if (returnString) // return as String
return ASCIIUtility.toString(buffer, start, start + count);
else
return new ByteArray(buffer, start, count);
} else if (parseAtoms) { // parse as an ATOM
int start = index; // track this, so that we can use to
// creating ByteArrayInputStream below.
String s = readAtom();
if (returnString)
return s;
else // *very* unlikely
return new ByteArray(buffer, start, index);
} else if (b == 'N' || b == 'n') { // the only valid value is 'NIL'
index += 3; // skip past NIL
return null;
}
return null; // Error
}
public int getType() {
return type;
}
public boolean isContinuation() {
return ((type & TAG_MASK) == CONTINUATION);
}
public boolean isTagged() {
return ((type & TAG_MASK) == TAGGED);
}
public boolean isUnTagged() {
return ((type & TAG_MASK) == UNTAGGED);
}
public boolean isOK() {
return ((type & TYPE_MASK) == OK);
}
public boolean isNO() {
return ((type & TYPE_MASK) == NO);
}
public boolean isBAD() {
return ((type & TYPE_MASK) == BAD);
}
public boolean isBYE() {
return ((type & TYPE_MASK) == BYE);
}
public boolean isSynthetic() {
return ((type & SYNTHETIC) == SYNTHETIC);
}
/**
* Return the tag, if this is a tagged statement.
* @return tag of this tagged statement
*/
public String getTag() {
return tag;
}
/**
* Return the rest of the response as a string, usually used to
* return the arbitrary message text after a NO response.
*/
public String getRest() {
skipSpaces();
return ASCIIUtility.toString(buffer, index, size);
}
/**
* Reset pointer to beginning of response.
*/
public void reset() {
index = pindex;
}
public String toString() {
return ASCIIUtility.toString(buffer, 0, size);
}
}

View File

@ -1,51 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
/**
* This class
*
* @author John Mani
*/
public interface ResponseHandler {
public void handleResponse(Response r);
}

View File

@ -1,164 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.iap;
import java.io.*;
import com.sun.mail.iap.ByteArray;
import com.sun.mail.util.ASCIIUtility;
/**
*
* Inputstream that is used to read a Response.
*
* @author Arun Krishnan
* @author Bill Shannon
*/
public class ResponseInputStream {
private static final int minIncrement = 256;
private static final int maxIncrement = 256 * 1024;
private static final int incrementSlop = 16;
// where we read from
private BufferedInputStream bin;
/**
* Constructor.
*/
public ResponseInputStream(InputStream in) {
bin = new BufferedInputStream(in, 2 * 1024);
}
/**
* Read a Response from the InputStream.
* @return ByteArray that contains the Response
*/
public ByteArray readResponse() throws IOException {
return readResponse(null);
}
/**
* Read a Response from the InputStream.
* @return ByteArray that contains the Response
*/
public ByteArray readResponse(ByteArray ba) throws IOException {
if (ba == null)
ba = new ByteArray(new byte[128], 0, 128);
byte[] buffer = ba.getBytes();
int idx = 0;
for (;;) { // read until CRLF with no preceeding literal
// XXX - b needs to be an int, to handle bytes with value 0xff
int b = 0;
boolean gotCRLF=false;
// Read a CRLF terminated line from the InputStream
while (!gotCRLF &&
((b = bin.read()) != -1)) {
switch (b) {
case '\n':
if ((idx > 0) && buffer[idx-1] == '\r')
gotCRLF = true;
default:
if (idx >= buffer.length) {
int incr = buffer.length;
if (incr > maxIncrement)
incr = maxIncrement;
ba.grow(incr);
buffer = ba.getBytes();
}
buffer[idx++] = (byte)b;
}
}
if (b == -1)
throw new IOException("Connection dropped by server?");
// Now lets check for literals : {<digits>}CRLF
// Note: index needs to >= 5 for the above sequence to occur
if (idx < 5 || buffer[idx-3] != '}')
break;
int i;
// look for left curly
for (i = idx - 4; i >= 0; i--)
if (buffer[i] == '{')
break;
if (i < 0) // Nope, not a literal ?
break;
int count = 0;
// OK, handle the literal ..
try {
count = ASCIIUtility.parseInt(buffer, i+1, idx-3);
} catch (NumberFormatException e) {
break;
}
// Now read 'count' bytes. (Note: count could be 0)
if (count > 0) {
int avail = buffer.length - idx; // available space in buffer
if (count + incrementSlop > avail) {
// need count-avail more bytes
ba.grow(minIncrement > count + incrementSlop - avail ?
minIncrement : count + incrementSlop - avail);
buffer = ba.getBytes();
}
/*
* read() might not return all the bytes in one shot,
* so call repeatedly till we are done
*/
int actual;
while (count > 0) {
actual = bin.read(buffer, idx, count);
count -= actual;
idx += actual;
}
}
// back to top of loop to read until CRLF
}
ba.setCount(idx);
return ba;
}
}

View File

@ -1,117 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import java.util.*;
/**
* An access control list entry for a particular authentication identifier
* (user or group). Associates a set of Rights with the identifier.
* See RFC 2086.
* <p>
*
* @author Bill Shannon
*/
public class ACL implements Cloneable {
private String name;
private Rights rights;
/**
* Construct an ACL entry for the given identifier and with no rights.
*
* @param name the identifier name
*/
public ACL(String name) {
this.name = name;
this.rights = new Rights();
}
/**
* Construct an ACL entry for the given identifier with the given rights.
*
* @param name the identifier name
* @param rights the rights
*/
public ACL(String name, Rights rights) {
this.name = name;
this.rights = rights;
}
/**
* Get the identifier name for this ACL entry.
*
* @return the identifier name
*/
public String getName() {
return name;
}
/**
* Set the rights associated with this ACL entry.
*
* @param rights the rights
*/
public void setRights(Rights rights) {
this.rights = rights;
}
/**
* Get the rights associated with this ACL entry.
* Returns the actual Rights object referenced by this ACL;
* modifications to the Rights object will effect this ACL.
*
* @return the rights
*/
public Rights getRights() {
return rights;
}
/**
* Clone this ACL entry.
*/
public Object clone() throws CloneNotSupportedException {
ACL acl = (ACL)super.clone();
acl.rights = (Rights)this.rights.clone();
return acl;
}
}

View File

@ -1,61 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import com.sun.mail.iap.*;
/**
* Information from the APPENDUID response code
* defined by the UIDPLUS extension -
* <A HREF="http://www.ietf.org/rfc/rfc2359.txt">RFC 2359</A>.
*
* @author Bill Shannon
*/
public class AppendUID {
public long uidvalidity = -1;
public long uid = -1;
public AppendUID(long uidvalidity, long uid) {
this.uidvalidity = uidvalidity;
this.uid = uid;
}
}

View File

@ -1,137 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import javax.mail.*;
import javax.mail.internet.*;
import com.sun.mail.util.*;
import com.sun.mail.iap.*;
import com.sun.mail.imap.protocol.*;
/**
* The default IMAP folder (root of the naming hierarchy).
*
* @author John Mani
*/
public class DefaultFolder extends IMAPFolder {
protected DefaultFolder(IMAPStore store) {
super("", UNKNOWN_SEPARATOR, store, null);
exists = true; // of course
type = HOLDS_FOLDERS; // obviously
}
public synchronized String getName() {
return fullName;
}
public Folder getParent() {
return null;
}
public synchronized Folder[] list(final String pattern)
throws MessagingException {
ListInfo[] li = null;
li = (ListInfo[])doCommand(new ProtocolCommand() {
public Object doCommand(IMAPProtocol p) throws ProtocolException {
return p.list("", pattern);
}
});
if (li == null)
return new Folder[0];
IMAPFolder[] folders = new IMAPFolder[li.length];
for (int i = 0; i < folders.length; i++)
folders[i] = ((IMAPStore)store).newIMAPFolder(li[i]);
return folders;
}
public synchronized Folder[] listSubscribed(final String pattern)
throws MessagingException {
ListInfo[] li = null;
li = (ListInfo[])doCommand(new ProtocolCommand() {
public Object doCommand(IMAPProtocol p) throws ProtocolException {
return p.lsub("", pattern);
}
});
if (li == null)
return new Folder[0];
IMAPFolder[] folders = new IMAPFolder[li.length];
for (int i = 0; i < folders.length; i++)
folders[i] = ((IMAPStore)store).newIMAPFolder(li[i]);
return folders;
}
public boolean hasNewMessages() throws MessagingException {
// Not applicable on DefaultFolder
return false;
}
public Folder getFolder(String name) throws MessagingException {
return ((IMAPStore)store).newIMAPFolder(name, UNKNOWN_SEPARATOR);
}
public boolean delete(boolean recurse) throws MessagingException {
// Not applicable on DefaultFolder
throw new MethodNotSupportedException("Cannot delete Default Folder");
}
public boolean renameTo(Folder f) throws MessagingException {
// Not applicable on DefaultFolder
throw new MethodNotSupportedException("Cannot rename Default Folder");
}
public void appendMessages(Message[] msgs) throws MessagingException {
// Not applicable on DefaultFolder
throw new MethodNotSupportedException("Cannot append to Default Folder");
}
public Message[] expunge() throws MessagingException {
// Not applicable on DefaultFolder
throw new MethodNotSupportedException("Cannot expunge Default Folder");
}
}

View File

@ -1,438 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import java.io.*;
import java.util.Enumeration;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import com.sun.mail.util.*;
import com.sun.mail.iap.*;
import com.sun.mail.imap.protocol.*;
/**
* An IMAP body part.
*
* @author John Mani
* @author Bill Shannon
*/
public class IMAPBodyPart extends MimeBodyPart implements ReadableMime {
private IMAPMessage message;
private BODYSTRUCTURE bs;
private String sectionId;
// processed values ..
private String type;
private String description;
private boolean headersLoaded = false;
private static final boolean decodeFileName =
PropUtil.getBooleanSystemProperty("mail.mime.decodefilename", false);
protected IMAPBodyPart(BODYSTRUCTURE bs, String sid, IMAPMessage message) {
super();
this.bs = bs;
this.sectionId = sid;
this.message = message;
// generate content-type
ContentType ct = new ContentType(bs.type, bs.subtype, bs.cParams);
type = ct.toString();
}
/* Override this method to make it a no-op, rather than throw
* an IllegalWriteException. This will permit IMAPBodyParts to
* be inserted in newly crafted MimeMessages, especially when
* forwarding or replying to messages.
*/
protected void updateHeaders() {
return;
}
public int getSize() throws MessagingException {
return bs.size;
}
public int getLineCount() throws MessagingException {
return bs.lines;
}
public String getContentType() throws MessagingException {
return type;
}
public String getDisposition() throws MessagingException {
return bs.disposition;
}
public void setDisposition(String disposition) throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public String getEncoding() throws MessagingException {
return bs.encoding;
}
public String getContentID() throws MessagingException {
return bs.id;
}
public String getContentMD5() throws MessagingException {
return bs.md5;
}
public void setContentMD5(String md5) throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public String getDescription() throws MessagingException {
if (description != null) // cached value ?
return description;
if (bs.description == null)
return null;
try {
description = MimeUtility.decodeText(bs.description);
} catch (UnsupportedEncodingException ex) {
description = bs.description;
}
return description;
}
public void setDescription(String description, String charset)
throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public String getFileName() throws MessagingException {
String filename = null;
if (bs.dParams != null)
filename = bs.dParams.get("filename");
if (filename == null && bs.cParams != null)
filename = bs.cParams.get("name");
if (decodeFileName && filename != null) {
try {
filename = MimeUtility.decodeText(filename);
} catch (UnsupportedEncodingException ex) {
throw new MessagingException("Can't decode filename", ex);
}
}
return filename;
}
public void setFileName(String filename) throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
protected InputStream getContentStream() throws MessagingException {
InputStream is = null;
boolean pk = message.getPeek(); // acquire outside of message cache lock
// Acquire MessageCacheLock, to freeze seqnum.
synchronized(message.getMessageCacheLock()) {
try {
IMAPProtocol p = message.getProtocol();
// Check whether this message is expunged
message.checkExpunged();
if (p.isREV1() && (message.getFetchBlockSize() != -1))
return new IMAPInputStream(message, sectionId,
message.ignoreBodyStructureSize() ? -1 : bs.size, pk);
// Else, vanila IMAP4, no partial fetch
int seqnum = message.getSequenceNumber();
BODY b;
if (pk)
b = p.peekBody(seqnum, sectionId);
else
b = p.fetchBody(seqnum, sectionId);
if (b != null)
is = b.getByteArrayInputStream();
} catch (ConnectionException cex) {
throw new FolderClosedException(
message.getFolder(), cex.getMessage());
} catch (ProtocolException pex) {
throw new MessagingException(pex.getMessage(), pex);
}
}
if (is == null)
throw new MessagingException("No content");
else
return is;
}
/**
* Return the MIME format stream of headers for this body part.
*/
private InputStream getHeaderStream() throws MessagingException {
if (!message.isREV1())
loadHeaders(); // will be needed below
// Acquire MessageCacheLock, to freeze seqnum.
synchronized(message.getMessageCacheLock()) {
try {
IMAPProtocol p = message.getProtocol();
// Check whether this message got expunged
message.checkExpunged();
if (p.isREV1()) {
int seqnum = message.getSequenceNumber();
BODY b = p.peekBody(seqnum, sectionId + ".MIME");
if (b == null)
throw new MessagingException("Failed to fetch headers");
ByteArrayInputStream bis = b.getByteArrayInputStream();
if (bis == null)
throw new MessagingException("Failed to fetch headers");
return bis;
} else {
// Can't read it from server, have to fake it
SharedByteArrayOutputStream bos =
new SharedByteArrayOutputStream(0);
LineOutputStream los = new LineOutputStream(bos);
try {
// Write out the header
Enumeration hdrLines = super.getAllHeaderLines();
while (hdrLines.hasMoreElements())
los.writeln((String)hdrLines.nextElement());
// The CRLF separator between header and content
los.writeln();
} catch (IOException ioex) {
// should never happen
} finally {
try {
los.close();
} catch (IOException cex) { }
}
return bos.toStream();
}
} catch (ConnectionException cex) {
throw new FolderClosedException(
message.getFolder(), cex.getMessage());
} catch (ProtocolException pex) {
throw new MessagingException(pex.getMessage(), pex);
}
}
}
/**
* Return the MIME format stream corresponding to this message part.
*
* @return the MIME format stream
* @since JavaMail 1.4.5
*/
public InputStream getMimeStream() throws MessagingException {
/*
* The IMAP protocol doesn't support returning the entire
* part content in one operation so we have to fake it by
* concatenating the header stream and the content stream.
*/
return new SequenceInputStream(getHeaderStream(), getContentStream());
}
public synchronized DataHandler getDataHandler()
throws MessagingException {
if (dh == null) {
if (bs.isMulti())
dh = new DataHandler(
new IMAPMultipartDataSource(
this, bs.bodies, sectionId, message)
);
else if (bs.isNested() && message.isREV1() && bs.envelope != null)
dh = new DataHandler(
new IMAPNestedMessage(message,
bs.bodies[0],
bs.envelope,
sectionId),
type
);
}
return super.getDataHandler();
}
public void setDataHandler(DataHandler content) throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public void setContent(Object o, String type) throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public void setContent(Multipart mp) throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public String[] getHeader(String name) throws MessagingException {
loadHeaders();
return super.getHeader(name);
}
public void setHeader(String name, String value)
throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public void addHeader(String name, String value)
throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public void removeHeader(String name) throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public Enumeration getAllHeaders() throws MessagingException {
loadHeaders();
return super.getAllHeaders();
}
public Enumeration getMatchingHeaders(String[] names)
throws MessagingException {
loadHeaders();
return super.getMatchingHeaders(names);
}
public Enumeration getNonMatchingHeaders(String[] names)
throws MessagingException {
loadHeaders();
return super.getNonMatchingHeaders(names);
}
public void addHeaderLine(String line) throws MessagingException {
throw new IllegalWriteException("IMAPBodyPart is read-only");
}
public Enumeration getAllHeaderLines() throws MessagingException {
loadHeaders();
return super.getAllHeaderLines();
}
public Enumeration getMatchingHeaderLines(String[] names)
throws MessagingException {
loadHeaders();
return super.getMatchingHeaderLines(names);
}
public Enumeration getNonMatchingHeaderLines(String[] names)
throws MessagingException {
loadHeaders();
return super.getNonMatchingHeaderLines(names);
}
private synchronized void loadHeaders() throws MessagingException {
if (headersLoaded)
return;
// "headers" should never be null since it's set in the constructor.
// If something did go wrong this will fix it, but is an unsynchronized
// assignment of "headers".
if (headers == null)
headers = new InternetHeaders();
// load headers
// Acquire MessageCacheLock, to freeze seqnum.
synchronized(message.getMessageCacheLock()) {
try {
IMAPProtocol p = message.getProtocol();
// Check whether this message got expunged
message.checkExpunged();
if (p.isREV1()) {
int seqnum = message.getSequenceNumber();
BODY b = p.peekBody(seqnum, sectionId + ".MIME");
if (b == null)
throw new MessagingException("Failed to fetch headers");
ByteArrayInputStream bis = b.getByteArrayInputStream();
if (bis == null)
throw new MessagingException("Failed to fetch headers");
headers.load(bis);
} else {
// RFC 1730 does not provide for fetching BodyPart headers
// So, just dump the RFC1730 BODYSTRUCTURE into the
// headerStore
// Content-Type
headers.addHeader("Content-Type", type);
// Content-Transfer-Encoding
headers.addHeader("Content-Transfer-Encoding", bs.encoding);
// Content-Description
if (bs.description != null)
headers.addHeader("Content-Description",
bs.description);
// Content-ID
if (bs.id != null)
headers.addHeader("Content-ID", bs.id);
// Content-MD5
if (bs.md5 != null)
headers.addHeader("Content-MD5", bs.md5);
}
} catch (ConnectionException cex) {
throw new FolderClosedException(
message.getFolder(), cex.getMessage());
} catch (ProtocolException pex) {
throw new MessagingException(pex.getMessage(), pex);
}
}
headersLoaded = true;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,269 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import java.io.*;
import javax.mail.*;
import com.sun.mail.imap.protocol.*;
import com.sun.mail.iap.*;
import com.sun.mail.util.*;
/**
* This class implements an IMAP data stream.
*
* @author John Mani
*/
public class IMAPInputStream extends InputStream {
private IMAPMessage msg; // this message
private String section; // section-id
private int pos; // track the position within the IMAP datastream
private int blksize; // number of bytes to read in each FETCH request
private int max; // the total number of bytes in this section.
// -1 indicates unknown
private byte[] buf; // the buffer obtained from fetchBODY()
private int bufcount; // The index one greater than the index of the
// last valid byte in 'buf'
private int bufpos; // The current position within 'buf'
private boolean lastBuffer; // is this the last buffer of data?
private boolean peek; // peek instead of fetch?
private ByteArray readbuf; // reuse for each read
// Allocate this much extra space in the read buffer to allow
// space for the FETCH response overhead
private static final int slop = 64;
/**
* Create an IMAPInputStream.
*/
public IMAPInputStream(IMAPMessage msg, String section, int max,
boolean peek) {
this.msg = msg;
this.section = section;
this.max = max;
this.peek = peek;
pos = 0;
blksize = msg.getFetchBlockSize();
}
/**
* Do a NOOP to force any untagged EXPUNGE responses
* and then check if this message is expunged.
*/
private void forceCheckExpunged()
throws MessageRemovedIOException, FolderClosedIOException {
synchronized (msg.getMessageCacheLock()) {
try {
msg.getProtocol().noop();
} catch (ConnectionException cex) {
throw new FolderClosedIOException(msg.getFolder(),
cex.getMessage());
} catch (FolderClosedException fex) {
throw new FolderClosedIOException(fex.getFolder(),
fex.getMessage());
} catch (ProtocolException pex) {
// ignore it
}
}
if (msg.isExpunged())
throw new MessageRemovedIOException();
}
/**
* Fetch more data from the server. This method assumes that all
* data has already been read in, hence bufpos > bufcount.
*/
private void fill() throws IOException {
/*
* If we've read the last buffer, there's no more to read.
* If we know the total number of bytes available from this
* section, let's check if we have consumed that many bytes.
*/
if (lastBuffer || max != -1 && pos >= max) {
if (pos == 0)
checkSeen();
readbuf = null; // XXX - return to pool?
return; // the caller of fill() will return -1.
}
BODY b = null;
if (readbuf == null)
readbuf = new ByteArray(blksize + slop);
ByteArray ba;
int cnt;
// Acquire MessageCacheLock, to freeze seqnum.
synchronized (msg.getMessageCacheLock()) {
try {
IMAPProtocol p = msg.getProtocol();
// Check whether this message is expunged
if (msg.isExpunged())
throw new MessageRemovedIOException(
"No content for expunged message");
int seqnum = msg.getSequenceNumber();
cnt = blksize;
if (max != -1 && pos + blksize > max)
cnt = max - pos;
if (peek)
b = p.peekBody(seqnum, section, pos, cnt, readbuf);
else
b = p.fetchBody(seqnum, section, pos, cnt, readbuf);
} catch (ProtocolException pex) {
forceCheckExpunged();
throw new IOException(pex.getMessage());
} catch (FolderClosedException fex) {
throw new FolderClosedIOException(fex.getFolder(),
fex.getMessage());
}
if (b == null || ((ba = b.getByteArray()) == null)) {
forceCheckExpunged();
throw new IOException("No content");
}
}
// make sure the SEEN flag is set after reading the first chunk
if (pos == 0)
checkSeen();
// setup new values ..
buf = ba.getBytes();
bufpos = ba.getStart();
int n = ba.getCount(); // will be zero, if all data has been
// consumed from the server.
// if we got less than we asked for, this is the last buffer of data
lastBuffer = n < cnt;
bufcount = bufpos + n;
pos += n;
}
/**
* Reads the next byte of data from this buffered input stream.
* If no byte is available, the value <code>-1</code> is returned.
*/
public synchronized int read() throws IOException {
if (bufpos >= bufcount) {
fill();
if (bufpos >= bufcount)
return -1; // EOF
}
return buf[bufpos++] & 0xff;
}
/**
* Reads up to <code>len</code> bytes of data from this
* input stream into the given buffer. <p>
*
* Returns the total number of bytes read into the buffer,
* or <code>-1</code> if there is no more data. <p>
*
* Note that this method mimics the "weird !" semantics of
* BufferedInputStream in that the number of bytes actually
* returned may be less that the requested value. So callers
* of this routine should be aware of this and must check
* the return value to insure that they have obtained the
* requisite number of bytes.
*/
public synchronized int read(byte b[], int off, int len)
throws IOException {
int avail = bufcount - bufpos;
if (avail <= 0) {
fill();
avail = bufcount - bufpos;
if (avail <= 0)
return -1; // EOF
}
int cnt = (avail < len) ? avail : len;
System.arraycopy(buf, bufpos, b, off, cnt);
bufpos += cnt;
return cnt;
}
/**
* Reads up to <code>b.length</code> bytes of data from this input
* stream into an array of bytes. <p>
*
* Returns the total number of bytes read into the buffer, or
* <code>-1</code> is there is no more data. <p>
*
* Note that this method mimics the "weird !" semantics of
* BufferedInputStream in that the number of bytes actually
* returned may be less that the requested value. So callers
* of this routine should be aware of this and must check
* the return value to insure that they have obtained the
* requisite number of bytes.
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Returns the number of bytes that can be read from this input
* stream without blocking.
*/
public synchronized int available() throws IOException {
return (bufcount - bufpos);
}
/**
* Normally the SEEN flag will have been set by now, but if not,
* force it to be set (as long as the folder isn't open read-only
* and we're not peeking).
* And of course, if there's no folder (e.g., a nested message)
* don't do anything.
*/
private void checkSeen() {
if (peek) // if we're peeking, don't set the SEEN flag
return;
try {
Folder f = msg.getFolder();
if (f != null && f.getMode() != Folder.READ_ONLY &&
!msg.isSet(Flags.Flag.SEEN))
msg.setFlag(Flags.Flag.SEEN, true);
} catch (MessagingException ex) {
// ignore it
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import java.io.InputStream;
import java.io.IOException;
import java.util.Vector;
import javax.mail.*;
import javax.mail.internet.*;
import com.sun.mail.util.*;
import com.sun.mail.iap.*;
import com.sun.mail.imap.protocol.*;
/**
* This class
*
* @author John Mani
*/
public class IMAPMultipartDataSource extends MimePartDataSource
implements MultipartDataSource {
private Vector parts;
protected IMAPMultipartDataSource(MimePart part, BODYSTRUCTURE[] bs,
String sectionId, IMAPMessage msg) {
super(part);
parts = new Vector(bs.length);
for (int i = 0; i < bs.length; i++)
parts.addElement(
new IMAPBodyPart(bs[i],
sectionId == null ?
Integer.toString(i+1) :
sectionId + "." + Integer.toString(i+1),
msg)
);
}
public int getCount() {
return parts.size();
}
public BodyPart getBodyPart(int index) throws MessagingException {
return (BodyPart)parts.elementAt(index);
}
}

View File

@ -1,151 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import java.io.*;
import javax.mail.*;
import com.sun.mail.imap.protocol.*;
import com.sun.mail.iap.ProtocolException;
/**
* This class implements a nested IMAP message
*
* @author John Mani
*/
public class IMAPNestedMessage extends IMAPMessage {
private IMAPMessage msg; // the enclosure of this nested message
/**
* Package private constructor. <p>
*
* Note that nested messages have no containing folder, nor
* a message number.
*/
IMAPNestedMessage(IMAPMessage m, BODYSTRUCTURE b, ENVELOPE e, String sid) {
super(m._getSession());
msg = m;
bs = b;
envelope = e;
sectionId = sid;
setPeek(m.getPeek());
}
/*
* Get the enclosing message's Protocol object. Overrides
* IMAPMessage.getProtocol().
*/
protected IMAPProtocol getProtocol()
throws ProtocolException, FolderClosedException {
return msg.getProtocol();
}
/*
* Is this an IMAP4 REV1 server?
*/
protected boolean isREV1() throws FolderClosedException {
return msg.isREV1();
}
/*
* Get the enclosing message's messageCacheLock. Overrides
* IMAPMessage.getMessageCacheLock().
*/
protected Object getMessageCacheLock() {
return msg.getMessageCacheLock();
}
/*
* Get the enclosing message's sequence number. Overrides
* IMAPMessage.getSequenceNumber().
*/
protected int getSequenceNumber() {
return msg.getSequenceNumber();
}
/*
* Check whether the enclosing message is expunged. Overrides
* IMAPMessage.checkExpunged().
*/
protected void checkExpunged() throws MessageRemovedException {
msg.checkExpunged();
}
/*
* Check whether the enclosing message is expunged. Overrides
* Message.isExpunged().
*/
public boolean isExpunged() {
return msg.isExpunged();
}
/*
* Get the enclosing message's fetchBlockSize.
*/
protected int getFetchBlockSize() {
return msg.getFetchBlockSize();
}
/*
* Get the enclosing message's ignoreBodyStructureSize.
*/
protected boolean ignoreBodyStructureSize() {
return msg.ignoreBodyStructureSize();
}
/*
* IMAPMessage uses RFC822.SIZE. We use the "size" field from
* our BODYSTRUCTURE.
*/
public int getSize() throws MessagingException {
return bs.size;
}
/*
* Disallow setting flags on nested messages
*/
public synchronized void setFlags(Flags flag, boolean set)
throws MessagingException {
// Cannot set FLAGS on a nested IMAP message
throw new MethodNotSupportedException(
"Cannot set flags on this nested message");
}
}

View File

@ -1,58 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import javax.mail.*;
/**
* This class provides access to an IMAP message store over SSL. <p>
*/
public class IMAPSSLStore extends IMAPStore {
/**
* Constructor that takes a Session object and a URLName that
* represents a specific IMAP server.
*/
public IMAPSSLStore(Session session, URLName url) {
super(session, url, "imaps", true); // call super constructor
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,444 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import java.io.PrintStream;
import java.util.*;
import java.util.logging.Level;
import javax.mail.*;
import com.sun.mail.util.PropUtil;
import com.sun.mail.util.MailLogger;
/**
* A cache of IMAPMessage objects along with the
* mapping from message number to IMAP sequence number.
*
* All operations on this object are protected by the messageCacheLock
* in IMAPFolder.
*/
public class MessageCache {
/*
* The array of IMAPMessage objects. Elements of the array might
* be null if no one has asked for the message. The array expands
* as needed and might be larger than the number of messages in the
* folder. The "size" field indicates the number of entries that
* are valid.
*/
private IMAPMessage[] messages;
/*
* A parallel array of sequence numbers for each message. If the
* array pointer is null, the sequence number of a message is just
* its message number. This is the common case, until a message is
* expunged.
*/
private int[] seqnums;
/*
* The amount of the messages (and seqnum) array that is valid.
* Might be less than the actual size of the array.
*/
private int size;
/**
* The folder these messages belong to.
*/
private IMAPFolder folder;
// debugging logger
private MailLogger logger;
/**
* Grow the array by at least this much, to avoid constantly
* reallocating the array.
*/
private static final int SLOP = 64;
/**
* Construct a new message cache of the indicated size.
*/
MessageCache(IMAPFolder folder, IMAPStore store, int size) {
this.folder = folder;
logger = folder.logger.getSubLogger("messagecache", "DEBUG IMAP MC",
store.getMessageCacheDebug());
if (logger.isLoggable(Level.CONFIG))
logger.config("create cache of size " + size);
ensureCapacity(size, 1);
}
/**
* Constructor for debugging and testing.
*/
MessageCache(int size, boolean debug) {
this.folder = null;
logger = new MailLogger(
this.getClass(), "messagecache",
"DEBUG IMAP MC", debug, System.out);
if (logger.isLoggable(Level.CONFIG))
logger.config("create DEBUG cache of size " + size);
ensureCapacity(size, 1);
}
/**
* Size of cache.
*/
public int size() {
return size;
}
/**
* Get the message object for the indicated message number.
* If the message object hasn't been created, create it.
*/
public IMAPMessage getMessage(int msgnum) {
// check range
if (msgnum < 1 || msgnum > size)
throw new ArrayIndexOutOfBoundsException(
"message number (" + msgnum + ") out of bounds (" + size + ")");
IMAPMessage msg = messages[msgnum-1];
if (msg == null) {
if (logger.isLoggable(Level.FINE))
logger.fine("create message number " + msgnum);
msg = folder.newIMAPMessage(msgnum);
messages[msgnum-1] = msg;
// mark message expunged if no seqnum
if (seqnumOf(msgnum) <= 0) {
logger.fine("it's expunged!");
msg.setExpunged(true);
}
}
return msg;
}
/**
* Get the message object for the indicated sequence number.
* If the message object hasn't been created, create it.
* Return null if there's no message with that sequence number.
*/
public IMAPMessage getMessageBySeqnum(int seqnum) {
int msgnum = msgnumOf(seqnum);
if (msgnum < 0) { // XXX - < 1 ?
if (logger.isLoggable(Level.FINE))
logger.fine("no message seqnum " + seqnum);
return null;
} else
return getMessage(msgnum);
}
/**
* Expunge the message with the given sequence number.
*/
public void expungeMessage(int seqnum) {
int msgnum = msgnumOf(seqnum);
if (msgnum < 0) {
if (logger.isLoggable(Level.FINE))
logger.fine("expunge no seqnum " + seqnum);
return; // XXX - should never happen
}
IMAPMessage msg = messages[msgnum-1];
if (msg != null) {
if (logger.isLoggable(Level.FINE))
logger.fine("expunge existing " + msgnum);
msg.setExpunged(true);
}
if (seqnums == null) { // time to fill it in
logger.fine("create seqnums array");
seqnums = new int[messages.length];
for (int i = 1; i < msgnum; i++)
seqnums[i-1] = i;
seqnums[msgnum - 1] = 0;
for (int i = msgnum + 1; i <= seqnums.length; i++)
seqnums[i-1] = i - 1;
} else {
seqnums[msgnum - 1] = 0;
for (int i = msgnum + 1; i <= seqnums.length; i++) {
assert seqnums[i-1] != 1;
if (seqnums[i-1] > 0)
seqnums[i-1]--;
}
}
}
/**
* Remove all the expunged messages from the array,
* returning a list of removed message objects.
*/
public IMAPMessage[] removeExpungedMessages() {
logger.fine("remove expunged messages");
List mlist = new ArrayList(); // list of expunged messages
/*
* Walk through the array compressing it by copying
* higher numbered messages further down in the array,
* effectively removing expunged messages from the array.
* oldnum is the index we use to walk through the array.
* newnum is the index where we copy the next valid message.
* oldnum == newnum until we encounter an expunged message.
*/
int oldnum = 1;
int newnum = 1;
while (oldnum <= size) {
// is message expunged?
if (seqnumOf(oldnum) <= 0) {
IMAPMessage m = getMessage(oldnum);
mlist.add(m);
} else {
// keep this message
if (newnum != oldnum) {
// move message down in the array (compact array)
messages[newnum-1] = messages[oldnum-1];
if (messages[newnum-1] != null)
messages[newnum-1].setMessageNumber(newnum);
}
newnum++;
}
oldnum++;
}
seqnums = null;
shrink(newnum, oldnum);
IMAPMessage[] rmsgs = new IMAPMessage[mlist.size()];
if (logger.isLoggable(Level.FINE))
logger.fine("return " + rmsgs.length);
mlist.toArray(rmsgs);
return rmsgs;
}
/**
* Remove expunged messages in msgs from the array,
* returning a list of removed message objects.
* All messages in msgs must be IMAPMessage objects
* from this folder.
*/
public IMAPMessage[] removeExpungedMessages(Message[] msgs) {
logger.fine("remove expunged messages");
List mlist = new ArrayList(); // list of expunged messages
/*
* Copy the message numbers of the expunged messages into
* a separate array and sort the array to make it easier to
* process later.
*/
int[] mnum = new int[msgs.length];
for (int i = 0; i < msgs.length; i++)
mnum[i] = msgs[i].getMessageNumber();
Arrays.sort(mnum);
/*
* Walk through the array compressing it by copying
* higher numbered messages further down in the array,
* effectively removing expunged messages from the array.
* oldnum is the index we use to walk through the array.
* newnum is the index where we copy the next valid message.
* oldnum == newnum until we encounter an expunged message.
*
* Even though we know the message number of the first possibly
* expunged message, we still start scanning at message number 1
* so that we can check whether there's any message whose
* sequence number is different than its message number. If there
* is, we can't throw away the seqnums array when we're done.
*/
int oldnum = 1;
int newnum = 1;
int mnumi = 0; // index into mnum
boolean keepSeqnums = false;
while (oldnum <= size) {
/*
* Are there still expunged messsages in msgs to consider,
* and is the message we're considering the next one in the
* list, and is it expunged?
*/
if (mnumi < mnum.length &&
oldnum == mnum[mnumi] &&
seqnumOf(oldnum) <= 0) {
IMAPMessage m = getMessage(oldnum);
mlist.add(m);
/*
* Just in case there are duplicate entries in the msgs array,
* we keep advancing mnumi past any duplicates, but of course
* stop when we get to the end of the array.
*/
while (mnumi < mnum.length && mnum[mnumi] <= oldnum)
mnumi++; // consider next message in array
} else {
// keep this message
if (newnum != oldnum) {
// move message down in the array (compact array)
messages[newnum-1] = messages[oldnum-1];
if (messages[newnum-1] != null)
messages[newnum-1].setMessageNumber(newnum);
if (seqnums != null)
seqnums[newnum-1] = seqnums[oldnum-1];
}
if (seqnums != null && seqnums[newnum-1] != newnum)
keepSeqnums = true;
newnum++;
}
oldnum++;
}
if (!keepSeqnums)
seqnums = null;
shrink(newnum, oldnum);
IMAPMessage[] rmsgs = new IMAPMessage[mlist.size()];
if (logger.isLoggable(Level.FINE))
logger.fine("return " + rmsgs.length);
mlist.toArray(rmsgs);
return rmsgs;
}
/**
* Shrink the messages and seqnums arrays. newend is one past last
* valid element. oldend is one past the previous last valid element.
*/
private void shrink(int newend, int oldend) {
size = newend - 1;
if (logger.isLoggable(Level.FINE))
logger.fine("size now " + size);
if (size == 0) { // no messages left
messages = null;
seqnums = null;
} else if (size > SLOP && size < messages.length / 2) {
// if array shrinks by too much, reallocate it
logger.fine("reallocate array");
IMAPMessage[] newm = new IMAPMessage[size + SLOP];
System.arraycopy(messages, 0, newm, 0, size);
messages = newm;
if (seqnums != null) {
int[] news = new int[size + SLOP];
System.arraycopy(seqnums, 0, news, 0, size);
seqnums = news;
}
} else {
if (logger.isLoggable(Level.FINE))
logger.fine("clean " + newend + " to " + oldend);
// clear out unused entries in array
for (int msgnum = newend; msgnum < oldend; msgnum++) {
messages[msgnum-1] = null;
if (seqnums != null)
seqnums[msgnum-1] = 0;
}
}
}
/**
* Add count messages to the cache.
* newSeqNum is the sequence number of the first message added.
*/
public void addMessages(int count, int newSeqNum) {
if (logger.isLoggable(Level.FINE))
logger.fine("add " + count + " messages");
// don't have to do anything other than making sure there's space
ensureCapacity(size + count, newSeqNum);
}
/*
* Make sure the arrays are at least big enough to hold
* "newsize" messages.
*/
private void ensureCapacity(int newsize, int newSeqNum) {
if (messages == null)
messages = new IMAPMessage[newsize + SLOP];
else if (messages.length < newsize) {
if (logger.isLoggable(Level.FINE))
logger.fine("expand capacity to " + newsize);
IMAPMessage[] newm = new IMAPMessage[newsize + SLOP];
System.arraycopy(messages, 0, newm, 0, messages.length);
messages = newm;
if (seqnums != null) {
int[] news = new int[newsize + SLOP];
System.arraycopy(seqnums, 0, news, 0, seqnums.length);
for (int i = size; i < news.length; i++)
news[i] = newSeqNum++;
seqnums = news;
if (logger.isLoggable(Level.FINE))
logger.fine("message " + newsize +
" has sequence number " + seqnums[newsize-1]);
}
} else if (newsize < size) { // shrinking?
// this should never happen
if (logger.isLoggable(Level.FINE))
logger.fine("shrink capacity to " + newsize);
for (int msgnum = newsize + 1; msgnum <= size; msgnum++) {
messages[msgnum-1] = null;
if (seqnums != null)
seqnums[msgnum-1] = -1;
}
}
size = newsize;
}
/**
* Return the sequence number for the given message number.
*/
public int seqnumOf(int msgnum) {
if (seqnums == null)
return msgnum;
else {
if (logger.isLoggable(Level.FINE))
logger.fine("msgnum " + msgnum + " is seqnum " +
seqnums[msgnum-1]);
return seqnums[msgnum-1];
}
}
/**
* Return the message number for the given sequence number.
*/
private int msgnumOf(int seqnum) {
if (seqnums == null)
return seqnum;
if (seqnum < 1) { // should never happen
if (logger.isLoggable(Level.FINE))
logger.fine("bad seqnum " + seqnum);
return -1;
}
for (int msgnum = seqnum; msgnum <= size; msgnum++) {
if (seqnums[msgnum-1] == seqnum)
return msgnum;
if (seqnums[msgnum-1] > seqnum)
break; // message doesn't exist
}
return -1;
}
}

View File

@ -1,460 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import java.util.*;
/**
* The Rights class represents the set of rights for an authentication
* identifier (for instance, a user or a group). <p>
*
* A right is represented by the <code>Rights.Right</code>
* inner class. <p>
*
* A set of standard rights are predefined (see RFC 2086). Most folder
* implementations are expected to support these rights. Some
* implementations may also support site-defined rights. <p>
*
* The following code sample illustrates how to examine your
* rights for a folder. <p>
* <pre>
*
* Rights rights = folder.myRights();
*
* // Check if I can write this folder
* if (rights.contains(Rights.Right.WRITE))
* System.out.println("Can write folder");
*
* // Now give Joe all my rights, except the ability to write the folder
* rights.remove(Rights.Right.WRITE);
* ACL acl = new ACL("joe", rights);
* folder.setACL(acl);
* </pre>
* <p>
*
* @author Bill Shannon
*/
public class Rights implements Cloneable {
private boolean[] rights = new boolean[128]; // XXX
/**
* This inner class represents an individual right. A set
* of standard rights objects are predefined here.
*/
public static final class Right {
private static Right[] cache = new Right[128];
// XXX - initialization order?
/**
* Lookup - mailbox is visible to LIST/LSUB commands.
*/
public static final Right LOOKUP = getInstance('l');
/**
* Read - SELECT the mailbox, perform CHECK, FETCH, PARTIAL,
* SEARCH, COPY from mailbox
*/
public static final Right READ = getInstance('r');
/**
* Keep seen/unseen information across sessions - STORE \SEEN flag.
*/
public static final Right KEEP_SEEN = getInstance('s');
/**
* Write - STORE flags other than \SEEN and \DELETED.
*/
public static final Right WRITE = getInstance('w');
/**
* Insert - perform APPEND, COPY into mailbox.
*/
public static final Right INSERT = getInstance('i');
/**
* Post - send mail to submission address for mailbox,
* not enforced by IMAP4 itself.
*/
public static final Right POST = getInstance('p');
/**
* Create - CREATE new sub-mailboxes in any implementation-defined
* hierarchy, RENAME or DELETE mailbox.
*/
public static final Right CREATE = getInstance('c');
/**
* Delete - STORE \DELETED flag, perform EXPUNGE.
*/
public static final Right DELETE = getInstance('d');
/**
* Administer - perform SETACL.
*/
public static final Right ADMINISTER = getInstance('a');
char right; // the right represented by this Right object
/**
* Private constructor used only by getInstance.
*/
private Right(char right) {
if ((int)right >= 128)
throw new IllegalArgumentException("Right must be ASCII");
this.right = right;
}
/**
* Get a Right object representing the specified character.
* Characters are assigned per RFC 2086.
*/
public static synchronized Right getInstance(char right) {
if ((int)right >= 128)
throw new IllegalArgumentException("Right must be ASCII");
if (cache[(int)right] == null)
cache[(int)right] = new Right(right);
return cache[(int)right];
}
public String toString() {
return String.valueOf(right);
}
}
/**
* Construct an empty Rights object.
*/
public Rights() { }
/**
* Construct a Rights object initialized with the given rights.
*
* @param rights the rights for initialization
*/
public Rights(Rights rights) {
System.arraycopy(rights.rights, 0, this.rights, 0, this.rights.length);
}
/**
* Construct a Rights object initialized with the given rights.
*
* @param rights the rights for initialization
*/
public Rights(String rights) {
for (int i = 0; i < rights.length(); i++)
add(Right.getInstance(rights.charAt(i)));
}
/**
* Construct a Rights object initialized with the given right.
*
* @param right the right for initialization
*/
public Rights(Right right) {
this.rights[(int)right.right] = true;
}
/**
* Add the specified right to this Rights object.
*
* @param right the right to add
*/
public void add(Right right) {
this.rights[(int)right.right] = true;
}
/**
* Add all the rights in the given Rights object to this
* Rights object.
*
* @param rights Rights object
*/
public void add(Rights rights) {
for (int i = 0; i < rights.rights.length; i++)
if (rights.rights[i])
this.rights[i] = true;
}
/**
* Remove the specified right from this Rights object.
*
* @param right the right to be removed
*/
public void remove(Right right) {
this.rights[(int)right.right] = false;
}
/**
* Remove all rights in the given Rights object from this
* Rights object.
*
* @param rights the rights to be removed
*/
public void remove(Rights rights) {
for (int i = 0; i < rights.rights.length; i++)
if (rights.rights[i])
this.rights[i] = false;
}
/**
* Check whether the specified right is present in this Rights object.
*
* @return true of the given right is present, otherwise false.
*/
public boolean contains(Right right) {
return this.rights[(int)right.right];
}
/**
* Check whether all the rights in the specified Rights object are
* present in this Rights object.
*
* @return true if all rights in the given Rights object are present,
* otherwise false.
*/
public boolean contains(Rights rights) {
for (int i = 0; i < rights.rights.length; i++)
if (rights.rights[i] && !this.rights[i])
return false;
// If we've made it till here, return true
return true;
}
/**
* Check whether the two Rights objects are equal.
*
* @return true if they're equal
*/
public boolean equals(Object obj) {
if (!(obj instanceof Rights))
return false;
Rights rights = (Rights)obj;
for (int i = 0; i < rights.rights.length; i++)
if (rights.rights[i] != this.rights[i])
return false;
return true;
}
/**
* Compute a hash code for this Rights object.
*
* @return the hash code
*/
public int hashCode() {
int hash = 0;
for (int i = 0; i < this.rights.length; i++)
if (this.rights[i])
hash++;
return hash;
}
/**
* Return all the rights in this Rights object. Returns
* an array of size zero if no rights are set.
*
* @return array of Rights.Right objects representing rights
*/
public Right[] getRights() {
Vector v = new Vector();
for (int i = 0; i < this.rights.length; i++)
if (this.rights[i])
v.addElement(Right.getInstance((char)i));
Right[] rights = new Right[v.size()];
v.copyInto(rights);
return rights;
}
/**
* Returns a clone of this Rights object.
*/
public Object clone() {
Rights r = null;
try {
r = (Rights)super.clone();
r.rights = new boolean[128];
System.arraycopy(this.rights, 0, r.rights, 0, this.rights.length);
} catch (CloneNotSupportedException cex) {
// ignore, can't happen
}
return r;
}
public String toString() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < this.rights.length; i++)
if (this.rights[i])
sb.append((char)i);
return sb.toString();
}
/*****
public static void main(String argv[]) throws Exception {
// a new rights object
Rights f1 = new Rights();
f1.add(Rights.Right.READ);
f1.add(Rights.Right.WRITE);
f1.add(Rights.Right.CREATE);
f1.add(Rights.Right.DELETE);
// check copy constructor
Rights fc = new Rights(f1);
if (f1.equals(fc) && fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// check clone
fc = (Rights)f1.clone();
if (f1.equals(fc) && fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// add a right and make sure it still works right
f1.add(Rights.Right.ADMINISTER);
// shouldn't be equal here
if (!f1.equals(fc) && !fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// check clone
fc = (Rights)f1.clone();
if (f1.equals(fc) && fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
fc.add(Rights.Right.INSERT);
if (!f1.equals(fc) && !fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// check copy constructor
fc = new Rights(f1);
if (f1.equals(fc) && fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// another new rights object
Rights f2 = new Rights(Rights.Right.READ);
f2.add(Rights.Right.WRITE);
if (f1.contains(Rights.Right.READ))
System.out.println("success");
else
System.out.println("fail");
if (f1.contains(Rights.Right.WRITE))
System.out.println("success");
else
System.out.println("fail");
if (f1.contains(Rights.Right.CREATE))
System.out.println("success");
else
System.out.println("fail");
if (f1.contains(Rights.Right.DELETE))
System.out.println("success");
else
System.out.println("fail");
if (f2.contains(Rights.Right.WRITE))
System.out.println("success");
else
System.out.println("fail");
System.out.println("----------------");
Right[] r = f1.getRights();
for (int i = 0; i < r.length; i++)
System.out.println(r[i]);
System.out.println("----------------");
if (f1.contains(f2)) // this should be true
System.out.println("success");
else
System.out.println("fail");
if (!f2.contains(f1)) // this should be false
System.out.println("success");
else
System.out.println("fail");
Rights f3 = new Rights();
f3.add(Rights.Right.READ);
f3.add(Rights.Right.WRITE);
f3.add(Rights.Right.CREATE);
f3.add(Rights.Right.DELETE);
f3.add(Rights.Right.ADMINISTER);
f3.add(Rights.Right.LOOKUP);
f1.add(Rights.Right.LOOKUP);
if (f1.equals(f3))
System.out.println("equals success");
else
System.out.println("fail");
if (f3.equals(f1))
System.out.println("equals success");
else
System.out.println("fail");
System.out.println("f1 hash code " + f1.hashCode());
System.out.println("f3 hash code " + f3.hashCode());
if (f1.hashCode() == f3.hashCode())
System.out.println("success");
else
System.out.println("fail");
}
****/
}

View File

@ -1,104 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
/**
* A particular sort criteria, as defined by
* <A HREF="http://www.ietf.org/rfc/rfc5256.txt">RFC 5256</A>.
* Sort criteria are used with the
* {@link IMAPFolder#getSortedMessages getSortedMessages} method.
* Multiple sort criteria are specified in an array with the order in
* the array specifying the order in which the sort criteria are applied.
*
* @since JavaMail 1.4.4
*/
public final class SortTerm {
/**
* Sort by message arrival date and time.
*/
public static final SortTerm ARRIVAL = new SortTerm("ARRIVAL");
/**
* Sort by email address of first Cc recipient.
*/
public static final SortTerm CC = new SortTerm("CC");
/**
* Sort by sent date and time.
*/
public static final SortTerm DATE = new SortTerm("DATE");
/**
* Sort by first From email address.
*/
public static final SortTerm FROM = new SortTerm("FROM");
/**
* Reverse the sort order of the following item.
*/
public static final SortTerm REVERSE = new SortTerm("REVERSE");
/**
* Sort by the message size.
*/
public static final SortTerm SIZE = new SortTerm("SIZE");
/**
* Sort by the base subject text. Note that the "base subject"
* is defined by RFC 5256 and doesn't include items such as "Re:"
* in the subject header.
*/
public static final SortTerm SUBJECT = new SortTerm("SUBJECT");
/**
* Sort by email address of first To recipient.
*/
public static final SortTerm TO = new SortTerm("TO");
private String term;
private SortTerm(String term) {
this.term = term;
}
public String toString() {
return term;
}
}

View File

@ -1,186 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap;
import java.util.Vector;
import javax.mail.*;
import com.sun.mail.util.*;
import com.sun.mail.imap.protocol.MessageSet;
import com.sun.mail.imap.protocol.UIDSet;
/**
* Holder for some static utility methods.
*
* @author John Mani
* @author Bill Shannon
*/
public final class Utility {
// Cannot be initialized
private Utility() { }
/**
* Run thru the given array of messages, apply the given
* Condition on each message and generate sets of contiguous
* sequence-numbers for the successful messages. If a message
* in the given array is found to be expunged, it is ignored.
*
* ASSERT: Since this method uses and returns message sequence
* numbers, you should use this method only when holding the
* messageCacheLock.
*/
public static
MessageSet[] toMessageSet(Message[] msgs, Condition cond) {
Vector v = new Vector(1);
int current, next;
IMAPMessage msg;
for (int i = 0; i < msgs.length; i++) {
msg = (IMAPMessage)msgs[i];
if (msg.isExpunged()) // expunged message, skip it
continue;
current = msg.getSequenceNumber();
// Apply the condition. If it fails, skip it.
if ((cond != null) && !cond.test(msg))
continue;
MessageSet set = new MessageSet();
set.start = current;
// Look for contiguous sequence numbers
for (++i; i < msgs.length; i++) {
// get next message
msg = (IMAPMessage)msgs[i];
if (msg.isExpunged()) // expunged message, skip it
continue;
next = msg.getSequenceNumber();
// Does this message match our condition ?
if ((cond != null) && !cond.test(msg))
continue;
if (next == current+1)
current = next;
else { // break in sequence
// We need to reexamine this message at the top of
// the outer loop, so decrement 'i' to cancel the
// outer loop's autoincrement
i--;
break;
}
}
set.end = current;
v.addElement(set);
}
if (v.isEmpty()) // No valid messages
return null;
else {
MessageSet[] sets = new MessageSet[v.size()];
v.copyInto(sets);
return sets;
}
}
/**
* Return UIDSets for the messages. Note that the UIDs
* must have already been fetched for the messages.
*/
public static UIDSet[] toUIDSet(Message[] msgs) {
Vector v = new Vector(1);
long current, next;
IMAPMessage msg;
for (int i = 0; i < msgs.length; i++) {
msg = (IMAPMessage)msgs[i];
if (msg.isExpunged()) // expunged message, skip it
continue;
current = msg.getUID();
UIDSet set = new UIDSet();
set.start = current;
// Look for contiguous UIDs
for (++i; i < msgs.length; i++) {
// get next message
msg = (IMAPMessage)msgs[i];
if (msg.isExpunged()) // expunged message, skip it
continue;
next = msg.getUID();
if (next == current+1)
current = next;
else { // break in sequence
// We need to reexamine this message at the top of
// the outer loop, so decrement 'i' to cancel the
// outer loop's autoincrement
i--;
break;
}
}
set.end = current;
v.addElement(set);
}
if (v.isEmpty()) // No valid messages
return null;
else {
UIDSet[] sets = new UIDSet[v.size()];
v.copyInto(sets);
return sets;
}
}
/**
* This interface defines the test to be executed in
* <code>toMessageSet()</code>.
*/
public static interface Condition {
public boolean test(IMAPMessage message);
}
}

View File

@ -1,623 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can
obtain a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
or packager/legal/LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.
When distributing the software, include this License Header Notice in each
file and include the License file at packager/legal/LICENSE.txt.
GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.
Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"
Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->
</HEAD>
<BODY BGCOLOR="white">
An IMAP protocol provider for the JavaMail API
that provides access to an IMAP message store.
Both the IMAP4 and IMAP4rev1 protocols are supported.
Refer to <A HREF="http://www.ietf.org/rfc/rfc2060.txt" TARGET="_top">
RFC 2060</A>
for more information.
<P>
The IMAP protocol provider can use SASL
(<A HREF="http://www.ietf.org/rfc/rfc2222.txt" TARGET="_top">RFC 2222</A>)
authentication mechanisms on systems that support the
<CODE>javax.security.sasl</CODE> APIs, such as J2SE 5.0.
In addition to the SASL mechanisms that are built into
the SASL implementation, users can also provide additional
SASL mechanisms of their own design to support custom authentication
schemes. See the
<A HREF="http://docs.oracle.com/javase/1.5.0/docs/guide/security/sasl/sasl-refguide.html" TARGET="_top">
Java SASL API Programming and Deployment Guide</A> for details.
Note that the current implementation doesn't support SASL mechanisms
that provide their own integrity or confidentiality layer.
<P>
A connected IMAPStore maintains a pool of IMAP protocol objects for
use in communicating with the IMAP server. The IMAPStore will create
the initial AUTHENTICATED connection and seed the pool with this
connection. As folders are opened and new IMAP protocol objects are
needed, the IMAPStore will provide them from the connection pool,
or create them if none are available. When a folder is closed,
its IMAP protocol object is returned to the connection pool if the
pool is not over capacity.
<P>
A mechanism is provided for timing out idle connection pool IMAP
protocol objects. Timed out connections are closed and removed (pruned)
from the connection pool.
<P>
The connected IMAPStore object may or may not maintain a separate IMAP
protocol object that provides the store a dedicated connection to the
IMAP server. This is provided mainly for compatibility with previous
implementations of the IMAP protocol provider.
<P>
The IMAP protocol provider supports the following properties,
which may be set in the JavaMail <code>Session</code> object.
The properties are always set as strings; the Type column describes
how the string is interpreted. For example, use
<PRE>
props.put("mail.imap.port", "888");
</PRE>
to set the <CODE>mail.imap.port</CODE> property, which is of type int.
<P>
Note that if you're using the "imaps" protocol to access IMAP over SSL,
all the properties would be named "mail.imaps.*".
<P>
<TABLE BORDER>
<TR>
<TH>Name</TH>
<TH>Type</TH>
<TH>Description</TH>
</TR>
<TR>
<TD>mail.imap.user</TD>
<TD>String</TD>
<TD>Default user name for IMAP.</TD>
</TR>
<TR>
<TD>mail.imap.host</TD>
<TD>String</TD>
<TD>The IMAP server to connect to.</TD>
</TR>
<TR>
<TD>mail.imap.port</TD>
<TD>int</TD>
<TD>The IMAP server port to connect to, if the connect() method doesn't
explicitly specify one. Defaults to 143.</TD>
</TR>
<TR>
<TD>mail.imap.partialfetch</TD>
<TD>boolean</TD>
<TD>Controls whether the IMAP partial-fetch capability should be used.
Defaults to true.</TD>
</TR>
<TR>
<TD>mail.imap.fetchsize</TD>
<TD>int</TD>
<TD>Partial fetch size in bytes. Defaults to 16K.</TD>
</TR>
<TR>
<TD>mail.imap.ignorebodystructuresize</TD>
<TD>boolean</TD>
<TD>The IMAP BODYSTRUCTURE response includes the exact size of each body part.
Normally, this size is used to determine how much data to fetch for each
body part.
Some servers report this size incorrectly in some cases; this property can
be set to work around such server bugs.
If this property is set to true, this size is ignored and data is fetched
until the server reports the end of data.
This will result in an extra fetch if the data size is a multiple of the
block size.
Defaults to false.</TD>
</TR>
<TR>
<TD>mail.imap.connectiontimeout</TD>
<TD>int</TD>
<TD>Socket connection timeout value in milliseconds.
Default is infinite timeout.</TD>
</TR>
<TR>
<TD>mail.imap.timeout</TD>
<TD>int</TD>
<TD>Socket I/O timeout value in milliseconds. Default is infinite timeout.</TD>
</TR>
<TR>
<TD>mail.imap.statuscachetimeout</TD>
<TD>int</TD>
<TD>Timeout value in milliseconds for cache of STATUS command response.
Default is 1000 (1 second). Zero disables cache.</TD>
</TR>
<TR>
<TD>mail.imap.appendbuffersize</TD>
<TD>int</TD>
<TD>
Maximum size of a message to buffer in memory when appending to an IMAP
folder. If not set, or set to -1, there is no maximum and all messages
are buffered. If set to 0, no messages are buffered. If set to (e.g.)
8192, messages of 8K bytes or less are buffered, larger messages are
not buffered. Buffering saves cpu time at the expense of short term
memory usage. If you commonly append very large messages to IMAP
mailboxes you might want to set this to a moderate value (1M or less).
</TD>
</TR>
<TR>
<TD>mail.imap.connectionpoolsize</TD>
<TD>int</TD>
<TD>Maximum number of available connections in the connection pool.
Default is 1.</TD>
</TR>
<TR>
<TD>mail.imap.connectionpooltimeout</TD>
<TD>int</TD>
<TD>Timeout value in milliseconds for connection pool connections. Default
is 45000 (45 seconds).</TD>
</TR>
<TR>
<TD>mail.imap.separatestoreconnection</TD>
<TD>boolean</TD>
<TD>Flag to indicate whether to use a dedicated store connection for store
commands. Default is false.</TD>
</TR>
<TR>
<TD>mail.imap.allowreadonlyselect</TD>
<TD>boolean</TD>
<TD>If false, attempts to open a folder read/write will fail
if the SELECT command succeeds but indicates that the folder is READ-ONLY.
This sometimes indicates that the folder contents can'tbe changed, but
the flags are per-user and can be changed, such as might be the case for
public shared folders. If true, such open attempts will succeed, allowing
the flags to be changed. The <code>getMode</code> method on the
<code>Folder</code> object will return <code>Folder.READ_ONLY</code>
in this case even though the <code>open</code> method specified
<code>Folder.READ_WRITE</code>. Default is false.</TD>
</TR>
<TR>
<TD>mail.imap.auth.login.disable</TD>
<TD>boolean</TD>
<TD>If true, prevents use of the non-standard <code>AUTHENTICATE LOGIN</code>
command, instead using the plain <code>LOGIN</code> command.
Default is false.</TD>
</TR>
<TR>
<TD>mail.imap.auth.plain.disable</TD>
<TD>boolean</TD>
<TD>If true, prevents use of the <code>AUTHENTICATE PLAIN</code> command.
Default is false.</TD>
</TR>
<TR>
<TD>mail.imap.auth.ntlm.disable</TD>
<TD>boolean</TD>
<TD>If true, prevents use of the <code>AUTHENTICATE NTLM</code> command.
Default is false.</TD>
</TR>
<TR>
<TD>mail.imap.proxyauth.user</TD>
<TD>String</TD>
<TD>If the server supports the PROXYAUTH extension, this property
specifies the name of the user to act as. Authenticate to the
server using the administrator's credentials. After authentication,
the IMAP provider will issue the <code>PROXYAUTH</code> command with
the user name specified in this property.
</TD>
</TR>
<TR>
<TD>mail.imap.localaddress</TD>
<TD>String</TD>
<TD>
Local address (host name) to bind to when creating the IMAP socket.
Defaults to the address picked by the Socket class.
Should not normally need to be set, but useful with multi-homed hosts
where it's important to pick a particular local address to bind to.
</TD>
</TR>
<TR>
<TD>mail.imap.localport</TD>
<TD>int</TD>
<TD>
Local port number to bind to when creating the IMAP socket.
Defaults to the port number picked by the Socket class.
</TD>
</TR>
<TR>
<TD>mail.imap.sasl.enable</TD>
<TD>boolean</TD>
<TD>
If set to true, attempt to use the javax.security.sasl package to
choose an authentication mechanism for login.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.imap.sasl.mechanisms</TD>
<TD>String</TD>
<TD>
A space or comma separated list of SASL mechanism names to try
to use.
</TD>
</TR>
<TR>
<TD>mail.imap.sasl.authorizationid</TD>
<TD>String</TD>
<TD>
The authorization ID to use in the SASL authentication.
If not set, the authentication ID (user name) is used.
</TD>
</TR>
<TR>
<TD>mail.imap.sasl.realm</TD>
<TD>String</TD>
<TD>The realm to use with SASL authentication mechanisms that
require a realm, such as DIGEST-MD5.</TD>
</TR>
<TR>
<TD>mail.imap.sasl. xgwtrustedapphack.enable</TD>
<TD>boolean</TD>
<TD>
If set to true, enables a workaround for a bug in the Novell Groupwise
XGWTRUSTEDAPP SASL mechanism, when that mechanism is being used.
Defaults to true.
</TD>
</TR>
<TR>
<TD>mail.imap.auth.ntlm.domain</TD>
<TD>String</TD>
<TD>
The NTLM authentication domain.
</TD>
</TR>
<TR>
<TD>mail.imap.auth.ntlm.flags</TD>
<TD>int</TD>
<TD>
NTLM protocol-specific flags.
See <A HREF="http://curl.haxx.se/rfc/ntlm.html#theNtlmFlags" TARGET="_top">
http://curl.haxx.se/rfc/ntlm.html#theNtlmFlags</A> for details.
</TD>
</TR>
<TR>
<TD>mail.imap.socketFactory</TD>
<TD>SocketFactory</TD>
<TD>
If set to a class that implements the
<code>javax.net.SocketFactory</code> interface, this class
will be used to create IMAP sockets. Note that this is an
instance of a class, not a name, and must be set using the
<code>put</code> method, not the <code>setProperty</code> method.
</TD>
</TR>
<TR>
<TD>mail.imap.socketFactory.class</TD>
<TD>String</TD>
<TD>
If set, specifies the name of a class that implements the
<code>javax.net.SocketFactory</code> interface. This class
will be used to create IMAP sockets.
</TD>
</TR>
<TR>
<TD>mail.imap.socketFactory.fallback</TD>
<TD>boolean</TD>
<TD>
If set to true, failure to create a socket using the specified
socket factory class will cause the socket to be created using
the <code>java.net.Socket</code> class.
Defaults to true.
</TD>
</TR>
<TR>
<TD>mail.imap.socketFactory.port</TD>
<TD>int</TD>
<TD>
Specifies the port to connect to when using the specified socket
factory.
If not set, the default port will be used.
</TD>
</TR>
<TR>
<TD>mail.imap.ssl.enable</TD>
<TD>boolean</TD>
<TD>
If set to true, use SSL to connect and use the SSL port by default.
Defaults to false for the "imap" protocol and true for the "imaps" protocol.
</TD>
</TR>
<TR>
<TD>mail.imap.ssl.checkserveridentity</TD>
<TD>boolean</TD>
<TD>
If set to true, check the server identity as specified by
<A HREF="http://www.ietf.org/rfc/rfc2595.txt" TARGET="_top">RFC 2595</A>.
These additional checks based on the content of the server's certificate
are intended to prevent man-in-the-middle attacks.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.imap.ssl.trust</TD>
<TD>String</TD>
<TD>
If set, and a socket factory hasn't been specified, enables use of a
{@link com.sun.mail.util.MailSSLSocketFactory MailSSLSocketFactory}.
If set to "*", all hosts are trusted.
If set to a whitespace separated list of hosts, those hosts are trusted.
Otherwise, trust depends on the certificate the server presents.
</TD>
</TR>
<TR>
<TD>mail.imap.ssl.socketFactory</TD>
<TD>SSLSocketFactory</TD>
<TD>
If set to a class that extends the
<code>javax.net.ssl.SSLSocketFactory</code> class, this class
will be used to create IMAP SSL sockets. Note that this is an
instance of a class, not a name, and must be set using the
<code>put</code> method, not the <code>setProperty</code> method.
</TD>
</TR>
<TR>
<TD>mail.imap.ssl.socketFactory.class</TD>
<TD>String</TD>
<TD>
If set, specifies the name of a class that extends the
<code>javax.net.ssl.SSLSocketFactory</code> class. This class
will be used to create IMAP SSL sockets.
</TD>
</TR>
<TR>
<TD>mail.imap.ssl.socketFactory.port</TD>
<TD>int</TD>
<TD>
Specifies the port to connect to when using the specified socket
factory.
If not set, the default port will be used.
</TD>
</TR>
<TR>
<TD>mail.imap.ssl.protocols</TD>
<TD>string</TD>
<TD>
Specifies the SSL protocols that will be enabled for SSL connections.
The property value is a whitespace separated list of tokens acceptable
to the <code>javax.net.ssl.SSLSocket.setEnabledProtocols</code> method.
</TD>
</TR>
<TR>
<TD>mail.imap.ssl.ciphersuites</TD>
<TD>string</TD>
<TD>
Specifies the SSL cipher suites that will be enabled for SSL connections.
The property value is a whitespace separated list of tokens acceptable
to the <code>javax.net.ssl.SSLSocket.setEnabledCipherSuites</code> method.
</TD>
</TR>
<TR>
<TD>mail.imap.starttls.enable</TD>
<TD>boolean</TD>
<TD>If true, enables the use of the <code>STARTTLS</code> command (if
supported by the server) to switch the connection to a TLS-protected
connection before issuing any login commands. Note that an appropriate
trust store must configured so that the client will trust the server's
certificate. This feature only works on J2SE 1.4 and newer systems.
Default is false.</TD>
</TR>
<TR>
<TD>mail.imap.starttls.required</TD>
<TD>boolean</TD>
<TD>
If true, requires the use of the <code>STARTTLS</code> command.
If the server doesn't support the STARTTLS command, or the command
fails, the connect method will fail.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.imap.socks.host</TD>
<TD>string</TD>
<TD>
Specifies the host name of a SOCKS5 proxy server that will be used for
connections to the mail server.
(Note that this only works on JDK 1.5 or newer.)
</TD>
</TR>
<TR>
<TD>mail.imap.socks.port</TD>
<TD>string</TD>
<TD>
Specifies the port number for the SOCKS5 proxy server.
This should only need to be used if the proxy server is not using
the standard port number of 1080.
</TD>
</TR>
<TR>
<TD>mail.imap.minidletime</TD>
<TD>int</TD>
<TD>
Applications typically call the idle method in a loop. If another
thread termiantes the IDLE command, it needs a chance to do its
work before another IDLE command is issued. The idle method enforces
a delay to prevent thrashing between the IDLE command and regular
commands. This property sets the delay in milliseconds. If not
set, the default is 10 milliseconds.
</TD>
</TR>
<TR>
<TD>mail.imap.enableimapevents</TD>
<TD>boolean</TD>
<TD>
Enable special IMAP-specific events to be delivered to the Store's
<code>ConnectionListener</code>. If true, unsolicited responses
received during the Store's <code>idle</code> method will be sent
as <code>ConnectionEvent</code>s with a type of
<code>IMAPStore.RESPONSE</code>. The event's message will be the
raw IMAP response string.
By default, these events are not sent.
NOTE: This capability is highly experimental and likely will change
in future releases.
</TD>
</TR>
<TR>
<TD>mail.imap.folder.class</TD>
<TD>String</TD>
<TD>
Class name of a subclass of <code>com.sun.mail.imap.IMAPFolder</code>.
The subclass can be used to provide support for additional IMAP commands.
The subclass must have public constructors of the form
<code>public MyIMAPFolder(String fullName, char separator, IMAPStore store,
Boolean isNamespace)</code> and
<code>public MyIMAPFolder(ListInfo li, IMAPStore store)</code>
</TD>
</TR>
</TABLE>
<P>
In general, applications should not need to use the classes in this
package directly. Instead, they should use the APIs defined by
<code>javax.mail</code> package (and subpackages). Applications should
never construct instances of <code>IMAPStore</code> or
<code>IMAPFolder</code> directly. Instead, they should use the
<code>Session</code> method <code>getStore</code> to acquire an
appropriate <code>Store</code> object, and from that acquire
<code>Folder</code> objects.
<P>
In addition to printing debugging output as controlled by the
{@link javax.mail.Session Session} configuration,
the com.sun.mail.imap provider logs the same information using
{@link java.util.logging.Logger} as described in the following table:
<P>
<TABLE BORDER>
<TR>
<TH>Logger Name</TH>
<TH>Logging Level</TH>
<TH>Purpose</TH>
</TR>
<TR>
<TD>com.sun.mail.imap</TD>
<TD>CONFIG</TD>
<TD>Configuration of the IMAPStore</TD>
</TR>
<TR>
<TD>com.sun.mail.imap</TD>
<TD>FINE</TD>
<TD>General debugging output</TD>
</TR>
<TR>
<TD>com.sun.mail.imap.connectionpool</TD>
<TD>CONFIG</TD>
<TD>Configuration of the IMAP connection pool</TD>
</TR>
<TR>
<TD>com.sun.mail.imap.connectionpool</TD>
<TD>FINE</TD>
<TD>Debugging output related to the IMAP connection pool</TD>
</TR>
<TR>
<TD>com.sun.mail.imap.messagecache</TD>
<TD>CONFIG</TD>
<TD>Configuration of the IMAP message cache</TD>
</TR>
<TR>
<TD>com.sun.mail.imap.messagecache</TD>
<TD>FINE</TD>
<TD>Debugging output related to the IMAP message cache</TD>
</TR>
<TR>
<TD>com.sun.mail.imap.protocol</TD>
<TD>FINEST</TD>
<TD>Complete protocol trace</TD>
</TR>
</TABLE>
<P>
<strong>WARNING:</strong> The APIs unique to this package should be
considered <strong>EXPERIMENTAL</strong>. They may be changed in the
future in ways that are incompatible with applications using the
current APIs.
</BODY>
</HTML>

View File

@ -1,194 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.text.StringCharacterIterator;
import java.text.CharacterIterator;
/**
* See the BASE64MailboxEncoder for a description of the RFC2060 and how
* mailbox names should be encoded. This class will do the correct decoding
* for mailbox names.
*
* @author Christopher Cotton
*/
public class BASE64MailboxDecoder {
public static String decode(String original) {
if (original == null || original.length() == 0)
return original;
boolean changedString = false;
int copyTo = 0;
// it will always be less than the original
char[] chars = new char[original.length()];
StringCharacterIterator iter = new StringCharacterIterator(original);
for(char c = iter.first(); c != CharacterIterator.DONE;
c = iter.next()) {
if (c == '&') {
changedString = true;
copyTo = base64decode(chars, copyTo, iter);
} else {
chars[copyTo++] = c;
}
}
// now create our string from the char array
if (changedString) {
return new String(chars, 0, copyTo);
} else {
return original;
}
}
protected static int base64decode(char[] buffer, int offset,
CharacterIterator iter) {
boolean firsttime = true;
int leftover = -1;
while(true) {
// get the first byte
byte orig_0 = (byte) iter.next();
if (orig_0 == -1) break; // no more chars
if (orig_0 == '-') {
if (firsttime) {
// means we got the string "&-" which is turned into a "&"
buffer[offset++] = '&';
}
// we are done now
break;
}
firsttime = false;
// next byte
byte orig_1 = (byte) iter.next();
if (orig_1 == -1 || orig_1 == '-')
break; // no more chars, invalid base64
byte a, b, current;
a = pem_convert_array[orig_0 & 0xff];
b = pem_convert_array[orig_1 & 0xff];
// The first decoded byte
current = (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3));
// use the leftover to create a Unicode Character (2 bytes)
if (leftover != -1) {
buffer[offset++] = (char)(leftover << 8 | (current & 0xff));
leftover = -1;
} else {
leftover = current & 0xff;
}
byte orig_2 = (byte) iter.next();
if (orig_2 == '=') { // End of this BASE64 encoding
continue;
} else if (orig_2 == -1 || orig_2 == '-') {
break; // no more chars
}
// second decoded byte
a = b;
b = pem_convert_array[orig_2 & 0xff];
current = (byte)(((a << 4) & 0xf0) | ((b >>> 2) & 0xf));
// use the leftover to create a Unicode Character (2 bytes)
if (leftover != -1) {
buffer[offset++] = (char)(leftover << 8 | (current & 0xff));
leftover = -1;
} else {
leftover = current & 0xff;
}
byte orig_3 = (byte) iter.next();
if (orig_3 == '=') { // End of this BASE64 encoding
continue;
} else if (orig_3 == -1 || orig_3 == '-') {
break; // no more chars
}
// The third decoded byte
a = b;
b = pem_convert_array[orig_3 & 0xff];
current = (byte)(((a << 6) & 0xc0) | (b & 0x3f));
// use the leftover to create a Unicode Character (2 bytes)
if (leftover != -1) {
buffer[offset++] = (char)(leftover << 8 | (current & 0xff));
leftover = -1;
} else {
leftover = current & 0xff;
}
}
return offset;
}
/**
* This character array provides the character to value map
* based on RFC1521, but with the modification from RFC2060
* which changes the '/' to a ','.
*/
// shared with BASE64MailboxEncoder
static final char pem_array[] = {
'A','B','C','D','E','F','G','H', // 0
'I','J','K','L','M','N','O','P', // 1
'Q','R','S','T','U','V','W','X', // 2
'Y','Z','a','b','c','d','e','f', // 3
'g','h','i','j','k','l','m','n', // 4
'o','p','q','r','s','t','u','v', // 5
'w','x','y','z','0','1','2','3', // 6
'4','5','6','7','8','9','+',',' // 7
};
private static final byte pem_convert_array[] = new byte[256];
static {
for (int i = 0; i < 255; i++)
pem_convert_array[i] = -1;
for(int i = 0; i < pem_array.length; i++)
pem_convert_array[pem_array[i]] = (byte) i;
}
}

View File

@ -1,260 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.io.*;
/**
*
*
from RFC2060
5.1.3. Mailbox International Naming Convention
By convention, international mailbox names are specified using a
modified version of the UTF-7 encoding described in [UTF-7]. The
purpose of these modifications is to correct the following problems
with UTF-7:
1) UTF-7 uses the "+" character for shifting; this conflicts with
the common use of "+" in mailbox names, in particular USENET
newsgroup names.
2) UTF-7's encoding is BASE64 which uses the "/" character; this
conflicts with the use of "/" as a popular hierarchy delimiter.
3) UTF-7 prohibits the unencoded usage of "\"; this conflicts with
the use of "\" as a popular hierarchy delimiter.
4) UTF-7 prohibits the unencoded usage of "~"; this conflicts with
the use of "~" in some servers as a home directory indicator.
5) UTF-7 permits multiple alternate forms to represent the same
string; in particular, printable US-ASCII chararacters can be
represented in encoded form.
In modified UTF-7, printable US-ASCII characters except for "&"
represent themselves; that is, characters with octet values 0x20-0x25
and 0x27-0x7e. The character "&" (0x26) is represented by the two-
octet sequence "&-".
All other characters (octet values 0x00-0x1f, 0x7f-0xff, and all
Unicode 16-bit octets) are represented in modified BASE64, with a
further modification from [UTF-7] that "," is used instead of "/".
Modified BASE64 MUST NOT be used to represent any printing US-ASCII
character which can represent itself.
"&" is used to shift to modified BASE64 and "-" to shift back to US-
ASCII. All names start in US-ASCII, and MUST end in US-ASCII (that
is, a name that ends with a Unicode 16-bit octet MUST end with a "-
").
Crispin Standards Track [Page 15]
RFC 2060 IMAP4rev1 December 1996
For example, here is a mailbox name which mixes English, Japanese,
and Chinese text: ~peter/mail/&ZeVnLIqe-/&U,BTFw-
* This class will do the correct Encoding for the IMAP mailboxes
*
* @author Christopher Cotton
*/
public class BASE64MailboxEncoder {
protected byte[] buffer = new byte[4];
protected int bufsize = 0;
protected boolean started = false;
protected Writer out = null;
public static String encode(String original) {
BASE64MailboxEncoder base64stream = null;
char origchars[] = original.toCharArray();
int length = origchars.length;
boolean changedString = false;
CharArrayWriter writer = new CharArrayWriter(length);
// loop over all the chars
for(int index = 0; index < length; index++) {
char current = origchars[index];
// octets in the range 0x20-0x25,0x27-0x7e are themselves
// 0x26 "&" is represented as "&-"
if (current >= 0x20 && current <= 0x7e) {
if (base64stream != null) {
base64stream.flush();
}
if (current == '&') {
changedString = true;
writer.write('&');
writer.write('-');
} else {
writer.write(current);
}
} else {
// use a B64MailboxEncoder to write out the other bytes
// as a modified BASE64. The stream will write out
// the beginning '&' and the ending '-' which is part
// of every encoding.
if (base64stream == null) {
base64stream = new BASE64MailboxEncoder(writer);
changedString = true;
}
base64stream.write(current);
}
}
if (base64stream != null) {
base64stream.flush();
}
if (changedString) {
return writer.toString();
} else {
return original;
}
}
/**
* Create a BASE64 encoder
*/
public BASE64MailboxEncoder(Writer what) {
out = what;
}
public void write(int c) {
try {
// write out the initial character if this is the first time
if (!started) {
started = true;
out.write('&');
}
// we write each character as a 2 byte unicode character
buffer[bufsize++] = (byte) (c >> 8);
buffer[bufsize++] = (byte) (c & 0xff);
if (bufsize >= 3) {
encode();
bufsize -= 3;
}
} catch (IOException e) {
//e.printStackTrace();
}
}
public void flush() {
try {
// flush any bytes we have
if (bufsize > 0) {
encode();
bufsize = 0;
}
// write the terminating character of the encoding
if (started) {
out.write('-');
started = false;
}
} catch (IOException e) {
//e.printStackTrace();
}
}
protected void encode() throws IOException {
byte a, b, c;
if (bufsize == 1) {
a = buffer[0];
b = 0;
c = 0;
out.write(pem_array[(a >>> 2) & 0x3F]);
out.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
// no padding characters are written
} else if (bufsize == 2) {
a = buffer[0];
b = buffer[1];
c = 0;
out.write(pem_array[(a >>> 2) & 0x3F]);
out.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
out.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
// no padding characters are written
} else {
a = buffer[0];
b = buffer[1];
c = buffer[2];
out.write(pem_array[(a >>> 2) & 0x3F]);
out.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
out.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
out.write(pem_array[c & 0x3F]);
// copy back the extra byte
if (bufsize == 4)
buffer[0] = buffer[3];
}
}
private final static char pem_array[] = {
'A','B','C','D','E','F','G','H', // 0
'I','J','K','L','M','N','O','P', // 1
'Q','R','S','T','U','V','W','X', // 2
'Y','Z','a','b','c','d','e','f', // 3
'g','h','i','j','k','l','m','n', // 4
'o','p','q','r','s','t','u','v', // 5
'w','x','y','z','0','1','2','3', // 6
'4','5','6','7','8','9','+',',' // 7
};
}

View File

@ -1,96 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.io.ByteArrayInputStream;
import com.sun.mail.iap.*;
import com.sun.mail.util.ASCIIUtility;
/**
* The BODY fetch response item.
*
* @author John Mani
*/
public class BODY implements Item {
static final char[] name = {'B','O','D','Y'};
public int msgno;
public ByteArray data;
public String section;
public int origin = 0;
/**
* Constructor
*/
public BODY(FetchResponse r) throws ParsingException {
msgno = r.getNumber();
r.skipSpaces();
int b;
while ((b = r.readByte()) != ']') { // skip section
if (b == 0)
throw new ParsingException(
"BODY parse error: missing ``]'' at section end");
}
if (r.readByte() == '<') { // origin
origin = r.readNumber();
r.skip(1); // skip '>';
}
data = r.readByteArray();
}
public ByteArray getByteArray() {
return data;
}
public ByteArrayInputStream getByteArrayInputStream() {
if (data != null)
return data.toByteArrayInputStream();
else
return null;
}
}

View File

@ -1,429 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.util.Vector;
import javax.mail.internet.ParameterList;
import com.sun.mail.iap.*;
import com.sun.mail.util.PropUtil;
/**
* A BODYSTRUCTURE response.
*
* @author John Mani
* @author Bill Shannon
*/
public class BODYSTRUCTURE implements Item {
static final char[] name =
{'B','O','D','Y','S','T','R','U','C','T','U','R','E'};
public int msgno;
public String type; // Type
public String subtype; // Subtype
public String encoding; // Encoding
public int lines = -1; // Size in lines
public int size = -1; // Size in bytes
public String disposition; // Disposition
public String id; // Content-ID
public String description; // Content-Description
public String md5; // MD-5 checksum
public String attachment; // Attachment name
public ParameterList cParams; // Body parameters
public ParameterList dParams; // Disposition parameters
public String[] language; // Language
public BODYSTRUCTURE[] bodies; // array of BODYSTRUCTURE objects
// for multipart & message/rfc822
public ENVELOPE envelope; // for message/rfc822
private static int SINGLE = 1;
private static int MULTI = 2;
private static int NESTED = 3;
private int processedType; // MULTI | SINGLE | NESTED
// special debugging output to debug parsing errors
private static boolean parseDebug =
PropUtil.getBooleanSystemProperty("mail.imap.parse.debug", false);
public BODYSTRUCTURE(FetchResponse r) throws ParsingException {
if (parseDebug)
System.out.println("DEBUG IMAP: parsing BODYSTRUCTURE");
msgno = r.getNumber();
if (parseDebug)
System.out.println("DEBUG IMAP: msgno " + msgno);
r.skipSpaces();
if (r.readByte() != '(')
throw new ParsingException(
"BODYSTRUCTURE parse error: missing ``('' at start");
if (r.peekByte() == '(') { // multipart
if (parseDebug)
System.out.println("DEBUG IMAP: parsing multipart");
type = "multipart";
processedType = MULTI;
Vector v = new Vector(1);
int i = 1;
do {
v.addElement(new BODYSTRUCTURE(r));
/*
* Even though the IMAP spec says there can't be any spaces
* between parts, some servers erroneously put a space in
* here. In the spirit of "be liberal in what you accept",
* we skip it.
*/
r.skipSpaces();
} while (r.peekByte() == '(');
// setup bodies.
bodies = new BODYSTRUCTURE[v.size()];
v.copyInto(bodies);
subtype = r.readString(); // subtype
if (parseDebug)
System.out.println("DEBUG IMAP: subtype " + subtype);
if (r.readByte() == ')') { // done
if (parseDebug)
System.out.println("DEBUG IMAP: parse DONE");
return;
}
// Else, we have extension data
if (parseDebug)
System.out.println("DEBUG IMAP: parsing extension data");
// Body parameters
cParams = parseParameters(r);
if (r.readByte() == ')') { // done
if (parseDebug)
System.out.println("DEBUG IMAP: body parameters DONE");
return;
}
// Disposition
byte b = r.readByte();
if (b == '(') {
if (parseDebug)
System.out.println("DEBUG IMAP: parse disposition");
disposition = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: disposition " +
disposition);
dParams = parseParameters(r);
if (r.readByte() != ')') // eat the end ')'
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
"missing ``)'' at end of disposition in multipart");
if (parseDebug)
System.out.println("DEBUG IMAP: disposition DONE");
} else if (b == 'N' || b == 'n') {
if (parseDebug)
System.out.println("DEBUG IMAP: disposition NIL");
r.skip(2); // skip 'NIL'
} else {
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
type + "/" + subtype + ": " +
"bad multipart disposition, b " + b);
}
// RFC3501 allows no body-fld-lang after body-fld-disp,
// even though RFC2060 required it
if ((b = r.readByte()) == ')') {
if (parseDebug)
System.out.println("DEBUG IMAP: no body-fld-lang");
return; // done
}
if (b != ' ')
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
"missing space after disposition");
// Language
if (r.peekByte() == '(') { // a list follows
language = r.readStringList();
if (parseDebug)
System.out.println(
"DEBUG IMAP: language len " + language.length);
} else {
String l = r.readString();
if (l != null) {
String[] la = { l };
language = la;
if (parseDebug)
System.out.println("DEBUG IMAP: language " + l);
}
}
// RFC3501 defines an optional "body location" next,
// but for now we ignore it along with other extensions.
// Throw away any further extension data
while (r.readByte() == ' ')
parseBodyExtension(r);
}
else { // Single part
if (parseDebug)
System.out.println("DEBUG IMAP: single part");
type = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: type " + type);
processedType = SINGLE;
subtype = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: subtype " + subtype);
// SIMS 4.0 returns NIL for a Content-Type of "binary", fix it here
if (type == null) {
type = "application";
subtype = "octet-stream";
}
cParams = parseParameters(r);
if (parseDebug)
System.out.println("DEBUG IMAP: cParams " + cParams);
id = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: id " + id);
description = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: description " + description);
/*
* XXX - Work around bug in Exchange 2010 that
* returns unquoted string.
*/
encoding = r.readAtomString();
if (encoding != null && encoding.equalsIgnoreCase("NIL"))
encoding = null;
if (parseDebug)
System.out.println("DEBUG IMAP: encoding " + encoding);
size = r.readNumber();
if (parseDebug)
System.out.println("DEBUG IMAP: size " + size);
if (size < 0)
throw new ParsingException(
"BODYSTRUCTURE parse error: bad ``size'' element");
// "text/*" & "message/rfc822" types have additional data ..
if (type.equalsIgnoreCase("text")) {
lines = r.readNumber();
if (parseDebug)
System.out.println("DEBUG IMAP: lines " + lines);
if (lines < 0)
throw new ParsingException(
"BODYSTRUCTURE parse error: bad ``lines'' element");
} else if (type.equalsIgnoreCase("message") &&
subtype.equalsIgnoreCase("rfc822")) {
// Nested message
processedType = NESTED;
// The envelope comes next, but sadly Gmail handles nested
// messages just like simple body parts and fails to return
// the envelope and body structure of the message (sort of
// like IMAP4 before rev1).
r.skipSpaces();
if (r.peekByte() == '(') { // the envelope follows
envelope = new ENVELOPE(r);
if (parseDebug)
System.out.println(
"DEBUG IMAP: got envelope of nested message");
BODYSTRUCTURE[] bs = { new BODYSTRUCTURE(r) };
bodies = bs;
lines = r.readNumber();
if (parseDebug)
System.out.println("DEBUG IMAP: lines " + lines);
if (lines < 0)
throw new ParsingException(
"BODYSTRUCTURE parse error: bad ``lines'' element");
} else {
if (parseDebug)
System.out.println("DEBUG IMAP: " +
"missing envelope and body of nested message");
}
} else {
// Detect common error of including lines element on other types
r.skipSpaces();
byte bn = r.peekByte();
if (Character.isDigit((char)bn)) // number
throw new ParsingException(
"BODYSTRUCTURE parse error: server erroneously " +
"included ``lines'' element with type " +
type + "/" + subtype);
}
if (r.peekByte() == ')') {
r.readByte();
if (parseDebug)
System.out.println("DEBUG IMAP: parse DONE");
return; // done
}
// Optional extension data
// MD5
md5 = r.readString();
if (r.readByte() == ')') {
if (parseDebug)
System.out.println("DEBUG IMAP: no MD5 DONE");
return; // done
}
// Disposition
byte b = r.readByte();
if (b == '(') {
disposition = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: disposition " +
disposition);
dParams = parseParameters(r);
if (parseDebug)
System.out.println("DEBUG IMAP: dParams " + dParams);
if (r.readByte() != ')') // eat the end ')'
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
"missing ``)'' at end of disposition");
} else if (b == 'N' || b == 'n') {
if (parseDebug)
System.out.println("DEBUG IMAP: disposition NIL");
r.skip(2); // skip 'NIL'
} else {
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
type + "/" + subtype + ": " +
"bad single part disposition, b " + b);
}
if (r.readByte() == ')') {
if (parseDebug)
System.out.println("DEBUG IMAP: disposition DONE");
return; // done
}
// Language
if (r.peekByte() == '(') { // a list follows
language = r.readStringList();
if (parseDebug)
System.out.println("DEBUG IMAP: language len " +
language.length);
} else { // protocol is unnessarily complex here
String l = r.readString();
if (l != null) {
String[] la = { l };
language = la;
if (parseDebug)
System.out.println("DEBUG IMAP: language " + l);
}
}
// RFC3501 defines an optional "body location" next,
// but for now we ignore it along with other extensions.
// Throw away any further extension data
while (r.readByte() == ' ')
parseBodyExtension(r);
if (parseDebug)
System.out.println("DEBUG IMAP: all DONE");
}
}
public boolean isMulti() {
return processedType == MULTI;
}
public boolean isSingle() {
return processedType == SINGLE;
}
public boolean isNested() {
return processedType == NESTED;
}
private ParameterList parseParameters(Response r)
throws ParsingException {
r.skipSpaces();
ParameterList list = null;
byte b = r.readByte();
if (b == '(') {
list = new ParameterList();
do {
String name = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: parameter name " + name);
if (name == null)
throw new ParsingException(
"BODYSTRUCTURE parse error: " +
type + "/" + subtype + ": " +
"null name in parameter list");
String value = r.readString();
if (parseDebug)
System.out.println("DEBUG IMAP: parameter value " + value);
list.set(name, value);
} while (r.readByte() != ')');
list.combineSegments();
} else if (b == 'N' || b == 'n') {
if (parseDebug)
System.out.println("DEBUG IMAP: parameter list NIL");
r.skip(2);
} else
throw new ParsingException("Parameter list parse error");
return list;
}
private void parseBodyExtension(Response r) throws ParsingException {
r.skipSpaces();
byte b = r.peekByte();
if (b == '(') {
r.skip(1); // skip '('
do {
parseBodyExtension(r);
} while (r.readByte() != ')');
} else if (Character.isDigit((char)b)) // number
r.readNumber();
else // nstring
r.readString();
}
}

View File

@ -1,216 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.util.Vector;
import java.util.Date;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.AddressException;
import javax.mail.internet.MailDateFormat;
import javax.mail.internet.MimeUtility;
import com.sun.mail.iap.*;
/**
* The ENEVELOPE item of an IMAP FETCH response.
*
* @author John Mani
* @author Bill Shannon
*/
public class ENVELOPE implements Item {
// IMAP item name
static final char[] name = {'E','N','V','E','L','O','P','E'};
public int msgno;
public Date date = null;
public String subject;
public InternetAddress[] from;
public InternetAddress[] sender;
public InternetAddress[] replyTo;
public InternetAddress[] to;
public InternetAddress[] cc;
public InternetAddress[] bcc;
public String inReplyTo;
public String messageId;
// Used to parse dates
private static MailDateFormat mailDateFormat = new MailDateFormat();
public ENVELOPE(FetchResponse r) throws ParsingException {
msgno = r.getNumber();
r.skipSpaces();
if (r.readByte() != '(')
throw new ParsingException("ENVELOPE parse error");
String s = r.readString();
if (s != null) {
try {
date = mailDateFormat.parse(s);
} catch (Exception pex) {
// We need to be *very* tolerant about bogus dates (and
// there's lot of 'em around), so we ignore any
// exception (including RunTimeExceptions) and just let
// date be null.
}
}
subject = r.readString();
from = parseAddressList(r);
sender = parseAddressList(r);
replyTo = parseAddressList(r);
to = parseAddressList(r);
cc = parseAddressList(r);
bcc = parseAddressList(r);
inReplyTo = r.readString();
messageId = r.readString();
if (r.readByte() != ')')
throw new ParsingException("ENVELOPE parse error");
}
private InternetAddress[] parseAddressList(Response r)
throws ParsingException {
r.skipSpaces(); // skip leading spaces
byte b = r.readByte();
if (b == '(') {
Vector v = new Vector();
do {
IMAPAddress a = new IMAPAddress(r);
// if we see an end-of-group address at the top, ignore it
if (!a.isEndOfGroup())
v.addElement(a);
} while (r.peekByte() != ')');
// skip the terminating ')' at the end of the addresslist
r.skip(1);
InternetAddress[] a = new InternetAddress[v.size()];
v.copyInto(a);
return a;
} else if (b == 'N' || b == 'n') { // NIL
r.skip(2); // skip 'NIL'
return null;
} else
throw new ParsingException("ADDRESS parse error");
}
}
class IMAPAddress extends InternetAddress {
private boolean group = false;
private InternetAddress[] grouplist;
private String groupname;
private static final long serialVersionUID = -3835822029483122232L;
IMAPAddress(Response r) throws ParsingException {
r.skipSpaces(); // skip leading spaces
if (r.readByte() != '(')
throw new ParsingException("ADDRESS parse error");
encodedPersonal = r.readString();
r.readString(); // throw away address_list
String mb = r.readString();
String host = r.readString();
// skip bogus spaces inserted by Yahoo IMAP server if
// "undisclosed-recipients" is a recipient
r.skipSpaces();
if (r.readByte() != ')') // skip past terminating ')'
throw new ParsingException("ADDRESS parse error");
if (host == null) {
// it's a group list, start or end
group = true;
groupname = mb;
if (groupname == null) // end of group list
return;
// Accumulate a group list. The members of the group
// are accumulated in a Vector and the corresponding string
// representation of the group is accumulated in a StringBuffer.
StringBuffer sb = new StringBuffer();
sb.append(groupname).append(':');
Vector v = new Vector();
while (r.peekByte() != ')') {
IMAPAddress a = new IMAPAddress(r);
if (a.isEndOfGroup()) // reached end of group
break;
if (v.size() != 0) // if not first element, need a comma
sb.append(',');
sb.append(a.toString());
v.addElement(a);
}
sb.append(';');
address = sb.toString();
grouplist = new IMAPAddress[v.size()];
v.copyInto(grouplist);
} else {
if (mb == null || mb.length() == 0)
address = host;
else if (host.length() == 0)
address = mb;
else
address = mb + "@" + host;
}
}
boolean isEndOfGroup() {
return group && groupname == null;
}
public boolean isGroup() {
return group;
}
public InternetAddress[] getGroup(boolean strict) throws AddressException {
if (grouplist == null)
return null;
return (InternetAddress[])grouplist.clone();
}
}

View File

@ -1,107 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import javax.mail.Flags;
import com.sun.mail.iap.*;
/**
* This class
*
* @author John Mani
*/
public class FLAGS extends Flags implements Item {
// IMAP item name
static final char[] name = {'F','L','A','G','S'};
public int msgno;
private static final long serialVersionUID = 439049847053756670L;
/**
* Constructor
*/
public FLAGS(IMAPResponse r) throws ParsingException {
msgno = r.getNumber();
r.skipSpaces();
String[] flags = r.readSimpleList();
if (flags != null) { // if not empty flaglist
for (int i = 0; i < flags.length; i++) {
String s = flags[i];
if (s.length() >= 2 && s.charAt(0) == '\\') {
switch (Character.toUpperCase(s.charAt(1))) {
case 'S': // \Seen
add(Flags.Flag.SEEN);
break;
case 'R': // \Recent
add(Flags.Flag.RECENT);
break;
case 'D':
if (s.length() >= 3) {
char c = s.charAt(2);
if (c == 'e' || c == 'E') // \Deleted
add(Flags.Flag.DELETED);
else if (c == 'r' || c == 'R') // \Draft
add(Flags.Flag.DRAFT);
} else
add(s); // unknown, treat it as a user flag
break;
case 'A': // \Answered
add(Flags.Flag.ANSWERED);
break;
case 'F': // \Flagged
add(Flags.Flag.FLAGGED);
break;
case '*': // \*
add(Flags.Flag.USER);
break;
default:
add(s); // unknown, treat it as a user flag
break;
}
} else
add(s);
}
}
}
}

View File

@ -1,78 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.lang.reflect.*;
import javax.mail.FetchProfile;
import com.sun.mail.iap.ParsingException;
/**
* Metadata describing a FETCH item.
* Note that the "name" field MUST be in uppercase. <p>
*
* @author Bill Shannon
* @since JavaMail 1.4.6
*/
public abstract class FetchItem {
private String name;
private FetchProfile.Item fetchProfileItem;
public FetchItem(String name, FetchProfile.Item fetchProfileItem) {
this.name = name;
this.fetchProfileItem = fetchProfileItem;
}
public String getName() {
return name;
}
public FetchProfile.Item getFetchProfileItem() {
return fetchProfileItem;
}
/**
* Parse the item into some kind of object appropriate for the item.
* Note that the item name will have been parsed and skipped already.
*/
public abstract Object parseItem(FetchResponse r) throws ParsingException;
}

View File

@ -1,279 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.io.*;
import java.util.*;
import com.sun.mail.util.*;
import com.sun.mail.iap.*;
/**
* This class represents a FETCH response obtained from the input stream
* of an IMAP server.
*
* @author John Mani
* @author Bill Shannon
*/
public class FetchResponse extends IMAPResponse {
/*
* Regular Items are saved in the items array.
* Extension items (items handled by subclasses
* that extend the IMAP provider) are saved in the
* extensionItems map, indexed by the FETCH item name.
* The map is only created when needed.
*
* XXX - Should consider unifying the handling of
* regular items and extension items.
*/
private Item[] items;
private Map extensionItems;
private final FetchItem[] fitems;
public FetchResponse(Protocol p)
throws IOException, ProtocolException {
super(p);
fitems = null;
parse();
}
public FetchResponse(IMAPResponse r)
throws IOException, ProtocolException {
this(r, null);
}
/**
* Construct a FetchResponse that handles the additional FetchItems.
*
* @since JavaMail 1.4.6
*/
public FetchResponse(IMAPResponse r, FetchItem[] fitems)
throws IOException, ProtocolException {
super(r);
this.fitems = fitems;
parse();
}
public int getItemCount() {
return items.length;
}
public Item getItem(int index) {
return items[index];
}
public Item getItem(Class c) {
for (int i = 0; i < items.length; i++) {
if (c.isInstance(items[i]))
return items[i];
}
return null;
}
public static Item getItem(Response[] r, int msgno, Class c) {
if (r == null)
return null;
for (int i = 0; i < r.length; i++) {
if (r[i] == null ||
!(r[i] instanceof FetchResponse) ||
((FetchResponse)r[i]).getNumber() != msgno)
continue;
FetchResponse f = (FetchResponse)r[i];
for (int j = 0; j < f.items.length; j++) {
if (c.isInstance(f.items[j]))
return f.items[j];
}
}
return null;
}
/**
* Return a map of the extension items found in this fetch response.
* The map is indexed by extension item name. Callers should not
* modify the map.
*
* @since JavaMail 1.4.6
*/
public Map getExtensionItems() {
if (extensionItems == null)
extensionItems = new HashMap();
return extensionItems;
}
private final static char[] HEADER = {'.','H','E','A','D','E','R'};
private final static char[] TEXT = {'.','T','E','X','T'};
private void parse() throws ParsingException {
skipSpaces();
if (buffer[index] != '(')
throw new ParsingException(
"error in FETCH parsing, missing '(' at index " + index);
Vector v = new Vector();
Item i = null;
do {
index++; // skip '(', or SPACE
if (index >= size)
throw new ParsingException(
"error in FETCH parsing, ran off end of buffer, size " + size);
i = parseItem();
if (i != null)
v.addElement(i);
else if (!parseExtensionItem())
throw new ParsingException(
"error in FETCH parsing, unrecognized item at index " + index);
} while (buffer[index] != ')');
index++; // skip ')'
items = new Item[v.size()];
v.copyInto(items);
}
/**
* Parse the item at the current position in the buffer,
* skipping over the item if successful. Otherwise, return null
* and leave the buffer position unmodified.
*/
private Item parseItem() throws ParsingException {
switch (buffer[index]) {
case 'E': case 'e':
if (match(ENVELOPE.name))
return new ENVELOPE(this);
break;
case 'F': case 'f':
if (match(FLAGS.name))
return new FLAGS((IMAPResponse)this);
break;
case 'I': case 'i':
if (match(INTERNALDATE.name))
return new INTERNALDATE(this);
break;
case 'B': case 'b':
if (match(BODYSTRUCTURE.name))
return new BODYSTRUCTURE(this);
else if (match(BODY.name)) {
if (buffer[index] == '[')
return new BODY(this);
else
return new BODYSTRUCTURE(this);
}
break;
case 'R': case 'r':
if (match(RFC822SIZE.name))
return new RFC822SIZE(this);
else if (match(RFC822DATA.name)) {
if (match(HEADER))
; // skip ".HEADER"
else if (match(TEXT))
; // skip ".TEXT"
return new RFC822DATA(this);
}
break;
case 'U': case 'u':
if (match(UID.name))
return new UID(this);
break;
default:
break;
}
return null;
}
/**
* If this item is a known extension item, parse it.
*/
private boolean parseExtensionItem() throws ParsingException {
if (fitems == null)
return false;
for (int i = 0; i < fitems.length; i++) {
if (match(fitems[i].getName())) {
getExtensionItems().put(fitems[i].getName(),
fitems[i].parseItem(this));
return true;
}
}
return false;
}
/**
* Does the current buffer match the given item name?
* itemName is the name of the IMAP item to compare against.
* NOTE that itemName *must* be all uppercase.
* If the match is successful, the buffer pointer (index)
* is incremented past the matched item.
*/
private boolean match(char[] itemName) {
int len = itemName.length;
for (int i = 0, j = index; i < len;)
// IMAP tokens are case-insensitive. We store itemNames in
// uppercase, so convert operand to uppercase before comparing.
if (Character.toUpperCase((char)buffer[j++]) != itemName[i++])
return false;
index += len;
return true;
}
/**
* Does the current buffer match the given item name?
* itemName is the name of the IMAP item to compare against.
* NOTE that itemName *must* be all uppercase.
* If the match is successful, the buffer pointer (index)
* is incremented past the matched item.
*/
private boolean match(String itemName) {
int len = itemName.length();
for (int i = 0, j = index; i < len;)
// IMAP tokens are case-insensitive. We store itemNames in
// uppercase, so convert operand to uppercase before comparing.
if (Character.toUpperCase((char)buffer[j++]) !=
itemName.charAt(i++))
return false;
index += len;
return true;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,142 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.io.*;
import java.util.*;
import com.sun.mail.util.*;
import com.sun.mail.iap.*;
/**
* This class represents a response obtained from the input stream
* of an IMAP server.
*
* @author John Mani
*/
public class IMAPResponse extends Response {
private String key;
private int number;
public IMAPResponse(Protocol c) throws IOException, ProtocolException {
super(c);
init();
}
private void init() throws IOException, ProtocolException {
// continue parsing if this is an untagged response
if (isUnTagged() && !isOK() && !isNO() && !isBAD() && !isBYE()) {
key = readAtom();
// Is this response of the form "* <number> <command>"
try {
number = Integer.parseInt(key);
key = readAtom();
} catch (NumberFormatException ne) { }
}
}
/**
* Copy constructor.
*/
public IMAPResponse(IMAPResponse r) {
super((Response)r);
key = r.key;
number = r.number;
}
/**
* For testing.
*/
public IMAPResponse(String r) throws IOException, ProtocolException {
super(r);
init();
}
/**
* Read a list of space-separated "flag_extension" sequences and
* return the list as a array of Strings. An empty list is returned
* as null. This is an IMAP-ism, and perhaps this method should
* moved into the IMAP layer.
*/
public String[] readSimpleList() {
skipSpaces();
if (buffer[index] != '(') // not what we expected
return null;
index++; // skip '('
Vector v = new Vector();
int start;
for (start = index; buffer[index] != ')'; index++) {
if (buffer[index] == ' ') { // got one item
v.addElement(ASCIIUtility.toString(buffer, start, index));
start = index+1; // index gets incremented at the top
}
}
if (index > start) // get the last item
v.addElement(ASCIIUtility.toString(buffer, start, index));
index++; // skip ')'
int size = v.size();
if (size > 0) {
String[] s = new String[size];
v.copyInto(s);
return s;
} else // empty list
return null;
}
public String getKey() {
return key;
}
public boolean keyEquals(String k) {
if (key != null && key.equalsIgnoreCase(k))
return true;
else
return false;
}
public int getNumber() {
return number;
}
}

View File

@ -1,271 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import javax.security.sasl.*;
import javax.security.auth.callback.*;
import com.sun.mail.iap.*;
import com.sun.mail.imap.*;
import com.sun.mail.util.*;
/**
* This class contains a single method that does authentication using
* SASL. This is in a separate class so that it can be compiled with
* J2SE 1.5. Eventually it should be merged into IMAPProtocol.java.
*/
public class IMAPSaslAuthenticator implements SaslAuthenticator {
private IMAPProtocol pr;
private String name;
private Properties props;
private MailLogger logger;
private String host;
public IMAPSaslAuthenticator(IMAPProtocol pr, String name, Properties props,
MailLogger logger, String host) {
this.pr = pr;
this.name = name;
this.props = props;
this.logger = logger;
this.host = host;
}
public boolean authenticate(String[] mechs, final String realm,
final String authzid, final String u,
final String p) throws ProtocolException {
synchronized (pr) { // authenticate method should be synchronized
Vector v = new Vector();
String tag = null;
Response r = null;
boolean done = false;
if (logger.isLoggable(Level.FINE)) {
logger.fine("SASL Mechanisms:");
for (int i = 0; i < mechs.length; i++)
logger.fine(" " + mechs[i]);
logger.fine("");
}
SaslClient sc;
CallbackHandler cbh = new CallbackHandler() {
public void handle(Callback[] callbacks) {
if (logger.isLoggable(Level.FINE))
logger.fine("SASL callback length: " + callbacks.length);
for (int i = 0; i < callbacks.length; i++) {
if (logger.isLoggable(Level.FINE))
logger.fine("SASL callback " + i + ": " + callbacks[i]);
if (callbacks[i] instanceof NameCallback) {
NameCallback ncb = (NameCallback)callbacks[i];
ncb.setName(u);
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pcb = (PasswordCallback)callbacks[i];
pcb.setPassword(p.toCharArray());
} else if (callbacks[i] instanceof RealmCallback) {
RealmCallback rcb = (RealmCallback)callbacks[i];
rcb.setText(realm != null ?
realm : rcb.getDefaultText());
} else if (callbacks[i] instanceof RealmChoiceCallback) {
RealmChoiceCallback rcb =
(RealmChoiceCallback)callbacks[i];
if (realm == null)
rcb.setSelectedIndex(rcb.getDefaultChoice());
else {
// need to find specified realm in list
String[] choices = rcb.getChoices();
for (int k = 0; k < choices.length; k++) {
if (choices[k].equals(realm)) {
rcb.setSelectedIndex(k);
break;
}
}
}
}
}
}
};
try {
sc = Sasl.createSaslClient(mechs, authzid, name, host,
(Map)props, cbh);
} catch (SaslException sex) {
logger.log(Level.FINE, "Failed to create SASL client", sex);
return false;
}
if (sc == null) {
logger.fine("No SASL support");
return false;
}
if (logger.isLoggable(Level.FINE))
logger.fine("SASL client " + sc.getMechanismName());
try {
tag = pr.writeCommand("AUTHENTICATE " + sc.getMechanismName(),
null);
} catch (Exception ex) {
logger.log(Level.FINE, "SASL AUTHENTICATE Exception", ex);
return false;
}
OutputStream os = pr.getIMAPOutputStream(); // stream to IMAP server
/*
* Wrap a BASE64Encoder around a ByteArrayOutputstream
* to craft b64 encoded username and password strings
*
* Note that the encoded bytes should be sent "as-is" to the
* server, *not* as literals or quoted-strings.
*
* Also note that unlike the B64 definition in MIME, CRLFs
* should *not* be inserted during the encoding process. So, I
* use Integer.MAX_VALUE (0x7fffffff (> 1G)) as the bytesPerLine,
* which should be sufficiently large !
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] CRLF = { (byte)'\r', (byte)'\n'};
// Hack for Novell GroupWise XGWTRUSTEDAPP authentication mechanism
boolean isXGWTRUSTEDAPP =
sc.getMechanismName().equals("XGWTRUSTEDAPP") &&
PropUtil.getBooleanProperty(props,
"mail." + name + ".sasl.xgwtrustedapphack.enable", true);
while (!done) { // loop till we are done
try {
r = pr.readResponse();
if (r.isContinuation()) {
byte[] ba = null;
if (!sc.isComplete()) {
ba = r.readByteArray().getNewBytes();
if (ba.length > 0)
ba = BASE64DecoderStream.decode(ba);
if (logger.isLoggable(Level.FINE))
logger.fine("SASL challenge: " +
ASCIIUtility.toString(ba, 0, ba.length) + " :");
ba = sc.evaluateChallenge(ba);
}
if (ba == null) {
logger.fine("SASL no response");
os.write(CRLF); // write out empty line
os.flush(); // flush the stream
bos.reset(); // reset buffer
} else {
if (logger.isLoggable(Level.FINE))
logger.fine("SASL response: " +
ASCIIUtility.toString(ba, 0, ba.length) + " :");
ba = BASE64EncoderStream.encode(ba);
if (isXGWTRUSTEDAPP)
bos.write(ASCIIUtility.getBytes("XGWTRUSTEDAPP "));
bos.write(ba);
bos.write(CRLF); // CRLF termination
os.write(bos.toByteArray()); // write out line
os.flush(); // flush the stream
bos.reset(); // reset buffer
}
} else if (r.isTagged() && r.getTag().equals(tag))
// Ah, our tagged response
done = true;
else if (r.isBYE()) // outta here
done = true;
else // hmm .. unsolicited response here ?!
v.addElement(r);
} catch (Exception ioex) {
logger.log(Level.FINE, "SASL Exception", ioex);
// convert this into a BYE response
r = Response.byeResponse(ioex);
done = true;
// XXX - ultimately return true???
}
}
if (sc.isComplete() /*&& res.status == SUCCESS*/) {
String qop = (String)sc.getNegotiatedProperty(Sasl.QOP);
if (qop != null && (qop.equalsIgnoreCase("auth-int") ||
qop.equalsIgnoreCase("auth-conf"))) {
// XXX - NOT SUPPORTED!!!
logger.fine(
"SASL Mechanism requires integrity or confidentiality");
return false;
}
}
/* Dispatch untagged responses.
* NOTE: in our current upper level IMAP classes, we add the
* responseHandler to the Protocol object only *after* the
* connection has been authenticated. So, for now, the below
* code really ends up being just a no-op.
*/
Response[] responses = new Response[v.size()];
v.copyInto(responses);
pr.notifyResponseHandlers(responses);
// Handle the final OK, NO, BAD or BYE response
pr.handleResult(r);
pr.setCapabilities(r);
/*
* If we're using the Novell Groupwise XGWTRUSTEDAPP mechanism
* we always have to issue a LOGIN command to select the user
* we want to operate as.
*/
if (isXGWTRUSTEDAPP) {
Argument args = new Argument();
args.writeString(authzid != null ? authzid : u);
responses = pr.command("LOGIN", args);
// dispatch untagged responses
pr.notifyResponseHandlers(responses);
// Handle result of this command
pr.handleResult(responses[responses.length-1]);
// If the response includes a CAPABILITY response code, process it
pr.setCapabilities(responses[responses.length-1]);
}
return true;
}
}
}

View File

@ -1,144 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.util.Date;
import java.util.TimeZone;
import java.util.Locale;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.text.FieldPosition;
import javax.mail.internet.MailDateFormat;
import com.sun.mail.iap.*;
/**
* This class
*
* @author John Mani
*/
public class INTERNALDATE implements Item {
static final char[] name =
{'I','N','T','E','R','N','A','L','D','A','T','E'};
public int msgno;
protected Date date;
/*
* Used to parse dates only. The parse method is thread safe
* so we only need to create a single object for use by all
* instances. We depend on the fact that the MailDateFormat
* class will parse dates in INTERNALDATE format as well as
* dates in RFC 822 format.
*/
private static MailDateFormat mailDateFormat = new MailDateFormat();
/**
* Constructor
*/
public INTERNALDATE(FetchResponse r) throws ParsingException {
msgno = r.getNumber();
r.skipSpaces();
String s = r.readString();
if (s == null)
throw new ParsingException("INTERNALDATE is NIL");
try {
date = mailDateFormat.parse(s);
} catch (ParseException pex) {
throw new ParsingException("INTERNALDATE parse error");
}
}
public Date getDate() {
return date;
}
// INTERNALDATE formatter
private static SimpleDateFormat df =
// Need Locale.US, the "MMM" field can produce unexpected values
// in non US locales !
new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss ", Locale.US);
/**
* Format given Date object into INTERNALDATE string
*/
public static String format(Date d) {
/*
* SimpleDateFormat objects aren't thread safe, so rather
* than create a separate such object for each request,
* we create one object and synchronize its use here
* so that only one thread is using it at a time. This
* trades off some potential concurrency for speed in the
* common case.
*
* This method is only used when formatting the date in a
* message that's being appended to a folder.
*/
StringBuffer sb = new StringBuffer();
synchronized (df) {
df.format(d, sb, new FieldPosition(0));
}
// compute timezone offset string
TimeZone tz = TimeZone.getDefault();
int offset = tz.getOffset(d.getTime()); // get offset from GMT
int rawOffsetInMins = offset / 60 / 1000; // offset from GMT in mins
if (rawOffsetInMins < 0) {
sb.append('-');
rawOffsetInMins = (-rawOffsetInMins);
} else
sb.append('+');
int offsetInHrs = rawOffsetInMins / 60;
int offsetInMins = rawOffsetInMins % 60;
sb.append(Character.forDigit((offsetInHrs/10), 10));
sb.append(Character.forDigit((offsetInHrs%10), 10));
sb.append(Character.forDigit((offsetInMins/10), 10));
sb.append(Character.forDigit((offsetInMins%10), 10));
return sb.toString();
}
}

View File

@ -1,54 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
/**
* A tagging interface for all IMAP data items.
* Note that the "name" field of all IMAP items MUST be in uppercase. <p>
*
* See the BODY, BODYSTRUCTURE, ENVELOPE, FLAGS, INTERNALDATE, RFC822DATA,
* RFC822SIZE, and UID classes.
*
* @author John Mani
*/
public interface Item {
}

View File

@ -1,102 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.util.Vector;
import com.sun.mail.iap.*;
/**
* A LIST response.
*
* @author John Mani
* @author Bill Shannon
*/
public class ListInfo {
public String name = null;
public char separator = '/';
public boolean hasInferiors = true;
public boolean canOpen = true;
public int changeState = INDETERMINATE;
public String[] attrs;
public static final int CHANGED = 1;
public static final int UNCHANGED = 2;
public static final int INDETERMINATE = 3;
public ListInfo(IMAPResponse r) throws ParsingException {
String[] s = r.readSimpleList();
Vector v = new Vector(); // accumulate attributes
if (s != null) {
// non-empty attribute list
for (int i = 0; i < s.length; i++) {
if (s[i].equalsIgnoreCase("\\Marked"))
changeState = CHANGED;
else if (s[i].equalsIgnoreCase("\\Unmarked"))
changeState = UNCHANGED;
else if (s[i].equalsIgnoreCase("\\Noselect"))
canOpen = false;
else if (s[i].equalsIgnoreCase("\\Noinferiors"))
hasInferiors = false;
v.addElement(s[i]);
}
}
attrs = new String[v.size()];
v.copyInto(attrs);
r.skipSpaces();
if (r.readByte() == '"') {
if ((separator = (char)r.readByte()) == '\\')
// escaped separator character
separator = (char)r.readByte();
r.skip(1); // skip <">
} else // NIL
r.skip(2);
r.skipSpaces();
name = r.readAtomString();
// decode the name (using RFC2060's modified UTF7)
name = BASE64MailboxDecoder.decode(name);
}
}

View File

@ -1,127 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import javax.mail.Flags;
import com.sun.mail.iap.*;
/**
* This class
*
* @author John Mani
*/
public class MailboxInfo {
public Flags availableFlags = null;
public Flags permanentFlags = null;
public int total = -1;
public int recent = -1;
public int first = -1;
public long uidvalidity = -1;
public long uidnext = -1;
public int mode;
public MailboxInfo(Response[] r) throws ParsingException {
for (int i = 0; i < r.length; i++) {
if (r[i] == null || !(r[i] instanceof IMAPResponse))
continue;
IMAPResponse ir = (IMAPResponse)r[i];
if (ir.keyEquals("EXISTS")) {
total = ir.getNumber();
r[i] = null; // remove this response
}
else if (ir.keyEquals("RECENT")) {
recent = ir.getNumber();
r[i] = null; // remove this response
}
else if (ir.keyEquals("FLAGS")) {
availableFlags = new FLAGS(ir);
r[i] = null; // remove this response
}
else if (ir.isUnTagged() && ir.isOK()) {
/* should be one of:
* OK [UNSEEN 12]
* OK [UIDVALIDITY 3857529045]
* OK [PERMANENTFLAGS (\Deleted)]
* OK [UIDNEXT 44]
*/
ir.skipSpaces();
if (ir.readByte() != '[') { // huh ???
ir.reset();
continue;
}
boolean handled = true;
String s = ir.readAtom();
if (s.equalsIgnoreCase("UNSEEN"))
first = ir.readNumber();
else if (s.equalsIgnoreCase("UIDVALIDITY"))
uidvalidity = ir.readLong();
else if (s.equalsIgnoreCase("PERMANENTFLAGS"))
permanentFlags = new FLAGS(ir);
else if (s.equalsIgnoreCase("UIDNEXT"))
uidnext = ir.readLong();
else
handled = false; // possibly an ALERT
if (handled)
r[i] = null; // remove this response
else
ir.reset(); // so ALERT can be read
}
}
/*
* The PERMANENTFLAGS response code is optional, and if
* not present implies that all flags in the required FLAGS
* response can be changed permanently.
*/
if (permanentFlags == null) {
if (availableFlags != null)
permanentFlags = new Flags(availableFlags);
else
permanentFlags = new Flags();
}
}
}

View File

@ -1,137 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.util.Vector;
/**
* This class holds the 'start' and 'end' for a range of messages
*/
public class MessageSet {
public int start;
public int end;
public MessageSet() { }
public MessageSet(int start, int end) {
this.start = start;
this.end = end;
}
/**
* Count the total number of elements in a MessageSet
**/
public int size() {
return end - start + 1;
}
/*
* Convert an array of integers into an array of MessageSets
*/
public static MessageSet[] createMessageSets(int[] msgs) {
Vector v = new Vector();
int i,j;
for (i=0; i < msgs.length; i++) {
MessageSet ms = new MessageSet();
ms.start = msgs[i];
// Look for contiguous elements
for (j=i+1; j < msgs.length; j++) {
if (msgs[j] != msgs[j-1] +1)
break;
}
ms.end = msgs[j-1];
v.addElement(ms);
i = j-1; // i gets incremented @ top of the loop
}
MessageSet[] msgsets = new MessageSet[v.size()];
v.copyInto(msgsets);
return msgsets;
}
/**
* Convert an array of MessageSets into an IMAP sequence range
*/
public static String toString(MessageSet[] msgsets) {
if (msgsets == null || msgsets.length == 0) // Empty msgset
return null;
int i = 0; // msgset index
StringBuffer s = new StringBuffer();
int size = msgsets.length;
int start, end;
for (;;) {
start = msgsets[i].start;
end = msgsets[i].end;
if (end > start)
s.append(start).append(':').append(end);
else // end == start means only one element
s.append(start);
i++; // Next MessageSet
if (i >= size) // No more MessageSets
break;
else
s.append(',');
}
return s.toString();
}
/*
* Count the total number of elements in an array of MessageSets
*/
public static int size(MessageSet[] msgsets) {
int count = 0;
if (msgsets == null) // Null msgset
return 0;
for (int i=0; i < msgsets.length; i++)
count += msgsets[i].size();
return count;
}
}

View File

@ -1,168 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.util.*;
import com.sun.mail.iap.*;
/**
* This class and its inner class represent the response to the
* NAMESPACE command. <p>
*
* See <A HREF="http://www.ietf.org/rfc/rfc2342.txt">RFC 2342</A>.
*
* @author Bill Shannon
*/
public class Namespaces {
/**
* A single namespace entry.
*/
public static class Namespace {
/**
* Prefix string for the namespace.
*/
public String prefix;
/**
* Delimiter between names in this namespace.
*/
public char delimiter;
/**
* Parse a namespace element out of the response.
*/
public Namespace(Response r) throws ProtocolException {
// Namespace_Element = "(" string SP (<"> QUOTED_CHAR <"> / nil)
// *(Namespace_Response_Extension) ")"
if (r.readByte() != '(')
throw new ProtocolException(
"Missing '(' at start of Namespace");
// first, the prefix
prefix = BASE64MailboxDecoder.decode(r.readString());
r.skipSpaces();
// delimiter is a quoted character or NIL
if (r.peekByte() == '"') {
r.readByte();
delimiter = (char)r.readByte();
if (delimiter == '\\')
delimiter = (char)r.readByte();
if (r.readByte() != '"')
throw new ProtocolException(
"Missing '\"' at end of QUOTED_CHAR");
} else {
String s = r.readAtom();
if (s == null)
throw new ProtocolException("Expected NIL, got null");
if (!s.equalsIgnoreCase("NIL"))
throw new ProtocolException("Expected NIL, got " + s);
delimiter = 0;
}
// at end of Namespace data?
if (r.peekByte() != ')') {
// otherwise, must be a Namespace_Response_Extension
// Namespace_Response_Extension = SP string SP
// "(" string *(SP string) ")"
r.skipSpaces();
r.readString();
r.skipSpaces();
r.readStringList();
}
if (r.readByte() != ')')
throw new ProtocolException("Missing ')' at end of Namespace");
}
};
/**
* The personal namespaces.
* May be null.
*/
public Namespace[] personal;
/**
* The namespaces for other users.
* May be null.
*/
public Namespace[] otherUsers;
/**
* The shared namespace.
* May be null.
*/
public Namespace[] shared;
/**
* Parse out all the namespaces.
*/
public Namespaces(Response r) throws ProtocolException {
personal = getNamespaces(r);
otherUsers = getNamespaces(r);
shared = getNamespaces(r);
}
/**
* Parse out one of the three sets of namespaces.
*/
private Namespace[] getNamespaces(Response r) throws ProtocolException {
r.skipSpaces();
// Namespace = nil / "(" 1*( Namespace_Element) ")"
if (r.peekByte() == '(') {
Vector v = new Vector();
r.readByte();
do {
Namespace ns = new Namespace(r);
v.addElement(ns);
} while (r.peekByte() != ')');
r.readByte();
Namespace[] nsa = new Namespace[v.size()];
v.copyInto(nsa);
return nsa;
} else {
String s = r.readAtom();
if (s == null)
throw new ProtocolException("Expected NIL, got null");
if (!s.equalsIgnoreCase("NIL"))
throw new ProtocolException("Expected NIL, got " + s);
return null;
}
}
}

View File

@ -1,78 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.io.ByteArrayInputStream;
import com.sun.mail.iap.*;
import com.sun.mail.util.ASCIIUtility;
/**
* This class
*
* @author John Mani
*/
public class RFC822DATA implements Item {
static final char[] name = {'R','F','C','8','2','2'};
public int msgno;
public ByteArray data;
/**
* Constructor
*/
public RFC822DATA(FetchResponse r) throws ParsingException {
msgno = r.getNumber();
r.skipSpaces();
data = r.readByteArray();
}
public ByteArray getByteArray() {
return data;
}
public ByteArrayInputStream getByteArrayInputStream() {
if (data != null)
return data.toByteArrayInputStream();
else
return null;
}
}

View File

@ -1,66 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import com.sun.mail.iap.*;
/**
* This class
*
* @author John Mani
*/
public class RFC822SIZE implements Item {
static final char[] name = {'R','F','C','8','2','2','.','S','I','Z','E'};
public int msgno;
public int size;
/**
* Constructor
*/
public RFC822SIZE(FetchResponse r) throws ParsingException {
msgno = r.getNumber();
r.skipSpaces();
size = r.readNumber();
}
}

View File

@ -1,53 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import com.sun.mail.iap.ProtocolException;
/**
* Interface to make it easier to call IMAPSaslAuthenticator.
*/
public interface SaslAuthenticator {
public boolean authenticate(String[] mechs, String realm, String authzid,
String u, String p) throws ProtocolException;
}

View File

@ -1,446 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.util.*;
import java.io.IOException;
import javax.mail.*;
import javax.mail.search.*;
import com.sun.mail.iap.*;
/**
* This class traverses a search-tree and generates the
* corresponding IMAP search sequence.
*
* Each IMAPProtocol instance contains an instance of this class,
* which might be subclassed by subclasses of IMAPProtocol to add
* support for additional product-specific search terms.
*
* @author John Mani
*/
public class SearchSequence {
/**
* Generate the IMAP search sequence for the given search expression.
*/
public Argument generateSequence(SearchTerm term, String charset)
throws SearchException, IOException {
/*
* Call the appropriate handler depending on the type of
* the search-term ...
*/
if (term instanceof AndTerm) // AND
return and((AndTerm)term, charset);
else if (term instanceof OrTerm) // OR
return or((OrTerm)term, charset);
else if (term instanceof NotTerm) // NOT
return not((NotTerm)term, charset);
else if (term instanceof HeaderTerm) // HEADER
return header((HeaderTerm)term, charset);
else if (term instanceof FlagTerm) // FLAG
return flag((FlagTerm)term);
else if (term instanceof FromTerm) { // FROM
FromTerm fterm = (FromTerm)term;
return from(fterm.getAddress().toString(), charset);
}
else if (term instanceof FromStringTerm) { // FROM
FromStringTerm fterm = (FromStringTerm)term;
return from(fterm.getPattern(), charset);
}
else if (term instanceof RecipientTerm) { // RECIPIENT
RecipientTerm rterm = (RecipientTerm)term;
return recipient(rterm.getRecipientType(),
rterm.getAddress().toString(),
charset);
}
else if (term instanceof RecipientStringTerm) { // RECIPIENT
RecipientStringTerm rterm = (RecipientStringTerm)term;
return recipient(rterm.getRecipientType(),
rterm.getPattern(),
charset);
}
else if (term instanceof SubjectTerm) // SUBJECT
return subject((SubjectTerm)term, charset);
else if (term instanceof BodyTerm) // BODY
return body((BodyTerm)term, charset);
else if (term instanceof SizeTerm) // SIZE
return size((SizeTerm)term);
else if (term instanceof SentDateTerm) // SENTDATE
return sentdate((SentDateTerm)term);
else if (term instanceof ReceivedDateTerm) // INTERNALDATE
return receiveddate((ReceivedDateTerm)term);
else if (term instanceof MessageIDTerm) // MessageID
return messageid((MessageIDTerm)term, charset);
else
throw new SearchException("Search too complex");
}
/* *
* Check if the "text" terms in the given SearchTerm contain
* non US-ASCII characters.
*/
public static boolean isAscii(SearchTerm term) {
if (term instanceof AndTerm || term instanceof OrTerm) {
SearchTerm[] terms;
if (term instanceof AndTerm)
terms = ((AndTerm)term).getTerms();
else
terms = ((OrTerm)term).getTerms();
for (int i = 0; i < terms.length; i++)
if (!isAscii(terms[i])) // outta here !
return false;
} else if (term instanceof NotTerm)
return isAscii(((NotTerm)term).getTerm());
else if (term instanceof StringTerm)
return isAscii(((StringTerm)term).getPattern());
else if (term instanceof AddressTerm)
return isAscii(((AddressTerm)term).getAddress().toString());
// Any other term returns true.
return true;
}
/**
* Does this string contain only ASCII characters?
*/
public static boolean isAscii(String s) {
int l = s.length();
for (int i=0; i < l; i++) {
if ((int)s.charAt(i) > 0177) // non-ascii
return false;
}
return true;
}
protected Argument and(AndTerm term, String charset)
throws SearchException, IOException {
// Combine the sequences for both terms
SearchTerm[] terms = term.getTerms();
// Generate the search sequence for the first term
Argument result = generateSequence(terms[0], charset);
// Append other terms
for (int i = 1; i < terms.length; i++)
result.append(generateSequence(terms[i], charset));
return result;
}
protected Argument or(OrTerm term, String charset)
throws SearchException, IOException {
SearchTerm[] terms = term.getTerms();
/* The IMAP OR operator takes only two operands. So if
* we have more than 2 operands, group them into 2-operand
* OR Terms.
*/
if (terms.length > 2) {
SearchTerm t = terms[0];
// Include rest of the terms
for (int i = 1; i < terms.length; i++)
t = new OrTerm(t, terms[i]);
term = (OrTerm)t; // set 'term' to the new jumbo OrTerm we
// just created
terms = term.getTerms();
}
// 'term' now has only two operands
Argument result = new Argument();
// Add the OR search-key, if more than one term
if (terms.length > 1)
result.writeAtom("OR");
/* If this term is an AND expression, we need to enclose it
* within paranthesis.
*
* AND expressions are either AndTerms or FlagTerms
*/
if (terms[0] instanceof AndTerm || terms[0] instanceof FlagTerm)
result.writeArgument(generateSequence(terms[0], charset));
else
result.append(generateSequence(terms[0], charset));
// Repeat the above for the second term, if there is one
if (terms.length > 1) {
if (terms[1] instanceof AndTerm || terms[1] instanceof FlagTerm)
result.writeArgument(generateSequence(terms[1], charset));
else
result.append(generateSequence(terms[1], charset));
}
return result;
}
protected Argument not(NotTerm term, String charset)
throws SearchException, IOException {
Argument result = new Argument();
// Add the NOT search-key
result.writeAtom("NOT");
/* If this term is an AND expression, we need to enclose it
* within paranthesis.
*
* AND expressions are either AndTerms or FlagTerms
*/
SearchTerm nterm = term.getTerm();
if (nterm instanceof AndTerm || nterm instanceof FlagTerm)
result.writeArgument(generateSequence(nterm, charset));
else
result.append(generateSequence(nterm, charset));
return result;
}
protected Argument header(HeaderTerm term, String charset)
throws SearchException, IOException {
Argument result = new Argument();
result.writeAtom("HEADER");
result.writeString(term.getHeaderName());
result.writeString(term.getPattern(), charset);
return result;
}
protected Argument messageid(MessageIDTerm term, String charset)
throws SearchException, IOException {
Argument result = new Argument();
result.writeAtom("HEADER");
result.writeString("Message-ID");
// XXX confirm that charset conversion ought to be done
result.writeString(term.getPattern(), charset);
return result;
}
protected Argument flag(FlagTerm term) throws SearchException {
boolean set = term.getTestSet();
Argument result = new Argument();
Flags flags = term.getFlags();
Flags.Flag[] sf = flags.getSystemFlags();
String[] uf = flags.getUserFlags();
if (sf.length == 0 && uf.length == 0)
throw new SearchException("Invalid FlagTerm");
for (int i = 0; i < sf.length; i++) {
if (sf[i] == Flags.Flag.DELETED)
result.writeAtom(set ? "DELETED": "UNDELETED");
else if (sf[i] == Flags.Flag.ANSWERED)
result.writeAtom(set ? "ANSWERED": "UNANSWERED");
else if (sf[i] == Flags.Flag.DRAFT)
result.writeAtom(set ? "DRAFT": "UNDRAFT");
else if (sf[i] == Flags.Flag.FLAGGED)
result.writeAtom(set ? "FLAGGED": "UNFLAGGED");
else if (sf[i] == Flags.Flag.RECENT)
result.writeAtom(set ? "RECENT": "OLD");
else if (sf[i] == Flags.Flag.SEEN)
result.writeAtom(set ? "SEEN": "UNSEEN");
}
for (int i = 0; i < uf.length; i++) {
result.writeAtom(set ? "KEYWORD" : "UNKEYWORD");
result.writeAtom(uf[i]);
}
return result;
}
protected Argument from(String address, String charset)
throws SearchException, IOException {
Argument result = new Argument();
result.writeAtom("FROM");
result.writeString(address, charset);
return result;
}
protected Argument recipient(Message.RecipientType type,
String address, String charset)
throws SearchException, IOException {
Argument result = new Argument();
if (type == Message.RecipientType.TO)
result.writeAtom("TO");
else if (type == Message.RecipientType.CC)
result.writeAtom("CC");
else if (type == Message.RecipientType.BCC)
result.writeAtom("BCC");
else
throw new SearchException("Illegal Recipient type");
result.writeString(address, charset);
return result;
}
protected Argument subject(SubjectTerm term, String charset)
throws SearchException, IOException {
Argument result = new Argument();
result.writeAtom("SUBJECT");
result.writeString(term.getPattern(), charset);
return result;
}
protected Argument body(BodyTerm term, String charset)
throws SearchException, IOException {
Argument result = new Argument();
result.writeAtom("BODY");
result.writeString(term.getPattern(), charset);
return result;
}
protected Argument size(SizeTerm term)
throws SearchException {
Argument result = new Argument();
switch (term.getComparison()) {
case ComparisonTerm.GT:
result.writeAtom("LARGER");
break;
case ComparisonTerm.LT:
result.writeAtom("SMALLER");
break;
default:
// GT and LT is all we get from IMAP for size
throw new SearchException("Cannot handle Comparison");
}
result.writeNumber(term.getNumber());
return result;
}
// Date SEARCH stuff ...
/**
* Print an IMAP Date string, that is suitable for the Date
* SEARCH commands.
*
* The IMAP Date string is :
* date ::= date_day "-" date_month "-" date_year
*
* Note that this format does not contain the TimeZone
*/
private static String monthTable[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
// A GregorianCalendar object in the current timezone
protected Calendar cal = new GregorianCalendar();
protected String toIMAPDate(Date date) {
StringBuffer s = new StringBuffer();
cal.setTime(date);
s.append(cal.get(Calendar.DATE)).append("-");
s.append(monthTable[cal.get(Calendar.MONTH)]).append('-');
s.append(cal.get(Calendar.YEAR));
return s.toString();
}
protected Argument sentdate(DateTerm term)
throws SearchException {
Argument result = new Argument();
String date = toIMAPDate(term.getDate());
switch (term.getComparison()) {
case ComparisonTerm.GT:
result.writeAtom("SENTSINCE " + date);
break;
case ComparisonTerm.EQ:
result.writeAtom("SENTON " + date);
break;
case ComparisonTerm.LT:
result.writeAtom("SENTBEFORE " + date);
break;
case ComparisonTerm.GE:
result.writeAtom("OR SENTSINCE " + date + " SENTON " + date);
break;
case ComparisonTerm.LE:
result.writeAtom("OR SENTBEFORE " + date + " SENTON " + date);
break;
case ComparisonTerm.NE:
result.writeAtom("NOT SENTON " + date);
break;
default:
throw new SearchException("Cannot handle Date Comparison");
}
return result;
}
protected Argument receiveddate(DateTerm term)
throws SearchException {
Argument result = new Argument();
String date = toIMAPDate(term.getDate());
switch (term.getComparison()) {
case ComparisonTerm.GT:
result.writeAtom("SINCE " + date);
break;
case ComparisonTerm.EQ:
result.writeAtom("ON " + date);
break;
case ComparisonTerm.LT:
result.writeAtom("BEFORE " + date);
break;
case ComparisonTerm.GE:
result.writeAtom("OR SINCE " + date + " ON " + date);
break;
case ComparisonTerm.LE:
result.writeAtom("OR BEFORE " + date + " ON " + date);
break;
case ComparisonTerm.NE:
result.writeAtom("NOT ON " + date);
break;
default:
throw new SearchException("Cannot handle Date Comparison");
}
return result;
}
}

View File

@ -1,114 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import com.sun.mail.iap.*;
/**
* STATUS response.
*
* @author John Mani
*/
public class Status {
public String mbox = null;
public int total = -1;
public int recent = -1;
public long uidnext = -1;
public long uidvalidity = -1;
public int unseen = -1;
static final String[] standardItems =
{ "MESSAGES", "RECENT", "UNSEEN", "UIDNEXT", "UIDVALIDITY" };
public Status(Response r) throws ParsingException {
mbox = r.readAtomString(); // mailbox := astring
// Workaround buggy IMAP servers that don't quote folder names
// with spaces.
final StringBuffer buffer = new StringBuffer();
boolean onlySpaces = true;
while (r.peekByte() != '(' && r.peekByte() != 0) {
final char next = (char)r.readByte();
buffer.append(next);
if (next != ' ') {
onlySpaces = false;
}
}
if (!onlySpaces) {
mbox = (mbox + buffer).trim();
}
if (r.readByte() != '(')
throw new ParsingException("parse error in STATUS");
do {
String attr = r.readAtom();
if (attr.equalsIgnoreCase("MESSAGES"))
total = r.readNumber();
else if (attr.equalsIgnoreCase("RECENT"))
recent = r.readNumber();
else if (attr.equalsIgnoreCase("UIDNEXT"))
uidnext = r.readLong();
else if (attr.equalsIgnoreCase("UIDVALIDITY"))
uidvalidity = r.readLong();
else if (attr.equalsIgnoreCase("UNSEEN"))
unseen = r.readNumber();
} while (r.readByte() != ')');
}
public static void add(Status s1, Status s2) {
if (s2.total != -1)
s1.total = s2.total;
if (s2.recent != -1)
s1.recent = s2.recent;
if (s2.uidnext != -1)
s1.uidnext = s2.uidnext;
if (s2.uidvalidity != -1)
s1.uidvalidity = s2.uidvalidity;
if (s2.unseen != -1)
s1.unseen = s2.unseen;
}
}

View File

@ -1,66 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import com.sun.mail.iap.*;
/**
* This class represents the UID data item
*
* @author John Mani
*/
public class UID implements Item {
static final char[] name = {'U','I','D'};
public int seqnum;
public long uid;
/**
* Constructor
*/
public UID(FetchResponse r) throws ParsingException {
seqnum = r.getNumber();
r.skipSpaces();
uid = r.readLong();
}
}

View File

@ -1,138 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.imap.protocol;
import java.util.Vector;
/**
* This class holds the 'start' and 'end' for a range of UIDs.
* Just like MessageSet except using long instead of int.
*/
public class UIDSet {
public long start;
public long end;
public UIDSet() { }
public UIDSet(long start, long end) {
this.start = start;
this.end = end;
}
/**
* Count the total number of elements in a UIDSet
**/
public long size() {
return end - start + 1;
}
/*
* Convert an array of longs into an array of UIDSets
*/
public static UIDSet[] createUIDSets(long[] msgs) {
Vector v = new Vector();
int i,j;
for (i=0; i < msgs.length; i++) {
UIDSet ms = new UIDSet();
ms.start = msgs[i];
// Look for contiguous elements
for (j=i+1; j < msgs.length; j++) {
if (msgs[j] != msgs[j-1] +1)
break;
}
ms.end = msgs[j-1];
v.addElement(ms);
i = j-1; // i gets incremented @ top of the loop
}
UIDSet[] msgsets = new UIDSet[v.size()];
v.copyInto(msgsets);
return msgsets;
}
/**
* Convert an array of UIDSets into an IMAP sequence range
*/
public static String toString(UIDSet[] msgsets) {
if (msgsets == null || msgsets.length == 0) // Empty msgset
return null;
int i = 0; // msgset index
StringBuffer s = new StringBuffer();
int size = msgsets.length;
long start, end;
for (;;) {
start = msgsets[i].start;
end = msgsets[i].end;
if (end > start)
s.append(start).append(':').append(end);
else // end == start means only one element
s.append(start);
i++; // Next UIDSet
if (i >= size) // No more UIDSets
break;
else
s.append(',');
}
return s.toString();
}
/*
* Count the total number of elements in an array of UIDSets
*/
public static long size(UIDSet[] msgsets) {
long count = 0;
if (msgsets == null) // Null msgset
return 0;
for (int i=0; i < msgsets.length; i++)
count += msgsets[i].size();
return count;
}
}

View File

@ -1,145 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.pop3;
import javax.mail.*;
/**
* The POP3 DefaultFolder. Only contains the "INBOX" folder.
*
* @author Christopher Cotton
*/
public class DefaultFolder extends Folder {
DefaultFolder(POP3Store store) {
super(store);
}
public String getName() {
return "";
}
public String getFullName() {
return "";
}
public Folder getParent() {
return null;
}
public boolean exists() {
return true;
}
public Folder[] list(String pattern) throws MessagingException {
Folder[] f = { getInbox() };
return f;
}
public char getSeparator() {
return '/';
}
public int getType() {
return HOLDS_FOLDERS;
}
public boolean create(int type) throws MessagingException {
return false;
}
public boolean hasNewMessages() throws MessagingException {
return false;
}
public Folder getFolder(String name) throws MessagingException {
if (!name.equalsIgnoreCase("INBOX")) {
throw new MessagingException("only INBOX supported");
} else {
return getInbox();
}
}
protected Folder getInbox() throws MessagingException {
return getStore().getFolder("INBOX");
}
public boolean delete(boolean recurse) throws MessagingException {
throw new MethodNotSupportedException("delete");
}
public boolean renameTo(Folder f) throws MessagingException {
throw new MethodNotSupportedException("renameTo");
}
public void open(int mode) throws MessagingException {
throw new MethodNotSupportedException("open");
}
public void close(boolean expunge) throws MessagingException {
throw new MethodNotSupportedException("close");
}
public boolean isOpen() {
return false;
}
public Flags getPermanentFlags() {
return new Flags(); // empty flags object
}
public int getMessageCount() throws MessagingException {
return 0;
}
public Message getMessage(int msgno) throws MessagingException {
throw new MethodNotSupportedException("getMessage");
}
public void appendMessages(Message[] msgs) throws MessagingException {
throw new MethodNotSupportedException("Append not supported");
}
public Message[] expunge() throws MessagingException {
throw new MethodNotSupportedException("expunge");
}
}

View File

@ -1,599 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.pop3;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.event.*;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.EOFException;
import java.util.Vector;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.lang.reflect.Constructor;
import com.sun.mail.util.LineInputStream;
import com.sun.mail.util.MailLogger;
/**
* A POP3 Folder (can only be "INBOX").
*
* See the <a href="package-summary.html">com.sun.mail.pop3</a> package
* documentation for further information on the POP3 protocol provider. <p>
*
* @author Bill Shannon
* @author John Mani (ported to the javax.mail APIs)
*/
public class POP3Folder extends Folder {
private String name;
private POP3Store store;
private volatile Protocol port;
private int total;
private int size;
private boolean exists = false;
private volatile boolean opened = false;
private Vector message_cache;
private boolean doneUidl = false;
private volatile TempFile fileCache = null;
MailLogger logger; // package private, for POP3Message
POP3Folder(POP3Store store, String name) {
super(store);
this.name = name;
this.store = store;
if (name.equalsIgnoreCase("INBOX"))
exists = true;
logger = new MailLogger(this.getClass(),
"DEBUG POP3", store.getSession());
}
public String getName() {
return name;
}
public String getFullName() {
return name;
}
public Folder getParent() {
return new DefaultFolder(store);
}
/**
* Always true for the folder "INBOX", always false for
* any other name.
*
* @return true for INBOX, false otherwise
*/
public boolean exists() {
return exists;
}
/**
* Always throws <code>MessagingException</code> because no POP3 folders
* can contain subfolders.
*
* @exception MessagingException always
*/
public Folder[] list(String pattern) throws MessagingException {
throw new MessagingException("not a directory");
}
/**
* Always returns a NUL character because POP3 doesn't support a hierarchy.
*
* @return NUL
*/
public char getSeparator() {
return '\0';
}
/**
* Always returns Folder.HOLDS_MESSAGES.
*
* @return Folder.HOLDS_MESSAGES
*/
public int getType() {
return HOLDS_MESSAGES;
}
/**
* Always returns <code>false</code>; the POP3 protocol doesn't
* support creating folders.
*
* @return false
*/
public boolean create(int type) throws MessagingException {
return false;
}
/**
* Always returns <code>false</code>; the POP3 protocol provides
* no way to determine when a new message arrives.
*
* @return false
*/
public boolean hasNewMessages() throws MessagingException {
return false; // no way to know
}
/**
* Always throws <code>MessagingException</code> because no POP3 folders
* can contain subfolders.
*
* @exception MessagingException always
*/
public Folder getFolder(String name) throws MessagingException {
throw new MessagingException("not a directory");
}
/**
* Always throws <code>MethodNotSupportedException</code>
* because the POP3 protocol doesn't allow the INBOX to
* be deleted.
*
* @exception MethodNotSupportedException always
*/
public boolean delete(boolean recurse) throws MessagingException {
throw new MethodNotSupportedException("delete");
}
/**
* Always throws <code>MethodNotSupportedException</code>
* because the POP3 protocol doesn't support multiple folders.
*
* @exception MethodNotSupportedException always
*/
public boolean renameTo(Folder f) throws MessagingException {
throw new MethodNotSupportedException("renameTo");
}
/**
* Throws <code>FolderNotFoundException</code> unless this
* folder is named "INBOX".
*
* @exception FolderNotFoundException if not INBOX
* @exception AuthenticationException authentication failures
* @exception MessagingException other open failures
*/
public synchronized void open(int mode) throws MessagingException {
checkClosed();
if (!exists)
throw new FolderNotFoundException(this, "folder is not INBOX");
try {
port = store.getPort(this);
Status s = port.stat();
total = s.total;
size = s.size;
this.mode = mode;
if (store.useFileCache) {
try {
fileCache = new TempFile(store.fileCacheDir);
} catch (IOException ex) {
logger.log(Level.FINE, "failed to create file cache", ex);
throw ex; // caught below
}
}
opened = true;
} catch (IOException ioex) {
try {
if (port != null)
port.quit();
} catch (IOException ioex2) {
// ignore
} finally {
port = null;
store.closePort(this);
}
throw new MessagingException("Open failed", ioex);
}
// Create the message cache vector of appropriate size
message_cache = new Vector(total);
message_cache.setSize(total);
doneUidl = false;
notifyConnectionListeners(ConnectionEvent.OPENED);
}
public synchronized void close(boolean expunge) throws MessagingException {
checkOpen();
try {
/*
* Some POP3 servers will mark messages for deletion when
* they're read. To prevent such messages from being
* deleted before the client deletes them, you can set
* the mail.pop3.rsetbeforequit property to true. This
* causes us to issue a POP3 RSET command to clear all
* the "marked for deletion" flags. We can then explicitly
* delete messages as desired.
*/
if (store.rsetBeforeQuit)
port.rset();
POP3Message m;
if (expunge && mode == READ_WRITE) {
// find all messages marked deleted and issue DELE commands
for (int i = 0; i < message_cache.size(); i++) {
if ((m = (POP3Message)message_cache.elementAt(i)) != null) {
if (m.isSet(Flags.Flag.DELETED))
try {
port.dele(i + 1);
} catch (IOException ioex) {
throw new MessagingException(
"Exception deleting messages during close",
ioex);
}
}
}
}
/*
* Flush and free all cached data for the messages.
*/
for (int i = 0; i < message_cache.size(); i++) {
if ((m = (POP3Message)message_cache.elementAt(i)) != null)
m.invalidate(true);
}
port.quit();
} catch (IOException ex) {
// do nothing
} finally {
port = null;
store.closePort(this);
message_cache = null;
opened = false;
notifyConnectionListeners(ConnectionEvent.CLOSED);
if (fileCache != null) {
fileCache.close();
fileCache = null;
}
}
}
public synchronized boolean isOpen() {
if (!opened)
return false;
try {
if (!port.noop())
throw new IOException("NOOP failed");
} catch (IOException ioex) {
try {
close(false);
} catch (MessagingException mex) {
// ignore it
} finally {
return false;
}
}
return true;
}
/**
* Always returns an empty <code>Flags</code> object because
* the POP3 protocol doesn't support any permanent flags.
*
* @return empty Flags object
*/
public Flags getPermanentFlags() {
return new Flags(); // empty flags object
}
/**
* Will not change while the folder is open because the POP3
* protocol doesn't support notification of new messages
* arriving in open folders.
*/
public synchronized int getMessageCount() throws MessagingException {
if (!opened)
return -1;
checkReadable();
return total;
}
public synchronized Message getMessage(int msgno)
throws MessagingException {
checkOpen();
POP3Message m;
// Assuming that msgno is <= total
if ((m = (POP3Message)message_cache.elementAt(msgno-1)) == null) {
m = createMessage(this, msgno);
message_cache.setElementAt(m, msgno-1);
}
return m;
}
protected POP3Message createMessage(Folder f, int msgno)
throws MessagingException {
POP3Message m = null;
Constructor cons = store.messageConstructor;
if (cons != null) {
try {
Object[] o = { this, new Integer(msgno) };
m = (POP3Message)cons.newInstance(o);
} catch (Exception ex) {
// ignore
}
}
if (m == null)
m = new POP3Message(this, msgno);
return m;
}
/**
* Always throws <code>MethodNotSupportedException</code>
* because the POP3 protocol doesn't support appending messages.
*
* @exception MethodNotSupportedException always
*/
public void appendMessages(Message[] msgs) throws MessagingException {
throw new MethodNotSupportedException("Append not supported");
}
/**
* Always throws <code>MethodNotSupportedException</code>
* because the POP3 protocol doesn't support expunging messages
* without closing the folder; call the {@link #close close} method
* with the <code>expunge</code> argument set to <code>true</code>
* instead.
*
* @exception MethodNotSupportedException always
*/
public Message[] expunge() throws MessagingException {
throw new MethodNotSupportedException("Expunge not supported");
}
/**
* Prefetch information about POP3 messages.
* If the FetchProfile contains <code>UIDFolder.FetchProfileItem.UID</code>,
* POP3 UIDs for all messages in the folder are fetched using the POP3
* UIDL command.
* If the FetchProfile contains <code>FetchProfile.Item.ENVELOPE</code>,
* the headers and size of all messages are fetched using the POP3 TOP
* and LIST commands.
*/
public synchronized void fetch(Message[] msgs, FetchProfile fp)
throws MessagingException {
checkReadable();
if (!doneUidl && store.supportsUidl &&
fp.contains(UIDFolder.FetchProfileItem.UID)) {
/*
* Since the POP3 protocol only lets us fetch the UID
* for a single message or for all messages, we go ahead
* and fetch UIDs for all messages here, ignoring the msgs
* parameter. We could be more intelligent and base this
* decision on the number of messages fetched, or the
* percentage of the total number of messages fetched.
*/
String[] uids = new String[message_cache.size()];
try {
if (!port.uidl(uids))
return;
} catch (EOFException eex) {
close(false);
throw new FolderClosedException(this, eex.toString());
} catch (IOException ex) {
throw new MessagingException("error getting UIDL", ex);
}
for (int i = 0; i < uids.length; i++) {
if (uids[i] == null)
continue;
POP3Message m = (POP3Message)getMessage(i + 1);
m.uid = uids[i];
}
doneUidl = true; // only do this once
}
if (fp.contains(FetchProfile.Item.ENVELOPE)) {
for (int i = 0; i < msgs.length; i++) {
try {
POP3Message msg = (POP3Message)msgs[i];
// fetch headers
msg.getHeader("");
// fetch message size
msg.getSize();
} catch (MessageRemovedException mex) {
// should never happen, but ignore it if it does
}
}
}
}
/**
* Return the unique ID string for this message, or null if
* not available. Uses the POP3 UIDL command.
*
* @return unique ID string
* @exception MessagingException
*/
public synchronized String getUID(Message msg) throws MessagingException {
checkOpen();
POP3Message m = (POP3Message)msg;
try {
if (!store.supportsUidl)
return null;
if (m.uid == POP3Message.UNKNOWN)
m.uid = port.uidl(m.getMessageNumber());
return m.uid;
} catch (EOFException eex) {
close(false);
throw new FolderClosedException(this, eex.toString());
} catch (IOException ex) {
throw new MessagingException("error getting UIDL", ex);
}
}
/**
* Return the size of this folder, as was returned by the POP3 STAT
* command when this folder was opened.
*
* @return folder size
* @exception IllegalStateException if the folder isn't open
*/
public synchronized int getSize() throws MessagingException {
checkOpen();
return size;
}
/**
* Return the sizes of all messages in this folder, as returned
* by the POP3 LIST command. Each entry in the array corresponds
* to a message; entry <i>i</i> corresponds to message number <i>i+1</i>.
*
* @return array of message sizes
* @exception IllegalStateException if the folder isn't open
* @since JavaMail 1.3.3
*/
public synchronized int[] getSizes() throws MessagingException {
checkOpen();
int sizes[] = new int[total];
InputStream is = null;
LineInputStream lis = null;
try {
is = port.list();
lis = new LineInputStream(is);
String line;
while ((line = lis.readLine()) != null) {
try {
StringTokenizer st = new StringTokenizer(line);
int msgnum = Integer.parseInt(st.nextToken());
int size = Integer.parseInt(st.nextToken());
if (msgnum > 0 && msgnum <= total)
sizes[msgnum - 1] = size;
} catch (Exception e) {
}
}
} catch (IOException ex) {
// ignore it?
} finally {
try {
if (lis != null)
lis.close();
} catch (IOException cex) { }
try {
if (is != null)
is.close();
} catch (IOException cex) { }
}
return sizes;
}
/**
* Return the raw results of the POP3 LIST command with no arguments.
*
* @return InputStream containing results
* @exception IllegalStateException if the folder isn't open
* @since JavaMail 1.3.3
*/
public synchronized InputStream listCommand()
throws MessagingException, IOException {
checkOpen();
return port.list();
}
/**
* Close the folder when we're finalized.
*/
protected void finalize() throws Throwable {
super.finalize();
close(false);
}
/* Ensure the folder is open */
private void checkOpen() throws IllegalStateException {
if (!opened)
throw new IllegalStateException("Folder is not Open");
}
/* Ensure the folder is not open */
private void checkClosed() throws IllegalStateException {
if (opened)
throw new IllegalStateException("Folder is Open");
}
/* Ensure the folder is open & readable */
private void checkReadable() throws IllegalStateException {
if (!opened || (mode != READ_ONLY && mode != READ_WRITE))
throw new IllegalStateException("Folder is not Readable");
}
/* Ensure the folder is open & writable */
/*
private void checkWritable() throws IllegalStateException {
if (!opened || mode != READ_WRITE)
throw new IllegalStateException("Folder is not Writable");
}
*/
/**
* Centralize access to the Protocol object by POP3Message
* objects so that they will fail appropriately when the folder
* is closed.
*/
Protocol getProtocol() throws MessagingException {
Protocol p = port; // read it before close() can set it to null
checkOpen();
// close() might happen here
return p;
}
/*
* Only here to make accessible to POP3Message.
*/
protected void notifyMessageChangedListeners(int type, Message m) {
super.notifyMessageChangedListeners(type, m);
}
/**
* Used by POP3Message.
*/
TempFile getFileCache() {
return fileCache;
}
}

View File

@ -1,648 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.pop3;
import java.io.*;
import java.util.Enumeration;
import java.util.logging.Level;
import java.lang.ref.SoftReference;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.event.*;
import com.sun.mail.util.ReadableMime;
/**
* A POP3 Message. Just like a MimeMessage except that
* some things are not supported.
*
* @author Bill Shannon
*/
public class POP3Message extends MimeMessage implements ReadableMime {
/*
* Our locking strategy is to always lock the POP3Folder before the
* POP3Message so we have to be careful to drop our lock before calling
* back to the folder to close it and notify of connection lost events.
*/
// flag to indicate we haven't tried to fetch the UID yet
static final String UNKNOWN = "UNKNOWN";
private POP3Folder folder; // overrides folder in MimeMessage
private int hdrSize = -1;
private int msgSize = -1;
String uid = UNKNOWN; // controlled by folder lock
// rawData itself is never null
private SoftReference rawData = new SoftReference(null);
public POP3Message(Folder folder, int msgno)
throws MessagingException {
super(folder, msgno);
this.folder = (POP3Folder)folder;
}
/**
* Set the specified flags on this message to the specified value.
*
* @param newFlags the flags to be set
* @param set the value to be set
*/
public synchronized void setFlags(Flags newFlags, boolean set)
throws MessagingException {
Flags oldFlags = (Flags)flags.clone();
super.setFlags(newFlags, set);
if (!flags.equals(oldFlags))
folder.notifyMessageChangedListeners(
MessageChangedEvent.FLAGS_CHANGED, this);
}
/**
* Return the size of the content of this message in bytes.
* Returns -1 if the size cannot be determined. <p>
*
* Note that this number may not be an exact measure of the
* content size and may or may not account for any transfer
* encoding of the content. <p>
*
* @return size of content in bytes
* @exception MessagingException
*/
public int getSize() throws MessagingException {
try {
synchronized (this) {
// if we already have the size, return it
if (msgSize > 0)
return msgSize;
}
/*
* Use LIST to determine the entire message
* size and subtract out the header size
* (which may involve loading the headers,
* which may load the content as a side effect).
* If the content is loaded as a side effect of
* loading the headers, it will set the size.
*
* Make sure to call loadHeaders() outside of the
* synchronization block. There's a potential race
* condition here but synchronization will occur in
* loadHeaders() to make sure the headers are only
* loaded once, and again in the following block to
* only compute msgSize once.
*/
if (headers == null)
loadHeaders();
synchronized (this) {
if (msgSize < 0)
msgSize = folder.getProtocol().list(msgnum) - hdrSize;
return msgSize;
}
} catch (EOFException eex) {
folder.close(false);
throw new FolderClosedException(folder, eex.toString());
} catch (IOException ex) {
throw new MessagingException("error getting size", ex);
}
}
/**
* Produce the raw bytes of the message. The data is fetched using
* the POP3 RETR command. If skipHeader is true, just the content
* is returned.
*/
private InputStream getRawStream(boolean skipHeader)
throws MessagingException {
InputStream rawcontent = null;
try {
synchronized(this) {
rawcontent = (InputStream)rawData.get();
if (rawcontent == null) {
TempFile cache = folder.getFileCache();
if (cache != null) {
Session s = ((POP3Store)(folder.getStore())).getSession();
if (folder.logger.isLoggable(Level.FINE))
folder.logger.fine("caching message #" + msgnum +
" in temp file");
AppendStream os = cache.getAppendStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
try {
folder.getProtocol().retr(msgnum, bos);
} finally {
bos.close();
}
rawcontent = os.getInputStream();
} else {
rawcontent = folder.getProtocol().retr(msgnum,
msgSize > 0 ? msgSize + hdrSize : 0);
}
if (rawcontent == null) {
expunged = true;
throw new MessageRemovedException(
"can't retrieve message #" + msgnum +
" in POP3Message.getContentStream"); // XXX - what else?
}
if (headers == null ||
((POP3Store)(folder.getStore())).forgetTopHeaders) {
headers = new InternetHeaders(rawcontent);
hdrSize =
(int)((SharedInputStream)rawcontent).getPosition();
} else {
/*
* Already have the headers, have to skip the headers
* in the content array and return the body.
*
* XXX - It seems that some mail servers return slightly
* different headers in the RETR results than were returned
* in the TOP results, so we can't depend on remembering
* the size of the headers from the TOP command and just
* skipping that many bytes. Instead, we have to process
* the content, skipping over the header until we come to
* the empty line that separates the header from the body.
*/
int offset = 0;
for (;;) {
int len = 0; // number of bytes in this line
int c1;
while ((c1 = rawcontent.read()) >= 0) {
if (c1 == '\n') // end of line
break;
else if (c1 == '\r') {
// got CR, is the next char LF?
if (rawcontent.available() > 0) {
rawcontent.mark(1);
if (rawcontent.read() != '\n')
rawcontent.reset();
}
break; // in any case, end of line
}
// not CR, NL, or CRLF, count the byte
len++;
}
// here when end of line or out of data
// if out of data, we're done
if (rawcontent.available() == 0)
break;
// if it was an empty line, we're done
if (len == 0)
break;
}
hdrSize =
(int)((SharedInputStream)rawcontent).getPosition();
}
// skipped the header, the message is what's left
msgSize = rawcontent.available();
rawData = new SoftReference(rawcontent);
}
}
} catch (EOFException eex) {
folder.close(false);
throw new FolderClosedException(folder, eex.toString());
} catch (IOException ex) {
throw new MessagingException("error fetching POP3 content", ex);
}
/*
* We have a cached stream, but we need to return
* a fresh stream to read from the beginning and
* that can be safely closed.
*/
rawcontent = ((SharedInputStream)rawcontent).newStream(
skipHeader ? hdrSize : 0, -1);
return rawcontent;
}
/**
* Produce the raw bytes of the content. The data is fetched using
* the POP3 RETR command.
*
* @see #contentStream
*/
protected synchronized InputStream getContentStream()
throws MessagingException {
if (contentStream != null)
return ((SharedInputStream)contentStream).newStream(0, -1);
InputStream cstream = getRawStream(true);
/*
* Keep a hard reference to the data if we're using a file
* cache or if the "mail.pop3.keepmessagecontent" prop is set.
*/
TempFile cache = folder.getFileCache();
if (cache != null ||
((POP3Store)(folder.getStore())).keepMessageContent)
contentStream = ((SharedInputStream)cstream).newStream(0, -1);
return cstream;
}
/**
* Return the MIME format stream corresponding to this message part.
*
* @return the MIME format stream
* @since JavaMail 1.4.5
*/
public InputStream getMimeStream() throws MessagingException {
return getRawStream(false);
}
/**
* Invalidate the cache of content for this message object, causing
* it to be fetched again from the server the next time it is needed.
* If <code>invalidateHeaders</code> is true, invalidate the headers
* as well.
*
* @param invalidateHeaders invalidate the headers as well?
*/
public synchronized void invalidate(boolean invalidateHeaders) {
content = null;
InputStream rstream = (InputStream)rawData.get();
if (rstream != null) {
// note that if the content is in the file cache, it will be lost
// and fetched from the server if it's needed again
try {
rstream.close();
} catch (IOException ex) {
// ignore it
}
rawData = new SoftReference(null);
}
if (contentStream != null) {
try {
contentStream.close();
} catch (IOException ex) {
// ignore it
}
contentStream = null;
}
msgSize = -1;
if (invalidateHeaders) {
headers = null;
hdrSize = -1;
}
}
/**
* Fetch the header of the message and the first <code>n</code> lines
* of the raw content of the message. The headers and data are
* available in the returned InputStream.
*
* @param n number of lines of content to fetch
* @return InputStream containing the message headers and n content lines
*/
public InputStream top(int n) throws MessagingException {
try {
synchronized (this) {
return folder.getProtocol().top(msgnum, n);
}
} catch (EOFException eex) {
folder.close(false);
throw new FolderClosedException(folder, eex.toString());
} catch (IOException ex) {
throw new MessagingException("error getting size", ex);
}
}
/**
* Get all the headers for this header_name. Note that certain
* headers may be encoded as per RFC 2047 if they contain
* non US-ASCII characters and these should be decoded. <p>
*
* @param name name of header
* @return array of headers
* @exception MessagingException
* @see javax.mail.internet.MimeUtility
*/
public String[] getHeader(String name)
throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getHeader(name);
}
/**
* Get all the headers for this header name, returned as a single
* String, with headers separated by the delimiter. If the
* delimiter is <code>null</code>, only the first header is
* returned.
*
* @param name the name of this header
* @param delimiter delimiter between returned headers
* @return the value fields for all headers with
* this name
* @exception MessagingException
*/
public String getHeader(String name, String delimiter)
throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getHeader(name, delimiter);
}
/**
* Set the value for this header_name. Throws IllegalWriteException
* because POP3 messages are read-only.
*
* @param name header name
* @param value header value
* @see javax.mail.internet.MimeUtility
* @exception IllegalWriteException because the underlying
* implementation does not support modification
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public void setHeader(String name, String value)
throws MessagingException {
// XXX - should check for read-only folder?
throw new IllegalWriteException("POP3 messages are read-only");
}
/**
* Add this value to the existing values for this header_name.
* Throws IllegalWriteException because POP3 messages are read-only.
*
* @param name header name
* @param value header value
* @see javax.mail.internet.MimeUtility
* @exception IllegalWriteException because the underlying
* implementation does not support modification
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public void addHeader(String name, String value)
throws MessagingException {
// XXX - should check for read-only folder?
throw new IllegalWriteException("POP3 messages are read-only");
}
/**
* Remove all headers with this name.
* Throws IllegalWriteException because POP3 messages are read-only.
*
* @exception IllegalWriteException because the underlying
* implementation does not support modification
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public void removeHeader(String name)
throws MessagingException {
// XXX - should check for read-only folder?
throw new IllegalWriteException("POP3 messages are read-only");
}
/**
* Return all the headers from this Message as an enumeration
* of Header objects. <p>
*
* Note that certain headers may be encoded as per RFC 2047
* if they contain non US-ASCII characters and these should
* be decoded. <p>
*
* @return array of header objects
* @exception MessagingException
* @see javax.mail.internet.MimeUtility
*/
public Enumeration getAllHeaders() throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getAllHeaders();
}
/**
* Return matching headers from this Message as an Enumeration of
* Header objects.
*
* @exception MessagingException
*/
public Enumeration getMatchingHeaders(String[] names)
throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getMatchingHeaders(names);
}
/**
* Return non-matching headers from this Message as an
* Enumeration of Header objects.
*
* @exception MessagingException
*/
public Enumeration getNonMatchingHeaders(String[] names)
throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getNonMatchingHeaders(names);
}
/**
* Add a raw RFC822 header-line.
* Throws IllegalWriteException because POP3 messages are read-only.
*
* @exception IllegalWriteException because the underlying
* implementation does not support modification
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public void addHeaderLine(String line) throws MessagingException {
// XXX - should check for read-only folder?
throw new IllegalWriteException("POP3 messages are read-only");
}
/**
* Get all header lines as an Enumeration of Strings. A Header
* line is a raw RFC822 header-line, containing both the "name"
* and "value" field.
*
* @exception MessagingException
*/
public Enumeration getAllHeaderLines() throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getAllHeaderLines();
}
/**
* Get matching header lines as an Enumeration of Strings.
* A Header line is a raw RFC822 header-line, containing both
* the "name" and "value" field.
*
* @exception MessagingException
*/
public Enumeration getMatchingHeaderLines(String[] names)
throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getMatchingHeaderLines(names);
}
/**
* Get non-matching header lines as an Enumeration of Strings.
* A Header line is a raw RFC822 header-line, containing both
* the "name" and "value" field.
*
* @exception MessagingException
*/
public Enumeration getNonMatchingHeaderLines(String[] names)
throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getNonMatchingHeaderLines(names);
}
/**
* POP3 message can't be changed. This method throws
* IllegalWriteException.
*
* @exception IllegalWriteException because the underlying
* implementation does not support modification
*/
public void saveChanges() throws MessagingException {
// POP3 Messages are read-only
throw new IllegalWriteException("POP3 messages are read-only");
}
/**
* Output the message as an RFC 822 format stream, without
* specified headers. If the property "mail.pop3.cachewriteto"
* is set to "true", and ignoreList is null, and the message hasn't
* already been cached as a side effect of other operations, the message
* content is cached before being written. Otherwise, the message is
* streamed directly to the output stream without being cached.
*
* @exception javax.mail.MessagingException
* @exception IOException if an error occurs writing to the stream
* or if an error is generated by the
* javax.activation layer.
* @see javax.activation.DataHandler#writeTo
*/
public synchronized void writeTo(OutputStream os, String[] ignoreList)
throws IOException, MessagingException {
InputStream rawcontent = (InputStream)rawData.get();
if (rawcontent == null && ignoreList == null &&
!((POP3Store)(folder.getStore())).cacheWriteTo) {
Session s = ((POP3Store)(folder.getStore())).getSession();
if (folder.logger.isLoggable(Level.FINE))
folder.logger.fine("streaming msg " + msgnum);
if (!folder.getProtocol().retr(msgnum, os)) {
expunged = true;
throw new MessageRemovedException("can't retrieve message #" +
msgnum + " in POP3Message.writeTo"); // XXX - what else?
}
} else if (rawcontent != null && ignoreList == null) {
// can just copy the cached data
InputStream in = ((SharedInputStream)rawcontent).newStream(0, -1);
try {
byte[] buf = new byte[16*1024];
int len;
while ((len = in.read(buf)) > 0)
os.write(buf, 0, len);
} finally {
try {
if (in != null)
in.close();
} catch (IOException ex) { }
}
} else
super.writeTo(os, ignoreList);
}
/**
* Load the headers for this message into the InternetHeaders object.
* The headers are fetched using the POP3 TOP command.
*/
private void loadHeaders() throws MessagingException {
assert !Thread.holdsLock(this);
try {
boolean fetchContent = false;
synchronized (this) {
if (headers != null) // check again under lock
return;
InputStream hdrs = null;
if (((POP3Store)(folder.getStore())).disableTop ||
(hdrs = folder.getProtocol().top(msgnum, 0)) == null) {
// possibly because the TOP command isn't supported,
// load headers as a side effect of loading the entire
// content.
fetchContent = true;
} else {
try {
hdrSize = hdrs.available();
headers = new InternetHeaders(hdrs);
} finally {
hdrs.close();
}
}
}
/*
* Outside the synchronization block...
*
* Do we need to fetch the entire mesage content in order to
* load the headers as a side effect? Yes, there's a race
* condition here - multiple threads could decide that the
* content needs to be fetched. Fortunately, they'll all
* synchronize in the getContentStream method and the content
* will only be loaded once.
*/
if (fetchContent) {
InputStream cs = null;
try {
cs = getContentStream();
} finally {
if (cs != null)
cs.close();
}
}
} catch (EOFException eex) {
folder.close(false);
throw new FolderClosedException(folder, eex.toString());
} catch (IOException ex) {
throw new MessagingException("error loading POP3 headers", ex);
}
}
}

View File

@ -1,55 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.pop3;
import javax.mail.*;
/**
* A POP3 Message Store using SSL. Contains only one folder, "INBOX".
*
* @author Bill Shannon
*/
public class POP3SSLStore extends POP3Store {
public POP3SSLStore(Session session, URLName url) {
super(session, url, "pop3s", true);
}
}

View File

@ -1,420 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.pop3;
import java.util.Properties;
import java.util.logging.Level;
import java.lang.reflect.*;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.PrintStream;
import java.io.IOException;
import java.io.EOFException;
import java.util.Collections;
import java.util.Map;
import com.sun.mail.util.PropUtil;
import com.sun.mail.util.MailLogger;
import com.sun.mail.util.SocketConnectException;
import com.sun.mail.util.MailConnectException;
/**
* A POP3 Message Store. Contains only one folder, "INBOX".
*
* See the <a href="package-summary.html">com.sun.mail.pop3</a> package
* documentation for further information on the POP3 protocol provider. <p>
*
* @author Bill Shannon
* @author John Mani
*/
public class POP3Store extends Store {
private String name = "pop3"; // my protocol name
private int defaultPort = 110; // default POP3 port
private boolean isSSL = false; // use SSL?
private Protocol port = null; // POP3 port for self
private POP3Folder portOwner = null; // folder owning port
private String host = null; // host
private int portNum = -1;
private String user = null;
private String passwd = null;
private boolean useStartTLS = false;
private boolean requireStartTLS = false;
private boolean usingSSL = false;
private Map capabilities;
private MailLogger logger;
// following set here and accessed by other classes in this package
volatile Constructor messageConstructor = null;
volatile boolean rsetBeforeQuit = false;
volatile boolean disableTop = false;
volatile boolean forgetTopHeaders = false;
volatile boolean supportsUidl = true;
volatile boolean cacheWriteTo = false;
volatile boolean useFileCache = false;
volatile File fileCacheDir = null;
volatile boolean keepMessageContent = false;
public POP3Store(Session session, URLName url) {
this(session, url, "pop3", false);
}
public POP3Store(Session session, URLName url,
String name, boolean isSSL) {
super(session, url);
if (url != null)
name = url.getProtocol();
this.name = name;
logger = new MailLogger(this.getClass(),
"DEBUG POP3", session);
if (!isSSL)
isSSL = PropUtil.getBooleanSessionProperty(session,
"mail." + name + ".ssl.enable", false);
if (isSSL)
this.defaultPort = 995;
else
this.defaultPort = 110;
this.isSSL = isSSL;
rsetBeforeQuit = getBoolProp("rsetbeforequit");
disableTop = getBoolProp("disabletop");
forgetTopHeaders = getBoolProp("forgettopheaders");
cacheWriteTo = getBoolProp("cachewriteto");
useFileCache = getBoolProp("filecache.enable");
String dir = session.getProperty("mail." + name + ".filecache.dir");
if (dir != null && logger.isLoggable(Level.CONFIG))
logger.config("mail." + name + ".filecache.dir: " + dir);
if (dir != null)
fileCacheDir = new File(dir);
keepMessageContent = getBoolProp("keepmessagecontent");
// mail.pop3.starttls.enable enables use of STLS command
useStartTLS = getBoolProp("starttls.enable");
// mail.pop3.starttls.required requires use of STLS command
requireStartTLS = getBoolProp("starttls.required");
String s = session.getProperty("mail." + name + ".message.class");
if (s != null) {
logger.log(Level.CONFIG, "message class: {0}", s);
try {
ClassLoader cl = this.getClass().getClassLoader();
// now load the class
Class messageClass = null;
try {
// First try the "application's" class loader.
// This should eventually be replaced by
// Thread.currentThread().getContextClassLoader().
messageClass = Class.forName(s, false, cl);
} catch (ClassNotFoundException ex1) {
// That didn't work, now try the "system" class loader.
// (Need both of these because JDK 1.1 class loaders
// may not delegate to their parent class loader.)
messageClass = Class.forName(s);
}
Class[] c = {javax.mail.Folder.class, int.class};
messageConstructor = messageClass.getConstructor(c);
} catch (Exception ex) {
logger.log(Level.CONFIG, "failed to load message class", ex);
}
}
}
/**
* Get the value of a boolean property.
* Print out the value if logging is enabled.
*/
private final synchronized boolean getBoolProp(String prop) {
prop = "mail." + name + "." + prop;
boolean val = PropUtil.getBooleanSessionProperty(session, prop, false);
if (logger.isLoggable(Level.CONFIG))
logger.config(prop + ": " + val);
return val;
}
/**
* Get a reference to the session.
*/
synchronized Session getSession() {
return session;
}
protected synchronized boolean protocolConnect(String host, int portNum,
String user, String passwd) throws MessagingException {
// check for non-null values of host, password, user
if (host == null || passwd == null || user == null)
return false;
// if port is not specified, set it to value of mail.pop3.port
// property if it exists, otherwise default to 110
if (portNum == -1)
portNum = PropUtil.getIntSessionProperty(session,
"mail." + name + ".port", -1);
if (portNum == -1)
portNum = defaultPort;
this.host = host;
this.portNum = portNum;
this.user = user;
this.passwd = passwd;
try {
port = getPort(null);
} catch (EOFException eex) {
throw new AuthenticationFailedException(eex.getMessage());
} catch (SocketConnectException scex) {
throw new MailConnectException(scex);
} catch (IOException ioex) {
throw new MessagingException("Connect failed", ioex);
}
return true;
}
/**
* Check whether this store is connected. Override superclass
* method, to actually ping our server connection. <p>
*/
/*
* Note that we maintain somewhat of an illusion of being connected
* even if we're not really connected. This is because a Folder
* can use the connection and close it when it's done. If we then
* ask whether the Store's connected we want the answer to be true,
* as long as we can reconnect at that point. This means that we
* need to be able to reconnect the Store on demand.
*/
public synchronized boolean isConnected() {
if (!super.isConnected())
// if we haven't been connected at all, don't bother with
// the NOOP.
return false;
try {
if (port == null)
port = getPort(null);
else if (!port.noop())
throw new IOException("NOOP failed");
return true;
} catch (IOException ioex) {
// no longer connected, close it down
try {
super.close(); // notifies listeners
} catch (MessagingException mex) {
// ignore it
} finally {
return false;
}
}
}
synchronized Protocol getPort(POP3Folder owner) throws IOException {
Protocol p;
// if we already have a port, remember who's using it
if (port != null && portOwner == null) {
portOwner = owner;
return port;
}
// need a new port, create it and try to login
p = new Protocol(host, portNum, logger,
session.getProperties(), "mail." + name, isSSL);
if (useStartTLS || requireStartTLS) {
if (p.hasCapability("STLS")) {
if (p.stls()) {
// success, refresh capabilities
p.setCapabilities(p.capa());
} else if (requireStartTLS) {
logger.fine("STLS required but failed");
try {
p.quit();
} catch (IOException ioex) {
} finally {
throw new EOFException("STLS required but failed");
}
}
} else if (requireStartTLS) {
logger.fine("STLS required but not supported");
try {
p.quit();
} catch (IOException ioex) {
} finally {
throw new EOFException("STLS required but not supported");
}
}
}
capabilities = p.getCapabilities(); // save for later, may be null
usingSSL = p.isSSL(); // in case anyone asks
/*
* If we haven't explicitly disabled use of the TOP command,
* and the server has provided its capabilities,
* and the server doesn't support the TOP command,
* disable the TOP command.
*/
if (!disableTop &&
capabilities != null && !capabilities.containsKey("TOP")) {
disableTop = true;
logger.fine("server doesn't support TOP, disabling it");
}
supportsUidl = capabilities == null || capabilities.containsKey("UIDL");
String msg = null;
if ((msg = p.login(user, passwd)) != null) {
try {
p.quit();
} catch (IOException ioex) {
} finally {
throw new EOFException(msg);
}
}
/*
* If a Folder closes the port, and then a Folder
* is opened, the Store won't have a port. In that
* case, the getPort call will come from Folder.open,
* but we need to keep track of the port in the Store
* so that a later call to Folder.isOpen, which calls
* Store.isConnected, will use the same port.
*/
if (port == null && owner != null) {
port = p;
portOwner = owner;
}
if (portOwner == null)
portOwner = owner;
return p;
}
synchronized void closePort(POP3Folder owner) {
if (portOwner == owner) {
port = null;
portOwner = null;
}
}
public synchronized void close() throws MessagingException {
try {
if (port != null)
port.quit();
} catch (IOException ioex) {
} finally {
port = null;
// to set the state and send the closed connection event
super.close();
}
}
public Folder getDefaultFolder() throws MessagingException {
checkConnected();
return new DefaultFolder(this);
}
/**
* Only the name "INBOX" is supported.
*/
public Folder getFolder(String name) throws MessagingException {
checkConnected();
return new POP3Folder(this, name);
}
public Folder getFolder(URLName url) throws MessagingException {
checkConnected();
return new POP3Folder(this, url.getFile());
}
/**
* Return a Map of the capabilities the server provided,
* as per RFC 2449. If the server doesn't support RFC 2449,
* an emtpy Map is returned. The returned Map can not be modified.
* The key to the Map is the upper case capability name as
* a String. The value of the entry is the entire String
* capability line returned by the server. <p>
*
* For example, to check if the server supports the STLS capability, use:
* <code>if (store.capabilities().containsKey("STLS")) ...</code>
*
* @return Map of capabilities
* @since JavaMail 1.4.3
*/
public Map capabilities() throws MessagingException {
Map c;
synchronized (this) {
c = capabilities;
}
if (c != null)
return Collections.unmodifiableMap(c);
else
return Collections.EMPTY_MAP;
}
/**
* Is this POP3Store using SSL to connect to the server?
*
* @return true if using SSL
* @since JavaMail 1.4.6
*/
public boolean isSSL() {
return usingSSL;
}
protected void finalize() throws Throwable {
super.finalize();
if (port != null) // don't force a connection attempt
close();
}
private void checkConnected() throws MessagingException {
if (!super.isConnected())
throw new MessagingException("Not connected");
}
}

View File

@ -1,847 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.pop3;
import java.util.*;
import java.net.*;
import java.io.*;
import java.security.*;
import java.util.logging.Level;
import javax.net.ssl.SSLSocket;
import com.sun.mail.util.*;
class Response {
boolean ok = false; // true if "+OK"
String data = null; // rest of line after "+OK" or "-ERR"
InputStream bytes = null; // all the bytes from a multi-line response
}
/**
* This class provides a POP3 connection and implements
* the POP3 protocol requests.
*
* APOP support courtesy of "chamness".
*
* @author Bill Shannon
*/
class Protocol {
private Socket socket; // POP3 socket
private String host; // host we're connected to
private Properties props; // session properties
private String prefix; // protocol name prefix, for props
private DataInputStream input; // input buf
private PrintWriter output; // output buf
private TraceInputStream traceInput;
private TraceOutputStream traceOutput;
private MailLogger logger;
private MailLogger traceLogger;
private String apopChallenge = null;
private Map capabilities = null;
private boolean pipelining;
private boolean noauthdebug = true; // hide auth info in debug output
private boolean traceSuspended; // temporarily suspend tracing
private static final int POP3_PORT = 110; // standard POP3 port
private static final String CRLF = "\r\n";
// sometimes the returned size isn't quite big enough
private static final int SLOP = 128;
/**
* Open a connection to the POP3 server.
*/
Protocol(String host, int port, MailLogger logger,
Properties props, String prefix, boolean isSSL)
throws IOException {
this.host = host;
this.props = props;
this.prefix = prefix;
this.logger = logger;
traceLogger = logger.getSubLogger("protocol", null);
noauthdebug = !PropUtil.getBooleanProperty(props,
"mail.debug.auth", false);
Response r;
boolean enableAPOP = getBoolProp(props, prefix + ".apop.enable");
boolean disableCapa = getBoolProp(props, prefix + ".disablecapa");
try {
if (port == -1)
port = POP3_PORT;
if (logger.isLoggable(Level.FINE))
logger.fine("connecting to host \"" + host +
"\", port " + port + ", isSSL " + isSSL);
socket = SocketFetcher.getSocket(host, port, props, prefix, isSSL);
initStreams();
r = simpleCommand(null);
} catch (IOException ioe) {
try {
socket.close();
} finally {
throw ioe;
}
}
if (!r.ok) {
try {
socket.close();
} finally {
throw new IOException("Connect failed");
}
}
if (enableAPOP) {
int challStart = r.data.indexOf('<'); // start of challenge
int challEnd = r.data.indexOf('>', challStart); // end of challenge
if (challStart != -1 && challEnd != -1)
apopChallenge = r.data.substring(challStart, challEnd + 1);
logger.log(Level.FINE, "APOP challenge: {0}", apopChallenge);
}
// if server supports RFC 2449, set capabilities
if (!disableCapa)
setCapabilities(capa());
pipelining = hasCapability("PIPELINING") ||
PropUtil.getBooleanProperty(props, prefix + ".pipelining", false);
if (pipelining)
logger.config("PIPELINING enabled");
}
/**
* Get the value of a boolean property.
* Print out the value if logging is enabled.
*/
private final synchronized boolean getBoolProp(Properties props,
String prop) {
boolean val = PropUtil.getBooleanProperty(props, prop, false);
if (logger.isLoggable(Level.CONFIG))
logger.config(prop + ": " + val);
return val;
}
private void initStreams() throws IOException {
boolean quote = PropUtil.getBooleanProperty(props,
"mail.debug.quote", false);
traceInput =
new TraceInputStream(socket.getInputStream(), traceLogger);
traceInput.setQuote(quote);
traceOutput =
new TraceOutputStream(socket.getOutputStream(), traceLogger);
traceOutput.setQuote(quote);
input = new DataInputStream(new BufferedInputStream(traceInput));
output = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(traceOutput, "iso-8859-1")));
// should be US-ASCII, but not all JDK's support
}
protected void finalize() throws Throwable {
super.finalize();
if (socket != null) { // Forgot to logout ?!
quit();
}
}
/**
* Parse the capabilities from a CAPA response.
*/
synchronized void setCapabilities(InputStream in) {
if (in == null) {
capabilities = null;
return;
}
capabilities = new HashMap(10);
BufferedReader r = null;
try {
r = new BufferedReader(new InputStreamReader(in, "us-ascii"));
} catch (UnsupportedEncodingException ex) {
// should never happen
assert false;
}
String s;
try {
while ((s = r.readLine()) != null) {
String cap = s;
int i = cap.indexOf(' ');
if (i > 0)
cap = cap.substring(0, i);
capabilities.put(cap.toUpperCase(Locale.ENGLISH), s);
}
} catch (IOException ex) {
// should never happen
} finally {
try {
in.close();
} catch (IOException ex) { }
}
}
/**
* Check whether the given capability is supported by
* this server. Returns <code>true</code> if so, otherwise
* returns false.
*/
synchronized boolean hasCapability(String c) {
return capabilities != null &&
capabilities.containsKey(c.toUpperCase(Locale.ENGLISH));
}
/**
* Return the map of capabilities returned by the server.
*/
synchronized Map getCapabilities() {
return capabilities;
}
/**
* Login to the server, using the USER and PASS commands.
*/
synchronized String login(String user, String password)
throws IOException {
Response r;
// only pipeline password if connection is secure
boolean batch = pipelining && socket instanceof SSLSocket;
try {
if (noauthdebug && isTracing()) {
logger.fine("authentication command trace suppressed");
suspendTracing();
}
String dpw = null;
if (apopChallenge != null)
dpw = getDigest(password);
if (apopChallenge != null && dpw != null) {
r = simpleCommand("APOP " + user + " " + dpw);
} else if (batch) {
String cmd = "USER " + user;
batchCommandStart(cmd);
issueCommand(cmd);
cmd = "PASS " + password;
batchCommandContinue(cmd);
issueCommand(cmd);
r = readResponse();
if (!r.ok) {
String err = r.data != null ? r.data : "USER command failed";
r = readResponse();
batchCommandEnd();
return err;
}
r = readResponse();
batchCommandEnd();
} else {
r = simpleCommand("USER " + user);
if (!r.ok)
return r.data != null ? r.data : "USER command failed";
r = simpleCommand("PASS " + password);
}
if (noauthdebug && isTracing())
logger.log(Level.FINE, "authentication command {0}",
(r.ok ? "succeeded" : "failed"));
if (!r.ok)
return r.data != null ? r.data : "login failed";
return null;
} finally {
resumeTracing();
}
}
/**
* Gets the APOP message digest.
* From RFC 1939:
*
* The 'digest' parameter is calculated by applying the MD5
* algorithm [RFC1321] to a string consisting of the timestamp
* (including angle-brackets) followed by a shared secret.
* The 'digest' parameter itself is a 16-octet value which is
* sent in hexadecimal format, using lower-case ASCII characters.
*
* @param password The APOP password
* @return The APOP digest or an empty string if an error occurs.
*/
private String getDigest(String password) {
String key = apopChallenge + password;
byte[] digest;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
digest = md.digest(key.getBytes("iso-8859-1")); // XXX
} catch (NoSuchAlgorithmException nsae) {
return null;
} catch (UnsupportedEncodingException uee) {
return null;
}
return toHex(digest);
}
private static char[] digits = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
/**
* Convert a byte array to a string of hex digits representing the bytes.
*/
private static String toHex(byte[] bytes) {
char[] result = new char[bytes.length * 2];
for (int index = 0, i = 0; index < bytes.length; index++) {
int temp = bytes[index] & 0xFF;
result[i++] = digits[temp >> 4];
result[i++] = digits[temp & 0xF];
}
return new String(result);
}
/**
* Close down the connection, sending the QUIT command.
*/
synchronized boolean quit() throws IOException {
boolean ok = false;
try {
Response r = simpleCommand("QUIT");
ok = r.ok;
} finally {
try {
socket.close();
} finally {
socket = null;
input = null;
output = null;
}
}
return ok;
}
/**
* Return the total number of messages and mailbox size,
* using the STAT command.
*/
synchronized Status stat() throws IOException {
Response r = simpleCommand("STAT");
Status s = new Status();
/*
* Normally the STAT command shouldn't fail but apparently it
* does when accessing Hotmail too often, returning:
* -ERR login allowed only every 15 minutes
* (Why it doesn't just fail the login, I don't know.)
* This is a serious failure that we don't want to hide
* from the user.
*/
if (!r.ok)
throw new IOException("STAT command failed: " + r.data);
if (r.data != null) {
try {
StringTokenizer st = new StringTokenizer(r.data);
s.total = Integer.parseInt(st.nextToken());
s.size = Integer.parseInt(st.nextToken());
} catch (Exception e) {
}
}
return s;
}
/**
* Return the size of the message using the LIST command.
*/
synchronized int list(int msg) throws IOException {
Response r = simpleCommand("LIST " + msg);
int size = -1;
if (r.ok && r.data != null) {
try {
StringTokenizer st = new StringTokenizer(r.data);
st.nextToken(); // skip message number
size = Integer.parseInt(st.nextToken());
} catch (Exception e) {
}
}
return size;
}
/**
* Return the size of all messages using the LIST command.
*/
synchronized InputStream list() throws IOException {
Response r = multilineCommand("LIST", 128); // 128 == output size est
return r.bytes;
}
/**
* Retrieve the specified message.
* Given an estimate of the message's size we can be more efficient,
* preallocating the array and returning a SharedInputStream to allow
* us to share the array.
*/
synchronized InputStream retr(int msg, int size) throws IOException {
Response r;
String cmd;
boolean batch = size == 0 && pipelining;
if (batch) {
cmd = "LIST " + msg;
batchCommandStart(cmd);
issueCommand(cmd);
cmd = "RETR " + msg;
batchCommandContinue(cmd);
issueCommand(cmd);
r = readResponse();
if (r.ok && r.data != null) {
// parse the LIST response to get the message size
try {
StringTokenizer st = new StringTokenizer(r.data);
st.nextToken(); // skip message number
size = Integer.parseInt(st.nextToken());
// don't allow ridiculous sizes
if (size > 1024*1024*1024 || size < 0)
size = 0;
else {
if (logger.isLoggable(Level.FINE))
logger.fine("pipeline message size " + size);
size += SLOP;
}
} catch (Exception e) {
}
}
r = readResponse();
if (r.ok)
r.bytes = readMultilineResponse(size + SLOP);
batchCommandEnd();
} else {
cmd = "RETR " + msg;
multilineCommandStart(cmd);
issueCommand(cmd);
r = readResponse();
if (!r.ok) {
multilineCommandEnd();
return null;
}
/*
* Many servers return a response to the RETR command of the form:
* +OK 832 octets
* If we don't have a size guess already, try to parse the response
* for data in that format and use it if found. It's only a guess,
* but it might be a good guess.
*/
if (size <= 0 && r.data != null) {
try {
StringTokenizer st = new StringTokenizer(r.data);
String s = st.nextToken();
String octets = st.nextToken();
if (octets.equals("octets")) {
size = Integer.parseInt(s);
// don't allow ridiculous sizes
if (size > 1024*1024*1024 || size < 0)
size = 0;
else {
if (logger.isLoggable(Level.FINE))
logger.fine("guessing message size: " + size);
size += SLOP;
}
}
} catch (Exception e) {
}
}
r.bytes = readMultilineResponse(size);
multilineCommandEnd();
}
if (r.ok) {
if (size > 0 && logger.isLoggable(Level.FINE))
logger.fine("got message size " + r.bytes.available());
}
return r.bytes;
}
/**
* Retrieve the specified message and stream the content to the
* specified OutputStream. Return true on success.
*/
synchronized boolean retr(int msg, OutputStream os) throws IOException {
String cmd = "RETR " + msg;
multilineCommandStart(cmd);
issueCommand(cmd);
Response r = readResponse();
if (!r.ok) {
multilineCommandEnd();
return false;
}
Throwable terr = null;
int b, lastb = '\n';
try {
while ((b = input.read()) >= 0) {
if (lastb == '\n' && b == '.') {
b = input.read();
if (b == '\r') {
// end of response, consume LF as well
b = input.read();
break;
}
}
/*
* Keep writing unless we get an error while writing,
* which we defer until all of the data has been read.
*/
if (terr == null) {
try {
os.write(b);
} catch (IOException ex) {
logger.log(Level.FINE, "exception while streaming", ex);
terr = ex;
} catch (RuntimeException ex) {
logger.log(Level.FINE, "exception while streaming", ex);
terr = ex;
}
}
lastb = b;
}
} catch (InterruptedIOException iioex) {
/*
* As above in simpleCommand, close the socket to recover.
*/
try {
socket.close();
} catch (IOException cex) { }
throw iioex;
}
if (b < 0)
throw new EOFException("EOF on socket");
// was there a deferred error?
if (terr != null) {
if (terr instanceof IOException)
throw (IOException)terr;
if (terr instanceof RuntimeException)
throw (RuntimeException)terr;
assert false; // can't get here
}
multilineCommandEnd();
return true;
}
/**
* Return the message header and the first n lines of the message.
*/
synchronized InputStream top(int msg, int n) throws IOException {
Response r = multilineCommand("TOP " + msg + " " + n, 0);
return r.bytes;
}
/**
* Delete (permanently) the specified message.
*/
synchronized boolean dele(int msg) throws IOException {
Response r = simpleCommand("DELE " + msg);
return r.ok;
}
/**
* Return the UIDL string for the message.
*/
synchronized String uidl(int msg) throws IOException {
Response r = simpleCommand("UIDL " + msg);
if (!r.ok)
return null;
int i = r.data.indexOf(' ');
if (i > 0)
return r.data.substring(i + 1);
else
return null;
}
/**
* Return the UIDL strings for all messages.
* The UID for msg #N is returned in uids[N-1].
*/
synchronized boolean uidl(String[] uids) throws IOException {
Response r = multilineCommand("UIDL", 15 * uids.length);
if (!r.ok)
return false;
LineInputStream lis = new LineInputStream(r.bytes);
String line = null;
while ((line = lis.readLine()) != null) {
int i = line.indexOf(' ');
if (i < 1 || i >= line.length())
continue;
int n = Integer.parseInt(line.substring(0, i));
if (n > 0 && n <= uids.length)
uids[n - 1] = line.substring(i + 1);
}
try {
r.bytes.close();
} catch (IOException ex) { }
return true;
}
/**
* Do a NOOP.
*/
synchronized boolean noop() throws IOException {
Response r = simpleCommand("NOOP");
return r.ok;
}
/**
* Do an RSET.
*/
synchronized boolean rset() throws IOException {
Response r = simpleCommand("RSET");
return r.ok;
}
/**
* Start TLS using STLS command specified by RFC 2595.
* If already using SSL, this is a nop and the STLS command is not issued.
*/
synchronized boolean stls() throws IOException {
if (socket instanceof SSLSocket)
return true; // nothing to do
Response r = simpleCommand("STLS");
if (r.ok) {
// it worked, now switch the socket into TLS mode
try {
socket = SocketFetcher.startTLS(socket, host, props, prefix);
initStreams();
} catch (IOException ioex) {
try {
socket.close();
} finally {
socket = null;
input = null;
output = null;
}
IOException sioex =
new IOException("Could not convert socket to TLS");
sioex.initCause(ioex);
throw sioex;
}
}
return r.ok;
}
/**
* Is this connection using SSL?
*/
synchronized boolean isSSL() {
return socket instanceof SSLSocket;
}
/**
* Get server capabilities using CAPA command specified by RFC 2449.
* Returns null if not supported.
*/
synchronized InputStream capa() throws IOException {
Response r = multilineCommand("CAPA", 128); // 128 == output size est
if (!r.ok)
return null;
return r.bytes;
}
/**
* Issue a simple POP3 command and return the response.
*/
private Response simpleCommand(String cmd) throws IOException {
simpleCommandStart(cmd);
issueCommand(cmd);
Response r = readResponse();
simpleCommandEnd();
return r;
}
/**
* Send the specified command.
*/
private void issueCommand(String cmd) throws IOException {
if (socket == null)
throw new IOException("Folder is closed"); // XXX
if (cmd != null) {
cmd += CRLF;
output.print(cmd); // do it in one write
output.flush();
}
}
/**
* Read the response to a command.
*/
private Response readResponse() throws IOException {
String line = null;
try {
line = input.readLine(); // XXX - readLine is deprecated
} catch (InterruptedIOException iioex) {
/*
* If we get a timeout while using the socket, we have no idea
* what state the connection is in. The server could still be
* alive, but slow, and could still be sending data. The only
* safe way to recover is to drop the connection.
*/
try {
socket.close();
} catch (IOException cex) { }
throw new EOFException(iioex.getMessage());
} catch (SocketException ex) {
/*
* If we get an error while using the socket, we have no idea
* what state the connection is in. The server could still be
* alive, but slow, and could still be sending data. The only
* safe way to recover is to drop the connection.
*/
try {
socket.close();
} catch (IOException cex) { }
throw new EOFException(ex.getMessage());
}
if (line == null) {
traceLogger.finest("<EOF>");
throw new EOFException("EOF on socket");
}
Response r = new Response();
if (line.startsWith("+OK"))
r.ok = true;
else if (line.startsWith("-ERR"))
r.ok = false;
else
throw new IOException("Unexpected response: " + line);
int i;
if ((i = line.indexOf(' ')) >= 0)
r.data = line.substring(i + 1);
return r;
}
/**
* Issue a POP3 command that expects a multi-line response.
* <code>size</code> is an estimate of the response size.
*/
private Response multilineCommand(String cmd, int size) throws IOException {
multilineCommandStart(cmd);
issueCommand(cmd);
Response r = readResponse();
if (!r.ok) {
multilineCommandEnd();
return r;
}
r.bytes = readMultilineResponse(size);
multilineCommandEnd();
return r;
}
/**
* Read the response to a multiline command after the command response.
* The size parameter indicates the expected size of the response;
* the actual size can be different. Returns an InputStream to the
* response bytes.
*/
private InputStream readMultilineResponse(int size) throws IOException {
SharedByteArrayOutputStream buf = new SharedByteArrayOutputStream(size);
int b, lastb = '\n';
try {
while ((b = input.read()) >= 0) {
if (lastb == '\n' && b == '.') {
b = input.read();
if (b == '\r') {
// end of response, consume LF as well
b = input.read();
break;
}
}
buf.write(b);
lastb = b;
}
} catch (InterruptedIOException iioex) {
/*
* As above in readResponse, close the socket to recover.
*/
try {
socket.close();
} catch (IOException cex) { }
throw iioex;
}
if (b < 0)
throw new EOFException("EOF on socket");
return buf.toStream();
}
/**
* Is protocol tracing enabled?
*/
protected boolean isTracing() {
return traceLogger.isLoggable(Level.FINEST);
}
/**
* Temporarily turn off protocol tracing, e.g., to prevent
* tracing the authentication sequence, including the password.
*/
private void suspendTracing() {
if (traceLogger.isLoggable(Level.FINEST)) {
traceInput.setTrace(false);
traceOutput.setTrace(false);
}
}
/**
* Resume protocol tracing, if it was enabled to begin with.
*/
private void resumeTracing() {
if (traceLogger.isLoggable(Level.FINEST)) {
traceInput.setTrace(true);
traceOutput.setTrace(true);
}
}
/*
* Probe points for GlassFish monitoring.
*/
private void simpleCommandStart(String command) { }
private void simpleCommandEnd() { }
private void multilineCommandStart(String command) { }
private void multilineCommandEnd() { }
private void batchCommandStart(String command) { }
private void batchCommandContinue(String command) { }
private void batchCommandEnd() { }
}

View File

@ -1,49 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.pop3;
/**
* Result of POP3 STAT command.
*/
class Status {
int total = 0; // number of messages in the mailbox
int size = 0; // size of the mailbox
};

View File

@ -1,193 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.pop3;
import java.util.*;
import java.net.*;
import java.io.*;
import java.security.*;
import com.sun.mail.util.PropUtil;
import javax.mail.util.SharedFileInputStream;
/**
* A temporary file used to cache POP3 messages.
*/
class TempFile {
private File file; // the temp file name
private WritableSharedFile sf;
/**
* Create a temp file in the specified directory (if not null).
* The file will be deleted when the JVM exits.
*/
public TempFile(File dir) throws IOException {
file = File.createTempFile("pop3.", ".mbox", dir);
// XXX - need JDK 6 to set permissions on the file to owner-only
file.deleteOnExit();
sf = new WritableSharedFile(file);
}
/**
* Return a stream for appending to the temp file.
*/
public AppendStream getAppendStream() throws IOException {
return sf.getAppendStream();
}
/**
* Close and remove this temp file.
*/
public void close() {
try {
sf.close();
} catch (IOException ex) {
// ignore it
}
file.delete();
}
protected void finalize() throws Throwable {
super.finalize();
close();
}
}
/**
* A subclass of SharedFileInputStream that also allows writing.
*/
class WritableSharedFile extends SharedFileInputStream {
private RandomAccessFile raf;
private AppendStream af;
public WritableSharedFile(File file) throws IOException {
super(file);
try {
raf = new RandomAccessFile(file, "rw");
} catch (IOException ex) {
// if anything goes wrong opening the writable file,
// close the readable file too
super.close();
}
}
/**
* Return the writable version of this file.
*/
public RandomAccessFile getWritableFile() {
return raf;
}
/**
* Close the readable and writable files.
*/
public void close() throws IOException {
try {
super.close();
} finally {
raf.close();
}
}
/**
* Update the size of the readable file after writing
* to the file. Updates the length to be the current
* size of the file.
*/
synchronized long updateLength() throws IOException {
datalen = in.length();
af = null;
return datalen;
}
/**
* Return a new AppendStream, but only if one isn't in active use.
*/
public synchronized AppendStream getAppendStream() throws IOException {
if (af != null)
throw new IOException(
"POP3 file cache only supports single threaded access");
af = new AppendStream(this);
return af;
}
}
/**
* A stream for writing to the temp file, and when done
* can return a stream for reading the data just written.
* NOTE: We assume that only one thread is writing to the
* file at a time.
*/
class AppendStream extends OutputStream {
private final WritableSharedFile tf;
private RandomAccessFile raf;
private final long start;
private long end;
public AppendStream(WritableSharedFile tf) throws IOException {
this.tf = tf;
raf = tf.getWritableFile();
start = raf.length();
raf.seek(start);
}
public void write(int b) throws IOException {
raf.write(b);
}
public void write(byte[] b) throws IOException {
raf.write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
raf.write(b, off, len);
}
public synchronized void close() throws IOException {
end = tf.updateLength();
raf = null; // no more writing allowed
}
public synchronized InputStream getInputStream() throws IOException {
return tf.newStream(start, end);
}
}

View File

@ -1,607 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can
obtain a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
or packager/legal/LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.
When distributing the software, include this License Header Notice in each
file and include the License file at packager/legal/LICENSE.txt.
GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.
Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"
Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->
</HEAD>
<BODY BGCOLOR="white">
A POP3 protocol provider for the JavaMail API
that provides access to a POP3 message store.
Refer to <A HREF="http://www.ietf.org/rfc/rfc1939.txt" TARGET="_top">
RFC 1939</A>
for more information.
<P>
The POP3 provider provides a Store object that contains a single Folder
named "INBOX". Due to the limitations of the POP3 protocol, many of
the JavaMail API capabilities like event notification, folder management,
flag management, etc. are not allowed. The corresponding methods throw
the MethodNotSupportedException exception; see below for details.
<P>
Note that JavaMail does <strong>not</strong> include a local store into
which messages can be downloaded and stored. See our
<A HREF="http://java.sun.com/products/javamail/Third_Party.html" TARGET="_top">
Third Party Products</A>
web page for availability of "mbox" and "MH" local store providers.
<P>
The POP3 provider is accessed through the JavaMail APIs by using the protocol
name "pop3" or a URL of the form "pop3://user:password@host:port/INBOX".
<P>
POP3 supports only a single folder named "INBOX".
<P>
POP3 supports <strong>no</strong> permanent flags (see
{@link javax.mail.Folder#getPermanentFlags Folder.getPermanentFlags()}).
In particular, the <code>Flags.Flag.RECENT</code> flag will never be set
for POP3
messages. It's up to the application to determine which messages in a
POP3 mailbox are "new". There are several strategies to accomplish
this, depending on the needs of the application and the environment:
<P>
<UL>
<LI>
A simple approach would be to keep track of the newest
message seen by the application.
</LI>
<LI>
An alternative would be to keep track of the UIDs (see below)
of all messages that have been seen.
</LI>
<LI>
Another approach is to download <strong>all</strong> messages into a local
mailbox, so that all messages in the POP3 mailbox are, by
definition, new.
</LI>
</UL>
<P>
All approaches will require some permanent storage associated with the client.
<P>
POP3 does not support the <code>Folder.expunge()</code> method. To delete and
expunge messages, set the <code>Flags.Flag.DELETED</code> flag on the messages
and close the folder using the <code>Folder.close(true)</code> method. You
cannot expunge without closing the folder.
<P>
POP3 does not provide a "received date", so the <code>getReceivedDate</code>
method will return null.
It may be possible to examine other message headers (e.g., the
"Received" headers) to estimate the received date, but these techniques
are error-prone at best.
<P>
The POP3 provider supports the POP3 UIDL command, see
{@link com.sun.mail.pop3.POP3Folder#getUID POP3Folder.getUID()}.
You can use it as follows:
<P>
<BLOCKQUOTE><PRE>
if (folder instanceof com.sun.mail.pop3.POP3Folder) {
com.sun.mail.pop3.POP3Folder pf =
(com.sun.mail.pop3.POP3Folder)folder;
String uid = pf.getUID(msg);
if (uid != null)
... // use it
}
</PRE></BLOCKQUOTE>
<P>
You can also pre-fetch all the UIDs for all messages like this:
<P>
<BLOCKQUOTE><PRE>
FetchProfile fp = new FetchProfile();
fp.add(UIDFolder.FetchProfileItem.UID);
folder.fetch(folder.getMessages(), fp);
</PRE></BLOCKQUOTE>
<P>
Then use the technique above to get the UID for each message. This is
similar to the technique used with the UIDFolder interface supported by
IMAP, but note that POP3 UIDs are strings, not integers like IMAP
UIDs. See the POP3 spec for details.
<P>
When the headers of a POP3 message are accessed, the POP3 provider uses
the TOP command to fetch all headers, which are then cached. Use of the
TOP command can be disabled with the <CODE>mail.pop3.disabletop</CODE>
property, in which case the entire message content is fetched with the
RETR command.
<P>
When the content of a POP3 message is accessed, the POP3 provider uses
the RETR command to fetch the entire message. Normally the message
content is cached in memory. By setting the
<CODE>mail.pop3.filecache.enable</CODE> property, the message content
will instead be cached in a temporary file. The file will be removed
when the folder is closed. Caching message content in a file is generally
slower, but uses substantially less memory and may be helpful when dealing
with very large messages.
<P>
The {@link com.sun.mail.pop3.POP3Message#invalidate POP3Message.invalidate}
method can be used to invalidate cached data without closing the folder.
Note that if the file cache is being used the data in the file will be
forgotten and fetched from the server if it's needed again, and stored again
in the file cache.
<P>
The POP3 CAPA command (defined by
<A HREF="http://www.ietf.org/rfc/rfc2449.txt" TARGET="_top">RFC 2449</A>)
will be used to determine the capabilities supported by the server.
Some servers don't implement the CAPA command, and some servers don't
return correct information, so various properties are available to
disable use of certain POP3 commands, including CAPA.
<P>
If the server advertises the PIPELINING capability (defined by
<A HREF="http://www.ietf.org/rfc/rfc2449.txt" TARGET="_top">RFC 2449</A>),
or the <CODE>mail.pop3.pipelining</CODE> property is set, the POP3
provider will send some commands in batches, which can significantly
improve performance and memory use.
Some servers that don't support the CAPA command or don't advertise
PIPELINING may still support pipelining; experimentation may be required.
<P>
If pipelining is supported and the connection is using
SSL, the USER and PASS commands will be sent as a batch.
(If SSL is not being used, the PASS command isn't sent
until the user is verified to avoid exposing the password
if the user name is bad.)
<P>
If pipelining is supported, when fetching a message with the RETR command,
the LIST command will be sent as well, and the result will be used to size
the I/O buffer, greatly reducing memory usage when fetching messages.
<P>
The POP3 protocol provider supports the following properties,
which may be set in the JavaMail <code>Session</code> object.
The properties are always set as strings; the Type column describes
how the string is interpreted. For example, use
<PRE>
props.put("mail.pop3.port", "888");
</PRE>
to set the <CODE>mail.pop3.port</CODE> property, which is of type int.
<P>
Note that if you're using the "pop3s" protocol to access POP3 over SSL,
all the properties would be named "mail.pop3s.*".
<P>
<TABLE BORDER>
<TR>
<TH>Name</TH>
<TH>Type</TH>
<TH>Description</TH>
</TR>
<TR>
<TD>mail.pop3.user</TD>
<TD>String</TD>
<TD>Default user name for POP3.</TD>
</TR>
<TR>
<TD>mail.pop3.host</TD>
<TD>String</TD>
<TD>The POP3 server to connect to.</TD>
</TR>
<TR>
<TD>mail.pop3.port</TD>
<TD>int</TD>
<TD>The POP3 server port to connect to, if the connect() method doesn't
explicitly specify one. Defaults to 110.</TD>
</TR>
<TR>
<TD>mail.pop3.connectiontimeout</TD>
<TD>int</TD>
<TD>Socket connection timeout value in milliseconds.
Default is infinite timeout.</TD>
</TR>
<TR>
<TD>mail.pop3.timeout</TD>
<TD>int</TD>
<TD>Socket I/O timeout value in milliseconds. Default is infinite timeout.</TD>
</TR>
<TR>
<TD>mail.pop3.rsetbeforequit</TD>
<TD>boolean</TD>
<TD>
Send a POP3 RSET command when closing the folder, before sending the
QUIT command. Useful with POP3 servers that implicitly mark all
messages that are read as "deleted"; this will prevent such messages
from being deleted and expunged unless the client requests so. Default
is false.
</TD>
</TR>
<TR>
<TD>mail.pop3.message.class</TD>
<TD>String</TD>
<TD>
Class name of a subclass of <code>com.sun.mail.pop3.POP3Message</code>.
The subclass can be used to handle (for example) non-standard
Content-Type headers. The subclass must have a public constructor
of the form <code>MyPOP3Message(Folder f, int msgno)
throws MessagingException</code>.
</TD>
</TR>
<TR>
<TD>mail.pop3.localaddress</TD>
<TD>String</TD>
<TD>
Local address (host name) to bind to when creating the POP3 socket.
Defaults to the address picked by the Socket class.
Should not normally need to be set, but useful with multi-homed hosts
where it's important to pick a particular local address to bind to.
</TD>
</TR>
<TR>
<TD>mail.pop3.localport</TD>
<TD>int</TD>
<TD>
Local port number to bind to when creating the POP3 socket.
Defaults to the port number picked by the Socket class.
</TD>
</TR>
<TR>
<TD>mail.pop3.apop.enable</TD>
<TD>boolean</TD>
<TD>
If set to true, use APOP instead of USER/PASS to login to the
POP3 server, if the POP3 server supports APOP. APOP sends a
digest of the password rather than the clear text password.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.pop3.socketFactory</TD>
<TD>SocketFactory</TD>
<TD>
If set to a class that implements the
<code>javax.net.SocketFactory</code> interface, this class
will be used to create POP3 sockets. Note that this is an
instance of a class, not a name, and must be set using the
<code>put</code> method, not the <code>setProperty</code> method.
</TD>
</TR>
<TR>
<TD>mail.pop3.socketFactory.class</TD>
<TD>String</TD>
<TD>
If set, specifies the name of a class that implements the
<code>javax.net.SocketFactory</code> interface. This class
will be used to create POP3 sockets.
</TD>
</TR>
<TR>
<TD>mail.pop3.socketFactory.fallback</TD>
<TD>boolean</TD>
<TD>
If set to true, failure to create a socket using the specified
socket factory class will cause the socket to be created using
the <code>java.net.Socket</code> class.
Defaults to true.
</TD>
</TR>
<TR>
<TD>mail.pop3.socketFactory.port</TD>
<TD>int</TD>
<TD>
Specifies the port to connect to when using the specified socket
factory.
If not set, the default port will be used.
</TD>
</TR>
<TR>
<TD>mail.pop3.ssl.enable</TD>
<TD>boolean</TD>
<TD>
If set to true, use SSL to connect and use the SSL port by default.
Defaults to false for the "pop3" protocol and true for the "pop3s" protocol.
</TD>
</TR>
<TR>
<TD>mail.pop3.ssl.checkserveridentity</TD>
<TD>boolean</TD>
<TD>
If set to true, check the server identity as specified by
<A HREF="http://www.ietf.org/rfc/rfc2595.txt" TARGET="_top">RFC 2595</A>.
These additional checks based on the content of the server's certificate
are intended to prevent man-in-the-middle attacks.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.pop3.ssl.trust</TD>
<TD>String</TD>
<TD>
If set, and a socket factory hasn't been specified, enables use of a
{@link com.sun.mail.util.MailSSLSocketFactory MailSSLSocketFactory}.
If set to "*", all hosts are trusted.
If set to a whitespace separated list of hosts, those hosts are trusted.
Otherwise, trust depends on the certificate the server presents.
</TD>
</TR>
<TR>
<TD>mail.pop3.ssl.socketFactory</TD>
<TD>SSLSocketFactory</TD>
<TD>
If set to a class that extends the
<code>javax.net.ssl.SSLSocketFactory</code> class, this class
will be used to create POP3 SSL sockets. Note that this is an
instance of a class, not a name, and must be set using the
<code>put</code> method, not the <code>setProperty</code> method.
</TD>
</TR>
<TR>
<TD>mail.pop3.ssl.socketFactory.class</TD>
<TD>String</TD>
<TD>
If set, specifies the name of a class that extends the
<code>javax.net.ssl.SSLSocketFactory</code> class. This class
will be used to create POP3 SSL sockets.
</TD>
</TR>
<TR>
<TD>mail.pop3.ssl.socketFactory.port</TD>
<TD>int</TD>
<TD>
Specifies the port to connect to when using the specified socket
factory.
If not set, the default port will be used.
</TD>
</TR>
<TR>
<TD>mail.pop3.ssl.protocols</TD>
<TD>string</TD>
<TD>
Specifies the SSL protocols that will be enabled for SSL connections.
The property value is a whitespace separated list of tokens acceptable
to the <code>javax.net.ssl.SSLSocket.setEnabledProtocols</code> method.
</TD>
</TR>
<TR>
<TD>mail.pop3.ssl.ciphersuites</TD>
<TD>string</TD>
<TD>
Specifies the SSL cipher suites that will be enabled for SSL connections.
The property value is a whitespace separated list of tokens acceptable
to the <code>javax.net.ssl.SSLSocket.setEnabledCipherSuites</code> method.
</TD>
</TR>
<TR>
<TD>mail.pop3.starttls.enable</TD>
<TD>boolean</TD>
<TD>
If true, enables the use of the <code>STLS</code> command (if
supported by the server) to switch the connection to a TLS-protected
connection before issuing any login commands. Note that an appropriate
trust store must configured so that the client will trust the server's
certificate.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.pop3.starttls.required</TD>
<TD>boolean</TD>
<TD>
If true, requires the use of the <code>STLS</code> command.
If the server doesn't support the STLS command, or the command
fails, the connect method will fail.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.pop3.socks.host</TD>
<TD>string</TD>
<TD>
Specifies the host name of a SOCKS5 proxy server that will be used for
connections to the mail server.
(Note that this only works on JDK 1.5 or newer.)
</TD>
</TR>
<TR>
<TD>mail.pop3.socks.port</TD>
<TD>string</TD>
<TD>
Specifies the port number for the SOCKS5 proxy server.
This should only need to be used if the proxy server is not using
the standard port number of 1080.
</TD>
</TR>
<TR>
<TD>mail.pop3.disabletop</TD>
<TD>boolean</TD>
<TD>
If set to true, the POP3 TOP command will not be used to fetch
message headers. This is useful for POP3 servers that don't
properly implement the TOP command, or that provide incorrect
information in the TOP command results.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.pop3.disablecapa</TD>
<TD>boolean</TD>
<TD>
If set to true, the POP3 CAPA command will not be used to fetch
server capabilities. This is useful for POP3 servers that don't
properly implement the CAPA command, or that provide incorrect
information in the CAPA command results.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.pop3.forgettopheaders</TD>
<TD>boolean</TD>
<TD>
If set to true, the headers that might have been retrieved using
the POP3 TOP command will be forgotten and replaced by headers
retrieved as part of the POP3 RETR command. Some servers, such
as some versions of Microsft Exchange and IBM Lotus Notes,
will return slightly different
headers each time the TOP or RETR command is used. To allow the
POP3 provider to properly parse the message content returned from
the RETR command, the headers also returned by the RETR command
must be used. Setting this property to true will cause these
headers to be used, even if they differ from the headers returned
previously as a result of using the TOP command.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.pop3.filecache.enable</TD>
<TD>boolean</TD>
<TD>
If set to true, the POP3 provider will cache message data in a temporary
file rather than in memory. Messages are only added to the cache when
accessing the message content. Message headers are always cached in
memory (on demand). The file cache is removed when the folder is closed
or the JVM terminates.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.pop3.filecache.dir</TD>
<TD>String</TD>
<TD>
If the file cache is enabled, this property can be used to override the
default directory used by the JDK for temporary files.
</TD>
</TR>
<TR>
<TD>mail.pop3.cachewriteto</TD>
<TD>boolean</TD>
<TD>
Controls the behavior of the
{@link com.sun.mail.pop3.POP3Message#writeTo writeTo} method
on a POP3 message object.
If set to true, and the message content hasn't yet been cached,
and ignoreList is null, the message is cached before being written.
Otherwise, the message is streamed directly
to the output stream without being cached.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.pop3.keepmessagecontent</TD>
<TD>boolean</TD>
<TD>
The content of a message is cached when it is first fetched.
Normally this cache uses a {@link java.lang.ref.SoftReference SoftReference}
to refer to the cached content. This allows the cached content to be purged
if memory is low, in which case the content will be fetched again if it's
needed.
If this property is set to true, a hard reference to the cached content
will be kept, preventing the memory from being reused until the folder
is closed or the cached content is explicitly invalidated (using the
{@link com.sun.mail.pop3.POP3Message#invalidate invalidate} method).
(This was the behavior in previous versions of JavaMail.)
Defaults to false.
</TD>
</TR>
</TABLE>
<P>
In general, applications should not need to use the classes in this
package directly. Instead, they should use the APIs defined by
<code>javax.mail</code> package (and subpackages). Applications should
never construct instances of <code>POP3Store</code> or
<code>POP3Folder</code> directly. Instead, they should use the
<code>Session</code> method <code>getStore</code> to acquire an
appropriate <code>Store</code> object, and from that acquire
<code>Folder</code> objects.
<P>
In addition to printing debugging output as controlled by the
{@link javax.mail.Session Session} configuration,
the com.sun.mail.pop3 provider logs the same information using
{@link java.util.logging.Logger} as described in the following table:
<P>
<TABLE BORDER>
<TR>
<TH>Logger Name</TH>
<TH>Logging Level</TH>
<TH>Purpose</TH>
</TR>
<TR>
<TD>com.sun.mail.pop3</TD>
<TD>CONFIG</TD>
<TD>Configuration of the POP3Store</TD>
</TR>
<TR>
<TD>com.sun.mail.pop3</TD>
<TD>FINE</TD>
<TD>General debugging output</TD>
</TR>
<TR>
<TD>com.sun.mail.pop3.protocol</TD>
<TD>FINEST</TD>
<TD>Complete protocol trace</TD>
</TR>
</TABLE>
<P>
<strong>WARNING:</strong> The APIs unique to this package should be
considered <strong>EXPERIMENTAL</strong>. They may be changed in the
future in ways that are incompatible with applications using the
current APIs.
</BODY>
</HTML>

View File

@ -1,229 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.security.*;
import com.sun.mail.util.*;
/**
* DIGEST-MD5 authentication support.
*
* @author Dean Gibson
* @author Bill Shannon
*/
public class DigestMD5 {
private MailLogger logger;
private MessageDigest md5;
private String uri;
private String clientResponse;
public DigestMD5(MailLogger logger) {
this.logger = logger.getLogger(this.getClass(), "DEBUG DIGEST-MD5");
logger.config("DIGEST-MD5 Loaded");
}
/**
* Return client's authentication response to server's challenge.
*
* @return byte array with client's response
*/
public byte[] authClient(String host, String user, String passwd,
String realm, String serverChallenge)
throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStream b64os = new BASE64EncoderStream(bos, Integer.MAX_VALUE);
SecureRandom random;
try {
//random = SecureRandom.getInstance("SHA1PRNG");
random = new SecureRandom();
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ex) {
logger.log(Level.FINE, "NoSuchAlgorithmException", ex);
throw new IOException(ex.toString());
}
StringBuffer result = new StringBuffer();
uri = "smtp/" + host;
String nc = "00000001";
String qop = "auth";
byte[] bytes = new byte[32]; // arbitrary size ...
int resp;
logger.fine("Begin authentication ...");
// Code based on http://www.ietf.org/rfc/rfc2831.txt
Hashtable map = tokenize(serverChallenge);
if (realm == null) {
String text = (String)map.get("realm");
realm = text != null ? new StringTokenizer(text, ",").nextToken()
: host;
}
// server challenge random value
String nonce = (String)map.get("nonce");
random.nextBytes(bytes);
b64os.write(bytes);
b64os.flush();
// client challenge random value
String cnonce = bos.toString("iso-8859-1"); // really ASCII?
bos.reset();
// DIGEST-MD5 computation, common portion (order critical)
md5.update(md5.digest(
ASCIIUtility.getBytes(user + ":" + realm + ":" + passwd)));
md5.update(ASCIIUtility.getBytes(":" + nonce + ":" + cnonce));
clientResponse = toHex(md5.digest())
+ ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":";
// DIGEST-MD5 computation, client response (order critical)
md5.update(ASCIIUtility.getBytes("AUTHENTICATE:" + uri));
md5.update(ASCIIUtility.getBytes(clientResponse + toHex(md5.digest())));
// build response text (order not critical)
result.append("username=\"" + user + "\"");
result.append(",realm=\"" + realm + "\"");
result.append(",qop=" + qop);
result.append(",nc=" + nc);
result.append(",nonce=\"" + nonce + "\"");
result.append(",cnonce=\"" + cnonce + "\"");
result.append(",digest-uri=\"" + uri + "\"");
result.append(",response=" + toHex(md5.digest()));
if (logger.isLoggable(Level.FINE))
logger.fine("Response => " + result.toString());
b64os.write(ASCIIUtility.getBytes(result.toString()));
b64os.flush();
return bos.toByteArray();
}
/**
* Allow the client to authenticate the server based on its
* response.
*
* @return true if server is authenticated
*/
public boolean authServer(String serverResponse) throws IOException {
Hashtable map = tokenize(serverResponse);
// DIGEST-MD5 computation, server response (order critical)
md5.update(ASCIIUtility.getBytes(":" + uri));
md5.update(ASCIIUtility.getBytes(clientResponse + toHex(md5.digest())));
String text = toHex(md5.digest());
if (!text.equals((String)map.get("rspauth"))) {
if (logger.isLoggable(Level.FINE))
logger.fine("Expected => rspauth=" + text);
return false; // server NOT authenticated by client !!!
}
return true;
}
/**
* Tokenize a response from the server.
*
* @return Hashtable containing key/value pairs from server
*/
private Hashtable tokenize(String serverResponse) throws IOException {
Hashtable map = new Hashtable();
byte[] bytes = serverResponse.getBytes("iso-8859-1"); // really ASCII?
String key = null;
int ttype;
StreamTokenizer tokens
= new StreamTokenizer(
new InputStreamReader(
new BASE64DecoderStream(
new ByteArrayInputStream(bytes, 4, bytes.length - 4)
), "iso-8859-1" // really ASCII?
)
);
tokens.ordinaryChars('0', '9'); // reset digits
tokens.wordChars('0', '9'); // digits may start words
while ((ttype = tokens.nextToken()) != StreamTokenizer.TT_EOF) {
switch (ttype) {
case StreamTokenizer.TT_WORD:
if (key == null) {
key = tokens.sval;
break;
}
// fall-thru
case '"':
if (logger.isLoggable(Level.FINE))
logger.fine("Received => " +
key + "='" + tokens.sval + "'");
if (map.containsKey(key)) { // concatenate multiple values
map.put(key, map.get(key) + "," + tokens.sval);
} else {
map.put(key, tokens.sval);
}
key = null;
break;
}
}
return map;
}
private static char[] digits = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
/**
* Convert a byte array to a string of hex digits representing the bytes.
*/
private static String toHex(byte[] bytes) {
char[] result = new char[bytes.length * 2];
for (int index = 0, i = 0; index < bytes.length; index++) {
int temp = bytes[index] & 0xFF;
result[i++] = digits[temp >> 4];
result[i++] = digits[temp & 0xF];
}
return new String(result);
}
}

View File

@ -1,105 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import javax.mail.SendFailedException;
import javax.mail.internet.InternetAddress;
/**
* This exception is thrown when the message cannot be sent. <p>
*
* The exception includes the address to which the message could not be
* sent. This will usually appear in a chained list of exceptions,
* one per address, attached to a top level SendFailedException that
* aggregates all the addresses.
*
* @since JavaMail 1.3.2
*/
public class SMTPAddressFailedException extends SendFailedException {
protected InternetAddress addr; // address that failed
protected String cmd; // command issued to server
protected int rc; // return code from SMTP server
private static final long serialVersionUID = 804831199768630097L;
/**
* Constructs an SMTPAddressFailedException with the specified
* address, return code, and error string.
*
* @param addr the address that failed
* @param cmd the command that was sent to the SMTP server
* @param rc the SMTP return code indicating the failure
* @param err the error string from the SMTP server
*/
public SMTPAddressFailedException(InternetAddress addr, String cmd, int rc,
String err) {
super(err);
this.addr = addr;
this.cmd = cmd;
this.rc = rc;
}
/**
* Return the address that failed.
*/
public InternetAddress getAddress() {
return addr;
}
/**
* Return the command that failed.
*/
public String getCommand() {
return cmd;
}
/**
* Return the return code from the SMTP server that indicates the
* reason for the failure. See
* <A HREF="http://www.ietf.org/rfc/rfc821.txt">RFC 821</A>
* for interpretation of the return code.
*/
public int getReturnCode() {
return rc;
}
}

View File

@ -1,104 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
/**
* This exception is chained off a SendFailedException when the
* <code>mail.smtp.reportsuccess</code> property is true. It
* indicates an address to which the message was sent. The command
* will be an SMTP RCPT command and the return code will be the
* return code from that command.
*
* @since JavaMail 1.3.2
*/
public class SMTPAddressSucceededException extends MessagingException {
protected InternetAddress addr; // address that succeeded
protected String cmd; // command issued to server
protected int rc; // return code from SMTP server
private static final long serialVersionUID = -1168335848623096749L;
/**
* Constructs an SMTPAddressSucceededException with the specified
* address, return code, and error string.
*
* @param addr the address that succeeded
* @param cmd the command that was sent to the SMTP server
* @param rc the SMTP return code indicating the success
* @param err the error string from the SMTP server
*/
public SMTPAddressSucceededException(InternetAddress addr,
String cmd, int rc, String err) {
super(err);
this.addr = addr;
this.cmd = cmd;
this.rc = rc;
}
/**
* Return the address that succeeded.
*/
public InternetAddress getAddress() {
return addr;
}
/**
* Return the command that succeeded.
*/
public String getCommand() {
return cmd;
}
/**
* Return the return code from the SMTP server that indicates the
* reason for the success. See
* <A HREF="http://www.ietf.org/rfc/rfc821.txt">RFC 821</A>
* for interpretation of the return code.
*/
public int getReturnCode() {
return rc;
}
}

View File

@ -1,342 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
/**
* This class is a specialization of the MimeMessage class that allows
* you to specify various SMTP options and parameters that will be
* used when this message is sent over SMTP. Simply use this class
* instead of MimeMessage and set SMTP options using the methods on
* this class. <p>
*
* See the <a href="package-summary.html">com.sun.mail.smtp</a> package
* documentation for further information on the SMTP protocol provider. <p>
*
* @author Bill Shannon
* @see javax.mail.internet.MimeMessage
*/
public class SMTPMessage extends MimeMessage {
/** Never notify of delivery status */
public static final int NOTIFY_NEVER = -1;
/** Notify of delivery success */
public static final int NOTIFY_SUCCESS = 1;
/** Notify of delivery failure */
public static final int NOTIFY_FAILURE = 2;
/** Notify of delivery delay */
public static final int NOTIFY_DELAY = 4;
/** Return full message with delivery status notification */
public static final int RETURN_FULL = 1;
/** Return only message headers with delivery status notification */
public static final int RETURN_HDRS = 2;
private static final String[] returnOptionString = { null, "FULL", "HDRS" };
private String envelopeFrom; // the string to use in the MAIL FROM: command
private int notifyOptions = 0;
private int returnOption = 0;
private boolean sendPartial = false;
private boolean allow8bitMIME = false;
private String submitter = null; // RFC 2554 AUTH=submitter
private String extension = null; // extensions to use with MAIL command
/**
* Default constructor. An empty message object is created.
* The <code>headers</code> field is set to an empty InternetHeaders
* object. The <code>flags</code> field is set to an empty Flags
* object. The <code>modified</code> flag is set to true.
*/
public SMTPMessage(Session session) {
super(session);
}
/**
* Constructs an SMTPMessage by reading and parsing the data from the
* specified MIME InputStream. The InputStream will be left positioned
* at the end of the data for the message. Note that the input stream
* parse is done within this constructor itself.
*
* @param session Session object for this message
* @param is the message input stream
* @exception MessagingException
*/
public SMTPMessage(Session session, InputStream is)
throws MessagingException {
super(session, is);
}
/**
* Constructs a new SMTPMessage with content initialized from the
* <code>source</code> MimeMessage. The new message is independent
* of the original. <p>
*
* Note: The current implementation is rather inefficient, copying
* the data more times than strictly necessary.
*
* @param source the message to copy content from
* @exception MessagingException
*/
public SMTPMessage(MimeMessage source) throws MessagingException {
super(source);
}
/**
* Set the From address to appear in the SMTP envelope. Note that this
* is different than the From address that appears in the message itself.
* The envelope From address is typically used when reporting errors.
* See <A HREF="http://www.ietf.org/rfc/rfc821.txt">RFC 821</A> for
* details. <p>
*
* If set, overrides the <code>mail.smtp.from</code> property.
*
* @param from the envelope From address
*/
public void setEnvelopeFrom(String from) {
envelopeFrom = from;
}
/**
* Return the envelope From address.
*
* @return the envelope From address, or null if not set
*/
public String getEnvelopeFrom() {
return envelopeFrom;
}
/**
* Set notification options to be used if the server supports
* Delivery Status Notification
* (<A HREF="http://www.ietf.org/rfc/rfc1891.txt">RFC 1891</A>).
* Either <code>NOTIFY_NEVER</code> or some combination of
* <code>NOTIFY_SUCCESS</code>, <code>NOTIFY_FAILURE</code>, and
* <code>NOTIFY_DELAY</code>. <p>
*
* If set, overrides the <code>mail.smtp.dsn.notify</code> property.
*
* @param options notification options
*/
public void setNotifyOptions(int options) {
if (options < -1 || options >= 8)
throw new IllegalArgumentException("Bad return option");
notifyOptions = options;
}
/**
* Get notification options. Returns zero if no options set.
*
* @return notification options
*/
public int getNotifyOptions() {
return notifyOptions;
}
/**
* Return notification options as an RFC 1891 string.
* Returns null if no options set.
*/
String getDSNNotify() {
if (notifyOptions == 0)
return null;
if (notifyOptions == NOTIFY_NEVER)
return "NEVER";
StringBuffer sb = new StringBuffer();
if ((notifyOptions & NOTIFY_SUCCESS) != 0)
sb.append("SUCCESS");
if ((notifyOptions & NOTIFY_FAILURE) != 0) {
if (sb.length() != 0)
sb.append(',');
sb.append("FAILURE");
}
if ((notifyOptions & NOTIFY_DELAY) != 0) {
if (sb.length() != 0)
sb.append(',');
sb.append("DELAY");
}
return sb.toString();
}
/**
* Set return option to be used if server supports
* Delivery Status Notification
* (<A HREF="http://www.ietf.org/rfc/rfc1891.txt">RFC 1891</A>).
* Either <code>RETURN_FULL</code> or <code>RETURN_HDRS</code>. <p>
*
* If set, overrides the <code>mail.smtp.dsn.ret</code> property.
*
* @param option return option
*/
public void setReturnOption(int option) {
if (option < 0 || option > RETURN_HDRS)
throw new IllegalArgumentException("Bad return option");
returnOption = option;
}
/**
* Return return option. Returns zero if no option set.
*
* @return return option
*/
public int getReturnOption() {
return returnOption;
}
/**
* Return return option as an RFC 1891 string.
* Returns null if no option set.
*/
String getDSNRet() {
return returnOptionString[returnOption];
}
/**
* If set to true, and the server supports the 8BITMIME extension, text
* parts of this message that use the "quoted-printable" or "base64"
* encodings are converted to use "8bit" encoding if they follow the
* RFC 2045 rules for 8bit text. <p>
*
* If true, overrides the <code>mail.smtp.allow8bitmime</code> property.
*
* @param allow allow 8-bit flag
*/
public void setAllow8bitMIME(boolean allow) {
allow8bitMIME = allow;
}
/**
* Is use of the 8BITMIME extension is allowed?
*
* @return allow 8-bit flag
*/
public boolean getAllow8bitMIME() {
return allow8bitMIME;
}
/**
* If set to true, and this message has some valid and some invalid
* addresses, send the message anyway, reporting the partial failure with
* a SendFailedException. If set to false (the default), the message is
* not sent to any of the recipients if there is an invalid recipient
* address. <p>
*
* If true, overrides the <code>mail.smtp.sendpartial</code> property.
*
* @param partial send partial flag
*/
public void setSendPartial(boolean partial) {
sendPartial = partial;
}
/**
* Send message if some addresses are invalid?
*
* @return send partial flag
*/
public boolean getSendPartial() {
return sendPartial;
}
/**
* Gets the submitter to be used for the RFC 2554 AUTH= value
* in the MAIL FROM command.
*
* @return the name of the submitter.
*/
public String getSubmitter() {
return submitter;
}
/**
* Sets the submitter to be used for the RFC 2554 AUTH= value
* in the MAIL FROM command. Normally only used by a server
* that's relaying a message. Clients will typically not
* set a submitter. See
* <A HREF="http://www.ietf.org/rfc/rfc2554.txt">RFC 2554</A>
* for details.
*
* @param submitter the name of the submitter
*/
public void setSubmitter(String submitter) {
this.submitter = submitter;
}
/**
* Gets the extension string to use with the MAIL command.
*
* @return the extension string
*
* @since JavaMail 1.3.2
*/
public String getMailExtension() {
return extension;
}
/**
* Set the extension string to use with the MAIL command.
* The extension string can be used to specify standard SMTP
* service extensions as well as vendor-specific extensions.
* Typically the application should use the
* {@link com.sun.mail.smtp.SMTPTransport SMTPTransport}
* method {@link com.sun.mail.smtp.SMTPTransport#supportsExtension
* supportsExtension}
* to verify that the server supports the desired service extension.
* See <A HREF="http://www.ietf.org/rfc/rfc1869.txt">RFC 1869</A>
* and other RFCs that define specific extensions. <p>
*
* For example: <p>
*
* <blockquote><pre>
* if (smtpTransport.supportsExtension("DELIVERBY"))
* smtpMsg.setMailExtension("BY=60;R");
* </pre></blockquote>
*
* @since JavaMail 1.3.2
*/
public void setMailExtension(String extension) {
this.extension = extension;
}
}

View File

@ -1,114 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import java.io.*;
import com.sun.mail.util.CRLFOutputStream;
/**
* In addition to converting lines into the canonical format,
* i.e., terminating lines with the CRLF sequence, escapes the "."
* by adding another "." to any "." that appears in the beginning
* of a line. See RFC821 section 4.5.2.
*
* @author Max Spivak
* @see CRLFOutputStream
*/
public class SMTPOutputStream extends CRLFOutputStream {
public SMTPOutputStream(OutputStream os) {
super(os);
}
public void write(int b) throws IOException {
// if that last character was a newline, and the current
// character is ".", we always write out an extra ".".
if ((lastb == '\n' || lastb == '\r' || lastb == -1) && b == '.') {
out.write('.');
}
super.write(b);
}
/*
* This method has been added to improve performance.
*/
public void write(byte b[], int off, int len) throws IOException {
int lastc = (lastb == -1) ? '\n' : lastb;
int start = off;
len += off;
for (int i = off; i < len; i++) {
if ((lastc == '\n' || lastc == '\r') && b[i] == '.') {
super.write(b, start, i - start);
out.write('.');
start = i;
}
lastc = b[i];
}
if ((len - start) > 0)
super.write(b, start, len - start);
}
/**
* Override flush method in FilterOutputStream.
*
* The MimeMessage writeTo method flushes its buffer at the end,
* but we don't want to flush data out to the socket until we've
* also written the terminating "\r\n.\r\n".
*
* We buffer nothing so there's nothing to flush. We depend
* on the fact that CRLFOutputStream also buffers nothing.
* SMTPTransport will manually flush the socket before reading
* the response.
*/
public void flush() {
// do nothing
}
/**
* Ensure we're at the beginning of a line.
* Write CRLF if not.
*/
public void ensureAtBOL() throws IOException {
if (!atBOL)
super.writeln();
}
}

View File

@ -1,58 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import javax.mail.*;
/**
* This class implements the Transport abstract class using SMTP
* over SSL for message submission and transport.
*
* @author Bill Shannon
*/
public class SMTPSSLTransport extends SMTPTransport {
/** Constructor */
public SMTPSSLTransport(Session session, URLName urlname) {
super(session, urlname, "smtps", true);
}
}

View File

@ -1,228 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import javax.security.sasl.*;
import javax.security.auth.callback.*;
import javax.mail.MessagingException;
import com.sun.mail.util.*;
/**
* This class contains a single method that does authentication using
* SASL. This is in a separate class so that it can be compiled with
* J2SE 1.5. Eventually it should be merged into SMTPTransport.java.
*/
public class SMTPSaslAuthenticator implements SaslAuthenticator {
private SMTPTransport pr;
private String name;
private Properties props;
private MailLogger logger;
private String host;
public SMTPSaslAuthenticator(SMTPTransport pr, String name,
Properties props, MailLogger logger, String host) {
this.pr = pr;
this.name = name;
this.props = props;
this.logger = logger;
this.host = host;
}
public boolean authenticate(String[] mechs, final String realm,
final String authzid, final String u,
final String p) throws MessagingException {
boolean done = false;
if (logger.isLoggable(Level.FINE)) {
logger.fine("SASL Mechanisms:");
for (int i = 0; i < mechs.length; i++)
logger.fine(" " + mechs[i]);
logger.fine("");
}
SaslClient sc;
CallbackHandler cbh = new CallbackHandler() {
public void handle(Callback[] callbacks) {
if (logger.isLoggable(Level.FINE))
logger.fine("SASL callback length: " + callbacks.length);
for (int i = 0; i < callbacks.length; i++) {
if (logger.isLoggable(Level.FINE))
logger.fine("SASL callback " + i + ": " + callbacks[i]);
if (callbacks[i] instanceof NameCallback) {
NameCallback ncb = (NameCallback)callbacks[i];
ncb.setName(u);
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pcb = (PasswordCallback)callbacks[i];
pcb.setPassword(p.toCharArray());
} else if (callbacks[i] instanceof RealmCallback) {
RealmCallback rcb = (RealmCallback)callbacks[i];
rcb.setText(realm != null ?
realm : rcb.getDefaultText());
} else if (callbacks[i] instanceof RealmChoiceCallback) {
RealmChoiceCallback rcb =
(RealmChoiceCallback)callbacks[i];
if (realm == null)
rcb.setSelectedIndex(rcb.getDefaultChoice());
else {
// need to find specified realm in list
String[] choices = rcb.getChoices();
for (int k = 0; k < choices.length; k++) {
if (choices[k].equals(realm)) {
rcb.setSelectedIndex(k);
break;
}
}
}
}
}
}
};
try {
sc = Sasl.createSaslClient(mechs, authzid, name, host,
(Map)props, cbh);
} catch (SaslException sex) {
logger.log(Level.FINE, "Failed to create SASL client: ", sex);
return false;
}
if (sc == null) {
logger.fine("No SASL support");
return false;
}
if (logger.isLoggable(Level.FINE))
logger.fine("SASL client " + sc.getMechanismName());
int resp;
try {
String mech = sc.getMechanismName();
String ir = null;
if (sc.hasInitialResponse()) {
byte[] ba = sc.evaluateChallenge(new byte[0]);
ba = BASE64EncoderStream.encode(ba);
ir = ASCIIUtility.toString(ba, 0, ba.length);
}
if (ir != null)
resp = pr.simpleCommand("AUTH " + mech + " " + ir);
else
resp = pr.simpleCommand("AUTH " + mech);
/*
* A 530 response indicates that the server wants us to
* issue a STARTTLS command first. Do that and try again.
*/
if (resp == 530) {
pr.startTLS();
if (ir != null)
resp = pr.simpleCommand("AUTH " + mech + " " + ir);
else
resp = pr.simpleCommand("AUTH " + mech);
}
if (resp == 235)
return true; // success already!
if (resp != 334)
return false;
} catch (Exception ex) {
logger.log(Level.FINE, "SASL AUTHENTICATE Exception", ex);
return false;
}
while (!done) { // loop till we are done
try {
if (resp == 334) {
byte[] ba = null;
if (!sc.isComplete()) {
ba = ASCIIUtility.getBytes(responseText(pr));
if (ba.length > 0)
ba = BASE64DecoderStream.decode(ba);
if (logger.isLoggable(Level.FINE))
logger.fine("SASL challenge: " +
ASCIIUtility.toString(ba, 0, ba.length) + " :");
ba = sc.evaluateChallenge(ba);
}
if (ba == null) {
logger.fine("SASL: no response");
resp = pr.simpleCommand("*");
} else {
if (logger.isLoggable(Level.FINE))
logger.fine("SASL response: " +
ASCIIUtility.toString(ba, 0, ba.length) + " :");
ba = BASE64EncoderStream.encode(ba);
resp = pr.simpleCommand(ba);
}
} else
done = true;
} catch (Exception ioex) {
logger.log(Level.FINE, "SASL Exception", ioex);
done = true;
// XXX - ultimately return true???
}
}
if (sc.isComplete() /*&& res.status == SUCCESS*/) {
String qop = (String)sc.getNegotiatedProperty(Sasl.QOP);
if (qop != null && (qop.equalsIgnoreCase("auth-int") ||
qop.equalsIgnoreCase("auth-conf"))) {
// XXX - NOT SUPPORTED!!!
logger.fine(
"SASL Mechanism requires integrity or confidentiality");
return false;
}
}
return true;
}
private static final String responseText(SMTPTransport pr) {
String resp = pr.getLastServerResponse().trim();
if (resp.length() > 4)
return resp.substring(4);
else
return "";
}
}

View File

@ -1,98 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import javax.mail.Address;
import javax.mail.SendFailedException;
import javax.mail.internet.InternetAddress;
/**
* This exception is thrown when the message cannot be sent. <p>
*
* This exception will usually appear first in a chained list of exceptions,
* followed by SMTPAddressFailedExceptions and/or
* SMTPAddressSucceededExceptions, * one per address.
* This exception corresponds to one of the SMTP commands used to
* send a message, such as the MAIL, DATA, and "end of data" commands,
* but not including the RCPT command.
*
* @since JavaMail 1.3.2
*/
public class SMTPSendFailedException extends SendFailedException {
protected InternetAddress addr; // address that failed
protected String cmd; // command issued to server
protected int rc; // return code from SMTP server
private static final long serialVersionUID = 8049122628728932894L;
/**
* Constructs an SMTPSendFailedException with the specified
* address, return code, and error string.
*
* @param cmd the command that was sent to the SMTP server
* @param rc the SMTP return code indicating the failure
* @param err the error string from the SMTP server
*/
public SMTPSendFailedException(String cmd, int rc, String err, Exception ex,
Address[] vs, Address[] vus, Address[] inv) {
super(err, ex, vs, vus, inv);
this.cmd = cmd;
this.rc = rc;
}
/**
* Return the command that failed.
*/
public String getCommand() {
return cmd;
}
/**
* Return the return code from the SMTP server that indicates the
* reason for the failure. See
* <A HREF="http://www.ietf.org/rfc/rfc821.txt">RFC 821</A>
* for interpretation of the return code.
*/
public int getReturnCode() {
return rc;
}
}

View File

@ -1,103 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import javax.mail.SendFailedException;
import javax.mail.internet.InternetAddress;
/**
* This exception is thrown when the message cannot be sent. <p>
*
* The exception includes the sender's address, which the mail server
* rejected.
*
* @since JavaMail 1.4.4
*/
public class SMTPSenderFailedException extends SendFailedException {
protected InternetAddress addr; // address that failed
protected String cmd; // command issued to server
protected int rc; // return code from SMTP server
private static final long serialVersionUID = 514540454964476947L;
/**
* Constructs an SMTPSenderFailedException with the specified
* address, return code, and error string.
*
* @param addr the address that failed
* @param cmd the command that was sent to the SMTP server
* @param rc the SMTP return code indicating the failure
* @param err the error string from the SMTP server
*/
public SMTPSenderFailedException(InternetAddress addr, String cmd, int rc,
String err) {
super(err);
this.addr = addr;
this.cmd = cmd;
this.rc = rc;
}
/**
* Return the address that failed.
*/
public InternetAddress getAddress() {
return addr;
}
/**
* Return the command that failed.
*/
public String getCommand() {
return cmd;
}
/**
* Return the return code from the SMTP server that indicates the
* reason for the failure. See
* <A HREF="http://www.ietf.org/rfc/rfc821.txt">RFC 821</A>
* for interpretation of the return code.
*/
public int getReturnCode() {
return rc;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.smtp;
import javax.mail.MessagingException;
/**
* Interface to make it easier to call SMTPSaslAuthenticator.
*/
public interface SaslAuthenticator {
public boolean authenticate(String[] mechs, String realm, String authzid,
String u, String p) throws MessagingException;
}

View File

@ -1,732 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can
obtain a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
or packager/legal/LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.
When distributing the software, include this License Header Notice in each
file and include the License file at packager/legal/LICENSE.txt.
GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.
Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"
Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->
</HEAD>
<BODY BGCOLOR="white">
An SMTP protocol provider for the JavaMail API
that provides access to an SMTP server.
Refer to <A HREF="http://www.ietf.org/rfc/rfc821.txt" TARGET="_top">RFC 821</A>
for more information.
<P>
When sending a message, detailed information on each address that
fails is available in an
{@link com.sun.mail.smtp.SMTPAddressFailedException SMTPAddressFailedException}
chained off the top level
{@link javax.mail.SendFailedException SendFailedException}
that is thrown.
In addition, if the <code>mail.smtp.reportsuccess</code> property
is set, an
{@link com.sun.mail.smtp.SMTPAddressSucceededException
SMTPAddressSucceededException}
will be included in the list for each address that is successful.
Note that this will cause a top level
{@link javax.mail.SendFailedException SendFailedException}
to be thrown even though the send was successful.
<P>
The SMTP provider also supports ESMTP
(<A HREF="http://www.ietf.org/rfc/rfc1651.txt" TARGET="_top">RFC 1651</A>).
It can optionally use SMTP Authentication
(<A HREF="http://www.ietf.org/rfc/rfc2554.txt" TARGET="_top">RFC 2554</A>)
using the LOGIN, PLAIN, DIGEST-MD5, and NTLM mechanisms
(<A HREF="http://www.ietf.org/rfc/rfc2595.txt" TARGET="_top">RFC 2595</A>
and <A HREF="http://www.ietf.org/rfc/rfc2831.txt" TARGET="_top">RFC 2831</A>).
<P>
To use SMTP authentication you'll need to set the <code>mail.smtp.auth</code>
property (see below) or provide the SMTP Transport
with a username and password when connecting to the SMTP server. You
can do this using one of the following approaches:
<P>
<UL>
<LI>
Provide an Authenticator object when creating your mail Session
and provide the username and password information during the
Authenticator callback.
<P>
Note that the <code>mail.smtp.user</code> property can be set to provide a
default username for the callback, but the password will still need to be
supplied explicitly.
<P>
This approach allows you to use the static Transport <code>send</code> method
to send messages.
</LI>
<P>
<LI>
Call the Transport <code>connect</code> method explicitly with username and
password arguments.
<P>
This approach requires you to explicitly manage a Transport object
and use the Transport <code>sendMessage</code> method to send the message.
The transport.java demo program demonstrates how to manage a Transport
object. The following is roughly equivalent to the static
Transport <code>send</code> method, but supplies the needed username and
password:
<P>
<BLOCKQUOTE><PRE>
Transport tr = session.getTransport("smtp");
tr.connect(smtphost, username, password);
msg.saveChanges(); // don't forget this
tr.sendMessage(msg, msg.getAllRecipients());
tr.close();
</PRE></BLOCKQUOTE>
</LI>
</UL>
<P>
When using DIGEST-MD5 authentication,
you'll also need to supply an appropriate realm;
your mail server administrator can supply this information.
You can set this using the <code>mail.smtp.sasl.realm</code> property,
or the <code>setSASLRealm</code> method on <code>SMTPTransport</code>.
<P>
The SMTP protocol provider can use SASL
(<A HREF="http://www.ietf.org/rfc/rfc2222.txt" TARGET="_top">RFC 2222</A>)
authentication mechanisms on systems that support the
<CODE>javax.security.sasl</CODE> APIs, such as J2SE 5.0.
In addition to the SASL mechanisms that are built into
the SASL implementation, users can also provide additional
SASL mechanisms of their own design to support custom authentication
schemes. See the
<A HREF="http://java.sun.com/j2se/1.5.0/docs/guide/security/sasl/sasl-refguide.html" TARGET="_top">
Java SASL API Programming and Deployment Guide</A> for details.
Note that the current implementation doesn't support SASL mechanisms
that provide their own integrity or confidentiality layer.
<P>
SMTP can also optionally request Delivery Status Notifications
(<A HREF="http://www.ietf.org/rfc/rfc1891.txt" TARGET="_top">RFC 1891</A>).
The delivery status will typically be reported using
a "multipart/report"
(<A HREF="http://www.ietf.org/rfc/rfc1892.txt" TARGET="_top">RFC 1892</A>)
message type with a "message/delivery-status"
(<A HREF="http://www.ietf.org/rfc/rfc1894.txt" TARGET="_top">RFC 1894</A>)
part.
You can use the classes in the {@link com.sun.mail.dsn} package to
handle these MIME types.
Note that you'll need to include <code>dsn.jar</code> in your CLASSPATH
as this support is not included in <code>mail.jar</code>.
<P>
See below for the properties to enable these features.
<P>
Note also that <strong>THERE IS NOT SUFFICIENT DOCUMENTATION HERE TO USE THESE
FEATURES!!!</strong> You will need to read the appropriate RFCs mentioned above
to understand what these features do and how to use them. Don't just
start setting properties and then complain to us when it doesn't work
like you expect it to work. <strong>READ THE RFCs FIRST!!!</strong>
<P>
The SMTP protocol provider supports the following properties,
which may be set in the JavaMail <code>Session</code> object.
The properties are always set as strings; the Type column describes
how the string is interpreted. For example, use
<PRE>
props.put("mail.smtp.port", "888");
</PRE>
to set the <CODE>mail.smtp.port</CODE> property, which is of type int.
<P>
Note that if you're using the "smtps" protocol to access SMTP over SSL,
all the properties would be named "mail.smtps.*".
<P>
<TABLE BORDER>
<TR>
<TH>Name</TH>
<TH>Type</TH>
<TH>Description</TH>
</TR>
<TR>
<TD>mail.smtp.user</TD>
<TD>String</TD>
<TD>Default user name for SMTP.</TD>
</TR>
<TR>
<TD>mail.smtp.host</TD>
<TD>String</TD>
<TD>The SMTP server to connect to.</TD>
</TR>
<TR>
<TD>mail.smtp.port</TD>
<TD>int</TD>
<TD>The SMTP server port to connect to, if the connect() method doesn't
explicitly specify one. Defaults to 25.</TD>
</TR>
<TR>
<TD>mail.smtp.connectiontimeout</TD>
<TD>int</TD>
<TD>Socket connection timeout value in milliseconds.
Default is infinite timeout.</TD>
</TR>
<TR>
<TD>mail.smtp.timeout</TD>
<TD>int</TD>
<TD>Socket I/O timeout value in milliseconds. Default is infinite timeout.</TD>
</TR>
<TR>
<TD>mail.smtp.from</TD>
<TD>String</TD>
<TD>
Email address to use for SMTP MAIL command. This sets the envelope
return address. Defaults to msg.getFrom() or
InternetAddress.getLocalAddress(). NOTE: mail.smtp.user was previously
used for this.
</TD>
</TR>
<TR>
<TD>mail.smtp.localhost</TD>
<TD>String</TD>
<TD>
Local host name used in the SMTP HELO or EHLO command.
Defaults to <code>InetAddress.getLocalHost().getHostName()</code>.
Should not normally need to
be set if your JDK and your name service are configured properly.
</TD>
</TR>
<TR>
<TD>mail.smtp.localaddress</TD>
<TD>String</TD>
<TD>
Local address (host name) to bind to when creating the SMTP socket.
Defaults to the address picked by the Socket class.
Should not normally need to be set, but useful with multi-homed hosts
where it's important to pick a particular local address to bind to.
</TD>
</TR>
<TR>
<TD>mail.smtp.localport</TD>
<TD>int</TD>
<TD>
Local port number to bind to when creating the SMTP socket.
Defaults to the port number picked by the Socket class.
</TD>
</TR>
<TR>
<TD>mail.smtp.ehlo</TD>
<TD>boolean</TD>
<TD>
If false, do not attempt to sign on with the EHLO command. Defaults to
true. Normally failure of the EHLO command will fallback to the HELO
command; this property exists only for servers that don't fail EHLO
properly or don't implement EHLO properly.
</TD>
</TR>
<TR>
<TD>mail.smtp.auth</TD>
<TD>boolean</TD>
<TD>If true, attempt to authenticate the user using the AUTH command.
Defaults to false.</TD>
</TR>
<TR>
<TD>mail.smtp.auth.mechanisms</TD>
<TD>String</TD>
<TD>
If set, lists the authentication mechanisms to consider, and the order
in which to consider them. Only mechanisms supported by the server and
supported by the current implementation will be used.
The default is <code>"LOGIN PLAIN DIGEST-MD5 NTLM"</code>, which includes all
the authentication mechanisms supported by the current implementation.
</TD>
</TR>
<TR>
<TD>mail.smtp.auth.login.disable</TD>
<TD>boolean</TD>
<TD>If true, prevents use of the <code>AUTH LOGIN</code> command.
Default is false.</TD>
</TR>
<TR>
<TD>mail.smtp.auth.plain.disable</TD>
<TD>boolean</TD>
<TD>If true, prevents use of the <code>AUTH PLAIN</code> command.
Default is false.</TD>
</TR>
<TR>
<TD>mail.smtp.auth.digest-md5.disable</TD>
<TD>boolean</TD>
<TD>If true, prevents use of the <code>AUTH DIGEST-MD5</code> command.
Default is false.</TD>
</TR>
<TR>
<TD>mail.smtp.auth.ntlm.disable</TD>
<TD>boolean</TD>
<TD>If true, prevents use of the <code>AUTH NTLM</code> command.
Default is false.</TD>
</TR>
<TR>
<TD>mail.smtp.auth.ntlm.domain</TD>
<TD>String</TD>
<TD>
The NTLM authentication domain.
</TD>
</TR>
<TR>
<TD>mail.smtp.auth.ntlm.flags</TD>
<TD>int</TD>
<TD>
NTLM protocol-specific flags.
See <A HREF="http://curl.haxx.se/rfc/ntlm.html#theNtlmFlags" TARGET="_top">
http://curl.haxx.se/rfc/ntlm.html#theNtlmFlags</A> for details.
</TD>
</TR>
<!--
<TR>
<TD>mail.smtp.auth.ntlm.unicode</TD>
<TD>boolean</TD>
<TD>
Set this to "true" if the username or password may use
Unicode UTF-8 encoded characters. Default is "true".
Currently has no effect.
</TD>
</TR>
<TR>
<TD>mail.smtp.auth.ntlm.lmcompat</TD>
<TD>int</TD>
<TD>
Sets the LM compatibility level, as described here:
<A HREF="http://curl.haxx.se/rfc/ntlm.html#ntlmVersion2" TARGET="_top">
http://curl.haxx.se/rfc/ntlm.html#ntlmVersion2</A>
Defaults to "3". Currently not used.
</TD>
</TR>
-->
<TR>
<TD>mail.smtp.submitter</TD>
<TD>String</TD>
<TD>The submitter to use in the AUTH tag in the MAIL FROM command.
Typically used by a mail relay to pass along information about the
original submitter of the message.
See also the {@link com.sun.mail.smtp.SMTPMessage#setSubmitter setSubmitter}
method of {@link com.sun.mail.smtp.SMTPMessage SMTPMessage}.
Mail clients typically do not use this.
</TD>
</TR>
<TR>
<TD>mail.smtp.dsn.notify</TD>
<TD>String</TD>
<TD>The NOTIFY option to the RCPT command. Either NEVER, or some
combination of SUCCESS, FAILURE, and DELAY (separated by commas).</TD>
</TR>
<TR>
<TD>mail.smtp.dsn.ret</TD>
<TD>String</TD>
<TD>The RET option to the MAIL command. Either FULL or HDRS.</TD>
</TR>
<TR>
<TD>mail.smtp.allow8bitmime</TD>
<TD>boolean</TD>
<TD>
If set to true, and the server supports the 8BITMIME extension, text
parts of messages that use the "quoted-printable" or "base64" encodings
are converted to use "8bit" encoding if they follow the RFC2045 rules
for 8bit text.
</TD>
</TR>
<TR>
<TD>mail.smtp.sendpartial</TD>
<TD>boolean</TD>
<TD>
If set to true, and a message has some valid and some invalid
addresses, send the message anyway, reporting the partial failure with
a SendFailedException. If set to false (the default), the message is
not sent to any of the recipients if there is an invalid recipient
address.
</TD>
</TR>
<TR>
<TD>mail.smtp.sasl.enable</TD>
<TD>boolean</TD>
<TD>
If set to true, attempt to use the javax.security.sasl package to
choose an authentication mechanism for login.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.smtp.sasl.mechanisms</TD>
<TD>String</TD>
<TD>
A space or comma separated list of SASL mechanism names to try
to use.
</TD>
</TR>
<TR>
<TD>mail.smtp.sasl.authorizationid</TD>
<TD>String</TD>
<TD>
The authorization ID to use in the SASL authentication.
If not set, the authentication ID (user name) is used.
</TD>
</TR>
<TR>
<TD>mail.smtp.sasl.realm</TD>
<TD>String</TD>
<TD>The realm to use with DIGEST-MD5 authentication.</TD>
</TR>
<TR>
<TD>mail.smtp.quitwait</TD>
<TD>boolean</TD>
<TD>
If set to false, the QUIT command is sent
and the connection is immediately closed.
If set to true (the default), causes the transport to wait
for the response to the QUIT command.
</TD>
</TR>
<TR>
<TD>mail.smtp.reportsuccess</TD>
<TD>boolean</TD>
<TD>
If set to true, causes the transport to include an
{@link com.sun.mail.smtp.SMTPAddressSucceededException
SMTPAddressSucceededException}
for each address that is successful.
Note also that this will cause a
{@link javax.mail.SendFailedException SendFailedException}
to be thrown from the
{@link com.sun.mail.smtp.SMTPTransport#sendMessage sendMessage}
method of
{@link com.sun.mail.smtp.SMTPTransport SMTPTransport}
even if all addresses were correct and the message was sent
successfully.
</TD>
</TR>
<TR>
<TD>mail.smtp.socketFactory</TD>
<TD>SocketFactory</TD>
<TD>
If set to a class that implements the
<code>javax.net.SocketFactory</code> interface, this class
will be used to create SMTP sockets. Note that this is an
instance of a class, not a name, and must be set using the
<code>put</code> method, not the <code>setProperty</code> method.
</TD>
</TR>
<TR>
<TD>mail.smtp.socketFactory.class</TD>
<TD>String</TD>
<TD>
If set, specifies the name of a class that implements the
<code>javax.net.SocketFactory</code> interface. This class
will be used to create SMTP sockets.
</TD>
</TR>
<TR>
<TD>mail.smtp.socketFactory.fallback</TD>
<TD>boolean</TD>
<TD>
If set to true, failure to create a socket using the specified
socket factory class will cause the socket to be created using
the <code>java.net.Socket</code> class.
Defaults to true.
</TD>
</TR>
<TR>
<TD>mail.smtp.socketFactory.port</TD>
<TD>int</TD>
<TD>
Specifies the port to connect to when using the specified socket
factory.
If not set, the default port will be used.
</TD>
</TR>
<TR>
<TD>mail.smtp.ssl.enable</TD>
<TD>boolean</TD>
<TD>
If set to true, use SSL to connect and use the SSL port by default.
Defaults to false for the "smtp" protocol and true for the "smtps" protocol.
</TD>
</TR>
<TR>
<TD>mail.smtp.ssl.checkserveridentity</TD>
<TD>boolean</TD>
<TD>
If set to true, check the server identity as specified by
<A HREF="http://www.ietf.org/rfc/rfc2595.txt" TARGET="_top">RFC 2595</A>.
These additional checks based on the content of the server's certificate
are intended to prevent man-in-the-middle attacks.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.smtp.ssl.trust</TD>
<TD>String</TD>
<TD>
If set, and a socket factory hasn't been specified, enables use of a
{@link com.sun.mail.util.MailSSLSocketFactory MailSSLSocketFactory}.
If set to "*", all hosts are trusted.
If set to a whitespace separated list of hosts, those hosts are trusted.
Otherwise, trust depends on the certificate the server presents.
</TD>
</TR>
<TR>
<TD>mail.smtp.ssl.socketFactory</TD>
<TD>SSLSocketFactory</TD>
<TD>
If set to a class that extends the
<code>javax.net.ssl.SSLSocketFactory</code> class, this class
will be used to create SMTP SSL sockets. Note that this is an
instance of a class, not a name, and must be set using the
<code>put</code> method, not the <code>setProperty</code> method.
</TD>
</TR>
<TR>
<TD>mail.smtp.ssl.socketFactory.class</TD>
<TD>String</TD>
<TD>
If set, specifies the name of a class that extends the
<code>javax.net.ssl.SSLSocketFactory</code> class. This class
will be used to create SMTP SSL sockets.
</TD>
</TR>
<TR>
<TD>mail.smtp.ssl.socketFactory.port</TD>
<TD>int</TD>
<TD>
Specifies the port to connect to when using the specified socket
factory.
If not set, the default port will be used.
</TD>
</TR>
<TR>
<TD>mail.smtp.ssl.protocols</TD>
<TD>string</TD>
<TD>
Specifies the SSL protocols that will be enabled for SSL connections.
The property value is a whitespace separated list of tokens acceptable
to the <code>javax.net.ssl.SSLSocket.setEnabledProtocols</code> method.
</TD>
</TR>
<TR>
<TD>mail.smtp.ssl.ciphersuites</TD>
<TD>string</TD>
<TD>
Specifies the SSL cipher suites that will be enabled for SSL connections.
The property value is a whitespace separated list of tokens acceptable
to the <code>javax.net.ssl.SSLSocket.setEnabledCipherSuites</code> method.
</TD>
</TR>
<TR>
<TD>mail.smtp.starttls.enable</TD>
<TD>boolean</TD>
<TD>
If true, enables the use of the <code>STARTTLS</code> command (if
supported by the server) to switch the connection to a TLS-protected
connection before issuing any login commands. Note that an appropriate
trust store must configured so that the client will trust the server's
certificate.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.smtp.starttls.required</TD>
<TD>boolean</TD>
<TD>
If true, requires the use of the <code>STARTTLS</code> command.
If the server doesn't support the STARTTLS command, or the command
fails, the connect method will fail.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.smtp.socks.host</TD>
<TD>string</TD>
<TD>
Specifies the host name of a SOCKS5 proxy server that will be used for
connections to the mail server.
(Note that this only works on JDK 1.5 or newer.)
</TD>
</TR>
<TR>
<TD>mail.smtp.socks.port</TD>
<TD>string</TD>
<TD>
Specifies the port number for the SOCKS5 proxy server.
This should only need to be used if the proxy server is not using
the standard port number of 1080.
</TD>
</TR>
<TR>
<TD>mail.smtp.mailextension</TD>
<TD>String</TD>
<TD>
Extension string to append to the MAIL command.
The extension string can be used to specify standard SMTP
service extensions as well as vendor-specific extensions.
Typically the application should use the
{@link com.sun.mail.smtp.SMTPTransport SMTPTransport}
method {@link com.sun.mail.smtp.SMTPTransport#supportsExtension
supportsExtension}
to verify that the server supports the desired service extension.
See <A HREF="http://www.ietf.org/rfc/rfc1869.txt" TARGET="_top">RFC 1869</A>
and other RFCs that define specific extensions.
</TD>
</TR>
<TR>
<TD>mail.smtp.userset</TD>
<TD>boolean</TD>
<TD>
If set to true, use the RSET command instead of the NOOP command
in the {@link javax.mail.Transport#isConnected isConnected} method.
In some cases sendmail will respond slowly after many NOOP commands;
use of RSET avoids this sendmail issue.
Defaults to false.
</TD>
</TR>
<TR>
<TD>mail.smtp.noop.strict</TD>
<TD>boolean</TD>
<TD>
If set to true (the default), insist on a 250 response code from the NOOP
command to indicate success. The NOOP command is used by the
{@link javax.mail.Transport#isConnected isConnected} method to determine
if the connection is still alive.
Some older servers return the wrong response code on success, some
servers don't implement the NOOP command at all and so always return
a failure code. Set this property to false to handle servers
that are broken in this way.
Normally, when a server times out a connection, it will send a 421
response code, which the client will see as the response to the next
command it issues.
Some servers send the wrong failure response code when timing out a
connection.
Do not set this property to false when dealing with servers that are
broken in this way.
</TD>
</TR>
</TABLE>
<P>
In general, applications should not need to use the classes in this
package directly. Instead, they should use the APIs defined by
<code>javax.mail</code> package (and subpackages). Applications should
never construct instances of <code>SMTPTransport</code> directly.
Instead, they should use the
<code>Session</code> method <code>getTransport</code> to acquire an
appropriate <code>Transport</code> object.
<P>
In addition to printing debugging output as controlled by the
{@link javax.mail.Session Session} configuration,
the com.sun.mail.smtp provider logs the same information using
{@link java.util.logging.Logger} as described in the following table:
<P>
<TABLE BORDER>
<TR>
<TH>Logger Name</TH>
<TH>Logging Level</TH>
<TH>Purpose</TH>
</TR>
<TR>
<TD>com.sun.mail.smtp</TD>
<TD>CONFIG</TD>
<TD>Configuration of the SMTPTransport</TD>
</TR>
<TR>
<TD>com.sun.mail.smtp</TD>
<TD>FINE</TD>
<TD>General debugging output</TD>
</TR>
<TR>
<TD>com.sun.mail.smtp.protocol</TD>
<TD>FINEST</TD>
<TD>Complete protocol trace</TD>
</TR>
</TABLE>
<P>
<strong>WARNING:</strong> The APIs unique to this package should be
considered <strong>EXPERIMENTAL</strong>. They may be changed in the
future in ways that are incompatible with applications using the
current APIs.
</BODY>
</HTML>

View File

@ -1,275 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
public class ASCIIUtility {
// Private constructor so that this class is not instantiated
private ASCIIUtility() { }
/**
* Convert the bytes within the specified range of the given byte
* array into a signed integer in the given radix . The range extends
* from <code>start</code> till, but not including <code>end</code>. <p>
*
* Based on java.lang.Integer.parseInt()
*/
public static int parseInt(byte[] b, int start, int end, int radix)
throws NumberFormatException {
if (b == null)
throw new NumberFormatException("null");
int result = 0;
boolean negative = false;
int i = start;
int limit;
int multmin;
int digit;
if (end > start) {
if (b[i] == '-') {
negative = true;
limit = Integer.MIN_VALUE;
i++;
} else {
limit = -Integer.MAX_VALUE;
}
multmin = limit / radix;
if (i < end) {
digit = Character.digit((char)b[i++], radix);
if (digit < 0) {
throw new NumberFormatException(
"illegal number: " + toString(b, start, end)
);
} else {
result = -digit;
}
}
while (i < end) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit((char)b[i++], radix);
if (digit < 0) {
throw new NumberFormatException("illegal number");
}
if (result < multmin) {
throw new NumberFormatException("illegal number");
}
result *= radix;
if (result < limit + digit) {
throw new NumberFormatException("illegal number");
}
result -= digit;
}
} else {
throw new NumberFormatException("illegal number");
}
if (negative) {
if (i > start + 1) {
return result;
} else { /* Only got "-" */
throw new NumberFormatException("illegal number");
}
} else {
return -result;
}
}
/**
* Convert the bytes within the specified range of the given byte
* array into a signed integer . The range extends from
* <code>start</code> till, but not including <code>end</code>. <p>
*/
public static int parseInt(byte[] b, int start, int end)
throws NumberFormatException {
return parseInt(b, start, end, 10);
}
/**
* Convert the bytes within the specified range of the given byte
* array into a signed long in the given radix . The range extends
* from <code>start</code> till, but not including <code>end</code>. <p>
*
* Based on java.lang.Long.parseLong()
*/
public static long parseLong(byte[] b, int start, int end, int radix)
throws NumberFormatException {
if (b == null)
throw new NumberFormatException("null");
long result = 0;
boolean negative = false;
int i = start;
long limit;
long multmin;
int digit;
if (end > start) {
if (b[i] == '-') {
negative = true;
limit = Long.MIN_VALUE;
i++;
} else {
limit = -Long.MAX_VALUE;
}
multmin = limit / radix;
if (i < end) {
digit = Character.digit((char)b[i++], radix);
if (digit < 0) {
throw new NumberFormatException(
"illegal number: " + toString(b, start, end)
);
} else {
result = -digit;
}
}
while (i < end) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit((char)b[i++], radix);
if (digit < 0) {
throw new NumberFormatException("illegal number");
}
if (result < multmin) {
throw new NumberFormatException("illegal number");
}
result *= radix;
if (result < limit + digit) {
throw new NumberFormatException("illegal number");
}
result -= digit;
}
} else {
throw new NumberFormatException("illegal number");
}
if (negative) {
if (i > start + 1) {
return result;
} else { /* Only got "-" */
throw new NumberFormatException("illegal number");
}
} else {
return -result;
}
}
/**
* Convert the bytes within the specified range of the given byte
* array into a signed long . The range extends from
* <code>start</code> till, but not including <code>end</code>. <p>
*/
public static long parseLong(byte[] b, int start, int end)
throws NumberFormatException {
return parseLong(b, start, end, 10);
}
/**
* Convert the bytes within the specified range of the given byte
* array into a String. The range extends from <code>start</code>
* till, but not including <code>end</code>. <p>
*/
public static String toString(byte[] b, int start, int end) {
int size = end - start;
char[] theChars = new char[size];
for (int i = 0, j = start; i < size; )
theChars[i++] = (char)(b[j++]&0xff);
return new String(theChars);
}
/**
* Convert the bytes into a String.
*
* @since JavaMail 1.4.4
*/
public static String toString(byte[] b) {
return toString(b, 0, b.length);
}
public static String toString(ByteArrayInputStream is) {
int size = is.available();
char[] theChars = new char[size];
byte[] bytes = new byte[size];
is.read(bytes, 0, size);
for (int i = 0; i < size;)
theChars[i] = (char)(bytes[i++]&0xff);
return new String(theChars);
}
public static byte[] getBytes(String s) {
char [] chars= s.toCharArray();
int size = chars.length;
byte[] bytes = new byte[size];
for (int i = 0; i < size;)
bytes[i] = (byte) chars[i++];
return bytes;
}
public static byte[] getBytes(InputStream is) throws IOException {
int len;
int size = 1024;
byte [] buf;
if (is instanceof ByteArrayInputStream) {
size = is.available();
buf = new byte[size];
len = is.read(buf, 0, size);
}
else {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
buf = new byte[size];
while ((len = is.read(buf, 0, size)) != -1)
bos.write(buf, 0, len);
buf = bos.toByteArray();
}
return buf;
}
}

View File

@ -1,470 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.util;
import java.io.*;
/**
* This class implements a BASE64 Decoder. It is implemented as
* a FilterInputStream, so one can just wrap this class around
* any input stream and read bytes from this filter. The decoding
* is done as the bytes are read out.
*
* @author John Mani
* @author Bill Shannon
*/
public class BASE64DecoderStream extends FilterInputStream {
// buffer of decoded bytes for single byte reads
private byte[] buffer = new byte[3];
private int bufsize = 0; // size of the cache
private int index = 0; // index into the cache
// buffer for almost 8K of typical 76 chars + CRLF lines,
// used by getByte method. this buffer contains encoded bytes.
private byte[] input_buffer = new byte[78*105];
private int input_pos = 0;
private int input_len = 0;;
private boolean ignoreErrors = false;
/**
* Create a BASE64 decoder that decodes the specified input stream.
* The System property <code>mail.mime.base64.ignoreerrors</code>
* controls whether errors in the encoded data cause an exception
* or are ignored. The default is false (errors cause exception).
*
* @param in the input stream
*/
public BASE64DecoderStream(InputStream in) {
super(in);
// default to false
ignoreErrors = PropUtil.getBooleanSystemProperty(
"mail.mime.base64.ignoreerrors", false);
}
/**
* Create a BASE64 decoder that decodes the specified input stream.
*
* @param in the input stream
* @param ignoreErrors ignore errors in encoded data?
*/
public BASE64DecoderStream(InputStream in, boolean ignoreErrors) {
super(in);
this.ignoreErrors = ignoreErrors;
}
/**
* Read the next decoded byte from this input stream. The byte
* is returned as an <code>int</code> in the range <code>0</code>
* to <code>255</code>. If no byte is available because the end of
* the stream has been reached, the value <code>-1</code> is returned.
* This method blocks until input data is available, the end of the
* stream is detected, or an exception is thrown.
*
* @return next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
public int read() throws IOException {
if (index >= bufsize) {
bufsize = decode(buffer, 0, buffer.length);
if (bufsize <= 0) // buffer is empty
return -1;
index = 0; // reset index into buffer
}
return buffer[index++] & 0xff; // Zero off the MSB
}
/**
* Reads up to <code>len</code> decoded bytes of data from this input stream
* into an array of bytes. This method blocks until some input is
* available.
* <p>
*
* @param buf the buffer into which the data is read.
* @param off the start offset of the data.
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception IOException if an I/O error occurs.
*/
public int read(byte[] buf, int off, int len) throws IOException {
// empty out single byte read buffer
int off0 = off;
while (index < bufsize && len > 0) {
buf[off++] = buffer[index++];
len--;
}
if (index >= bufsize)
bufsize = index = 0;
int bsize = (len / 3) * 3; // round down to multiple of 3 bytes
if (bsize > 0) {
int size = decode(buf, off, bsize);
off += size;
len -= size;
if (size != bsize) { // hit EOF?
if (off == off0) // haven't returned any data
return -1;
else // returned some data before hitting EOF
return off - off0;
}
}
// finish up with a partial read if necessary
for (; len > 0; len--) {
int c = read();
if (c == -1) // EOF
break;
buf[off++] = (byte)c;
}
if (off == off0) // haven't returned any data
return -1;
else // returned some data before hitting EOF
return off - off0;
}
/**
* Skips over and discards n bytes of data from this stream.
*/
public long skip(long n) throws IOException {
long skipped = 0;
while (n-- > 0 && read() >= 0)
skipped++;
return skipped;
}
/**
* Tests if this input stream supports marks. Currently this class
* does not support marks
*/
public boolean markSupported() {
return false; // Maybe later ..
}
/**
* Returns the number of bytes that can be read from this input
* stream without blocking. However, this figure is only
* a close approximation in case the original encoded stream
* contains embedded CRLFs; since the CRLFs are discarded, not decoded
*/
public int available() throws IOException {
// This is only an estimate, since in.available()
// might include CRLFs too ..
return ((in.available() * 3)/4 + (bufsize-index));
}
/**
* This character array provides the character to value map
* based on RFC1521.
*/
private final static char pem_array[] = {
'A','B','C','D','E','F','G','H', // 0
'I','J','K','L','M','N','O','P', // 1
'Q','R','S','T','U','V','W','X', // 2
'Y','Z','a','b','c','d','e','f', // 3
'g','h','i','j','k','l','m','n', // 4
'o','p','q','r','s','t','u','v', // 5
'w','x','y','z','0','1','2','3', // 6
'4','5','6','7','8','9','+','/' // 7
};
private final static byte pem_convert_array[] = new byte[256];
static {
for (int i = 0; i < 255; i++)
pem_convert_array[i] = -1;
for (int i = 0; i < pem_array.length; i++)
pem_convert_array[pem_array[i]] = (byte)i;
}
/**
* The decoder algorithm. Most of the complexity here is dealing
* with error cases. Returns the number of bytes decoded, which
* may be zero. Decoding is done by filling an int with 4 6-bit
* values by shifting them in from the bottom and then extracting
* 3 8-bit bytes from the int by shifting them out from the bottom.
*
* @param outbuf the buffer into which to put the decoded bytes
* @param pos position in the buffer to start filling
* @param len the number of bytes to fill
* @return the number of bytes filled, always a multiple
* of three, and may be zero
* @exception IOException if the data is incorrectly formatted
*/
private int decode(byte[] outbuf, int pos, int len) throws IOException {
int pos0 = pos;
while (len >= 3) {
/*
* We need 4 valid base64 characters before we start decoding.
* We skip anything that's not a valid base64 character (usually
* just CRLF).
*/
int got = 0;
int val = 0;
while (got < 4) {
int i = getByte();
if (i == -1 || i == -2) {
boolean atEOF;
if (i == -1) {
if (got == 0)
return pos - pos0;
if (!ignoreErrors)
throw new DecodingException(
"BASE64Decoder: Error in encoded stream: " +
"needed 4 valid base64 characters " +
"but only got " + got + " before EOF" +
recentChars());
atEOF = true; // don't read any more
} else { // i == -2
// found a padding character, we're at EOF
// XXX - should do something to make EOF "sticky"
if (got < 2 && !ignoreErrors)
throw new DecodingException(
"BASE64Decoder: Error in encoded stream: " +
"needed at least 2 valid base64 characters," +
" but only got " + got +
" before padding character (=)" +
recentChars());
// didn't get any characters before padding character?
if (got == 0)
return pos - pos0;
atEOF = false; // need to keep reading
}
// pad partial result with zeroes
// how many bytes will we produce on output?
// (got always < 4, so size always < 3)
int size = got - 1;
if (size == 0)
size = 1;
// handle the one padding character we've seen
got++;
val <<= 6;
while (got < 4) {
if (!atEOF) {
// consume the rest of the padding characters,
// filling with zeroes
i = getByte();
if (i == -1) {
if (!ignoreErrors)
throw new DecodingException(
"BASE64Decoder: Error in encoded " +
"stream: hit EOF while looking for " +
"padding characters (=)" +
recentChars());
} else if (i != -2) {
if (!ignoreErrors)
throw new DecodingException(
"BASE64Decoder: Error in encoded " +
"stream: found valid base64 " +
"character after a padding character " +
"(=)" + recentChars());
}
}
val <<= 6;
got++;
}
// now pull out however many valid bytes we got
val >>= 8; // always skip first one
if (size == 2)
outbuf[pos + 1] = (byte)(val & 0xff);
val >>= 8;
outbuf[pos] = (byte)(val & 0xff);
// len -= size; // not needed, return below
pos += size;
return pos - pos0;
} else {
// got a valid byte
val <<= 6;
got++;
val |= i;
}
}
// read 4 valid characters, now extract 3 bytes
outbuf[pos + 2] = (byte)(val & 0xff);
val >>= 8;
outbuf[pos + 1] = (byte)(val & 0xff);
val >>= 8;
outbuf[pos] = (byte)(val & 0xff);
len -= 3;
pos += 3;
}
return pos - pos0;
}
/**
* Read the next valid byte from the input stream.
* Buffer lots of data from underlying stream in input_buffer,
* for efficiency.
*
* @return the next byte, -1 on EOF, or -2 if next byte is '='
* (padding at end of encoded data)
*/
private int getByte() throws IOException {
int c;
do {
if (input_pos >= input_len) {
try {
input_len = in.read(input_buffer);
} catch (EOFException ex) {
return -1;
}
if (input_len <= 0)
return -1;
input_pos = 0;
}
// get the next byte in the buffer
c = input_buffer[input_pos++] & 0xff;
// is it a padding byte?
if (c == '=')
return -2;
// no, convert it
c = pem_convert_array[c];
// loop until we get a legitimate byte
} while (c == -1);
return c;
}
/**
* Return the most recent characters, for use in an error message.
*/
private String recentChars() {
// reach into the input buffer and extract up to 10
// recent characters, to help in debugging.
String errstr = "";
int nc = input_pos > 10 ? 10 : input_pos;
if (nc > 0) {
errstr += ", the " + nc +
" most recent characters were: \"";
for (int k = input_pos - nc; k < input_pos; k++) {
char c = (char)(input_buffer[k] & 0xff);
switch (c) {
case '\r': errstr += "\\r"; break;
case '\n': errstr += "\\n"; break;
case '\t': errstr += "\\t"; break;
default:
if (c >= ' ' && c < 0177)
errstr += c;
else
errstr += ("\\" + (int)c);
}
}
errstr += "\"";
}
return errstr;
}
/**
* Base64 decode a byte array. No line breaks are allowed.
* This method is suitable for short strings, such as those
* in the IMAP AUTHENTICATE protocol, but not to decode the
* entire content of a MIME part.
*
* NOTE: inbuf may only contain valid base64 characters.
* Whitespace is not ignored.
*/
public static byte[] decode(byte[] inbuf) {
int size = (inbuf.length / 4) * 3;
if (size == 0)
return inbuf;
if (inbuf[inbuf.length - 1] == '=') {
size--;
if (inbuf[inbuf.length - 2] == '=')
size--;
}
byte[] outbuf = new byte[size];
int inpos = 0, outpos = 0;
size = inbuf.length;
while (size > 0) {
int val;
int osize = 3;
val = pem_convert_array[inbuf[inpos++] & 0xff];
val <<= 6;
val |= pem_convert_array[inbuf[inpos++] & 0xff];
val <<= 6;
if (inbuf[inpos] != '=') // End of this BASE64 encoding
val |= pem_convert_array[inbuf[inpos++] & 0xff];
else
osize--;
val <<= 6;
if (inbuf[inpos] != '=') // End of this BASE64 encoding
val |= pem_convert_array[inbuf[inpos++] & 0xff];
else
osize--;
if (osize > 2)
outbuf[outpos + 2] = (byte)(val & 0xff);
val >>= 8;
if (osize > 1)
outbuf[outpos + 1] = (byte)(val & 0xff);
val >>= 8;
outbuf[outpos] = (byte)(val & 0xff);
outpos += osize;
size -= 4;
}
return outbuf;
}
/*** begin TEST program ***
public static void main(String argv[]) throws Exception {
FileInputStream infile = new FileInputStream(argv[0]);
BASE64DecoderStream decoder = new BASE64DecoderStream(infile);
int c;
while ((c = decoder.read()) != -1)
System.out.print((char)c);
System.out.flush();
}
*** end TEST program ***/
}

View File

@ -1,322 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.util;
import java.io.*;
/**
* This class implements a BASE64 encoder. It is implemented as
* a FilterOutputStream, so one can just wrap this class around
* any output stream and write bytes into this filter. The encoding
* is done as the bytes are written out.
*
* @author John Mani
* @author Bill Shannon
*/
public class BASE64EncoderStream extends FilterOutputStream {
private byte[] buffer; // cache of bytes that are yet to be encoded
private int bufsize = 0; // size of the cache
private byte[] outbuf; // line size output buffer
private int count = 0; // number of bytes that have been output
private int bytesPerLine; // number of bytes per line
private int lineLimit; // number of input bytes to output bytesPerLine
private boolean noCRLF = false;
private static byte[] newline = new byte[] { '\r', '\n' };
/**
* Create a BASE64 encoder that encodes the specified output stream.
*
* @param out the output stream
* @param bytesPerLine number of bytes per line. The encoder inserts
* a CRLF sequence after the specified number of bytes,
* unless bytesPerLine is Integer.MAX_VALUE, in which
* case no CRLF is inserted. bytesPerLine is rounded
* down to a multiple of 4.
*/
public BASE64EncoderStream(OutputStream out, int bytesPerLine) {
super(out);
buffer = new byte[3];
if (bytesPerLine == Integer.MAX_VALUE || bytesPerLine < 4) {
noCRLF = true;
bytesPerLine = 76;
}
bytesPerLine = (bytesPerLine / 4) * 4; // Rounded down to 4n
this.bytesPerLine = bytesPerLine; // save it
lineLimit = bytesPerLine / 4 * 3;
if (noCRLF) {
outbuf = new byte[bytesPerLine];
} else {
outbuf = new byte[bytesPerLine + 2];
outbuf[bytesPerLine] = (byte)'\r';
outbuf[bytesPerLine + 1] = (byte)'\n';
}
}
/**
* Create a BASE64 encoder that encodes the specified input stream.
* Inserts the CRLF sequence after outputting 76 bytes.
*
* @param out the output stream
*/
public BASE64EncoderStream(OutputStream out) {
this(out, 76);
}
/**
* Encodes <code>len</code> bytes from the specified
* <code>byte</code> array starting at offset <code>off</code> to
* this output stream.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if an I/O error occurs.
*/
public synchronized void write(byte[] b, int off, int len)
throws IOException {
int end = off + len;
// finish off incomplete coding unit
while (bufsize != 0 && off < end)
write(b[off++]);
// finish off line
int blen = ((bytesPerLine - count) / 4) * 3;
if (off + blen <= end) {
// number of bytes that will be produced in outbuf
int outlen = encodedSize(blen);
if (!noCRLF) {
outbuf[outlen++] = (byte)'\r';
outbuf[outlen++] = (byte)'\n';
}
out.write(encode(b, off, blen, outbuf), 0, outlen);
off += blen;
count = 0;
}
// do bulk encoding a line at a time.
for (; off + lineLimit <= end; off += lineLimit)
out.write(encode(b, off, lineLimit, outbuf));
// handle remaining partial line
if (off + 3 <= end) {
blen = end - off;
blen = (blen / 3) * 3; // round down
// number of bytes that will be produced in outbuf
int outlen = encodedSize(blen);
out.write(encode(b, off, blen, outbuf), 0, outlen);
off += blen;
count += outlen;
}
// start next coding unit
for (; off < end; off++)
write(b[off]);
}
/**
* Encodes <code>b.length</code> bytes to this output stream.
*
* @param b the data to be written.
* @exception IOException if an I/O error occurs.
*/
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
/**
* Encodes the specified <code>byte</code> to this output stream.
*
* @param c the <code>byte</code>.
* @exception IOException if an I/O error occurs.
*/
public synchronized void write(int c) throws IOException {
buffer[bufsize++] = (byte)c;
if (bufsize == 3) { // Encoding unit = 3 bytes
encode();
bufsize = 0;
}
}
/**
* Flushes this output stream and forces any buffered output bytes
* to be encoded out to the stream.
*
* @exception IOException if an I/O error occurs.
*/
public synchronized void flush() throws IOException {
if (bufsize > 0) { // If there's unencoded characters in the buffer ..
encode(); // .. encode them
bufsize = 0;
}
out.flush();
}
/**
* Forces any buffered output bytes to be encoded out to the stream
* and closes this output stream
*/
public synchronized void close() throws IOException {
flush();
if (count > 0 && !noCRLF) {
out.write(newline);
out.flush();
}
out.close();
}
/** This array maps the characters to their 6 bit values */
private final static char pem_array[] = {
'A','B','C','D','E','F','G','H', // 0
'I','J','K','L','M','N','O','P', // 1
'Q','R','S','T','U','V','W','X', // 2
'Y','Z','a','b','c','d','e','f', // 3
'g','h','i','j','k','l','m','n', // 4
'o','p','q','r','s','t','u','v', // 5
'w','x','y','z','0','1','2','3', // 6
'4','5','6','7','8','9','+','/' // 7
};
/**
* Encode the data stored in <code>buffer</code>.
* Uses <code>outbuf</code> to store the encoded
* data before writing.
*
* @exception IOException if an I/O error occurs.
*/
private void encode() throws IOException {
int osize = encodedSize(bufsize);
out.write(encode(buffer, 0, bufsize, outbuf), 0, osize);
// increment count
count += osize;
// If writing out this encoded unit caused overflow,
// start a new line.
if (count >= bytesPerLine) {
if (!noCRLF)
out.write(newline);
count = 0;
}
}
/**
* Base64 encode a byte array. No line breaks are inserted.
* This method is suitable for short strings, such as those
* in the IMAP AUTHENTICATE protocol, but not to encode the
* entire content of a MIME part.
*/
public static byte[] encode(byte[] inbuf) {
if (inbuf.length == 0)
return inbuf;
return encode(inbuf, 0, inbuf.length, null);
}
/**
* Internal use only version of encode. Allow specifying which
* part of the input buffer to encode. If outbuf is non-null,
* it's used as is. Otherwise, a new output buffer is allocated.
*/
private static byte[] encode(byte[] inbuf, int off, int size,
byte[] outbuf) {
if (outbuf == null)
outbuf = new byte[encodedSize(size)];
int inpos, outpos;
int val;
for (inpos = off, outpos = 0; size >= 3; size -= 3, outpos += 4) {
val = inbuf[inpos++] & 0xff;
val <<= 8;
val |= inbuf[inpos++] & 0xff;
val <<= 8;
val |= inbuf[inpos++] & 0xff;
outbuf[outpos+3] = (byte)pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos+2] = (byte)pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos+1] = (byte)pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos+0] = (byte)pem_array[val & 0x3f];
}
// done with groups of three, finish up any odd bytes left
if (size == 1) {
val = inbuf[inpos++] & 0xff;
val <<= 4;
outbuf[outpos+3] = (byte)'='; // pad character;
outbuf[outpos+2] = (byte)'='; // pad character;
outbuf[outpos+1] = (byte)pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos+0] = (byte)pem_array[val & 0x3f];
} else if (size == 2) {
val = inbuf[inpos++] & 0xff;
val <<= 8;
val |= inbuf[inpos++] & 0xff;
val <<= 2;
outbuf[outpos+3] = (byte)'='; // pad character;
outbuf[outpos+2] = (byte)pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos+1] = (byte)pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos+0] = (byte)pem_array[val & 0x3f];
}
return outbuf;
}
/**
* Return the corresponding encoded size for the given number
* of bytes, not including any CRLF.
*/
private static int encodedSize(int size) {
return ((size + 2) / 3) * 4;
}
/*** begin TEST program
public static void main(String argv[]) throws Exception {
FileInputStream infile = new FileInputStream(argv[0]);
BASE64EncoderStream encoder = new BASE64EncoderStream(System.out);
int c;
while ((c = infile.read()) != -1)
encoder.write(c);
encoder.close();
}
*** end TEST program **/
}

View File

@ -1,71 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.util;
import java.io.*;
/**
* This class implements a 'B' Encoder as defined by RFC2047 for
* encoding MIME headers. It subclasses the BASE64EncoderStream
* class.
*
* @author John Mani
*/
public class BEncoderStream extends BASE64EncoderStream {
/**
* Create a 'B' encoder that encodes the specified input stream.
* @param out the output stream
*/
public BEncoderStream(OutputStream out) {
super(out, Integer.MAX_VALUE); // MAX_VALUE is 2^31, should
// suffice (!) to indicate that
// CRLFs should not be inserted
}
/**
* Returns the length of the encoded version of this byte array.
*/
public static int encodedLength(byte[] b) {
return ((b.length + 2)/3) * 4;
}
}

View File

@ -1,109 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.util;
import java.io.*;
/**
* Convert lines into the canonical format, that is, terminate lines with the
* CRLF sequence.
*
* @author John Mani
*/
public class CRLFOutputStream extends FilterOutputStream {
protected int lastb = -1;
protected boolean atBOL = true; // at beginning of line?
private static final byte[] newline = { (byte)'\r', (byte)'\n' };
public CRLFOutputStream(OutputStream os) {
super(os);
}
public void write(int b) throws IOException {
if (b == '\r') {
writeln();
} else if (b == '\n') {
if (lastb != '\r')
writeln();
} else {
out.write(b);
atBOL = false;
}
lastb = b;
}
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
int start = off;
len += off;
for (int i = start; i < len ; i++) {
if (b[i] == '\r') {
out.write(b, start, i - start);
writeln();
start = i + 1;
} else if (b[i] == '\n') {
if (lastb != '\r') {
out.write(b, start, i - start);
writeln();
}
start = i + 1;
}
lastb = b[i];
}
if ((len - start) > 0) {
out.write(b, start, len - start);
atBOL = false;
}
}
/*
* Just write out a new line, something similar to out.println()
*/
public void writeln() throws IOException {
out.write(newline);
atBOL = true;
}
}

View File

@ -1,63 +0,0 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.mail.util;
import java.io.IOException;
/**
* A special IOException that indicates a failure to decode data due
* to an error in the formatting of the data. This allows applications
* to distinguish decoding errors from other I/O errors.
*
* @author Bill Shannon
*/
public class DecodingException extends IOException {
private static final long serialVersionUID = -6913647794421459390L;
/**
* Constructor
*/
public DecodingException(String s) {
super(s);
}
}

Some files were not shown because too many files have changed in this diff Show More