Commit Graph

535 Commits

Author SHA1 Message Date
Oswald Buddenhagen
926788f3ae supplement open_box() with box existence information from list_store()
there is no point in trying to open a non-existing box before trying to
create it.
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
7b7304b625 split create_box() off from open_box()
this allows us to do something else than creating missing boxes
depending on circumstances. hypothetically, that is.
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
f1809ddd2b open the mailboxes after loading the sync state
this allows us to react differently to a box'es absence depending on the
state. hypothetically, so far.
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
f43617cd94 lock sync state lazily
don't try to lock it until we actually read or write it.
the idea is to not fail with SyncState * if we tried to load the state
before selecting a non-existing mailbox. this is ok, because if the
mailbox is missing, we obviously have no sync state pertaining to it,
either.
as a side effect, this allows simplifying an error path.
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
fb19d644f7 split off open_box() from select_box()
aka prepare_paths() reloaded. we'll need it in a moment.
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
97a42cd825 factor out {prepare,lock,save,load}_state() 2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
5af1796777 de-duplicate handling of box operation (create & expunge) options
loops work just fine ...
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
9982e7bf08 make some driver function names more descriptive 2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
00ebf45be2 rename driver::prepare_opts() => prepare_load()
... and move it to the right place in the structure and fix the doc to
not claim that it is called before select().
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
bac2b00f1b disable use of LITERAL+ for payloads > 100k
when LITERAL+ is used, the server has no chance for early rejection of
messages. this means that the client can upload megabytes for nothing.
so simply don't use LITERAL+ for big messages. of course this adds
server roundtrips, but that's tough luck.

the limit could be arguably higher than 100k (or even configurable).
i set it to ~2 sec with my fairly average DSL line.
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
6c959c3ee4 fix handling of unsolicited BYE responses
they can come in at any time, after which we must expect the connection
to be closed (and not complain about it).
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
4f3ef54f3a fix treatment of untagged NO and BAD responses
they aren't possible greeting responses. however, they are warning resp.
error reports from the server, so print them accordingly.
2015-01-11 15:05:29 +01:00
Oswald Buddenhagen
139b90be29 added support for IMAP DEFLATE
initial patch by Jesse Weaver <pianohacker@gmail.com>, but mostly
rewritten by me.
2015-01-11 15:05:28 +01:00
Oswald Buddenhagen
f0b80e7d35 make socket writing buffered
the primary objective is reducing the number of small SSL packets (which
are always padded), but fewer syscalls in the non-SSL case should be
good as well.
2015-01-11 15:05:28 +01:00
Oswald Buddenhagen
efb23ab96a vectorize socket_write()
the objective is making the buffer code aware of the total size of a
write in advance. this commit doesn't take advantage of that yet.
2015-01-11 15:05:28 +01:00
Oswald Buddenhagen
3f629af07e remove support for faking notifications
with the existence of timers, this is now superfluous.
2015-01-11 15:05:28 +01:00
Oswald Buddenhagen
a4e2f1a60d use null timer instead of faking a socket notification 2015-01-11 15:05:28 +01:00
Oswald Buddenhagen
7b76d9ff7e add timers to mainloop
they are called "wakeups", though, as timer_t already exists in time.h.
2015-01-11 15:05:28 +01:00
Oswald Buddenhagen
1fd66195d8 change socket notifier design
instead of keeping the structures in an opaque array (which was a shadow
of the struct pollfd array if poll() was supported), make them directly
addressable.

this has the advantage that notifier-altering operations (mostly
en-/disabling) don't need to look up the structure by file handle each
time.
on the downside, data locality in the main loop is worse.
neither of these have any real effect on performance.

note that the structures are not allocated separately, but embedded into
the the parent structure (like sockets already were).
2015-01-11 15:05:28 +01:00
Oswald Buddenhagen
f68e021b90 factor out socket_open_internal() 2015-01-11 15:05:28 +01:00
Oswald Buddenhagen
42cedc8f81 introduce uchar, ushort & uint typedefs 2015-01-11 15:05:28 +01:00
Oswald Buddenhagen
b730f66f7d Merge branch 'isync_1_1_branch' into HEAD
Conflicts:
	src/socket.c
2015-01-11 14:32:15 +01:00
Oswald Buddenhagen
2fa75cf159 fix UID assignment with some non-UIDPLUS servers
the seznam.cz IMAP server seems very eager to send UIDNEXT responses
despite not supporting UIDPLUS. this doesn't appear to be a particularly
sensible combination, but it's valid nonetheless.

however, that means that we need to save the UIDNEXT value before we
start storing messages, lest imap_find_new_msgs() will simply overlook
them. we do that outside the driver, in an already present field - this
actually makes the main path more consistent with the journal recovery
path.

analysis by Tomas Tintera <trosos@seznam.cz>.

REFMAIL: 20141220215032.GA10115@kyvadlo.trosos.seznam.cz
2015-01-11 14:29:19 +01:00
Oswald Buddenhagen
958af473a0 fix conditional for early failure in cancel_done() 2015-01-02 12:38:48 +01:00
Oswald Buddenhagen
9eba3d8cd9 don't leave 2nd store in limbo if opening 1st store fails synchronously
we can't leave the store FRESH, as otherwise the error handling code
will assume it is still being opened and will return to the main loop.
depending on the config this would cause an immediate termination or an
indefinite wait.
2015-01-02 11:29:51 +01:00
Oswald Buddenhagen
3db3f4718e remove stray CRLF from AUTHENTICATE continuations
this re-introduces 6741bc94 (just a bit differently), thus effectively
reverting fbfcfea5. i suppose this extra CRLF is needed by a broken
CRAM-MD5 implementation of some server, which is why it was there in the
original implementation as well. however, it breaks more pedantic
non-broken servers. if somebody complains, we'll need to add a much
more sophisticated hack.
2014-12-29 02:30:33 +01:00
Oswald Buddenhagen
518b5630dc cleanup dead cram() prototype 2014-12-29 02:30:33 +01:00
Oswald Buddenhagen
5dfca41422 fix more memcmp() abuse
amends 1217193fb and 4f383a807.
2014-12-29 02:30:01 +01:00
Oswald Buddenhagen
6f7d416bb8 fix acceptance of trusted SSL certs
we should make no assumptions about the layout of OpenSSL's certificate
store, in particular when they are wrong. so copy the interesting part
instead of "deep-linking" into it.

this code is uglier than it should be, but OpenSSL's extensive use of
macros to manage data types would force us to include the ssl headers
into our headers otherwise, which would be even uglier.

REFMAIL: <545442CC.9020400@nodivisions.com>
2014-11-08 14:00:28 +01:00
Oswald Buddenhagen
f377e7b696 introduce FieldDelimiter and InfoDelimiter options
... for windows fs compatibility.

the maildir-specific InfoDelimiter inherits the global FieldDelimiter
(which affects SyncState), based on the assumption that if the sync
state is on a windows FS, the mailboxes certainly will be as well, while
the inverse is not necessarily true (when running on unix, anyway).

REFMAIL: <CA+m_8J1ynqAjHRJagvKt9sb31yz047Q7NH-ODRmHOKyfru8vtA@mail.gmail.com>
2014-10-25 17:42:48 +02:00
Oswald Buddenhagen
85fd5ceb54 move orig_name out of store_t
it's state specific to the synchronizer.
2014-10-25 15:06:50 +02:00
Oswald Buddenhagen
7ee0483436 nuke home-grown CRAM-MD5 support
it was obsoleted by SASL support.
i deem the additional dependency acceptable when one wants the feature.
2014-10-20 10:10:55 +02:00
Oswald Buddenhagen
eb1005151c add SASL support
patch initially by Jack Stone <jwjstone@fastmail.fm>,
cleaned up by Jan Synacek <jsynacek@redhat.com>,
... and then almost completely rewritten by me. ^^
2014-10-20 10:10:55 +02:00
Oswald Buddenhagen
360600b98d factor out ensure_user() and ensure_password() 2014-10-18 16:18:48 +02:00
Oswald Buddenhagen
1217193fbb rework authentication mechanism configuration
RequireCRAM (another fairly stupid "use if available" option) is now
deprecated. instead, the AuthMech option can be used to give a precise
list of acceptable authentication mechanisms (which is currently "a bit"
short). in particular, this allows *not* using CRAM-MD5 even if it's
available.
2014-10-18 16:18:48 +02:00
Oswald Buddenhagen
aba3524d9b make it possible to disable usage of system cert store 2014-10-18 16:18:48 +02:00
Oswald Buddenhagen
7822bd8a91 require Host if SSL is used despite Tunnel 2014-10-18 16:18:48 +02:00
Oswald Buddenhagen
7ce57b9c00 make SSL certificate verification less arcane
instead of using a callback which messes with the certificate chain
verification, simply let OpenSSL ignore errors during that phase and
check the result only afterwards.
2014-10-18 16:18:48 +02:00
Oswald Buddenhagen
2745813367 re-design SSL/TLS configuration
the combinations of the various options made quite a mess. additionally,
'RequireSSL no' is inherently insecure - "use SSL if available" is plain
stupid.

the old options are still accepted, but will elicit a warning.
2014-10-18 16:18:48 +02:00
Oswald Buddenhagen
aa4f7a7d00 move use_imaps out of server_conf_t
it doesn't belong there - it's a property of imap_server_conf_t.
the port setup is now done while reading the config.

this makes socket.[hc] imap-agnostic.
2014-10-18 16:15:02 +02:00
Oswald Buddenhagen
3742fc475b deprecate the compat wrapper
after a decade, it's about time to phase it out.
2014-10-18 16:15:02 +02:00
Oswald Buddenhagen
47897d2403 fix memory management of current mailbox name
it was a stupid idea to store the pointer to a variable we need to
dispose in a structure which has its own lifetime.
2014-10-04 18:37:34 +02:00
Oswald Buddenhagen
4f383a8074 stop abusing memcmp()
memcmp() is unfortunately not guaranteed to read forward byte-by-byte,
which means that the clever use as a strncmp() without the pointless
strlen()s is not permitted, and can actually misbehave with
SSE-optimized string functions.

so implement proper equals() and starts_with() functions. as a bonus,
the calls are less cryptic.
2014-10-04 18:37:34 +02:00
Oswald Buddenhagen
003ddb2199 permit IMAP Stores with explicitly empty Path
this is useful if the server sends an unhelpful NAMESPACE like
"INBOX." (which precludes clean use of Patterns with the real INBOX).
2014-10-04 18:37:34 +02:00
Oswald Buddenhagen
f385355bdb don't attempt to filter LIST response if there is no Path
we won't filter anything in that case anyway.
2014-10-04 18:37:34 +02:00
Oswald Buddenhagen
608834c6f1 permit Maildir Stores without a Path
it is perfectly reasonable to have a Store which has only an Inbox.
2014-10-04 18:37:33 +02:00
Oswald Buddenhagen
6ad7371f46 use resolved Path for initial filtering of LIST response
otherwise we'd ignore NAMESPACE, and funny things could happen.
2014-10-04 18:37:33 +02:00
Oswald Buddenhagen
de82023427 consider unexpected structure of NAMESPACE fatal 2014-10-04 18:37:33 +02:00
Oswald Buddenhagen
2a2c53ae43 ignore INBOX only in Path itself, not its subfolders
a box foo/INBOX cannot be mistaken for the INBOX, so there is no point
in filtering these out.
2014-10-04 11:45:30 +02:00
Oswald Buddenhagen
313c9193f8 use \fB and \fI consistently
notably, the docu for the Sync option had it mixed up in the
description.
2014-07-12 14:08:34 +02:00
Oswald Buddenhagen
9a463768ea complain about RequireSSL with no SSL versions enabled 2014-07-06 10:10:12 +02:00
Oswald Buddenhagen
06c731cbf8 actually use STARTTLS if only TLSv1.1 or TLSv1.2 is enabled 2014-07-06 10:09:38 +02:00
Oswald Buddenhagen
95db373e54 clarify error message about missing connection details 2014-07-06 09:09:54 +02:00
Oswald Buddenhagen
834a65d85c make store/account error messages less redundant
this will become more relevant when more are added.
2014-07-06 09:09:54 +02:00
Oswald Buddenhagen
d9c78b7787 clarify effect of Tunnel on Host and Port 2014-07-06 09:09:54 +02:00
Oswald Buddenhagen
639c84ea28 don't ignore RequireSSL for PREAUTHenticated connections
such connections don't support STARTTLS. that is reasonable, as whatever
makes the connection preauthenticated (typically a Tunnel used to launch
imapd via a shell login) must already rely on the connection's security.
consequently, we would not try to use STARTTLS with such connections.
unfortunately, we'd also skip the RequireSSL check as a side effect.

this means that a rogue server (via a MITM attack) could simply offer a
preauthenticated connection to make us not use SSL, and thus bypass
server authentication. as a result, we could send potentially sensitive
data to the attacker:
- with Patterns used, we would send a LIST command which reveals the
  remote Path setting. this isn't very useful to an attacker. also, IMAP
  Accounts usually rely on the server-provided NAMESPACE to start with.
- with Create enabled for the remote Store, we would upload messages
  from newly appeared local folders. this isn't a very likely situation,
  unless the attacker manages to convince the victim to move/copy
  interesting mails to a new folder right before the attack.
- with Expunge enabled for the local Store, previously synchronized
  folders would be wiped. however, this would require the attacker to
  know the correct UIDVALIDITY of each remote folder, which would
  require incredible luck or convincing the victim to disclose them.
  the first mismatch would likely tip off the victim.

in practice, someone with the level of technical and social engineering
skills required for this attack would very likely find more attractive
attack vectors. therefore, i don't consider this a particularly serious
issue.

configurations with UseIMAPS enabled or using a secure Tunnel were not
affected to start with.

a side effect of this fix is that most users of Tunnel will now need to
explicitly set RequireSSL to false.
an alternative approach would be defaulting all SSL-related settings to
off when Tunnel is used. this would be too invasive for a patch release,
but i'll consider it for 1.2.

see also CVE-2014-2567 for the Trojita MUA.
2014-07-06 09:09:54 +02:00
Oswald Buddenhagen
526231bc22 initialize store_t::name
the field is marked foreign (for the drivers), so a recycled store may
contain an old pointer in it. that would make our error path crash.

REFMAIL: CAF_KswU7aBS7unnK+rdZy1PG_8SZUAW=tcg75HixDLLE0w3Lhw@mail.gmail.com
2014-07-02 08:50:22 +02:00
Oswald Buddenhagen
29b07ca7a6 actually print the faulty mailbox name, not some garbage
REFMAIL: CAF_KswU7aBS7unnK+rdZy1PG_8SZUAW=tcg75HixDLLE0w3Lhw@mail.gmail.com
2014-07-02 08:49:47 +02:00
Oswald Buddenhagen
3d5539bb63 detect inconsistent state of highest assigned UID
the highest assigned UID must always be at least as high as the highest
actually found UID, as otherwise we'd hand out duplicate UIDs at some
point. also, getting into such a state in the first place indicates some
potentially serious trouble, or at least external interference (e.g.,
moving/copying a message from another folder without giving it a
pristine filename).

REFMAIL: 20140626211831.GA11590@sie.protva.ru
2014-06-28 12:06:12 +02:00
Oswald Buddenhagen
8513358e0a zero-terminate imap literals
now that we properly support literals for strings, we must expect that
the consumer code will use them as strings.

amends fc77feacc.

discovered by Armands Liepins <armandsl@gmail.com>

REFMAIL: CAF_KswXoxdm7KXnWW4b_1odf=XsE4qRqRN4AsecwcPF1d+dSTA@mail.gmail.com
2014-06-28 11:04:41 +02:00
Oswald Buddenhagen
4ab12ae76e don't lie about the default of User
unlike the isync wrapper, mbsync does not have a default for the IMAP
user. the remote user seldomly matches the local one, so "forwarding" it
is more confusing than helpful.

CCMAIL: 744389@bugs.debian.org
2014-04-13 17:07:53 +02:00
Oswald Buddenhagen
4d8575100d don't forget to reset message counts when skipping scan
amends b6949c64d2.

CCMAIL: 744259@bugs.debian.org
2014-04-12 19:05:08 +02:00
Oswald Buddenhagen
8844ff3063 remove apparently pointless resetting of recent message count
past this point, it's not used for anything anyway.
2014-04-12 19:00:33 +02:00
Oswald Buddenhagen
532d964aea error-check renaming of uid mapping database
for pedantry.

found by coverity.
2014-04-12 18:59:45 +02:00
Oswald Buddenhagen
09db83809a error-check reading of old uidvalidity and maxuid files
found by coverity.
2014-04-12 18:34:26 +02:00
Oswald Buddenhagen
2d4bc1e613 error-check committing of sync state
a failure here is rather unlikely, but let's be pedantic.
a failure is not fatal (we'll just enter the journal replay path next
time), so only print warnings.

found by coverity.
2014-04-12 18:31:18 +02:00
Oswald Buddenhagen
aa0118d047 better error messages for sync state and journal related errors
we can make perfectly good use of errno here.
2014-04-12 18:30:09 +02:00
Oswald Buddenhagen
c6ddad6ac4 remove pointless/counterproductive "Disk full?" error message suffixes
the affected functions will set errno to ENOSPC when necessary.
2014-04-12 18:28:21 +02:00
Oswald Buddenhagen
d7d5fd20bc fix "inverse copy&pasto" in account labeling code
the code was copied and the original adjusted ... but not quite
completely.
this means that clashing server names never really worked since - not
that i would have expected this to be a particularly common
configuration to start with. :D

also added comments explaining why there are two implementations of the
same thing.

amends aea4be19e3 (anno 2006).

found by coverity.
2014-04-12 16:56:00 +02:00
Oswald Buddenhagen
9932352df0 assert !where implying !pseudo
to help poor coverity.
2014-04-12 16:06:33 +02:00
Oswald Buddenhagen
c5f2943ff6 don't crash in message expiration debug print
we would try to print the uids from the non-existing srec of unpaired
messages while preparing expiration.
this would happen only if a) MaxMessages was configured and b) new
messages appeared on the slave but we were not pushing, so it's a bit of
a corner case.

found by coverity.
2014-04-12 15:28:28 +02:00
Oswald Buddenhagen
31ba8375b0 fix segfault on passing --{create,expunge}-{master,slave}
stupid copy&pasto.

found by coverity.
2014-04-12 15:16:22 +02:00
Oswald Buddenhagen
ae49a37a3e don't crash on malformed response code
this would happen in the absurd corner case that the response code is
properly terminated with a closing bracket, but the atom itself is an
unterminated double-quoted string.

NOT found by coverity.
2014-04-12 15:02:40 +02:00
Oswald Buddenhagen
fd872a7ff7 don't crash on truncated LIST response
found by coverity.
2014-04-12 14:58:18 +02:00
Oswald Buddenhagen
0dfbf6f6fb remove pointless pointer assignment 2014-04-12 13:08:10 +02:00
Oswald Buddenhagen
d34baeb886 fix hypothetical buffer overflows
if something managed to make the maildir .uidvalidity files big enough
(possible only by appending garbage or scrambling them alltogether), we
would overflow the read buffer by one when appending the terminating
null.
this is not expected to have any real-world impact.

found by coverity.
2014-04-12 13:03:46 +02:00
Oswald Buddenhagen
df29c592d1 close a bunch of fd leaks in error paths
found by coverity.
2014-04-12 12:46:36 +02:00
Oswald Buddenhagen
dec5f73f57 actually use prime numbers for all hash bucket sizes
for some reason lost in history, the prime_deltas were actually wrong,
leading to using composite numbers.
the right sequence is available at http://oeis.org/A092131.
2014-03-19 10:27:06 +01:00
Oswald Buddenhagen
bee7ceb0fb fix zero MaxSize override in Channels
REFMAIL: CA+Tk8fzb9i9LrC_k4G978c5XR5urNz_s0fpOn_-6EsdrBnEzSQ@mail.gmail.com
2014-03-19 10:09:20 +01:00
Oswald Buddenhagen
19d86d2aa9 rework maildir store mapping
the trivial approach of having "home" and "root" stores produced ugly
results, and totally failed with the introduction of nested folder
handling.
instead, create a store per local directory, just as one would manually.

CCMAIL: 737708@bugs.debian.org
2014-03-10 12:20:29 +01:00
Oswald Buddenhagen
0edb606e0f don't needlessly quote strings 2014-03-10 12:20:29 +01:00
Oswald Buddenhagen
183f256557 don't needlessly spell out INBOX 2014-03-10 12:20:29 +01:00
Oswald Buddenhagen
bf9d7c7695 write Sync and Expunge to global section if applicable
makes for leaner Channel sections.

note: the global delete and expunge variables exist so the command line
can override the config file despite the otherwise backwards behavior.
2014-03-10 12:20:18 +01:00
Oswald Buddenhagen
f55f42bdfc don't bother checking impossible condition
the config readear already verified that at least host or tunnel are
set.
2014-03-09 15:56:52 +01:00
Oswald Buddenhagen
3161540ab9 fix crash on store without prior fetch with non-UIDPLUS servers
we'd never initialize the message list append pointer, so
imap_find_new_msgs()'s FETCH would go awry.

REFMAIL: <20140207101719.GB17125@mac.home>
2014-02-08 13:29:35 +01:00
Oswald Buddenhagen
12be7dd1f3 remove pointless use of AI_V4MAPPED flag
this flag is ineffective if ai_family is not explicitly AF_INET6.
on top of that, attempting to use it breaks on FreeBSD.
2014-02-02 12:24:34 +01:00
Oswald Buddenhagen
1c758be695 fix typos 2014-01-25 13:19:02 +01:00
Oswald Buddenhagen
f4a192f375 don't error out if we don't get an X-TUID header
the BODY[] item in the FETCH response corresponds to what we requested,
and its presence doesn't imply that it actually contains anything useful
- new messages may appear in the mailbox in addition to those we stored
ourselves, and these will obviously have no TUID.
2014-01-25 11:34:03 +01:00
Oswald Buddenhagen
aee0fa3b68 make date parsing portable, take 2
the global timezone variable is glibc-specific.
so use timegm() instead of mktime() for the conversion.
as that is specific to the BSDs and glibc, provide a fallback.
amends 62a6099.
2014-01-02 21:09:09 +01:00
Oswald Buddenhagen
6d2fd370a6 fix _POSIX_SYNCHRONIZED_IO usage
it can be -1 for unsupported, or 0 for runtime detection (which we don't
do).
2014-01-02 21:09:09 +01:00
Oswald Buddenhagen
760bfa2cc6 pre-release doc updates 2013-12-15 13:46:25 +01:00
Oswald Buddenhagen
8b2bc912b4 elaborate on expunging and trashing 2013-12-15 13:46:25 +01:00
Oswald Buddenhagen
4481702da3 clarify wording in MapInbox doc 2013-12-15 13:46:25 +01:00
Oswald Buddenhagen
4fa5779193 avoid array underflow in IMAP LIST .lock workaround
suggested by Mark Wielaard <mark@klomp.org>.

fwiw, the workaround really is still necessary with panda imap ...
2013-12-15 13:46:06 +01:00
Oswald Buddenhagen
359091625d MaxMessages: ignore entries with no master while calculating bulk fetch 2013-12-13 15:38:50 +01:00
Oswald Buddenhagen
2bbd07ec87 adjust comments to new reality 2013-12-11 16:29:34 +01:00
Oswald Buddenhagen
5a21042e98 ensure sequencing of message propagation and store closing
by putting the message propagation last, d3f634702 uncovered a
long-standing problem: we might have closed the source store before all
messages were propagated from it.
2013-12-11 16:29:33 +01:00
Oswald Buddenhagen
c47ee1c8c4 fix error paths wrt sync drivers, take 3
msgs_copied() was not checked at all, and msgs_flags_set() was doing it
wrong (sync_close() was not checked).

instead of trying to fix/extend the msgs_flags_set() model (ref-counting
and cancelation checking in lower-level functions, and return values to
propagate the status), place the refs/derefs around higher-level scopes
and do the checking only there. this is effectively simpler, and does
away with some obscure macros.
2013-12-11 16:29:33 +01:00
Oswald Buddenhagen
2f0fbcd306 don't use UID EXPUNGE unless trashing
a simple CLOSE is way more efficient, so use it if no adverse effects
can come from it.
2013-12-11 16:29:33 +01:00
Oswald Buddenhagen
03b3b566f1 reshuffle sources a bit
split header and move some code to more logical places.
2013-12-08 23:19:12 +01:00