mirror of
https://github.com/imapsync/imapsync.git
synced 2025-06-11 23:24:30 +02:00
1.5
This commit is contained in:
commit
8dd42376aa
8 changed files with 1167 additions and 0 deletions
39
ChangeLog
Normal file
39
ChangeLog
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
RCS file: RCS/imapsync,v
|
||||||
|
Working file: imapsync
|
||||||
|
head: 1.5
|
||||||
|
branch:
|
||||||
|
locks: strict
|
||||||
|
gilles: 1.5
|
||||||
|
access list:
|
||||||
|
symbolic names:
|
||||||
|
keyword substitution: kv
|
||||||
|
total revisions: 5; selected revisions: 5
|
||||||
|
description:
|
||||||
|
----------------------------
|
||||||
|
revision 1.5 locked by: gilles;
|
||||||
|
date: 2003/03/14 01:20:37; author: gilles; state: Exp; lines: +14 -6
|
||||||
|
Better debug output.
|
||||||
|
----------------------------
|
||||||
|
revision 1.4
|
||||||
|
date: 2003/03/14 01:01:08; author: gilles; state: Exp; lines: +143 -15
|
||||||
|
Added documentation.
|
||||||
|
Added --folder option.
|
||||||
|
Added error counter.
|
||||||
|
----------------------------
|
||||||
|
revision 1.3
|
||||||
|
date: 2003/03/12 23:19:58; author: gilles; state: Exp; lines: +276 -166
|
||||||
|
Adapted from transfert-bal-verify.pl
|
||||||
|
Added usage()
|
||||||
|
Changed variable names.
|
||||||
|
Added get_options()
|
||||||
|
Added option controls.
|
||||||
|
----------------------------
|
||||||
|
revision 1.2
|
||||||
|
date: 2001/07/29 23:27:52; author: gilles; state: Exp; lines: +7 -4
|
||||||
|
8bit -> X
|
||||||
|
----------------------------
|
||||||
|
revision 1.1
|
||||||
|
date: 2001/07/29 22:34:01; author: gilles; state: Exp;
|
||||||
|
Initial revision
|
||||||
|
=============================================================================
|
339
GPL
Normal file
339
GPL
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
675 Mass Ave, Cambridge, MA 02139, USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, 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 or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
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 give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
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 Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
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 Program, 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 Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) 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; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, 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 executable. However, as a
|
||||||
|
special exception, the source code 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.
|
||||||
|
|
||||||
|
If distribution of executable or 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 counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program 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.
|
||||||
|
|
||||||
|
5. 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 Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program 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 to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. 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 Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program 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 Program.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program 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.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the 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 Program
|
||||||
|
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 Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, 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
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Appendix: How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) 19yy <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
35
INSTALL
Normal file
35
INSTALL
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# $Id: INSTALL,v 1.1 2003/03/12 23:14:27 gilles Exp gilles $
|
||||||
|
#
|
||||||
|
# INSTALL file for ftpsync
|
||||||
|
|
||||||
|
|
||||||
|
GETTING
|
||||||
|
-------
|
||||||
|
|
||||||
|
http://www.linux-france.org/prj/imapsync/dist/
|
||||||
|
|
||||||
|
|
||||||
|
TESTING
|
||||||
|
-------
|
||||||
|
|
||||||
|
You need a running imap server on localhost with two accounts
|
||||||
|
toto@est.belle with a password located in the file /var/tmp/secret1
|
||||||
|
titi@est.belle with a password located in the file /var/tmp/secret2
|
||||||
|
|
||||||
|
Of course, you can change the file tests.sh and run the tests with :
|
||||||
|
|
||||||
|
sh tests.sh
|
||||||
|
|
||||||
|
The tests.sh script break on first failure ("set -e" directive).
|
||||||
|
|
||||||
|
INSTALLING
|
||||||
|
----------
|
||||||
|
To see what will be done, just run:
|
||||||
|
|
||||||
|
make -n install
|
||||||
|
|
||||||
|
To install imapsync, just run:
|
||||||
|
|
||||||
|
make install
|
||||||
|
|
||||||
|
or copy the file imapsync where you want it to be.
|
89
Makefile
Normal file
89
Makefile
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
|
||||||
|
# $Id: Makefile,v 1.1 2003/03/12 23:14:02 gilles Exp gilles $
|
||||||
|
|
||||||
|
TARGET=imapsync
|
||||||
|
|
||||||
|
.PHONY: help usage all
|
||||||
|
|
||||||
|
help: usage
|
||||||
|
|
||||||
|
usage:
|
||||||
|
@echo " $(TARGET) $(VERSION), You can do :"
|
||||||
|
@echo make install # as root
|
||||||
|
@echo make testf # run tests
|
||||||
|
@echo make testv # run tests verbosely
|
||||||
|
@echo make all
|
||||||
|
|
||||||
|
all: test ChangeLog README
|
||||||
|
|
||||||
|
.PHONY: test testp testf
|
||||||
|
|
||||||
|
.test: $(TARGET) tests.sh
|
||||||
|
sh tests.sh 1>/dev/null
|
||||||
|
touch .test
|
||||||
|
|
||||||
|
testv:
|
||||||
|
sh -x tests.sh
|
||||||
|
|
||||||
|
test: .test
|
||||||
|
|
||||||
|
testf: clean_test test
|
||||||
|
|
||||||
|
testp :
|
||||||
|
perl -c $(TARGET)
|
||||||
|
|
||||||
|
ChangeLog: $(TARGET)
|
||||||
|
rlog $(TARGET) > ChangeLog
|
||||||
|
|
||||||
|
README: $(TARGET)
|
||||||
|
perldoc -t $(TARGET) > README
|
||||||
|
|
||||||
|
.PHONY: clean clean_tilde clean_test
|
||||||
|
|
||||||
|
clean: clean_tilde clean_test
|
||||||
|
|
||||||
|
clean_test:
|
||||||
|
rm -f .test
|
||||||
|
|
||||||
|
clean_tilde:
|
||||||
|
rm -f *~
|
||||||
|
|
||||||
|
.PHONY: install dist
|
||||||
|
|
||||||
|
install: testp
|
||||||
|
cp $(TARGET) /usr/bin/$(TARGET)
|
||||||
|
chmod 755 /usr/bin/$(TARGET)
|
||||||
|
|
||||||
|
DIST_NAME=$(TARGET)-$(VERSION)
|
||||||
|
DIST_FILE=$(DIST_NAME).tgz
|
||||||
|
VERSION=$(shell ./$(TARGET) --version)
|
||||||
|
|
||||||
|
dist: cidone clean_dist all INSTALL
|
||||||
|
echo making tarball $(DIST_FILE)
|
||||||
|
mkdir -p dist
|
||||||
|
mkdir -p ../prepa_dist/$(DIST_NAME)
|
||||||
|
rsync -aCv --delete ./ ../prepa_dist/$(DIST_NAME)
|
||||||
|
cd ../prepa_dist && tar czfv $(DIST_FILE) $(DIST_NAME)
|
||||||
|
cp -f ../prepa_dist/$(DIST_FILE) dist/
|
||||||
|
cd dist && md5sum $(DIST_FILE) > $(DIST_FILE).md5
|
||||||
|
cd dist && md5sum -c $(DIST_FILE).md5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: cidone clean_dist
|
||||||
|
|
||||||
|
cidone:
|
||||||
|
rcsdiff RCS/*
|
||||||
|
|
||||||
|
clean_dist:
|
||||||
|
rm -f dist/*
|
||||||
|
|
||||||
|
# Local goals
|
||||||
|
|
||||||
|
.PHONY: lfo
|
||||||
|
|
||||||
|
lfo: dist
|
||||||
|
rsync -av --delete . \
|
||||||
|
/home/gilles/public_html/www.linux-france.org/html/prj/$(TARGET)/
|
||||||
|
sh ~/memo/lfo-rsync
|
||||||
|
|
93
README
Normal file
93
README
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
NAME
|
||||||
|
imapsync - synchronize mailboxes between two imap servers.
|
||||||
|
|
||||||
|
$Revision: 1.5 $
|
||||||
|
|
||||||
|
INSTALL
|
||||||
|
Get imapsync at http://www.linux-france.org/prj/imapsync/dist/
|
||||||
|
tar xzvf imapsync-x.xx.tgz # x.xx is the version number
|
||||||
|
Read the INSTALL file.
|
||||||
|
freshmeat record: http://freshmeat.net/projects/imapsync/
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
imapsync [options] SOURCE DEST
|
||||||
|
|
||||||
|
imapsync [--host1 server1] [--port1 <num>]
|
||||||
|
[--user1 <string>] [--passfile1 <string>]
|
||||||
|
[--host2 server2] [--port2 <num>]
|
||||||
|
[--user2 <string>] [--passfile2 <string>]
|
||||||
|
[--folder <string> --folder <string> ...]
|
||||||
|
[--delete] [--expunge]
|
||||||
|
[--dry]
|
||||||
|
[--debug] [--debugimap]
|
||||||
|
[--version] [--help]
|
||||||
|
|
||||||
|
imapsync --help
|
||||||
|
imapsync
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The command imapsync is a tool allowing incremental and recursive imap
|
||||||
|
transfer from one mailbox to another.
|
||||||
|
|
||||||
|
We sometimes need to transfer mailboxes from one imap server to another.
|
||||||
|
This is called migration.
|
||||||
|
|
||||||
|
imapsync is the adequate tool because it reduces the amount of data
|
||||||
|
transfered by not transfering a given message if it is already on both
|
||||||
|
sides. All flags are preserved, unread will stay unread, read will stay
|
||||||
|
read, deleted will stay deleted.
|
||||||
|
|
||||||
|
OPTIONS
|
||||||
|
Invoke: imapsync --help
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
I wrote imapsync because an enterprise (basystemes) paid me to install a
|
||||||
|
new imap server without loosing huge old mailboxes located on a far away
|
||||||
|
remote imap server accessible by a low bandwith link. The tool imapcp
|
||||||
|
(written in python) could not help me because I had to verify every
|
||||||
|
mailbox was well transfered and delete it after a good transfert.
|
||||||
|
imapsync started its life being a copy_folder.pl patch. The tool
|
||||||
|
copy_folder.pl comes from the Mail-IMAPClient-2.1.3 perl module tarball
|
||||||
|
source (in the examples/ directory).
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
While working on imapsync parameters please run imapsync in dry mode (no
|
||||||
|
modification induced) with the --dry option. Nothing bad can be done
|
||||||
|
this way.
|
||||||
|
|
||||||
|
To synchronize the imap account "buddy" on host "imap.src.fr" to the
|
||||||
|
imap account "max" on host "imap.dest.fr" (the passwords are located in
|
||||||
|
too files "/etc/secret1" for "buddy", "/etc/secret2" for "max") :
|
||||||
|
|
||||||
|
imapsync --host1 imap.src.fr --user1 buddy --passfile1 /etc/secret1 \
|
||||||
|
--host2 imap.dest.fr --user2 max --passfile2 /etc/secret2
|
||||||
|
|
||||||
|
Then, you will have buddy's mailbox updated from max's mailbox.
|
||||||
|
|
||||||
|
EXIT STATUS
|
||||||
|
imapsync will exit with a 0 status (return code) if everything went
|
||||||
|
good. Otherwise, it exits with a non-zero status.
|
||||||
|
|
||||||
|
So if you have a buggy internet connection, you can use this loop in a
|
||||||
|
Bourne shell:
|
||||||
|
|
||||||
|
while ! imapsync ...; do
|
||||||
|
echo imapsync not complete
|
||||||
|
done
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Gilles LAMIRAL lamiral@linux-france.org
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
imapsync is free, gratis and open source software cover by the GNU
|
||||||
|
General Public License. See the GPL file included in the distribution or
|
||||||
|
the web site http://www.gnu.org/licenses/licenses.html
|
||||||
|
|
||||||
|
BUGS
|
||||||
|
No known bug. Report any bugs to the author: lamiral@linux-france.org
|
||||||
|
|
||||||
|
SIMILAR SOFTWARES
|
||||||
|
None known. Feedback will be welcome.
|
||||||
|
|
||||||
|
$Id: imapsync,v 1.5 2003/03/14 01:20:37 gilles Exp gilles $
|
||||||
|
|
445
imapsync
Executable file
445
imapsync
Executable file
|
@ -0,0 +1,445 @@
|
||||||
|
#!/usr/bin/perl -w
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
imapsync - synchronize mailboxes between two imap servers.
|
||||||
|
|
||||||
|
$Revision: 1.5 $
|
||||||
|
|
||||||
|
=head1 INSTALL
|
||||||
|
|
||||||
|
Get imapsync at http://www.linux-france.org/prj/imapsync/dist/
|
||||||
|
tar xzvf imapsync-x.xx.tgz # x.xx is the version number
|
||||||
|
Read the INSTALL file.
|
||||||
|
freshmeat record: http://freshmeat.net/projects/imapsync/
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
imapsync [options] SOURCE DEST
|
||||||
|
|
||||||
|
imapsync [--host1 server1] [--port1 <num>]
|
||||||
|
[--user1 <string>] [--passfile1 <string>]
|
||||||
|
[--host2 server2] [--port2 <num>]
|
||||||
|
[--user2 <string>] [--passfile2 <string>]
|
||||||
|
[--folder <string> --folder <string> ...]
|
||||||
|
[--delete] [--expunge]
|
||||||
|
[--dry]
|
||||||
|
[--debug] [--debugimap]
|
||||||
|
[--version] [--help]
|
||||||
|
|
||||||
|
imapsync --help
|
||||||
|
imapsync
|
||||||
|
|
||||||
|
=cut
|
||||||
|
# comment
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
The command imapsync is a tool allowing incremental and recursive
|
||||||
|
imap transfer from one mailbox to another.
|
||||||
|
|
||||||
|
We sometimes need to transfer mailboxes from one imap server to
|
||||||
|
another. This is called migration.
|
||||||
|
|
||||||
|
imapsync is the adequate tool because it reduces the amount of data
|
||||||
|
transfered by not transfering a given message if it is already on
|
||||||
|
both sides. All flags are preserved, unread will stay unread, read
|
||||||
|
will stay read, deleted will stay deleted.
|
||||||
|
|
||||||
|
=head1 OPTIONS
|
||||||
|
|
||||||
|
Invoke: imapsync --help
|
||||||
|
|
||||||
|
=head1 HISTORY
|
||||||
|
|
||||||
|
I wrote imapsync because an enterprise (basystemes) paid me to install
|
||||||
|
a new imap server without loosing huge old mailboxes located on a far
|
||||||
|
away remote imap server accessible by a low bandwith link. The tool
|
||||||
|
imapcp (written in python) could not help me because I had to verify
|
||||||
|
every mailbox was well
|
||||||
|
transfered and delete it after a good transfert. imapsync started its life
|
||||||
|
being a copy_folder.pl patch.
|
||||||
|
The tool copy_folder.pl comes from the Mail-IMAPClient-2.1.3 perl
|
||||||
|
module tarball source (in the examples/ directory).
|
||||||
|
|
||||||
|
=head1 EXAMPLES
|
||||||
|
|
||||||
|
While working on imapsync parameters please run imapsync in dry mode (no
|
||||||
|
modification induced) with the --dry option. Nothing bad can be done
|
||||||
|
this way.
|
||||||
|
|
||||||
|
To synchronize the imap account "buddy" on host "imap.src.fr" to the
|
||||||
|
imap account "max" on host "imap.dest.fr" (the passwords are located
|
||||||
|
in too files "/etc/secret1" for "buddy", "/etc/secret2" for "max") :
|
||||||
|
|
||||||
|
imapsync --host1 imap.src.fr --user1 buddy --passfile1 /etc/secret1 \
|
||||||
|
--host2 imap.dest.fr --user2 max --passfile2 /etc/secret2
|
||||||
|
|
||||||
|
Then, you will have buddy's mailbox updated from max's mailbox.
|
||||||
|
|
||||||
|
=head1 EXIT STATUS
|
||||||
|
|
||||||
|
imapsync will exit with a 0 status (return code) if everything went good.
|
||||||
|
Otherwise, it exits with a non-zero status.
|
||||||
|
|
||||||
|
So if you have a buggy internet connection, you can use this loop
|
||||||
|
in a Bourne shell:
|
||||||
|
|
||||||
|
while ! imapsync ...; do
|
||||||
|
echo imapsync not complete
|
||||||
|
done
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Gilles LAMIRAL lamiral@linux-france.org
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
imapsync is free, gratis and open source software cover by the GNU General
|
||||||
|
Public License. See the GPL file included in the distribution or the web site
|
||||||
|
http://www.gnu.org/licenses/licenses.html
|
||||||
|
|
||||||
|
=head1 BUGS
|
||||||
|
|
||||||
|
No known bug.
|
||||||
|
Report any bugs to the author: lamiral@linux-france.org
|
||||||
|
|
||||||
|
=head1 SIMILAR SOFTWARES
|
||||||
|
|
||||||
|
None known.
|
||||||
|
Feedback will be welcome.
|
||||||
|
|
||||||
|
$Id: imapsync,v 1.5 2003/03/14 01:20:37 gilles Exp gilles $
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
|
||||||
|
++$|;
|
||||||
|
use strict;
|
||||||
|
use Getopt::Long;
|
||||||
|
use Mail::IMAPClient;
|
||||||
|
use Digest::MD5 qw(md5_base64);
|
||||||
|
|
||||||
|
|
||||||
|
my(
|
||||||
|
$rcs, $debug, $debugimap, $error,
|
||||||
|
$host1, $host2, $port1, $port2,
|
||||||
|
$user1, $user2, $password1, $password2, $passfile1, $passfile2,
|
||||||
|
@folder,
|
||||||
|
$delete, $expunge, $dry,
|
||||||
|
$version, $VERSION, $help,
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
use vars qw ($opt_G); # missing code for this will be option.
|
||||||
|
|
||||||
|
|
||||||
|
$rcs = ' $Id: imapsync,v 1.5 2003/03/14 01:20:37 gilles Exp gilles $ ';
|
||||||
|
$rcs =~ m/,v (\d+\.\d+)/;
|
||||||
|
$VERSION = ($1) ? $1 : "UNKNOWN";
|
||||||
|
$error=0;
|
||||||
|
|
||||||
|
get_options();
|
||||||
|
|
||||||
|
sub missing_option {
|
||||||
|
my ($option) = @_;
|
||||||
|
die "$option option must be used, run $0 --help for help\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$host1 || missing_option("--host1") ;
|
||||||
|
$port1 = (defined($port1)) ? $port1 : 143;
|
||||||
|
$user1 || missing_option("--user1");
|
||||||
|
$password1 || $passfile1 || missing_option("--passfile1 or --password1");
|
||||||
|
$password1 = (defined($passfile1)) ? firstline ($passfile1) : $password1;
|
||||||
|
|
||||||
|
$host2 || missing_option("--host2") ;
|
||||||
|
$port2 = (defined($port2)) ? $port2 : 143;
|
||||||
|
$user2 || missing_option("--user2");
|
||||||
|
$password2 || $passfile2 || missing_option("--passfile2 or --password2");
|
||||||
|
$password2 = (defined($passfile2)) ? firstline ($passfile2) : $password2;
|
||||||
|
|
||||||
|
print "From imap server [$host1] port [$port1] user [$user1]\n";
|
||||||
|
print "To imap server [$host2] port [$port2] user [$user2]\n";
|
||||||
|
|
||||||
|
my $from = ();
|
||||||
|
my $to = ();
|
||||||
|
$from = Mail::IMAPClient->new( Server => $host1,
|
||||||
|
User => $user1,
|
||||||
|
Password => $password1,
|
||||||
|
Fast_IO => 1,
|
||||||
|
Uid => 1,
|
||||||
|
Peek => 1,
|
||||||
|
Debug => $debugimap,)
|
||||||
|
or die "can't open imap connection on [$host1] with user [$user1]\n";
|
||||||
|
|
||||||
|
|
||||||
|
$to = Mail::IMAPClient->new( Server => $host2,
|
||||||
|
User => $user2,
|
||||||
|
Password=> $password2,
|
||||||
|
Fast_IO => 1,
|
||||||
|
Uid => 1,
|
||||||
|
Peek => 1,
|
||||||
|
Debug => 0,)
|
||||||
|
or die "can't open imap connection on [$host2] with user [$user2]\n";
|
||||||
|
|
||||||
|
my @f_folders = (scalar(@folder)) ? @folder : @{$from->folders()};
|
||||||
|
|
||||||
|
FOLDER: foreach my $f_fold (@f_folders) {
|
||||||
|
my $t_fold;
|
||||||
|
print "From Folder $f_fold\n";
|
||||||
|
unless ($f_fold =~ m/^INBOX/) {
|
||||||
|
$t_fold = "INBOX." . $f_fold;
|
||||||
|
}else {
|
||||||
|
$t_fold = $f_fold;
|
||||||
|
}
|
||||||
|
$t_fold =~ s@\\@\.@g;
|
||||||
|
$t_fold =~ s@\/@\.@g;
|
||||||
|
unless ($from->select($f_fold)) {
|
||||||
|
warn
|
||||||
|
"From Folder $f_fold : Could not select ",
|
||||||
|
$from->LastError, "\n";
|
||||||
|
$error++;
|
||||||
|
next FOLDER;
|
||||||
|
}
|
||||||
|
unless ($to->exists($t_fold)) {
|
||||||
|
print "To Folder $t_fold does not exist\n";
|
||||||
|
print "Creating folder $t_fold\n";
|
||||||
|
unless ($dry){
|
||||||
|
unless ($to->create($t_fold)){
|
||||||
|
warn "Couldn't create $t_fold ",
|
||||||
|
$to->LastError,"\n";
|
||||||
|
$error++;
|
||||||
|
next FOLDER;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
next FOLDER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unless ($to->select($t_fold)) {
|
||||||
|
warn
|
||||||
|
"To Folder $t_fold : Could not select ",
|
||||||
|
$to->LastError, "\n";
|
||||||
|
$error++;
|
||||||
|
next FOLDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($expunge){
|
||||||
|
print "Expunging $f_fold and $t_fold\n";
|
||||||
|
$from->expunge();
|
||||||
|
$to->expunge();
|
||||||
|
}
|
||||||
|
|
||||||
|
my @f_msgs = $from->search("ALL");
|
||||||
|
$debug and print "LIST FROM : @f_msgs\n";
|
||||||
|
my @t_msgs = $to->search("ALL");
|
||||||
|
$debug and print "LIST TO : @t_msgs\n";
|
||||||
|
|
||||||
|
my %f_hash = ();
|
||||||
|
my %t_hash = ();
|
||||||
|
|
||||||
|
sub header_parse {
|
||||||
|
# @msgs_all;
|
||||||
|
# %hash;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$debug and print "From Parse\n";
|
||||||
|
foreach my $m (@f_msgs) {
|
||||||
|
$debug and print "-" x 50, "\nMSG $m\n";
|
||||||
|
my $head = $from->parse_headers($m,"ALL");
|
||||||
|
my $headstr;
|
||||||
|
$debug and print "Head NUM:", scalar(keys(%$head)), "\n";
|
||||||
|
next unless(scalar(keys(%$head)));
|
||||||
|
foreach my $h (sort keys(%$head)){
|
||||||
|
my $val = $head->{$h}[0];
|
||||||
|
# no accent in headers !
|
||||||
|
$val =~ y/éèàù/XXXX/;
|
||||||
|
$debug and print "H $h:", $val, "\n";
|
||||||
|
$headstr .= "$h:". $val;
|
||||||
|
}
|
||||||
|
my $m_md5 = md5_base64($headstr);
|
||||||
|
my $size = $from->size($m);
|
||||||
|
$debug and print "From $m:$m_md5:$size\n";
|
||||||
|
|
||||||
|
$f_hash{"$m_md5:$size"}{'5'} = "$m_md5:$size";
|
||||||
|
$f_hash{"$m_md5:$size"}{'s'} = $size;
|
||||||
|
$f_hash{"$m_md5:$size"}{'m'} = $m;
|
||||||
|
}
|
||||||
|
|
||||||
|
$debug and print "To Parse\n";
|
||||||
|
foreach my $m (@t_msgs) {
|
||||||
|
$debug and print "-" x 50, "\nMSG $m\n";
|
||||||
|
my $head = $to->parse_headers($m,"ALL");
|
||||||
|
my $headstr;
|
||||||
|
$debug and print "Head NUM:", scalar(keys(%$head)), "\n";
|
||||||
|
next unless(scalar(keys(%$head)));
|
||||||
|
foreach my $h (sort keys(%$head)){
|
||||||
|
$debug and print "$h:", $head->{$h}[0], "\n";
|
||||||
|
$headstr .= "$h:".$head->{$h}[0];
|
||||||
|
}
|
||||||
|
my $m_md5 = md5_base64($headstr);
|
||||||
|
my $size = $to->size($m);
|
||||||
|
$debug and print "To $m:$m_md5:$size\n";
|
||||||
|
$t_hash{"$m_md5:$size"}{'5'} = "$m_md5:$size";
|
||||||
|
$t_hash{"$m_md5:$size"}{'s'} = $size;
|
||||||
|
$t_hash{"$m_md5:$size"}{'m'} = $m;
|
||||||
|
}
|
||||||
|
$debug and print "Verifying\n";
|
||||||
|
# messages in "from" that are not good in "to"
|
||||||
|
|
||||||
|
MESS: foreach my $m_id (keys(%f_hash)) {
|
||||||
|
my $f_size = $f_hash{$m_id}{'s'};
|
||||||
|
my $f_msg = $f_hash{$m_id}{'m'};
|
||||||
|
$debug and print "key $m_id #$f_msg\n";
|
||||||
|
unless (exists($t_hash{$m_id})) {
|
||||||
|
print "Message NO msg #$f_msg $m_id in $t_fold\n";
|
||||||
|
# copy
|
||||||
|
print "Copying msg #$f_msg:$f_size to folder $t_fold\n";
|
||||||
|
unless ($dry) {
|
||||||
|
my $string = $from->message_string($f_msg);
|
||||||
|
#$opt_y and print $string;
|
||||||
|
my $new_id;
|
||||||
|
unless($new_id = $to->append($t_fold,$string)){
|
||||||
|
warn "Couldn't append msg #$f_msg to folder $t_fold",
|
||||||
|
$to->LastError, "\n";
|
||||||
|
$error++;
|
||||||
|
next MESS;
|
||||||
|
}else{
|
||||||
|
# good
|
||||||
|
print "Copied msg #$f_msg to folder $t_fold msg #$new_id\n";
|
||||||
|
$to->store($new_id,
|
||||||
|
"+FLAGS (" . join(" ",
|
||||||
|
@{$from->flags($f_msg)}
|
||||||
|
) . ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next MESS;
|
||||||
|
}else{
|
||||||
|
$debug and print "Message $m_id found in t:$t_fold\n";
|
||||||
|
}
|
||||||
|
#$debug and print "MESSAGE $m_id\n";
|
||||||
|
my $t_size = $t_hash{$m_id}{'s'};
|
||||||
|
my $t_msg = $t_hash{$m_id}{'m'};
|
||||||
|
unless ($f_size == $t_size) {
|
||||||
|
print
|
||||||
|
"Message $m_id SZ_BAD f:$f_msg:$f_size t:$t_msg:$t_size\n";
|
||||||
|
# delete in to and recopy ?
|
||||||
|
# NO recopy CODE HERE. to be written if needed.
|
||||||
|
$error++;
|
||||||
|
if ($opt_G){
|
||||||
|
print "Deleting msg f:#$t_msg in folder $t_fold\n";
|
||||||
|
$to->delete_message($t_msg);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
# Good
|
||||||
|
$debug and print
|
||||||
|
"Message $m_id SZ_GOOD f:$f_msg:$f_size t:$t_msg:$t_size\n";
|
||||||
|
if($delete) {
|
||||||
|
print "Deleting msg #$f_msg in folder $f_fold\n";
|
||||||
|
$from->delete_message($f_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stats();
|
||||||
|
|
||||||
|
sub stats {
|
||||||
|
print "Detected $error errors\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub get_options
|
||||||
|
{
|
||||||
|
my $numopt = scalar(@ARGV);
|
||||||
|
my $opt_ret = GetOptions(
|
||||||
|
"debug" => \$debug,
|
||||||
|
"debugimap" => \$debugimap,
|
||||||
|
"host1=s" => \$host1,
|
||||||
|
"host2=s" => \$host2,
|
||||||
|
"port1=i" => \$port1,
|
||||||
|
"port2=i" => \$port2,
|
||||||
|
"user1=s" => \$user1,
|
||||||
|
"user2=s" => \$user2,
|
||||||
|
"password1=s" => \$password1,
|
||||||
|
"password2=s" => \$password2,
|
||||||
|
"passfile1=s" => \$passfile1,
|
||||||
|
"passfile2=s" => \$passfile2,
|
||||||
|
"folder=s" => \@folder,
|
||||||
|
"delete!" => \$delete,
|
||||||
|
"dry!" => \$dry,
|
||||||
|
"expunge!" => \$expunge,
|
||||||
|
"version" => \$version,
|
||||||
|
"help" => \$help,
|
||||||
|
);
|
||||||
|
|
||||||
|
$debug and print "get options: [$opt_ret]\n";
|
||||||
|
print "$VERSION\n" and exit if ($version) ;
|
||||||
|
usage() and exit if ($help or ! $numopt) ;
|
||||||
|
exit unless ($opt_ret) ;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub firstline {
|
||||||
|
# extract the first line of a file (without \n)
|
||||||
|
|
||||||
|
my($file) = @_;
|
||||||
|
my $line = "";
|
||||||
|
|
||||||
|
open FILE, $file or die("$! $file");
|
||||||
|
chomp($line = <FILE>);
|
||||||
|
close FILE;
|
||||||
|
$line = ($line) ? $line : "!EMPTY! $file";
|
||||||
|
return $line;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub usage {
|
||||||
|
print <<EOF;
|
||||||
|
|
||||||
|
usage: $0 [options]
|
||||||
|
|
||||||
|
Several options are mandatory.
|
||||||
|
|
||||||
|
--host1 <string> : "from" imap server. Mandatory.
|
||||||
|
--port1 <int> : port to connect. Default is 143.
|
||||||
|
--user1 <string> : user to login. Mandatory.
|
||||||
|
--password1 <string> : password for the user1. Dangerous, use --passfile1
|
||||||
|
--passfile1 <string> : password file for the user1. Contains the password.
|
||||||
|
--host2 <string> : "destination" imap server. Mandatory.
|
||||||
|
--port2 <int> : port to connect. Default is 143.
|
||||||
|
--user2 <string> : user to login. Mandatory.
|
||||||
|
--password2 <string> : password for the user2. Dangerous, use --passfile2
|
||||||
|
--passfile2 <string> : password file for the user2. Contains the password.
|
||||||
|
--folder <string> : sync only this folder
|
||||||
|
--folder <string> : and this one.
|
||||||
|
--folder <string> : and this one, etc.
|
||||||
|
--delete : delete messages in "from" imap server after
|
||||||
|
a successful transfert. useful in case you
|
||||||
|
want to migrate from one server to another one.
|
||||||
|
With imap, delete tags messages as deleted, they
|
||||||
|
are not really deleted. See expunge.
|
||||||
|
--expunge : expunge messages on both account.
|
||||||
|
expunge delete messages marked deleted.
|
||||||
|
--dry : do nothing, just print what would be done.
|
||||||
|
--debug : debug mode.
|
||||||
|
--debugimap : imap debug mode.
|
||||||
|
--version : print sotfware version.
|
||||||
|
--help : print this.
|
||||||
|
|
||||||
|
Example: to synchronise imap account "foo" on "imap.truc.org"
|
||||||
|
to imap account "bar" on "imap.trac.org"
|
||||||
|
|
||||||
|
$0 \\
|
||||||
|
--host1 imap.troc.org --user1 foo --passfile1 /etc/secret1 \\
|
||||||
|
--host2 imap.trac.org --user2 bar --passfile2 /etc/secret2
|
||||||
|
|
||||||
|
|
||||||
|
$rcs
|
||||||
|
imapsync copyleft is the GNU General Public License.
|
||||||
|
EOF
|
||||||
|
}
|
3
memo
Normal file
3
memo
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
perl -mMail::IMAPClient -e ''
|
||||||
|
|
124
tests.sh
Normal file
124
tests.sh
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# $Id: tests.sh,v 1.1 2003/03/12 23:14:45 gilles Exp gilles $
|
||||||
|
|
||||||
|
# $Log: tests.sh,v $
|
||||||
|
# Revision 1.1 2003/03/12 23:14:45 gilles
|
||||||
|
# Initial revision
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
#### Shell pragmas
|
||||||
|
|
||||||
|
exec 3>&2
|
||||||
|
#set -x # debug mode. See what is running
|
||||||
|
set -e # exit on first failure
|
||||||
|
|
||||||
|
#### functions definitions
|
||||||
|
|
||||||
|
echo3() {
|
||||||
|
#echo '#####################################################' >&3
|
||||||
|
echo "$*" >&3
|
||||||
|
}
|
||||||
|
|
||||||
|
run_test() {
|
||||||
|
echo3 "#### $test_count $1"
|
||||||
|
$1
|
||||||
|
if test x"$?" = x"0"; then
|
||||||
|
echo "$1 passed"
|
||||||
|
else
|
||||||
|
echo "$1 failed" >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_tests() {
|
||||||
|
for t in $*; do
|
||||||
|
test_count=`expr 1 + $test_count`
|
||||||
|
run_test $t
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#### Variable definitions
|
||||||
|
|
||||||
|
prog=imapsync
|
||||||
|
host1=localhost
|
||||||
|
host2=localhost
|
||||||
|
passfile1=/var/tmp/secret1
|
||||||
|
passfile2=/var/tmp/secret2
|
||||||
|
user1=toto@est.belle
|
||||||
|
user2=titi@est.belle
|
||||||
|
|
||||||
|
dirtest=/tmp/${prog}/test
|
||||||
|
|
||||||
|
test_count=0
|
||||||
|
|
||||||
|
##### The tests functions
|
||||||
|
|
||||||
|
perl_syntax() {
|
||||||
|
perl -c ./${prog}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
no_args() {
|
||||||
|
./${prog}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleaning_test_directory() {
|
||||||
|
test -d $dirtest && find $dirtest -type d| xargs chmod 700
|
||||||
|
rm -rf $dirtest
|
||||||
|
mkdir -p $dirtest
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
first_sync() {
|
||||||
|
./imapsync \
|
||||||
|
--host1 $host1 --user1 $user1 --passfile1 $passfile1 \
|
||||||
|
--host2 $host2 --user2 $user2 --passfile2 $passfile2
|
||||||
|
}
|
||||||
|
|
||||||
|
loulplume() {
|
||||||
|
if test X`hostname` = X"plume"; then
|
||||||
|
echo3 Here is plume
|
||||||
|
./imapsync \
|
||||||
|
--host1 loul --user1 tata --passfile1 /var/tmp/secret.tata \
|
||||||
|
--host2 plume --user2 tata@est.belle --passfile2 /var/tmp/secret.tata
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
plumeloul() {
|
||||||
|
if test X`hostname` = X"plume"; then
|
||||||
|
echo3 Here is plume
|
||||||
|
./imapsync \
|
||||||
|
--host1 plume --user1 tata@est.belle --passfile1 /var/tmp/secret.tata \
|
||||||
|
--host2 loul --user2 tata --passfile2 /var/tmp/secret.tata
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# mandatory tests
|
||||||
|
|
||||||
|
run_tests perl_syntax
|
||||||
|
|
||||||
|
# All tests
|
||||||
|
|
||||||
|
test $# -eq 0 && run_tests \
|
||||||
|
no_args \
|
||||||
|
first_sync \
|
||||||
|
loulplume \
|
||||||
|
plumeloul
|
||||||
|
|
||||||
|
# selective tests
|
||||||
|
|
||||||
|
test $# -gt 0 && run_tests $*
|
||||||
|
|
||||||
|
# If there, all is good
|
||||||
|
|
||||||
|
echo3 ALL $test_count TESTS SUCCESSFUL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue