text:
User Migration: Difference between revisions
|Line 1,233:
|Line 1,233:
|Line 1,266:
|Line 1,271:
== Migrating from Maildir ==
== Migrating from Maildir ==
Revision as of 18:18, 29 October 2008
It has been suggested to break out this page into seperate pages in the migration category. Thoughts? Talk page[1]
Migration from one mail system to another is often painful. It can result in a user having to look in two different places to find mail, or in the worst case mail disappearing.
Copying the contents of one mail system to another often seems like a good idea, that way if anything goes wrong at least the old mail is still available. Ideally you know exactly what you are going to do at the start, you move everything across, and then you kill the old mail system (or at least hide it from mail clients). That way users are not confused by having two sets of identical folders.
In reality, you may have a period of overlapping mail servers. After user data has been migrated to Zimbra, users can access their mail via the web client without any additional setup until their mail client has been configured to access the Zimbra server.
Migrating Mail
Bulk Creating the Accounts
The first step in migrating users is to create the accounts, this is a topic of its own at Bulk Create
Migrating from an existing IMAP server (Recommended Method)
Currently, the recommended method for migrating users to Zimbra from an existing IMAP server is with the imapsync tool written by Gilles Lamiral. When in doubt, please refer to the documentation for your version of imapsync for up-to-date options and settings.
The following guide to imapsync was originally posted to the forums by GertThiel:
Before you can use imapsync you must have both the source IMAP message store and ZCS up running and accessible to user accounts via IMAP. You can check that using an email client before starting the migration. You will need the login names (i.e. email addresses) and passwords for the users to be migrated. In addition, imapsync will not be able to authenticate to the Zimbra server until you enable clear text login for the IMAP service. You can set that option under the IMAP tab of the Global Settings or individual Server settings in the Zimbra Admin Console UI. There are also a few Perl module dependances, including; Digest::MD5, IO::Socket::SSL,Term::ReadKey, Digest:HMAC libmail:imapclient. You can install these with your favorite package manager, from RPM's or with cpan. Finally, consider that imapsync will be a heavy load on your CPU and memory; the system running the migration will be less responsive.
Imapsync will run faster and consume less CPU with larger I/O buffers. The default is only 4KB; increasing it by one or two orders of magnitude is recommended for typical Zimbra-ready configurations. Examples below use 8MB buffer size.
For this example my existing IMAP server is running on server.gtds.lan and I set up Zimbra on a new machine named zimbra.gtds.lan.
imapsync --buffersize 8192000 --nosyncacls --subscribe --syncinternaldates \ --host1 server.gtds.lan --user1 yourAccount --password1 yourPassword \ --host2 zimbra.gtds.lan --user2 yourZimbraAccount --password2 yourZimbraPassword
Of course the complete command belongs on one line (signified by the backslashes: \).
A slightly more secure method is to write each password into a separate file, and then use the --passfile{1|2} options intead of the --password{1|2} options:
imapsync --buffersize 8192000 --nosyncacls --subscribe --syncinternaldates \ --host1 server.gtds.lan --user1 yourAccount --passfile1 yourPasswordFile \ --host2 zimbra.gtds.lan --user2 yourZimbraAccount --passfile2 yourZimbraPasswordFile
If your old IMAP server doesen't support NAMESPACE you have to also add appropriate options for example on iMail 6.0 --sep1 . --prefix1 INBOX. are required.
If you receive this error (and using the above command line you are pretty much guaranteed to): NO CAPABILITY for AUTHENTICATE LOGIN from your Zimbra server please add the switch --noauthmd5 to the end of your very long command line.
Your destination account on the Zimbra server should also have Clear Text Login enabled. You can enable this under the administration GUI in the Configuration menu, under Servers, in the IMAP tab of your server. Click the checkbox. It is assumed your source server also has Clear Text login enabled, but to do that please read the documentation of your respective server.
You may interrupt imapsync at any time with CTRL-C. Simply restart the same command again to resume the migration. You can also run it more than once to sync changes for a staged migration. Imapsync will not copy the same data twice, so you do not have to be concerned about duplicate messages.
I used imapsync to migrate from a Cyrus IMAPd to Zimbra. The ReadMe lists a number of other IMAP servers compatible with imapsync.
script to download and build imapsync and all of the required packages
#!/bin/bash # #CopyLeft 2006 Steve Fink #stevef-at-ublug.org # #This script will get all of #the necessary packages to #build imapsync 1.219 except OpenSSL #OpenSSL & it's development libraries are #required and OpenSSL is usually installed #already so check and get the matching libraries # #you have to run this script as root #or under sudo so it can do all the installs # #I don't recommend doing the extended tests #they mostly fail anyway but imapsync still works mkdir imapsync cd imapsync # wget http://search.cpan.org/CPAN/authors/id/D/DC/DCONWAY/Parse-RecDescent-1.94.tar.gz tar xvfpz Parse-RecDescent-1.94.tar.gz rm Parse-RecDescent-1.94.tar.gz cd Parse-RecDescent-1.94/ perl Makefile.PL make make install # cd .. wget http://search.cpan.org/CPAN/authors/id/G/GA/GAAS/Digest-MD5-2.33.tar.gz tar xvfpz Digest-MD5-2.33.tar.gz rm Digest-MD5-2.33.tar.gz cd Digest-MD5-2.33/ perl Makefile.PL make make install # cd .. wget http://search.cpan.org/CPAN/authors/id/J/JS/JSTOWE/TermReadKey-2.30.tar.gz tar xvfpz TermReadKey-2.30.tar.gz rm TermReadKey-2.30.tar.gz cd TermReadKey-2.30/ perl Makefile.PL make make install # cd .. wget http://search.cpan.org/CPAN/authors/id/A/AS/ASPA/IO-Socket-SSL-0.81.tar.gz tar xvfpz IO-Socket-SSL-0.81.tar.gz rm IO-Socket-SSL-0.81.tar.gz cd IO-Socket-SSL-0.81/ perl Makefile.PL make make install # cd .. wget http://search.cpan.org/CPAN/authors/id/F/FL/FLORA/Net_SSLeay.pm-1.30.tar.gz tar xvfpz Net_SSLeay.pm-1.30.tar.gz rm Net_SSLeay.pm-1.30.tar.gz cd Net_SSLeay.pm-1.30/ ./Makefile.PL -t make install # cd .. wget http://search.cpan.org/CPAN/authors/id/D/DJ/DJKERNEN/Mail-IMAPClient-2.2.9.tar.gz tar xvfpz Mail-IMAPClient-2.2.9.tar.gz rm Mail-IMAPClient-2.2.9.tar.gz cd Mail-IMAPClient-2.2.9/ perl Makefile.PL make make test make install # cd .. wget http://www.linux-france.org/prj/imapsync/dist/imapsync-1.219.tgz tar xvfpz imapsync-1.219.tgz rm imapsync-1.219.tgz cd imapsync-1.219/ perl -c imapsync make install # cd .. cd .. rm -Rf imapsync/
Save this script as buildimapsync, chmod 755 buildimapsync, sudo buildimapsync. Note that common build tools, such as make and a C compiler must be available.
Note: see Talk:User_Migration if you're having problems with the imapsync source.
Note: The current version (as of 2007 05 22) of imapsync is 1.219. If that last wget command returns 404 Not Found, check the parent folder for a newer version.
Note: The linux-france.org server has been unreachable for a very long time. Try a mirror site (v1.217) or (v1.223) if the link above does not work.
If you use version 1.223, once installed change line 1163 of /usr/bin/imapsync to this:
$d = UnixDate(ParseDate($d), "%d-%b-%Y %H:%M:%S %z");
(Thanks to Spremeau in the message boards for this tip)
Enabling Emails With Large File Attachments (Zimbra IMAP Max Size is 10mb)
The default Zimbra IMAP maximum email size is 10mb. This will cause errors to be raised during the imapsync for emails which are larger than 10mb. Errors such as the following will be displayed in the imapsync log.
+ Copying msg #131:11690588 to folder Folders/Projects/Consulting flags from : [\Seen]["16-Jul-2007 14:57:35 +1000"] Couldn't append msg #131 (Subject:[RE: Consultancy Approval]) to folder Folders/Projects/Consulting: 5160 BAD parse error: request too long
+ Copying msg #87598:54935762 to folder INBOX flags from : [\Seen]["08-Feb-2008 14:09:05 -0500"] Couldn't append msg #87598 (Subject:[Re: photos]) to folder INBOX: 894 NO [TOOBIG] request too long
The Zimbra IMAP server uses zimbraFileUploadMaxSize to set the max size. The default is 10mb if it's not set. At this time the only way to set it is via the command line.
Use the following command as the zimbra user to increase to 50mb:
zmprov mcf zimbraFileUploadMaxSize 50000000
Then restart the mailboxd server process.
For more details see this thread, http://www.zimbra.com/forums/developers/1461-max-imap-message-size.html
UPDATE: Since Zimbra 5.0.6 the parameter has changed to zimbraMtaMaxMessageSize:
zmprov mcf zimbraMtaMaxMessageSize 50000000
See this bug report http://bugzilla.zimbra.com/show_bug.cgi?id=27610
imapsync over SSL
You can use SSL connections with imapsync providing "--ssl1" and/or "--ssl2" (and the "--port1 and/or --port2" if defaults are different) for each of the accounts you wish to migrate.
For example:
[root@freebsd ~]# imapsync \ --buffersize 8192000 --nosyncacls --subscribe --syncinternaldates \ --host1 oldmail.mydomain.com --user1 user1 --password1 secret1 --ssl1 \ --port1 993 \ --host2 zimbra.mydomain.com --user2 user2 --password2 secret2 --ssl2 \ --port2 993 \ --noauthmd5
Installing imapsync on FreeBSD 6.2:
1. Installing the binary:
[root@freebsd ~]# pkg_add -r imapsync
2. Installing the port (from latest sources):
[root@freebsd ~]# cd /usr/ports/mail/imapsync [root@freebsd ~]# make install clean
Make sure you have updated your ports with portsnap. If you are updating your ports for the first time:
[root@freebsd ~]# portsnap fetch [root@freebsd ~]# portsnap extract
More details on how to use portsnap:
The following version worked for me using option 2 above:
Mail::IMAPClient version is 2.2.9 and imapsync version 1.223 2007/10/30
Installing imapsync on Ubuntu 7.10:
[user1@ubuntu:~]$ sudo apt-get install imapsync
The command above will automatically build imapsync. You should be able to use the command above to accomplish an imapsync over SSL migration.
The following version worked for me on Ubuntu 7.10:
Mail::IMAPClient version is 2.2.9 and imapsync version 1.219 2007/04/04
NOTE: imapsync will not be able to authenticate to ZCS until you "Enable clear text login" for the IMAP service. You can set that option under Global Settings or under Servers under IMAP in the ZCS Administration Console.
Batch Proccessing
You can automate multiple users by using this script.
#!/bin/bash logfile="sinklog.txt" host1=188.8.131.52 #host1 is Source host2=321.321.321.321 #host2 is Dest domain=xyz.com #domain is where email account is #everything after @ symbol ###### Do not modify past here ####################################### date=`date +%X_-_%x` echo "" >> $logfile echo "------------------------------------" >> $logfile echo "IMAPSync started.. $date" >> $logfile echo "" >> $logfile { while IFS=';' read u1 p1; do user=$u1"@"$domain echo "Syncing User $user" date=`date +%X_-_%x` echo "Start Syncing User $u1" echo "Starting $u1 $date" >> $logfile imapsync --nosyncacls --syncinternaldates --host1 $host1 --user1 "$user" --password1 \ "$p1"--host2 $host2 --user2 "$user" --password2 "$p1" date=`date +%X_-_%x` echo "User $user done" echo "Finished $user $date" >> $logfile echo "" >> $logfile done ; } < userlist.txt date=`date +%X_-_%x` echo "" >> $logfile echo "IMAPSync Finished.. $date" >> $logfile echo "------------------------------------" >> $logfile
Now create a CSV file with the user names and passwords in the following format.
user;password user2;password2
Here is a second batch script that will allow different usernames on the Source and Destination servers. Name this file imapsyncbatch then chmod to 755 execute with ./imapsyncbatch can be used with the --dry option for a dry run.
#!/bin/bash ##Modified by Steve Fink stevef-at-ublug.org ##This IMAPSync Batch Script is used when you have different ##usernames on the Source and Destination servers ##(kinda what IMAPSync was intended for) ##the format for the user-list.csv file is ##sourceusername,sourcepassword,destinationusername,destinationpassword ## Get the info while [ -z $infile ]; do echo "What is the path to the input file?" read infile done while [ -z $host1 ]; do echo "What is the Source Host? (mail1.domain.com)" read host1 done while [ -z $host2 ]; do echo "What is the Destination Host? (mail2.domain.com)" read host2 done while [ -z $domain ]; do echo "What is the Domain? (domain.com)" read domain done while [ -z $logfile ]; do echo "Where would you like the log? (synclog.txt)" read logfile done if [ ! -f $infile ] then { echo "The input file does not exist!" echo "" echo "What is the path to the input file?" read infile } fi INPUTFILE=$infile clear echo "" echo "" echo "IMAPSync is about to begin using:" echo "Input File $INPUTFILE" echo "Source Host $host1" echo "Destination Host $host2" echo "Domain $domain" echo "Log File $logfile" echo "" echo "" echo "Is this information correct?" echo "Press Enter to continue or" echo "Hit CTRL+C to start over" read wait ## Begin IMAPSync date=`date +%X_-_%x` echo "IMAPSync Logfile started @ $logfile" echo "" >> $logfile echo "------------------------------------" >> $logfile echo "IMAPSync started.. $date" >> $logfile echo "" >> $logfile #Get rid of the commas tr "," " " <$INPUTFILE | while read u1 p1 u2 p2 do user=$u1"@"$domain user2=$u2"@"$domain echo "Syncing User $user to $user2" date=`date +%X_-_%x` echo "Start Syncing User $user to $user2" echo "Starting $u1 $date" >> $logfile imapsync $1 --nosyncacls --syncinternaldates \ --exclude "#KnownSpam" --exclude "#FalsePositives" \ --exclude "Trash" --exclude "Deleted Items" \ --exclude "Deleted Messages" --exclude "Deleted" \ --exclude "Sent" --exclude "Sent Items" \ --exclude "Sent Messages" \ --host1 $host1 --user1 "$user" --password1 "$p1" \ --host2 $host2 --user2 "$user2" --password2 "$p2" date=`date +%X_-_%x` echo "User $user to $user2 done" echo "Finished $user to $user2 $date" >> $logfile echo "" >> $logfile done date=`date +%X_-_%x` echo "" >> $logfile echo "IMAPSync Finished.. $date" >> $logfile echo "------------------------------------" >> $logfile
The format for the .csv file for this script is: sourceusername,sourcepassword,destinationusername,destinationpassword
Batch processing without knowing the passwords
In the case your authentication backend stores user password in encrypted format and you don't know them, you may have the possibility to add a second authentication backend with the same users but a password of your choice.
During a cyrus imap to zimbra migration, here's how it worked :
- temporary openldap installed on third server, provisioned with the list of accounts to be migrated
- zimbra's external authentication configured with this ldap server (you can use 2 different ldap urls, only bind account must be the same)
- cyrus imap was already set up to use pam_ldap, which did not manage well the presence of 2 different ldap servers for authentication (if the official ldap server denied authentication, the second wasn't used)
- if cyrus imap relies on pam_ldap, you can switch to pam_mysql for example. Create a database, table with login and password, and feed...
With that in place, you can keep your cyrus and zimbra server running with no change for the users, but synchronize with the scripts showed above.
Migrating from POP3
pop2imap is a tool used to get a pop inbox and syncronise it to an IMAP folder. You can get it from [2]
It is very similar to imapsync above.
pop2imap \ --host1 some.pop.com.au --user1 yourAccount --passfile1 yourPasswordFile \ --host2 zimbra.imap.com.au --user2 yourZimbraAccount --passfile2 yourZimbraPasswordFile \ --folder MyOldPOPMail
Will copy the INBOX on your pop account to MyOldPOPMail folder.
There are some problems with pop2imap though.
- It will not create the folder, you must have that manually created
- It does not support SSL, however this is easy to do with "stunnel" - providing the SSL tunnel to the server
- It downloads all of the messages first to get headers, although some pop servers do this well, many do not and this is a very time consuming operation. Modifications to the script are simple to skip this step and force a copy of the mail (technically no longer a sync, but a straight copy).
Also check this out... http://www.athensfbc.com/imap_tools/ it has batch mode with lists built in for all activities...POP3-IMAP, IMAP-IMAP...
Migrating from Dovecot
See User_Migration_From_Dovecot_With_External_LDAP
Migrating from iMail
The first step is to export the users information including the password. I used this utility for CommuniGate Pro which creates a fixed length file. I then coverted it to a Tab-Delimited file with this utility so that I could use the Bulk Create process. After you create your Domains and provision the accounts, turn on IMAP4 for iMail and use the IMAP migration process.
Migrating from Exchange
There are a least two ways to migrate the content of the individual MS Exchange user. First, is to use the Zimbra Migration Wizard. Second, is to export the contents of the MS Exchange folders to a .pst file and import them using the Zimbra PST Import Wizard. A third option is to export the MS Exchange data to a .pst file and restore it once the Zimbra profile is created for a corresponding Zimbra user either through the Zimbra Connector for Outlook or through IMAP.
See forums: Migration from Exchange
Information on using the Zimbra Exchange Migration Wizard can be found in the Migration Wizard for Exchange Installation Guide.
Migrating from Kerio Mail Server
Only mail can be migrated at the moment. Refer to "Migrating from an existing IMAP server" for instructions on how to setup imapsync.
Using the following imapsync command to migrate emails from a single user to zimbra
perl imapsync --buffersize 8192000 --nosyncacls --subscribe --syncinternaldates \ --host1 kerio.host.com --user1 firstname.lastname@example.com --password1 keriopasswd --sep1 "/" --prefix1 "" \ --host2 zimbra.host.com --user2 firstname.lastname@example.com --password2 zimbrapasswd
Migrating from Outlook
If you are using the Outlook email client without Exchange, you can import the local mail folders directly into Zimbra with the PST Import Wizard. Information on using the PST Import Wizard can be found in the Import Wizard for Outlook Guide.
Migrating from MBOX files
The MBOX file format is commonly used by many programs, most notably sendmail. The advantage of migrating from MBOX files is that no passwords or special accounts are needed. The following perl script will forward from an MBOX file to the designated address, while preserving attachments:
#!/usr/bin/perl use strict; use Email::Folder; use Mail::Mailer; use MIME::Parser; use Net::SMTP; my $mbox = $ARGV[0]; my $email = $ARGV[1]; my $server = $ARGV[2]; $server = 'smtp' if(!defined($server)); die "Usage: $0 mbox dest_address [smtp server]" if(!defined($mbox) || !-f $mbox); die "Usage: $0 mbox dest_address [smtp server]" if(!defined($email) || $email !~ m/\@/); my $folder = Email::Folder->new($mbox || die "Usage: $0 mbox dest_address [smtp server] Forward all mail found in mail file mbox to address. "); my $count=0; my @messages=$folder->messages; my $total=@messages; foreach (@messages){ $count++; my $parser = new MIME::Parser; $parser->output_under("/tmp"); $parser->decode_headers(0); $parser->ignore_errors(1); my $entity = $parser->parse_data($_->as_string); my $header = $entity->head; my $sender = $entity->head->get('From'); next if $header->get("subject") =~ m/FOLDER INTERNAL/; $header->replace('To', $email); $header->delete('Received'); $header->delete('MIME-Version'); $header->delete('Return-Path'); $header->delete('User-Agent'); $header->delete('Message-ID'); $header->delete('X-Mailer'); $header->delete('X-Security'); $header->delete('X-Spam-Checker-Version'); $entity->head($header); $entity->sync_headers; print "Message $count / $total\n"; print "Sending message with subject: " . $entity->head->get("subject"); print " to $email via $server\n"; my $smtp = new Net::SMTP($server) or die "No mailserver"; $smtp->mail($sender) or die "unable to set sender"; $smtp->to($email) or die "unable to address message"; $smtp->data() or die "unable to start data send"; $smtp->datasend($entity->as_string()) or die "Message send failed"; $smtp->dataend() or die "Message end failed"; $smtp->quit(); print "Done\n\n"; }
You will need the following CPAN packages: * Mail::IMAPClient to generate the folders and add the messages * Mail::Box::Mbox to read the messages from the mbox files * Mail::Message::Convert::MailInternet to get the Mail::Message objects into RFC 822 format * File::Find to make it easy to download the whole thing
#!/usr/bin/perl # # mbox2imap.pl # # Perl script to migrate a Kmail mbox store to IMAP. Change check_file for evolution # # Copyright 2005 Marco R. Gazzetta # 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. # # contact the author directly for more information at: # marcog AT pobox com # http://diva.homelinux.org # use File::Find; use Mail::IMAPClient; use Mail::Box::Mbox; use Mail::Message::Convert::MailInternet; my $cache = "$ENV{HOME}/.mailboxes"; my %folders = (); if (-e $cache) { open CACHE, $cache; while (<CACHE>) { chomp; @array = split /\|/; $folders{$array[0]} = $array[1]; } } else { # First, get the local folders find(\&check_file, "$ENV{HOME}/Mail"); open CACHE, "> $cache"; for (sort keys %folders) { print CACHE "$_|$folders{$_}\n"; } } sub check_file { # the regex checks for files whose name does NOT start with a dot # notice that File::Find sets $_ to the file name, while $File::Find::name # is with path if (!/^\..*/) { my $file = $File::Find::name; my $name = $File::Find::name; # delete non-kmail part of name $name =~ s/\/[^.]+\//\//g; # now normalize the directories $name =~ s/\/\.([^\/]+)\.directory\//\/$1\//g; # replace the directory artifacts $name =~ s/\/\.([^\/]+)\.directory\//\/$1\//g; # twice, because the first regex gets only half the line $name =~ s/\//./g; # replace all slashes with dots $name =~ s/\./_/g; # replace all dots with underscores $folders{"INBOX$name"} = $file; } } # open connection my $imap = Mail::IMAPClient->new( Server => 'server.domain.com', User => 'marco', Password => 'supersecret') || die "Could not connect to IMAP server.\n"; # push all messages in all folders (sorting is only so that a folder is created before the subfolders) for $f (sort keys %folders) { my $l = $folders{$f}; if (!$imap->exists($f)) { print "WARNING: Creating folder " . $f . " since it does not exist on the server.\n"; $imap->create($f) or print "ERROR: Could not create folder.\n"; } # Now copy all files from the local store to the IMAP store my $box = Mail::Box::Mbox->new("folder" => $l); my $conv = Mail::Message::Convert::MailInternet->new; print $f . ": " . $imap->message_count($f) . "\n"; # debug output only my $count = 1; foreach ($box->messages()) { $imap->append($f, $conv->export($_)->as_string()); # as_string ensures RFC 822 format print $count++ . "\n"; } print $f . ": " . $imap->message_count($f) . "\n"; } $imap->close();
A python solution that I found to be easier to install (required no extra installation on Centos 4.4) was the mbox2imap script found at: http://people.cs.uchicago.edu/~brendan/scripts/mbox2imap . Here is a modified version that adds the ability to pass the imap password on the command line:
#!/usr/bin/env python # Upload mbox format email to an IMAP server ######################################################################## # Libraries ######################################################################## import email, email.Errors, mailbox, imaplib, getpass, sys, getopt import os.path, StringIO, re ######################################################################## # Configuration defaults ######################################################################## # Store configuration in a dictionary so that we need only one argument # to "global" in funtions to reference all the values. # config = {} # Set defaults # config['self'] = os.path.basename(sys.argv[0]) config['verbose'] = 5 # "notice"; Syslog-style priority level config['user'] = getpass.getuser() config['imapmailbox'] = 'INBOX' config['imapserver'] = 'laime.cs.uchicago.edu' config['recursive_mode'] = 0 config['passwd'] = '' ######################################################################## # Functions ######################################################################## def main(): output('info', 'main(): starting') global config process_options() if config['recursive_mode'] == 1: output('debug', 'main(): about to run recursive_upload()') recursive_upload() else: output('debug', 'main(): about to run single_upload()') single_upload() output('info', 'main(): completed') ######################################################################## # Log in to the IMAP server and return an object representing the # authenticated session # def login(): output('info', 'login(): starting') global config print "%s: Authenticating to IMAP server" % config['self'] server = imaplib.IMAP4_SSL(config['imapserver']) if len(config['passwd']) == 0: check_response(server.login(config['user'], getpass.getpass())) else: check_response(server.login(config['user'], config['passwd'])) return server ######################################################################## # TODO test mbox files with . in the name # TODO test both absolute and relative paths in upload # Given an mbox file path, translate it to an IMAP-style mailbox path def source2target(source): output('info', 'source2target(%s): starting' % source) target = source if re.search(r'\.', source) != None: output('warning', 'mbox file "%s" contains "." character' % source) output('warning', 'Replacing "." with "_"') target = re.sub(r'\.', '_', target) # Translate to IMAP-style path separator (replace "/" with ".") target = re.sub(r'/', '.', target) # Strip off the containing directory (up to the first "." character) target = re.sub(r'^[^\.]+.', '', target) output('info', 'source2target(%s): returning %s' % (source, target) ) return target ######################################################################## # Upload all files in a hierarchy to an IMAP server def recursive_upload(): output('info', 'recursive_upload(): starting') global config if not os.path.isdir(config['source']): output('crit', 'Argument must be a directory when using -r') output('crit', 'Given "%s")' % config['source']) sys.exit(1) source_list = build_file_list(config['source']) output('debug', 'recursive_upload(): source_list = %s' % source_list) # Need to know what to strip off when creating targets on the # IMAP server # base = os.path.dirname(config['source']) base = base + '/' target_list = source_list # If the source directory was specified as a path with more that # one component, we need to strip it down to the last componend(the # containing directory) since that is what the hierarchy on the IMAP # server will be created relative to. # target_list = map(lambda x: re.sub('^' + base, '', x), target_list) target_list = map(source2target, target_list) output('debug', 'recursive_upload(): target_list = %s' % target_list) # Want to be able to explain what is going to happen to the user # before they have to type in their password. That is why login() # is called here. # server = login() create_imap_mailboxes(target_list, server) for source in source_list: output('debug', 'recursive_upload(): source = %s' % source) target = source output('debug', 'recursive_upload(): target = %s' % target) output('debug', 'recursive_upload(): base = %s' % base) target = re.sub('^' + base, '', target) output('debug', 'recursive_upload(): target = %s' % target) target = source2target(target) output('debug', 'recursive_upload(): target = %s' % target) output('debug', 'recursive_upload(): source = %s' % source) output('debug', 'recursive_upload(): target = %s' % target) output('notice', 'Starting upload of %s to %s' % (source, target) ) upload(source, target, server) output('notice', 'Finished upload of %s to %s' % (source, target) ) output('info', 'recursive_upload(): completed') ######################################################################## def single_upload(): output('info', 'single_upload(): starting') global config source = config['source'] target = config['imapmailbox'] # Want to be able to explain what is going to happen to the user # before they have to type in their password. That is why login() # is called here. # server = login() output('notice', 'Starting upload of %s to %s' % (source, target) ) upload(source, target, server) output('notice', 'Finished upload of %s to %s' % (source, target) ) output('info', 'single_upload(): completed') ######################################################################## # Process command line options def process_options(): output('info', 'process_options(): starting') global config try: opts, args = getopt.getopt(sys.argv[1:], "i:rs:u:v:p:") except getopt.GetoptError: usage() sys.exit(1) for option, argument in opts: if option == '-i': config['imapmailbox'] = argument if option == '-r': config['recursive_mode'] = 1 if option == "-s": config['imapserver'] = argument if option == "-u": config['user'] = argument if option == "-v": config['verbose'] = argument if option == '-p': config['passwd'] = argument # Make sure desired log level is stored as an integer config['verbose'] = numeric_log_level(config['verbose']) output('debug', 'process_options(): opts = %s' % opts) output('debug', 'process_options(): args = %s' % args) # Summarize config output('debug', "process_options(): config['imapmailbox'] = %s" % config['imapmailbox'] ) output('debug', "process_options(): config['imapserver'] = %s" % config['imapserver'] ) output('debug', "process_options(): config['user'] = %s" % config['user'] ) output('debug', "process_options(): config['verbose'] = %s" % config['verbose'] ) output('debug', "process_options(): config['recursive_mode'] = %s" % config['recursive_mode'] ) if len(args) == 0: usage() sys.exit() if len(args) != 1: output('crit', 'Too many file arguments: %s' % ' '.join(args)) output('crit', 'Expecting only one; aborting') sys.exit(1) config['source'] = args[0] output('info', 'process_options(): completed') ######################################################################## # Return true if file is in mbox format def is_mbox_file(file): output('info', 'is_mbox_file(%s): starting' % file) return open(file).readline()[0:5] == 'From ' ######################################################################## # Given a directory, return a list of contained mbox files def build_file_list(node): output('info', 'build_file_list(%s): starting' % node) file_children = [] directory_children = [] for entry in os.listdir(node): if os.path.isfile(node + '/' + entry): if is_mbox_file(node + '/' + entry): file_children.append(entry) elif os.path.isdir(node + '/' + entry): directory_children.append(entry) # Add containing directory to each entry flat = map(lambda x: node + '/' + x, file_children) # Recursively process directory children for entry in directory_children: flat.extend(build_file_list(node + '/' + entry)) return flat ######################################################################## def create_imap_mailboxes(imap_mailboxes, server): output('info', 'create_imap_mailboxes(%s): starting' % imap_mailboxes) # Attempting to create a mailbox that already exists produces an # IMAP protocol error, so we only want to attempt to create a # mailbox that does not exist. To do this, we need a list of the # current mailboxes. We can get that with the list() method of the # IMAP4_SSL object, but the output it returns is formatted in a # strange way: # # (\Noinferiors) "." "INBOX" # # We need to extract the string in the INBOX location. Use map() to # iterate over the list and pull out the folder name using a regular # expression. # extract = lambda x: re.search(r'^.*"\." "(.*)"', x).group(1) current_mailboxes = server.list()[1] current_mailboxes = map(extract, current_mailboxes) for mailbox in imap_mailboxes: if not current_mailboxes.__contains__(mailbox): output('notice', 'Creating mailbox: ' + mailbox) check_response(server.create(mailbox)) ######################################################################## # Take an integer or string log level and return an integer log level # def numeric_log_level(level): # If level is an integer between 0 and 7, pass it back if range(8).__contains__(level): return(level) if level == 'debug': return(7) if level == 'info': return(6) if level == 'notice': return(5) if level == 'warning': return(4) if level == 'err': return(3) if level == 'crit': return(2) if level == 'alert': return(1) if level == 'emerg': return(0) # crit, alert, emerg: critical error, immediate termination # err: non-fatal problem # warning: possibly negative informational message # notice: neutral informational... TODO # info: function calls, arguments # debug: protocol, data details output('warning', 'Unknown log level "%s", assuming "emerg"' % level) return(0) ######################################################################## # Take an integer or string log level and return a string log level # def string_log_level(level): string_levels = ['emerg', 'alert', 'crit', 'err', 'warning', 'notice', 'info', 'debug'] # If level is already a valid string, pass it back if string_levels.__contains__(level): return(level) # If level is a string between 0 and 7, return appropriate string if range(8).__contains__(level): return(string_levels[level]) output('warning', 'Unknown log level "%s", assuming "emerg"' % level) return('emerg') ######################################################################## def output(level, message): global config if numeric_log_level(level) <= config['verbose']: print "%s: (%s) %s" % (config['self'], string_log_level(level), message) ######################################################################## # TODO def usage(): global config print '''Usage: %s [OPTION]... FILE Upload contents of mbox FILE to an SSL IMAP server. -i MAILBOX when not using -r, upload to MAILBOX (default: %s) -r recursively upload mbox files (FILE must be a directory) -s SERVER connect to SERVER (default: %s) -u USER authenticate as USER -v LEVEL set verbosity to LEVEL (syslog priority style) -p PASSWORD password for USER Note: "." characters are not allowed in IMAP mailbox names or directory names. Such characters will be converted to "_" on the server. When using -r, IMAP mailbox names will be derived from mbox file hierarchy structure. Warning: Please do not delete source mail until you have verified that it has been uploaded successfully. This tool has been written with safety in mind, but there are no guarantees. ''' % (config['self'], config['imapmailbox'], config['imapserver']) ######################################################################## def msgfactory(fp): try: return email.message_from_file(fp) except email.Errors.MessageParseError: # Don't return None since that will stop the mailbox iterator return '' ######################################################################## def check_response(response): output('info', 'check_response(): starting') r = response[0] data = response[1] output('debug', 'IMAP protocol response: %s' % str(r)) output('debug', 'IMAP protocol data: %s' % str(data)) if r != 'OK': output(1, "IMAP protocol error") output(1, "Protocol response: " + str(r)) output(1, "Diagnostic message: " + str(data)) ######################################################################## # Extract the subject from a string representing an email message def get_subject(msg_txt): output('info', 'get_subject(): starting') buffer = StringIO.StringIO(msg_txt) for line in buffer: if re.search(r'^Subject:', line): return line.rstrip() if line == '\n': # End of headers. If we reached here, there is no subject. output('warning', 'Message does not have a subject') return '' ######################################################################## ######################################################################## def check_response(response): output('info', 'check_response(): starting') r = response[0] data = response[1] output('debug', 'IMAP protocol response: %s' % str(r)) output('debug', 'IMAP protocol data: %s' % str(data)) if r != 'OK': output(1, "IMAP protocol error") output(1, "Protocol response: " + str(r)) output(1, "Diagnostic message: " + str(data)) ######################################################################## # Extract the subject from a string representing an email message def get_subject(msg_txt): output('info', 'get_subject(): starting') buffer = StringIO.StringIO(msg_txt) for line in buffer: if re.search(r'^Subject:', line): return line.rstrip() if line == '\n': # End of headers. If we reached here, there is no subject. output('warning', 'Message does not have a subject') return '' ######################################################################## def upload(from_file, to_mailbox, server): output('info', 'upload(%s, %s): starting' % (from_file, to_mailbox) ) fp = open(from_file, 'r') mbox = mailbox.UnixMailbox(fp, msgfactory) for msg_obj in mbox: msg_txt = msg_obj.as_string(unixfrom=False) subject = get_subject(msg_txt) output('notice', 'Uploading message: %s' % subject) # Regarding third argument to append, # see RFC 3501 sections 2.3.3, 6.3.11 check_response(server.append(to_mailbox, "", "", msg_txt)) ######################################################################## main()
Someone wrote a script that iterated over the mbox names, got the password from a csv file and uploaded the emails automatically using this tool. (location?)
MBOX > Maildir > Zimbra hash-dirs
If the mbox file can be converted to maildir format, you can use the zmmailbox utility to add messages to a user's mailbox. This will preserve the original time and date information, and will allow administrators to sort the mail into folders giong through IMAP.
OR zmlmtpinject
Usage for both outlined here: http://www.zimbra.com/forums/installation/12617-recover-data-store-folders.html#post64962
#!/usr/local/bin/perl # # mbox2maildir: coverts mbox file to maildir directory - the reverse of # maildir2mbox from the qmail distribution. # # Usage: mbox2maildir uses the same environment variables as maildir2mbox: # MAILDIR is the name of your maildir directory; MAIL is the name of your # mbox file; MAILTMP is ignored. MAIL is deleted after the conversion. # # WARNING: there is no locking; don't run more than one of these! you # have been warned. # # based on convert-and-create by Russell Nelson <firstname.lastname@example.com> # kludged into this by Ivan Kohler <email@example.com> 97-sep-17 require 'stat.pl'; local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; local $SIG{QUIT} = 'IGNORE'; local $SIG{TERM} = 'IGNORE'; local $SIG{TSTP} = 'IGNORE'; ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwuid($<); die "fatal: home dir $dir doesn't exist\n" unless -e $dir; &Stat($dir); die "fatal: $name is $uid, but $dir is owned by $st_uid\n" if $uid != $st_uid; chdir($dir) or die "fatal: unable to chdir to $dir\n"; $spoolname = "$ENV{MAILDIR}"; -d $spoolname or mkdir $spoolname,0700 or die("fatal: $spoolname doesn't exist and can't be created.\n"); chdir($spoolname) or die("fatal: unable to chdir to $spoolname.\n"); -d "tmp" or mkdir("tmp",0700) or die("fatal: unable to make tmp/ subdir\n"); -d "new" or mkdir("new",0700) or die("fatal: unable to make new/ subdir\n"); -d "cur" or mkdir("cur",0700) or die("fatal: unable to make cur/ subdir\n"); open(SPOOL, "<$ENV{MAIL}") or die "Unable to open $ENV{$MAIL}\n"; $i = time; while(<SPOOL>) { if (/^From /) { $fn = sprintf("new/%d.$$.mbox", $i); open(OUT, ">$fn") or die("fatal: unable to create new message"); $i++; next; } s/^>From /From /; print OUT or die("fatal: unable to write to new message"); } close(SPOOL); close(OUT); unlink("$ENV{MAIL}");
Migrating from Lotus Notes/Domino
Information on migrating from Lotus Notes/Domino to ZCS can be found in the Migration Wizard for Domino Installation Guide
Migrating User Password from Shadow Password to Zimbra
Basically we will use the hash password from /etc/shadow. Get the hash values in between the first and second colon only. Eg:
Then run this as user zimbra.
zmprov ma user1@domain userPassword '{crypt}$1$MWAOIgPB$skcX.nKYV9JSctTR60uat/'
A simple batch script to migrate bulk shadow password into zimbra password as below:
#!/usr/bin/perl # Usage: as root # ./shadow2zm.pl /etc/shadow > shadow.zm # as zimbra # zmprov < shadow.zm $domain="my.domain.com"; while(<>) { chomp; my ($uname,$pass) = split(/:/); print qq{zmprov ma $uname\@$domain userPassword '{crypt}$pass'\n}; print qq{\n}; }
Credit to bewley from this forum post
In some cases above perl script doesn't work very well. And if user doesn't already exist you will get en error. My script will import and create all users from shadow file (with exception of system accounts).
#!/bin/bash # Shadow to Zimbra import # # Created by Jarosław Czarniak on 26-10-2008 # clear echo "Usage: as \"zimbra\" user on destination server" echo "# zmprov < shadow.file" domain="jarsat.pl" # change to your domain! file="shadow.file" x=0 echo ''>$file for linia in `cat /etc/shadow` do user=`echo $linia|cut -f1 -d":"` pass=`echo $linia|cut -f2 -d":"` if [ "$pass" != "*" ] then if [ "$pass" != "!" ] then echo "zmprov ca $user@$domain temppasswordQAZXSW displayName $user">>$file echo "zmprov ma $user@$domain userPassword '{crypt}$pass'">>$file x=$[x+1] fi fi done echo echo echo "$x accounts exported to \"$PWD/$file\"" sleep 5
Migrating Users Password from Postfix Admin
Save this script as something.php, make chmod +x something.php and run. Script will export import all email account into designated file.
#!/usr/bin/php5 // Postfix.admin to Zimbra import // // Created by Jarosław Czarniak on 26-10-2008 // <? ///////////////////////////////////////////////////////// $user="mysql_login"; $pass="mysql_pass"; $base="mysql_database"; $tabl="mailbox"; //table $file="mysql.file"; ///////////////////////////////////////////////////////// echo "Usage: as \"zimbra\" user on destination server:\n"; echo "# zmprov < mysql.file\n\n"; echo ""; $mydb = mysql_connect('localhost',$user, $pass) or die ('Błąd połączenia z serwerem'); mysql_select_db($base); mysql_query("SET CHARACTER SET utf8"); mysql_query("SET NAMES utf8"); $query = "SELECT username,password,name,maildir,quota,domain FROM ".$tabl; $dane = mysql_query($query) or die ('Błąd podczas zapytania do bazy1'.mysql_error()); $handle = fopen($file, "w"); while ($row = mysql_fetch_array($dane, MYSQL_NUM)) { $StringData = "zmprov ca ".$row[0]." dsfs123hsdyfgbsdgfbsd displayName ".$row[2]."\n"; fwrite($handle, $StringData); $StringData = "zmprov ma ".$row[0]." userPassword '{crypt}".$row[1]."'"."\n"; fwrite($handle, $StringData); } ?>
Migrating from Maildir
Place this script in your /home directory (/home NOT /home/USER/ !!!) and run. Script will import all emails from "cur" and "new" directories from /home/USER/Maildir/ (and all subdirectories) into /Import IMAP folder.
#!/bin/bash # # Maildir to Zimbra import # # Created by Jarosław Czarniak on 26-10-2008 # clear chown -R zimbra:zimbra * domain="jarsat.pl" # change to your domain! IMPORT="/Import" for user in `ls -d1 */|sed s/\\\///` do echo echo "User $user" echo echo "createFolder $IMPORT" > /tmp/tmp.txt /opt/zimbra/bin/zmmailbox -z -m $user@$domain < /tmp/tmp.txt # # CUR # for sciezka in `find $user -maxdepth 10 -type d -name cur` do echo echo "Directory $sciezka" echo nazwa=`echo $sciezka|cut -f3 -d"/"|sed s/\\\.//` if [ "$nazwa" = "cur" ] then echo "addMessage ${IMPORT} $PWD/$user/Maildir/cur" > /tmp/tmp.txt /opt/zimbra/bin/zmmailbox -z -m $user@$domain < /tmp/tmp.txt else echo "createFolder ${IMPORT}/$nazwa" > /tmp/tmp.txt /opt/zimbra/bin/zmmailbox -z -m $user@$domain < /tmp/tmp.txt echo "addMessage ${IMPORT}/$nazwa ${PWD}/${sciezka}" > /tmp/tmp.txt /opt/zimbra/bin/zmmailbox -z -m $user@$domain < /tmp/tmp.txt fi done # # NEW # for sciezka in `find $user -maxdepth 10 -type d -name new` do echo echo "Directory $sciezka" echo nazwa=`echo $sciezka|cut -f3 -d"/"|sed s/\\\.//` if [ "$nazwa" = "new" ] then echo "addMessage ${IMPORT} $PWD/$user/Maildir/new" > /tmp/tmp.txt /opt/zimbra/bin/zmmailbox -z -m $user@$domain < /tmp/tmp.txt else echo "createFolder ${IMPORT}/$nazwa" > /tmp/tmp.txt /opt/zimbra/bin/zmmailbox -z -m $user@$domain < /tmp/tmp.txt echo "addMessage ${IMPORT}/$nazwa ${PWD}/${sciezka}" > /tmp/tmp.txt /opt/zimbra/bin/zmmailbox -z -m $user@$domain < /tmp/tmp.txt fi done done
Migrating Contacts and Calendar
If your mail migration strategy doesn't cover contacts and calendar, you can import via the REST (REpresentational State Transfer) [3] interface. (Currently, contacts and calendar are only imported with the Exchange migration tool and the PST Import Wizard, so this applies to most IMAP migrations).
Procedure Overview
The basic procedure is this:
- Export calendar or contact data from your existing server into a csv or ics file
- Migrate that data file to a host that can access the zimbra server
- Use the REST interface to insert the data into Zimbra
REST overview
Today, within the Zimbra Collaboration Suite we have a number of different server-side URLs that our client accesses to download an attachment, export contacts as CSV, export a calendar as an ICS, file etc. We are also adding sharing (what would collaboration be without sharing, after all) of calendars, contacts, etc. Not only within a particular Zimbra community, but between Zimbra communities and the public at large.
In order to facilitate this, we are coming up with a clean, consistent URL interface to all our resources. The best way to describe this is with some examples.
Lets say I want access to my calendar folder from within iCal. The URL would look like:
The default format on calendar folders is ICS, so no need to specify the format.
Lets say I want to export my contacts folder so I can import them into another account:
Contact folders have a default type of CSV, so like calendars, no need to specify the format.
How about an RSS feed of unread messages in my inbox:
By specifying an extension of ".rss" on the inbox folder, the server will automatically generate an RSS feed on it. Adding the "query" parameter lets me further refine what gets returned. You can also specify "?fmt=rss" instead of using the ".rss" extension if you'd like. You can also use the encoding for double quotes, %22 (For example, inbox.rss?query=%22is:unread%22)
Lets do something a little more interesting. How about a zip file containing all messages in my talks/ajax folder:
The server zips them all up and returns the zip file.
Another interesting example is say you have created a public calendar that you want to share with everyone. Once you have granted access to the calendar, it is up to the consumer to chose what format they want to view it in:
http://server/zimbra/user/roland/calendar/talks.ics http://server/zimbra/user/roland/calendar/talks.html?view=month http://server/zimbra/user/roland/calendar/talks.atom http://server/zimbra/user/roland/calendar/talks.xml http://server/zimbra/user/roland/calendar/talks.txt
How about accessing another user's calendar/folder? Once they grant you access, you can use the same exact syntax:
One last interesting example to leave you with. Lets say you have a friend at widgets.com who you know is running Zimbra and who has shared their calendar with you, but you don't know the name of their public Zimbra server. As long as they publish some DNS SRV records for _zimbra._tcp.widgets.com, then you can access it directly from your Zimbra without needing to know his server's address:
This last format (email@example.com) is also necessary when accessing resources in a non-default domain on your local Zimbra server.
REST file formats
Format Types
We are supporting a number of different "formats" for returned data. The formats we currently have implemented are:
|For generating an ATOM feed of mail messages and calendar appts.
|For exporting contacts.
|For exporting calendar appointments. See RFC 2445.
|Calendar free/busy data. See RFC 2445.
|Default formatter used to output messages and attachments in their "native" format. Used by the web client to reference attachments for downloading.
|For generating an RSS feed of mail messages and calendar appts.
|Similar to the native formatter, used by sync clients to retrieve raw message data, along with some extra meta-data in the HTTP header (tags, flags, received date).
|For exporting vcard files (vcard 3.0)
|For exporting a set of messages (folder or search result) as a ZIP file.
Time Range Specifications
The time range can be specified in a number of different formats:
- (milliseconds UTC)
- {relative dates}
relative dates are either in the future (p/+/{not-specified}) or the past (m/-), along with a numeric value, followed by the units.
For units, everything after the first character is ignored (except for the "mi" case):
- m(onths)
- mi(nutes)
- d(ays)
- w(eeks)
- h(ours)
- y(ears)
|1 day from now
|2 days from now
|1 day from now
|2 days ago
|60 minutes from now
|1 week from now
|6 months from now
|1 year from now
The start/end query parameters apply to the atom, ics, rss, and ifb formatters.
Format Examples
Returns an Atom feed for all messages in the inbox. If you only want unread messages as part of the feed, you could include a search query:
You can also request an Atom feed of a calendar folder as well:
Note that "calendar" is the pathname to the folder called "calendar", it isn't a special-cased pathname. If you had a calendar folder called "talks", then you can access that folder via:
When used with a calendar folder, the Atom feed will (by default) generate a feed of all appointments -/+ 7 days from the current time. To specify a different time range, you can use the start/end query parameters:
Exports all contacts in the contacts folder. If you want to export only contacts tagged "zimbra", you can specify a query:
This will only export contacts that are tagged with "zimbra".
Will export all appointments in the calendar folder in the ICS format, suitable for import into a calendar client such as Apple's iCal, or Mozilla's Sunbird calendar client.
Will export the free/busy data in the calendar folder for the next 60 days. Note that this is the free/busy data for the calendar folder only. If someone has multiple calendar folders then you'd want to use the following URL instead:
That URL will return free/busy data across all calendars that are configured to be included in free/busy data.
The native formatter is used to request raw RFC 822 messages (for example, to implement "show original") or to down an attachment. For example, lets assume that message id 376 in my inbox is a multipart/mixed MIME message, and part 2 is an image.
The following URL (which is normally generated automatically when you are viewing your mail and click on an attachment), would download that attachment and display it in your browser:
Lets say part 3 in that same message is a word doc, you could display that via:
Finally, lets say you have the Network edition installed and want to view that same word doc as HTML instead of downloading the word doc and opening it up as an attachment. Adding "view=html" to the end of the URL will convert the word doc to HTML:
An upcoming release will expose this functionality directly in the web UI.
Returns an RSS feed for all messages in the inbox. All the other examples given for the Atom formatter also apply to the RSS formatter.
One further note on both the Atom and RSS formatters is that the calendar feeds provided by them currently only include the title/notes data. As soon as a more complete server-side I18N infrastructure is in place (we have been focused on the web client) the Atom/RSS feeds for calendars will be much more detailed.
The sync formatter is similar to the native formatter, with the only exception being it adds some extra meta-data to the output for sync clients.
The "vcf" formatter can export your contacts as series of vcards (vCard 3.0), or can be used to export a single contact as a vCard (to be used by the web client in a future version).
To get all your contacts as a series of vCard entries, specify "vcf" as the formatter on the GET url:
The Zip formatter allows you to request a set of messages (currently only mail messages, at some point will probably allow attachments/contacts/appts as well) returned to you as a Zip file.
For example, if you want a copy of all messages in your inbox, you could use the following URL:
If you wanted all messages across all folders that were from Ross, you could use a query that returned only those:
The zip file will consist of a set of RFC822 files, with the name of the file based on the subject of the message.
Importing into Zimbra
We've added the ability to update/create content by POST'ing content to REST urls. GETs continue to remain read only, with no side-effects (as they should be).
For example, you can POST an RFC822 formatted message to your inbox REST url to append messages to the inbox folder. Using the popular curl program, this would look like the following:
curl -u schemers:password --data-binary @/tmp/rfc822.txt https://server/service/home/schemers/inbox
Note, you currently have to use /service/home for POSTs instead of /zimbra/home, because /zimbra/home issues a redirect, which isn't allowed with POSTs. We'll be fixing that in an upcoming release.
Other items that can be updated this way are calendar appointments (ICS), and contacts (csv and the new vcf (vCard) format):
curl -u schemers:password --data-binary @/tmp/new.csv http://server/service/home/schemers/contacts?fmt=csv
curl -u schemers:password --data-binary @/tmp/new.ics http://server/service/home/schemers/calendar?fmt=ics
curl -u schemers:password --data-binary @/tmp/new.vcf http://server/service/home/schemers/contacts?fmt=vcf
The full user name (firstname.lastname@example.com) is required when importing to resources on a non-default domain on your local Zimbra server.
NOTE - this works for resource accounts as well.
The target "contacts" in the above command corresponds to the actual folder name on the Zimbra server, rather than a service. This means that you can import to user-defined folders by specifying the appropriate target name in the command. If you have created a folder named "SharedContacts", for example, the command to import into this folder would be
curl -u schemers:password --data-binary @/tmp/new.csv http://server/service/home/schemers/sharedcontacts?fmt=csv
Migrating Contacts from Clients into Zimbra
From Eudora
1) In Eudora, select the Address Book that you wish to import to Zimbra. (Select Tools/Address Book) and then Click on the correct Book.
2) Select File/Save As, Save as type: CSV Files (*.csv) and type in an appropriate file name. Click Save
3) Open Notepad, Open the file.csv that you saved in step 2.
4) Insert the following line EXACTLY. (Must be the first line in the file.)
5) (Make sure to press enter after the above line and save and close notepad.)
6) Login to Zimbra, and go to Options/Address Book, Click Browse and select the file. Click import.
7) Select the address book to import into or select New to create new address book. Wait until box in bottom left hand corner says import complete.
Click Address Book and make sure the contacts imported.
Zimbra To Zimbra Server Migration
as a whole method
Unofficial method (work with 5.0, may work with <5.0): http://www.zimbra.com/forums/migration/22697-zimbra-zimbra-migration-script.html
Official method (only work > 5.0.9) http://www.zimbrablog.com/blog/archives/2008/09/zcs-to-zcs-migrations.html
item to item method
Here is a script that is a modification of the script above for using curl to migrate users between zimbra boxes using imap protocol. It also transfers calendars and contacts from zimbra server to zimbra server. I just started working on it and here is what i have so far. It worked on two servers i just migrated last week, i hope it helps :)
NOTE: Modified perl below: was not using IO::Scalar or File::Path so no need to use; now supports user names with "@" via wget; support for command line arguments; support for SSL imap; support for various input file separators; other samll tweaks - email@example.com
#!/usr/bin/perl use strict; use warnings; ############################################################################# # Please make changes below to suit your system and requirements # NOTE: hard code host1 & host2 - or pass in as first two parameters to script my $host1=shift; #host1 is Source my $host2=shift; #host2 is Dest # NOTE: enable ssl for imapsync my $imapsync = " -ssl1 -ssl2"; ############################## # NOTE: Do not set these here - they come from userlist.txt my $user; my $pass; my $data_file="userlist.txt"; open(DAT, $data_file) || die("Could not open file!"); while (<DAT>) { chomp; # NOTE: userlist.txt can have username@domain password (or comma, tab or |) ($user,$pass)=split(/[\|\s\t,]+/,$_); ############## open (TESTOUT, "imapsync --buffersize 18192000 --nosyncacls --subscribe --syncinternaldates --noauthmd5 --host1 $host1 --user1 $user --password1 $pass --host2 $host2 --user2 $user --password2 $pass $imapsync|"); while (<TESTOUT>){ print $_; } close TESTOUT; ### get contacts open (TESTOUT, "wget --user $user --password $pass https://$host1/zimbra/user/$user/contacts.csv --no-check-certificate|"); while (<TESTOUT>){ print $_; } close TESTOUT; ### get calendar open (TESTOUT, "wget --user $user --password $pass https://$host1/zimbra/user/$user/calendar.ics --no-check-certificate |"); while (<TESTOUT>){ print $_; } close TESTOUT; ### import calendars open (TESTOUT, "curl -u $user:$pass --data-binary \@calendar.ics https://$host2/service/home/$user/calendar?fmt=ics --insecure|"); while (<TESTOUT>){ print $_; } close TESTOUT; ### import contacts open (TESTOUT, "curl -u $user:$pass --data-binary \@contacts.csv https://$host2/service/home/$user/contacts?fmt=csv --insecure|"); while (<TESTOUT>){ print $_; } close TESTOUT; ### remove files unlink 'calendar.ics'; unlink 'contacts.csv'; ############### }
users and passwords go in a text file userlist.txt in the format: username|password.
With some versions of wget you may need to specify the username and password as command line arguements (ie --http-passwd=thepass --email@example.com) instead of in the URL (ie https://usersname:pass@theurl). If you are getting the error Bad Port, then give this a try.
Copy Calendar From One Zimbra User to Another
In this example we will export a calendar called "LPO calendar" from one user to another user and name it "LPO" in the destination account.
- Export the calendar "LPO calendar" from user SRC_USER:
[root@zimbra ~]# curl -u admin 'https://zimbra:7071/home/SRC_USER/LPO%20calendar?fmt=ics' > LPO.ics
- Adjust all the meeting organizer addresses. If you don't do this, the destination user will see the appointments, but can not edit them.
[root@zimbra ~]# cat LPO.ics | sed 's/SRC_USER@/DST_USER@/g' > LPO-dest.ics
- Create empty calendar in destination user account.
[root@zimbra ~]# su - zimbra -c 'zmmailbox -z -m DST_USER createFolder --view appointment /LPO'
- Import modified ical data into new calendar.
[root@zebra ~]# curl -u "admin" --data-binary @LPO-dest.ics 'https://zimbra:7071/home/DST_USER/LPO?fmt=ics'
Copy All Messages, Contacts, Calendars, and Mail Filters
I have written a script, which can be run in batch, to copy user data between servers or between mailboxes. This will copy contacts and calendars from every folder no just /Contacts and /Calendar. I used this script two times to copy pretty much everything important when migrating from 4.5.8 to 5.0.2. It doesn't support shared folders, task lists, documents, briefcase, and some other things (I recreated shared folders manually with zmmailbox) but support could be added given enough motivation :)
ZCS Tools currently contains these Migration scripts written in Python/Bash. These scripts are packaged as zimbraMigration-0.x and require imapsync to be installed.
Import distribution list
I wrote a simply bash script to migrate distribution lists from one Zimbra server to another it creates a provisioning script for each list.
myPath=$(pwd) /opt/zimbra/bin/zmprov gadl | while read listname; do echo "/opt/zimbra/bin/zmprov cdl $listname" > $myPath/$listname /opt/zimbra/bin/zmprov gdl $listname | grep zimbraMailForwardingAddress > $myPath/$listname.tmp cat $myPath/$listname.tmp | sed 's/zimbraMailForwardingAddress: //g' | while read member; do echo "/opt/zimbra/bin/zmprov adlm $listname $member" >> $myPath/$listname done /bin/rm $myPath/$listname.tmp done
Migrating Sieve Filter Rules
You have a few options to migrate Sieve rules. Generally you can take existing rules and then just dump them into the account attribute zimbraMailSieveScript. The server will be able to process these rules. However, if you intend to enable the client to edit the rules you will need to make sure they conform to a ZCS-specific set of characteristics. There are two ways to do this.
Using zmmailbox addFilterRule
Within the zmmailbox command there is a "addFilterRule" command. This allows you to add a named filter to a particular user. Its usage defines the parameters that ZWC can understand for editing. Given that for any migration scenario you'll likely end up parsing the rules, this will let you reconstruct the rules in a syntax ZWC understands. You will need to find a "name" for each rule. It could be as simple as "rule1", "rule2", etc.
Here's the usage for addFilterRule
[zimbra@qa03 ~]$ zmmailbox help filter
addFilterRule(afrl) add filter rule
deleteFilterRule(dfrl) add filter rule
getFilterRules(gfrl) get filter rules
modifyFilterRule(mfrl) add filter rule
header "name" is|not_is|contains|not_contains|matches|not_matches "value"
header "name" exists|not_exists
date before|not_before|after|not_after "YYYYMMDD"
size under|not_under|over|not_over "1|1K|1M"
body contains|not_contains "text"
addressbook in|not_in "header-name"
attachment exists|not_exists
fileinto "/path"
tag "/tag"
mark read|flagged
redirect "address"
Also, for add filter rule:
mbox> afrl
addFilterRule(afrl) [opts] {name} [*active|inactive] [any|*all] {conditions}+ {actions}+ -a/--after <arg> add after filter-name -f/--first add as first filter rule -l/--last add as last filter rule -b/--before <arg> add before filter-name
Each zmmailbox script invokes a Java VM (just like zmprov). So you'll want to create a script to be loaded into zmmailbox. That script would look something like
adminAuthenticate ...
selectMailbox user1 ...
addFilterRule rule1 header "from" contains "kevin" discard
addFilterRule rule2 ....
selectMailbox user2
addFilterRule ....
Then you can run it via
zmmailbox < scriptname.
Processing a Sieve script and inserting it via zmprov
Alternately you can process the existing Sieve scripts to conform to ZCS expectations and then insert the whole script via
zmprov ma account zimbraMailSieveScript ..... You'll need to restrict the entered rules to the Sieve commands as documented above (if ZWC or ZCO are expected to edit them). Each filter rule will need a comment above it; this comment is the filter's name as identified in addFilterRule. Creating one or two simple rules using the web client will give you a framework for the created rule.
Please see User Migration Troubleshooting if you are having problems migrating data to your Zimbra installation.


text:
Category:Terms of use
The Wikimedia Terms of use are a global policy applicable on all Wikimedia projects hosted by the Wikimedia Foundation. These pages on Meta-Wiki are intended for public review by the Wikimedia community, proposed updates, and archiving of discussions.
The latest official version of Wikimedia Terms of use, approved by the Wikimedia Foundation, is archived and published on its official website.
This category has only the following subcategory.
Pages in category "Terms of use"
The following 7 pages are in this category, out of 7 total.

subset: commoncrawl


text:
The Outdoor Plus Tacoma 48" Ash Concrete Top & Black Powder Coated Base Liquid Propane Fire Table with Match Lit with Flame Sense Ignition
The Outdoor Plus Tacoma 48" Ash Concrete Top & Black Powder Coated Base Liquid Propane Fire Table with Match Lit with Flame Sense Ignition
- Free Shipping on Orders Over $300
- Same-Day Order Processing
- Easy Monthly Installments Starting at 0% APR*
• Text or call 888-992-1556
• Email firstname.lastname@example.com
• Start a live chat
Our team is available to serve you 8:00 AM - 11:59 PM ET, 7 days a week.
The 48-inch Rectangular Tacoma GFRC Concrete Fire Pit is the complete addition to finalize your outdoor design with. The Outdoor Plus takes the time to ensure each Fire Pit is consistent. The Outdoor Plus prides itself on being able to cut, bend, grind, weld, powder coat its own products. The Outdoor Plus's products are produced in the USA to bring you the fastest lead moments in the industry.
The Rectangular Tacoma GFRC Concrete Fire Pit enhances any outdoor space with its unique and stylish design. Each fire pit is individually handmade. Its powder-coated aluminum construction offers durability and longevity in a variety of environments. Because of its handmade nature, slight variations in color and texture may occur. Designed and built applying for the newest technological advances in burner construction and energy conservation, this beautiful high-end fire pit is perfect for both, residential and commercial projects.
The Rectangular Tacoma GFRC Concrete Fire Pit brings simplicity and elegance to any patio or backyard. The Tempe is sure to create beautiful ambient lighting in your outdoor space. It has 24-inch 304 stainless steel burner that produces 45,000 BTUs of heat and glimmering flames. This fire pit comes with lava rock burning display but you can upgrade to fire glass (sold separately). If substituting for fire glass, 25 pounds is usually recommended. The burner is compatible with natural gas and liquid propane.
The Rectangular Tacoma GFRC Concrete Fire Pit comes with different ignition options: Match Lit or Electronic Ignition. LC Certified Match Light Ignition System that provides a simple manual ignition process that connects to your existing gas source and valve. And 12V Electronic ignition system that will relight your fire pit if the wind blows it out. The electronic ignition can be wired by your local electrician to be controlled by a light switch, pool controller (with available relay), or home automation system.
What's Included
- Fire Table
- Pan
- Burner
- Whistle Free Hose
- Gas Orifice
- Nipple
- Lava Rock
- Made in the USA
- Individually Handmade
- Durable & Long Lasting
- Material: GFRC Concrete
- 1-year warranty against manufacturing defects
- Comes with Stainless Steel Fire Pan, Burner
- Exterior Features Weather-Resistant Coating
- Includes all the Lava Rock each model holds
- Ideal for both residential and commercial projects
- Produces 40,000 BTUs flames
- Suggested Fire Glass: 25 lbs
- Burner holes are individually drilled, not punched, providing better flame performance
- Includes access door for 20lb propane tank storage.
- GFRC Top Finish: Ash, Black, Brown, Chocolate, Chestnut, Gray, Limestone, Natural Gray, Vanilla, Metallic Bronze, Metallic Copper, Metallic Pearl, Metallic Slate, Metallic Silver, Rustic Coffee, Rustic Gray, Rustic Moss Stone, Rustic White
- Base Finish: Black, Copper Vein, Gray, Java, Pewter, Silver Vein, White
- Wood Grain Textured Finish for a realistic wooden appearance
|Item Number
|UPC Code
|The Outdoor Plus
|Brand Name
|The Outdoor Plus
|GFRC Concrete
|Ash Concrete Top & Black Powder Coated Base
|Fuel Type
|Liquid Propane
|Match Lit with Flame Sense Ignition
|Hides Propane Tank
|Burner Material
|304 Stainless Steel
|Product Category
|Fire Table
|48" x 30"
|33" x 18"
Documents & Files
What our customers are saying...
Researched and ordered my fireplace from US FIreplace Store. Pricing was a fair value however, the customer service was EXCELLENT! I had an issue with the direct vent venting. I called US Fireplace and the correct items were sent out the next day AND Janessa stayed on top of my return authorization and sent me the permissions and documents I needed to return the incorrect item and no cost to me, including return shipping. Overall, I am a very satisfied customer and my fireplace looks and operates flawlessly. I am glad that I selected US FIreplace to source my direct vent fireplace. Thank you for the great service.
Monteagle, TN
I had placed an order, through Lowe's Home Improvement, for an Electric Firebox: Revillusion RBF42. Ordered 1st part of January. Was told I would have it in 3 weeks. When checking to see is it came in, was told it was delayed to 3/15. Was then told is was delayed until 4/25. Waited until 4/27 to check on it. Was then told it was now delayed until August. This firebox was going in a new Sun Room addition. I could not get my final inspection until the Firebox was installed. I went on line and googled for this same product. US Fireplace Store web site was given to me. This was on a Saturday. I call and reached a very nice man. Explain what I was look for. He checked and told me they had 30 of them in stock. I almost fell out of my chair. I clarified with him the product I was wanting. I ask how soon could I get it. He told me it would ship today. Again, was amazed. It arrived on the following Monday. What a pleasure and a relief working with US Fireplace Store and their employees. Exceed my expectations.
Thomas W.
Fort Mill, SC
Great prices, quick delivery and fast hassle free services on the issue I encountered. I had purchased an electric fireplace unit that would not fit into the existing fireplace space. With one email I was able to get the wrong fireplace refunded and picked up at my home at no extra cost and the new one I purchased and delivered free of charge. Great company.
John P.
Denvers, MA
Trusted by thousands of customers, big and small
Why US Fireplace Store
Live Chat Support
No chatbots. Speak with a human. Average response time is 48 seconds.
Easy Returns
Need to return the merchandise? We accept returns for 30 days from the date of delivery.
7 Days/Week Service
We're here to help on live chat, email & phone. 8:00 AM - 11:59 PM Eastern Time.
20,000+ Products
Best selection of hearth & heating products on the internet. Fireplaces, stoves, fire pits, heaters, log sets and more.
Pay Over Time
0% APR is available for 3 and 12- month financing.* See if you prequalify today.
Staff Picks
Check out the Staff Picks collection. See the top products selected by our team.


text:
Contact us at the Consulting WP office nearest to you or submit a business inquiry online.
Georgia governor candidate Stacey Abrams is $200,000 in debt. She's not alone
- April 2, 2018
- Posted by: elofoq
- Category: Competitive research
Bring to the table win-win survival strategies to ensure proactive domination.
Harvest great ideas from your company's best assets
- December 25, 2015
- Posted by: elofoq
- Category: Competitive research
In particular, the initial state of the company's sales and operations planning capabilities limited their ability to account for demand variability or raw material lead times in production and distribution. Improve sales and operations and production planning.
how can we help you?


text:
Shop by Popular Occasions
You and I Flowers and Gifts - Flower Delivery in Perris, CA
Why buy from us?
is yours!
will be automatically appliedin checkout.
Coupon redeemable for online
purchases only.
Valid through .
Our Lovingly Reviews
You and I Flowers and Gifts
Perris, CA 92571
Send a Beautiful Flower Arrangement in Perris Today
Shop from our wide selection of floral designs, bountiful bouquets, and other creative floral arrangements to send a meaningful gift in CA from a floral artist. Be prepared with the best gift for memorable days like Valentine's Day and Mother's Day, when deciding on a gift can be tough.
Don't miss out on other great gifts:
Perris's Local Florist - Dedicated to Quality and Satisfaction
You and I Flowers and Gifts works hard to craft outstanding floral arrangements and provide exceptional customer satisfaction to Perris, CA. Our arrangements are florist-designed, and hand-delivered with 100% satisfaction guarantee.
Join our community of happy customers in Perris by ordering and supporting your local florist, You and I Flowers and Gifts.


text:
Separate names with a comma.
Just like you, Heligods staff are regular everyday fliers. Join our forum and participate in what will become the worlds greatest rc helicopter forum..
A big thank you to the following people who helped us put together this site:
Pope Francis
Deli Lama
George Bush
Gene Simmons (aka Crash)


text:
Stay connected and sign-up for emails to get exclusive deals and event info.
Something on your mind? Get a little more 411, pal. Ask a product specific question about Romeo y Julieta Reserve Maduro Churchill.
© 2023 Thompson Cigar
Thompson Cigar does not sell products to anyone under the age of 21. If you do not meet the minimum age requirement, please do not enter our site.


text:
Townhomes for Sale in Loch Raven Manor | Towson, MD - March 2018 Home Values
This is a snapshot of recent sales in the Loch Raven Manor neighborhood of Towson, MD. Real estate market data and analysis is provided by Peggy Yee, Realtor. Please click here for the March 2018 full market report of townhomes for sale in Loch Raven Manor, Towson MD.
Highest and Lowest Sold Townhomes in Loch Raven Manor
In the past 6 months, 14 properties have sold in Loch Raven Manor ranging from a 4-bed, 1.5-bath Townhome for $155,000 to a 3-bed, 2-bath Townhome for $271,500.
Loch Raven Manor Community Real Estate Market Activity
These market activity gauges show the market trends for the previous month (January) as compared to the 5-year February average. The market supply is 0.3 months, which indicates the total number of months it would take for the current inventory to sell. The average sold price is $230,000 and the average days on market is 11 days. Click here for the full March 2018 market report for the Loch Raven Manor area including total number of sold homes and average price per square foot.
Find Townhomes for Sale in Loch Raven Manor
Visit my website to see all available Loch Raven Manor Townhomes or to be notified when new homes come on the market.
What Is Your Home Worth?
Are you thinking about selling or want to know what the current value of your home is? Click here to find out what your Loch Raven Manor home is currently worth or to get prices of recently sold homes in your neighborhood.
About Peggy Yee
Peggy Yee is a supervising broker at Frankly Realtors and was one of Northern Virginia Magazines Top Realtors in 2017. She has been quoted in the Around Reston Magazine, Washington Post, Money Magazine, Consumer Reports, Zillow, Trulia and Realtor.com. Peggy is 100% committed to making your move the best experience possible! See what Peggy's previous clients are saying. Click here for Seller Video Testimonials. Click here for Buyer Video Testimonials. Click here for Zillow Reviews.


text:
Century Centurion Series 3/4 HP, 48Y Frame Motor QC1072 - Square Flange
This item is IN STOCK
This item is TEMPORARILY OUT OF STOCK
Usually Ships Within 1 Business Day
Expedited Shipping NOT Available Not Available Outside Contiguous US
Item Details
Century Centurion Series Motor QC1072
The Centurion line of pool motors combine the proven performance of the Century Centurion 56 frame platform with the next generation of features for increased reliability, added performance, premium efficiency, and serviceability.
This is the first full line of upgraded pool motors... the "best of the best" from Century.
- Centurion Series Conservationist Energy Efficient Motor
- No-adjust start switch that is rated for over one million cycles for motor longevity
- Unique electrical design with a unique, advanced cooling system that helps extend the life of the motor
- Heavy duty shaft made from 303 grade stainless steel helps prevent corrosion
- EZ wrench access that doesn't require the removal of the wiring compartment canopy
- Angled terminal makes wiring connections a breeze
- Patented voltage change dial for easy voltage selection
- Patented bonding lug for easy ground connections
- Patented bearing lock clip for for assured bearing retention
- All motors are rated 115/208-230 +/-10% volts to handle voltage variations throughout the US and Canada
- Double sealed bearings and, on shaft end, an integrated Patented SmithSealTM bearing protector to resist water damage
- Rugged motor enclosure system for enhanced durability and premium protection against corrosion
- A full class F insulation system and 50° C ambient capability for increased motor life over class B insulation systems
- Horsepower: 3/4
- Service Factor: 1.9
- Total Horsepower: 1.24
- Volts: 115/230
- Amps: 12.6/6.3
- Frame: 48Y
- Flange: Square
- Shaft: Threaded
- Series: Centurion Conservationist Energy Efficient
- Full Rated
- Not available for sale to the State of California
Century QC1072


text:
Time zone at the center of Loudoun County: US/Eastern
Current time zone offset: UTC/GMT -5 hours
The current time and date at the center of Loudoun County is 7:04 AM on Saturday, December 9, 2023. Search for a particular city within Loudoun County to find the local time in that city.
Travelmath provides a database of counties in the United States, marking the latitude and longitude of the center of each county. You can use this to look up the county of your home city, or explore surrounding counties in your state. Find out how far it is to drive to another county, or just browse the database for a research project.


text:
What is Half of 2/815?
Are you looking to work out and calculate half of 2/815? In this really simple guide, we'll teach you exactly what half of 2/815 is and walk you through the step-by-process of how to calculate half of any fraction.
As always with our series of calculation posts, it's important to remember that the number above the fraction line is called the numerator and the number below the line is called the denomination.
Want to quickly learn or refresh memory on how to calculate a half fraction play this quick and informative video now!
So what do we mean by half? Half means there are two of the thing, and so all you need to do is divide it by two. Half of 2/815 is just another way of saying 2/815 divided by 2:
Now we know that "half" means to divide by 2, how do we half 2/815? Remember that a fraction a part of the whole, so the higher the denominator is, the smaller the piece. The answer is that the numerator stays the same and we multiply the denominator by 2:
That's it! Working out half of 2/815 really is that easy. Hopefully you understood the process and can use the same techniques to halve other fractions as well. The complete answer is below (simplified to the lowest form):
Convert Half of 2/815 to Decimal
Here's a little bonus calculation for you to easily work out the decimal format of half 2/815. All you need to do is divide the numerator by the denominator and you can convert any fraction to decimal:
Cite, Link, or Reference This Page
If you found this content useful in your research, please do us a great favor and use the tool below to make sure you properly reference us wherever you use it. We really appreciate your support!
What is half of 2/815?
"What is half of 2/815?". VisualFractions.com. Accessed on December 11, 2023. http://visualfractions.com/calculator/half-fractions/what-is-half-of-2-815/.
"What is half of 2/815?". VisualFractions.com, http://visualfractions.com/calculator/half-fractions/what-is-half-of-2-815/. Accessed 11 December, 2023.
What is half of 2/815?. VisualFractions.com. Retrieved from http://visualfractions.com/calculator/half-fractions/what-is-half-of-2-815/.
Preset List of Half Fraction Examples
Below are links to some preset calculations that are commonly searched for:


text:
Download free wallpaper for your phone Anime, Dusk, Clouds, Twilight, Girl.
The picture for the screensaver of Android phones and Iphone Anime, Dusk, Clouds, Twilight, Girl you can download in high quality, in the resolution: 2160x3840, 1440x2560, 1366x768, 1080x1920, 1024x600, 960x544, 800x1280, 800x600, 720x1280, 540x960, 480x854, 480x800, 360x640, 320x480, 320x240, 240x400, 240x320 etc. In any case, you can make the final setting of the display of wallpapers directly from the phone when installing them. You can download wallpaper Anime, Dusk, Clouds, Twilight, Girl, №124190 for your mobile phone, like any others in our catalog, absolutely free.
Attention! This image may be copyrighted. By downloading the image "Anime, Dusk, Clouds, Twilight, Girl" for free you take responsibility for its use.


text:
Click on the title of a recipe or the photo of a dish to read the full recipe on its author's blog.
What kind of recipes from Very Good Recipes are you looking for? Choose a dish or an ingredient to refine the selection.
Sign-in on Very Good Recipes to save your favorite recipes on your recipe book.
Connect with Facebook :
Or sign-in with your Very Good Recipes account:
Don't have an account yet? Register to discover and share recipes with other bloggers and readers passionate about cooking.
Newly added:→ The vegetarian aroma . . .
To be the next, submit your blog!
To find out about new things happening on the site, taste new features or add your grain or salt, join us on the Very Good Recipes blog!
Now cooking:→ Gigot Bergére by Kollywood


text:
Kingston, NY Body Rubs
We want to have a night out at a swingers club in Kingston
Kingston, NY Body Rubs
First name: Nevim, Age: 31 yo, City: Kingston (IL)
Hi libertines, We are a naughty couple, my name is Nevim and I'm 31 years old and my husband 31 years old. We live in Kingston. We love going to private clubs to play. We are a very open couple. I personally prefer threesomes because I'm without limits and my boyfriend is okay with swapping... To meet, we suggest you give us a rendezvous in the woods. We're also available in the late afternoon. We just want to enjoy ourselves with you. This is why we are on this libertine site because we like to play with new coquins during hot evenings. To contact us, simply send a message. We just want sex between libertines.
A girl in a relationship is looking for a one-day libertine at Kingston
Kingston, NY Body Rubs
First name: Marie-brigitte, Age: 46 yo, City: Kingston (IL)
I'm only on this libertine site to have some fun between consenting adults. My partner is fully aware of this process. I want a man who is confident and has a big penis so that my man can see me make him cum. I'm a very greedy libertine with the guys. I'm most excited about being with two perverted guys because it turns me on to have two cocks just for myself and my little guy loves sharing me. We're available on weekends to have fun and catch up. We want to set up a meeting with you in a public place if that's okay. Please contact us if you would like a threesome. We look forward to reading your messages. See you soon.
A meeting between libertines for a hot plan on Kingston
Kingston, NY Body Rubs
First name: Hatoumassa, Age: 32 yo, City: Kingston (IL)
Hi everyone, I'm a lovely woman in a relationship, my name is Hatoumassa and I'm 32 years old. I live in Kingston and I'm really slutty. We've been into swinging for a while now. We approach new practices between libertines at times, currently it is voyeurism. We want a man the same age as us for this sex plan. I'm a very horny girl and I want a good fuck so we can enjoy ourselves together. We are available on weekends. We don't mind coming to your place, or if you prefer we can meet at our home. Now that you know what I'm looking for, feel free to leave me a comment. I'm sure I'll have a great time with you. I'm leaving. I kiss you.
Ephemeral encounter Kingston: sensual woman without taboo
Kingston, NY Body Rubs
First name: Marie-violette, Age: 18 yo, City: Kingston (IL)
I am inexperienced in erotic games like swinging or others. I would like to do these practices with a man who is an expert. We can meet at my house or the restaurant. I am available after work, I'm not grumpy. Since I am new to libertinage, I demand a good fuck who knows how to do it. I want to be taken care of and be your submissive during this fuck so that you can have fun with me and especially reach an extreme orgasm. I leave you in the hope of finding your little words to satisfy my most secret sexual impulses. I'm not looking for another plan so if you can't handle my desires. Do not contact me. Notify me! Kisses!
Couple looking for a third in Kingston
Kingston, NY Body Rubs
First name: Claire-hélène, Age: 18 yo, City: Kingston (IL)
My boyfriend and I love going to swingers clubs in Kingston so we can meet new couples. It's mostly for me because I'm tireless with men and I have no taboos. We can meet up in the evening, but we prefer it to happen at our place. We have quite a few accessories. Our ideal would be a guy around the same age as us for this sex evening. As a very greedy woman, I need a real man to come together and enjoy it. Please contact us if you would like to have this plan in a trio. We look forward to reading your messages. Kisses.
A couple who enjoys threesomes is looking to hook up with someone at an adult club in Kingston
Kingston, NY Body Rubs
First name: Tamina, Age: 21 yo, City: Kingston (IL)
With the guys, I'm a frank and naughty libertine. What I prefer is to find myself with 2 very perverse guys because it makes me all hot to have two penises just for me and my naughty one enjoys making me happy. I can give you a date at your place. I'm waiting for us to set a date in an exhibition place on Kingston. I want a fun and open-minded man who will make me feel good with my husband because I am a naughty girl who loves having 2 cocks all to herself. To meet us, just leave a comment. We only want hot sex between adults.
I'm a hot 22 year old woman looking for a virile man on Kingston
Kingston, NY Body Rubs
First name: Scolastie, Age: 22 yo, City: Kingston (IL)
Hi, my name is Scolastie and I've been single for a week since I dumped my boyfriend because he was cheating on me. I'm here to find a hot guy. I am available on weekends and in the mornings. You can come over to my place. Role-playing games are part of my desires. I dream of a guy who can be creative in this area to follow me in my stories and take me into his universe and dreams. I want a boy who is good in bed. Someone to do exhibition without hassle. I look forward to hearing your meeting proposals. I'm looking forward to getting to know you. I think we're going to have a lot of fun during this hookup. Good job! I give you a big hug.
A young nymphomaniac girl looking for sex Kingston
Kingston, NY Body Rubs
First name: Sweety, Age: 33 yo, City: Kingston (IL)
I prefer a younger guy with a really huge cock to give me lots of sensations because I'm a very naughty girl. I know how to handle my encounters to turn them on. I love the practices of libertinism. I am free at the beginning of the week but rather after work. I am looking forward to hearing your comments. Before we meet again. See you soon! Big kisses.
Plan hot on Kingston with a mature couple
Kingston, NY Body Rubs
First name: Narjiss, Age: 34 yo, City: Kingston (IL)
Hello, my name is Narjiss and I am 34 years old. I'm with someone and we're pretty hot. We don't have a problem with receiving you for this plan or going on a date where you want. Age is not a primary criterion, but a good feeling is essential to make love in our company. We want a naughty man for some fun. We love sadomasochism. The best is when I'm handcuffed so my man can watch you make love to me while I'm extremely excited. We are on this libertine dating site to enjoy ourselves with men. You have the right to leave us a message if you want to see us. Bye.
A woman who is new to this whole thing looking for her first one night stand on Kingston
Kingston, NY Body Rubs
First name: Hilde, Age: 24 yo, City: Kingston (IL)
I love foreplay because it gives me a lot of pleasure. I'm a really slutty young woman when I have sex with a good guy. I'm attracted to very sexy bad boys. I also want a well-endowed guy because otherwise I don't feel anything. I absolutely need to have an orgasm. I can have a one night stand every night if I wanted to. You can choose the location, but only on Kingston. So I'm here to have an intense night of sex with a nice guy. If you please, then contact me. It will be a pleasure to share my email or phone number so we can connect. Kisses.
- Washington Terrace, UT Body Rubs
- Warrington, FL Body Rubs
- Galax, VA Body Rubs
- Minden, LA Body Rubs
- Napa, CA Body Rubs
- Muncy, PA Body Rubs
- Dearborn Heights, MI Body Rubs
- Hopatcong, NJ Body Rubs
- Bartow, FL Body Rubs
- Walkertown, NC Body Rubs
- McPherson, KS Body Rubs
- White Oak, MD Body Rubs
- La Plata, MD Body Rubs
- Olivarez, TX Body Rubs
- Richmond, MI Body Rubs
- Cutler, CA Body Rubs
- Quincy, IL Body Rubs
- Waite Park, MN Body Rubs
- Corry, PA Body Rubs
- Vero Beach, FL Body Rubs


text:
wells fargo merchant account services you say? Here is the real deal with that wells fargo merchant account services's …We have seen so many business owner's make this mistake. Business owners looking for a Merchant Account or Merchant Services Account always expect the best. The way we think is that "quality comes with cost" and that is what many business owners live for………… to have top quality services!
wells fargo merchant account services
Well we have wells fargo merchant account services from 30% off of most merchants or merchant account holders from the first time they do a transaction with our processing rates.
Also- With the brand new 0% processing fees we suggest this company called Merchant Services Complete to actually set up up with the fee passed on to your customer instead of your company paying for it. They prefer real phone calls instead of an email. Here is there phone number 928-706-6769. Merchant Services Complete Here is their website if it helps.
Also, only for our website visitors they give a free merchant credit card processing machine for every merchant that set's up an account with them.
Hope this helps you get set up to accept credit cards with a great company Holtsville


text:
Export 5 results:Author [ Title] Type Year
Filters: Author is William A. Miller [Clear All Filters]
"Cool colored roofs to save energy and improve air quality." ACEEE Summer Study on Energy Efficiency in Buildings, August 22-27, 2004. 1st ed. Vol. 1. American Council for an Energy-Efficient Economy, 2004. 1-16. 11 Vol..
"Methods of creating solar-reflective nonwhite surfaces and their application to residential roofing materials." Solar Energy Materials and Solar Cells 91.4 (2007) 304-314..
"Potentials of urban heat island mitigation." Proceedings of the 1st International Passive and Low Energy Cooling for the Built Evironment 2005: 11..
"Weathering of roofing materials – An overview." Construction and Building Materials 22.4 (2008) 423-433..


text:
No products
Made of glass, BNC, cable length 2 m...
Viewed products
New product
0 Item Items
This product is no longer in stock
Warning: Last items in stock!
Availability date:
By buying this product you can collect up to 1 loyalty point. Your cart will total 1 loyalty point that can be converted into a voucher of 0,20 €.
Bache bassin en 0.8 mm epaisseur
Recipient :
* Required fields
or Cancel


text:
Attorney General Marty Jackley
South Dakota Child Identification Program Event in Rapid City
FOR IMMEDIATE RELEASE: Wednesday, April 19, 2016CONTACT: Sara Rabern (605)773-3215
PIERRE, S.D – Attorney General Marty Jackley and the South Dakota Masons want to remind parents and guardians of the upcoming South Dakota Child Identification Program (SDCHIP) event:
Youth and Family Services Kids FairRapid City Civic Center444 Mount Rushmore RoadRapid City, SD Friday, April 22, 2015 8:30 a.m. -4:00 p.m. Saturday, April 23, 8:30 a.m. - 4:00 p.m.Sunday, April 24, 12:00 p.m. - 4:00 p.m.
SDCHIP is part of MASONICHIP, an initiative of the Masons of North American that generates completed packages of various identifying items of children for parents or guardians. The types of identification that are collected include: dental impressions, DNA cheek swab, digital still photo, fingerprints and video imaged interview. All of the identifying materials generated by the program are returned to the child's family to be kept as an identification kit in the event that a child becomes missing. This kit will aid law enforcement in the recovery of a missing child. The program is offered to the public at no charge.
"SD CHIP is a comprehensive child identification program designed to assist in the event a child becomes missing," said Jackley. "The Masons should be commended not only for the creation of this important program, but the time put forth to volunteer and administer the program throughout South Dakota."
Agencies who assist in the implementation of the program include: Masoniship International, South Dakota Academy of Physician Assistants, South Dakota Sheriff's Association, South Dakota Dental Association, South Dakota Highway Patrol and the Attorney General's Office. For more information please visit www.sd-chip.org.


text:
Indigo Pillow 40*40
- A unique addition to your home decor, this pillow is made with handmade indigo block print technique
- 100% cotton
- Not includes filling (standard Ikea pillow sizes)
- 40cm height 40cm width
- Hand wash only, dry in shade
- PLEASE NOTE: Each pillow is quite unique and any shifts, marks or omissions on the fabric are due to its handmade nature
- A unique addition to your home decor, this pillow is made with handmade indigo block print technique
- 100% cotton
- Not includes filling (standard Ikea pillow sizes)
- 40cm height 40cm width
- Hand wash only, dry in shade
- PLEASE NOTE: Each pillow is quite unique and any shifts, marks or omissions on the fabric are due to its handmade nature
Standard shipping with registered mail - up to 7 business days: 20 NIS
Express shipping to your door- up to 3 business days: 50 NIS
Free shipping: on all orders over 500 NIS (with standard registered mail) or reduced express shipping for order over 500 NIS: 25 NIS
Please note, delivery to more remote places may take longer.
We offer a collect from store service available at our Haifa studio store from Sunday to Thursday.
Special instructions
Once your order has shipped, you will receive an email with tracking information to track your items progress online.
Please be sure to enter your correct mobile number when prompted at the checkout as the courier service may need to contact you.
Rest of the world
Our worldwide shipping option is unavailable at the moment.
while we are working on making this option available for you, please don't hesitate to contact email@example.com for special requests.
If you'd like to return an item from your order, you must contact us within 14 days of receiving the item to organise either an exchange/refund via email: email@example.com.
To be eligible for a return, your item must be in its new, unworn state with its original tags and packaging within 14 days from the date of receipt (for orders placed online) or the date of purchase where an item was purchased in our store.
Once your return is received and inspected, we will send you an email to notify you that we have received your returned item. We will also notify you regarding the approval or rejection of your refund. If your return is approved, then your refund will be processed, and a credit will automatically be applied to your credit card or original method of payment, within 7-10 working days.
To return your product, send your items to: 5 Jerusalem street Haifa IL 3313211
Regrettably, returns shipping costs will not be refunded (although some exceptions do apply) unless your item is faulty whereby the original shipping cost and the returns postage will be refunded. If you receive a refund, the cost of return shipping will be deducted from your refund where an exchange has taken place.
Depending on where you live, the time it may take for your exchanged product to reach you, may vary.
Until your item has arrived with us, we do not take responsibility for the shipping of this item and therefore suggest you consider using a trackable shipping service or purchasing shipping insurance. We don't guarantee that we will receive your returned item.
Please allow 7-10 business days for your refund to be processed. If you haven't received a refund within that time, first check your bank account again.
Then contact your credit card company, it may take some time before your refund to appear on your account.
Finally we advise you to contact your bank. There is often some processing time before a refund is posted.
If you've done all of this and you still have not received your refund yet, please contact us at email@example.com.
If you need to exchange an item, send us an email at firstname.lastname@example.com and send your item to: 5 Jerusalem street Haifa IL 3313211
Unfortunately we do not offer refunds on any Gift Cards purchased.