Bug Summary

File:src/camel/providers/pop3/camel-pop3-store.c
Warning:line 526, column 18
Read function called when stream is in EOF state. Function has no effect

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -O3 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name camel-pop3-store.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/GNOME/evolution-data-server/_build -fcoverage-compilation-dir=/builds/GNOME/evolution-data-server/_build -resource-dir /usr/bin/../lib/clang/22 -D GLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_68 -D GLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_68 -D G_LOG_DOMAIN="camel-pop3-provider" -D LDAP_DEPRECATED -D SOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_3_2 -D SOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_3_2 -D _LARGEFILE64_SOURCE=1 -D camelpop3_EXPORTS -I /builds/GNOME/evolution-data-server/_build -I /builds/GNOME/evolution-data-server/_build/src -I /builds/GNOME/evolution-data-server/_build/src/camel -I /builds/GNOME/evolution-data-server/src -I /builds/GNOME/evolution-data-server/src/camel -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/nss3 -I /usr/include/nspr4 -D NDEBUG -I /usr/include -D WITH_GZFILEOP -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/nss3 -I /usr/include/nspr4 -internal-isystem /usr/bin/../lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -Wno-sign-compare -Wno-missing-field-initializers -Wno-missing-include-dirs -Wno-deprecated-declarations -Wno-cast-function-type -Wwrite-strings -fconst-strings -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/GNOME/evolution-data-server/_build/scan-build/2026-08-11-054813-10-1 -x c /builds/GNOME/evolution-data-server/src/camel/providers/pop3/camel-pop3-store.c
1/*
2 * SPDX-FileCopyrightText: (C) 1999-2008 Novell, Inc. (www.novell.com)
3 * SPDX-License-Identifier: LGPL-2.0-or-later
4 * SPDX-FileContributor: Dan Winship <danw@ximian.com>
5 * SPDX-FileContributor: Michael Zucchi <notzed@ximian.com>
6 */
7
8#include "evolution-data-server-config.h"
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <unistd.h>
14#include <sys/types.h>
15#include <ctype.h>
16
17#include <glib/gi18n-lib.h>
18#include <glib/gstdio.h>
19
20#include "camel-pop3-folder.h"
21#include "camel-pop3-settings.h"
22#include "camel-pop3-store.h"
23
24#ifdef G_OS_WIN32
25#include <winsock2.h>
26#include <ws2tcpip.h>
27#endif
28
29/* Specified in RFC 1939 */
30#define POP3_PORT110 110
31#define POP3S_PORT995 995
32
33/* defines the length of the server error message we can display in the error dialog */
34#define POP3_ERROR_SIZE_LIMIT60 60
35
36struct _CamelPOP3StorePrivate {
37 GMutex property_lock;
38 CamelDataCache *cache;
39 CamelPOP3Engine *engine;
40};
41
42enum {
43 PROP_0,
44 PROP_CONNECTABLE,
45 PROP_HOST_REACHABLE
46};
47
48extern CamelServiceAuthType camel_pop3_password_authtype;
49extern CamelServiceAuthType camel_pop3_apop_authtype;
50
51/* Forward Declarations */
52static void camel_network_service_init (CamelNetworkServiceInterface *iface);
53
54G_DEFINE_TYPE_WITH_CODE (static void camel_pop3_store_init (CamelPOP3Store *self); static
void camel_pop3_store_class_init (CamelPOP3StoreClass *klass
); static GType camel_pop3_store_get_type_once (void); static
gpointer camel_pop3_store_parent_class = ((void*)0); static gint
CamelPOP3Store_private_offset; static void camel_pop3_store_class_intern_init
(gpointer klass) { camel_pop3_store_parent_class = g_type_class_peek_parent
(klass); if (CamelPOP3Store_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CamelPOP3Store_private_offset); camel_pop3_store_class_init
((CamelPOP3StoreClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer camel_pop3_store_get_instance_private
(CamelPOP3Store *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CamelPOP3Store_private_offset)))); } GType camel_pop3_store_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = camel_pop3_store_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType camel_pop3_store_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((camel_store_get_type ()), g_intern_static_string ("CamelPOP3Store"
), sizeof (CamelPOP3StoreClass), (GClassInitFunc)(void (*)(void
)) camel_pop3_store_class_intern_init, sizeof (CamelPOP3Store
), (GInstanceInitFunc)(void (*)(void)) camel_pop3_store_init,
(GTypeFlags) 0); { {{ CamelPOP3Store_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CamelPOP3StorePrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) camel_network_service_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (camel_network_service_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
55 CamelPOP3Store,static void camel_pop3_store_init (CamelPOP3Store *self); static
void camel_pop3_store_class_init (CamelPOP3StoreClass *klass
); static GType camel_pop3_store_get_type_once (void); static
gpointer camel_pop3_store_parent_class = ((void*)0); static gint
CamelPOP3Store_private_offset; static void camel_pop3_store_class_intern_init
(gpointer klass) { camel_pop3_store_parent_class = g_type_class_peek_parent
(klass); if (CamelPOP3Store_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CamelPOP3Store_private_offset); camel_pop3_store_class_init
((CamelPOP3StoreClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer camel_pop3_store_get_instance_private
(CamelPOP3Store *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CamelPOP3Store_private_offset)))); } GType camel_pop3_store_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = camel_pop3_store_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType camel_pop3_store_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((camel_store_get_type ()), g_intern_static_string ("CamelPOP3Store"
), sizeof (CamelPOP3StoreClass), (GClassInitFunc)(void (*)(void
)) camel_pop3_store_class_intern_init, sizeof (CamelPOP3Store
), (GInstanceInitFunc)(void (*)(void)) camel_pop3_store_init,
(GTypeFlags) 0); { {{ CamelPOP3Store_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CamelPOP3StorePrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) camel_network_service_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (camel_network_service_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
56 camel_pop3_store,static void camel_pop3_store_init (CamelPOP3Store *self); static
void camel_pop3_store_class_init (CamelPOP3StoreClass *klass
); static GType camel_pop3_store_get_type_once (void); static
gpointer camel_pop3_store_parent_class = ((void*)0); static gint
CamelPOP3Store_private_offset; static void camel_pop3_store_class_intern_init
(gpointer klass) { camel_pop3_store_parent_class = g_type_class_peek_parent
(klass); if (CamelPOP3Store_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CamelPOP3Store_private_offset); camel_pop3_store_class_init
((CamelPOP3StoreClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer camel_pop3_store_get_instance_private
(CamelPOP3Store *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CamelPOP3Store_private_offset)))); } GType camel_pop3_store_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = camel_pop3_store_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType camel_pop3_store_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((camel_store_get_type ()), g_intern_static_string ("CamelPOP3Store"
), sizeof (CamelPOP3StoreClass), (GClassInitFunc)(void (*)(void
)) camel_pop3_store_class_intern_init, sizeof (CamelPOP3Store
), (GInstanceInitFunc)(void (*)(void)) camel_pop3_store_init,
(GTypeFlags) 0); { {{ CamelPOP3Store_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CamelPOP3StorePrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) camel_network_service_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (camel_network_service_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
57 CAMEL_TYPE_STORE,static void camel_pop3_store_init (CamelPOP3Store *self); static
void camel_pop3_store_class_init (CamelPOP3StoreClass *klass
); static GType camel_pop3_store_get_type_once (void); static
gpointer camel_pop3_store_parent_class = ((void*)0); static gint
CamelPOP3Store_private_offset; static void camel_pop3_store_class_intern_init
(gpointer klass) { camel_pop3_store_parent_class = g_type_class_peek_parent
(klass); if (CamelPOP3Store_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CamelPOP3Store_private_offset); camel_pop3_store_class_init
((CamelPOP3StoreClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer camel_pop3_store_get_instance_private
(CamelPOP3Store *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CamelPOP3Store_private_offset)))); } GType camel_pop3_store_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = camel_pop3_store_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType camel_pop3_store_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((camel_store_get_type ()), g_intern_static_string ("CamelPOP3Store"
), sizeof (CamelPOP3StoreClass), (GClassInitFunc)(void (*)(void
)) camel_pop3_store_class_intern_init, sizeof (CamelPOP3Store
), (GInstanceInitFunc)(void (*)(void)) camel_pop3_store_init,
(GTypeFlags) 0); { {{ CamelPOP3Store_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CamelPOP3StorePrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) camel_network_service_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (camel_network_service_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
58 G_ADD_PRIVATE (CamelPOP3Store)static void camel_pop3_store_init (CamelPOP3Store *self); static
void camel_pop3_store_class_init (CamelPOP3StoreClass *klass
); static GType camel_pop3_store_get_type_once (void); static
gpointer camel_pop3_store_parent_class = ((void*)0); static gint
CamelPOP3Store_private_offset; static void camel_pop3_store_class_intern_init
(gpointer klass) { camel_pop3_store_parent_class = g_type_class_peek_parent
(klass); if (CamelPOP3Store_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CamelPOP3Store_private_offset); camel_pop3_store_class_init
((CamelPOP3StoreClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer camel_pop3_store_get_instance_private
(CamelPOP3Store *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CamelPOP3Store_private_offset)))); } GType camel_pop3_store_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = camel_pop3_store_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType camel_pop3_store_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((camel_store_get_type ()), g_intern_static_string ("CamelPOP3Store"
), sizeof (CamelPOP3StoreClass), (GClassInitFunc)(void (*)(void
)) camel_pop3_store_class_intern_init, sizeof (CamelPOP3Store
), (GInstanceInitFunc)(void (*)(void)) camel_pop3_store_init,
(GTypeFlags) 0); { {{ CamelPOP3Store_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CamelPOP3StorePrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) camel_network_service_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (camel_network_service_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
59 G_IMPLEMENT_INTERFACE (static void camel_pop3_store_init (CamelPOP3Store *self); static
void camel_pop3_store_class_init (CamelPOP3StoreClass *klass
); static GType camel_pop3_store_get_type_once (void); static
gpointer camel_pop3_store_parent_class = ((void*)0); static gint
CamelPOP3Store_private_offset; static void camel_pop3_store_class_intern_init
(gpointer klass) { camel_pop3_store_parent_class = g_type_class_peek_parent
(klass); if (CamelPOP3Store_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CamelPOP3Store_private_offset); camel_pop3_store_class_init
((CamelPOP3StoreClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer camel_pop3_store_get_instance_private
(CamelPOP3Store *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CamelPOP3Store_private_offset)))); } GType camel_pop3_store_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = camel_pop3_store_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType camel_pop3_store_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((camel_store_get_type ()), g_intern_static_string ("CamelPOP3Store"
), sizeof (CamelPOP3StoreClass), (GClassInitFunc)(void (*)(void
)) camel_pop3_store_class_intern_init, sizeof (CamelPOP3Store
), (GInstanceInitFunc)(void (*)(void)) camel_pop3_store_init,
(GTypeFlags) 0); { {{ CamelPOP3Store_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CamelPOP3StorePrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) camel_network_service_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (camel_network_service_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
60 CAMEL_TYPE_NETWORK_SERVICE,static void camel_pop3_store_init (CamelPOP3Store *self); static
void camel_pop3_store_class_init (CamelPOP3StoreClass *klass
); static GType camel_pop3_store_get_type_once (void); static
gpointer camel_pop3_store_parent_class = ((void*)0); static gint
CamelPOP3Store_private_offset; static void camel_pop3_store_class_intern_init
(gpointer klass) { camel_pop3_store_parent_class = g_type_class_peek_parent
(klass); if (CamelPOP3Store_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CamelPOP3Store_private_offset); camel_pop3_store_class_init
((CamelPOP3StoreClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer camel_pop3_store_get_instance_private
(CamelPOP3Store *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CamelPOP3Store_private_offset)))); } GType camel_pop3_store_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = camel_pop3_store_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType camel_pop3_store_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((camel_store_get_type ()), g_intern_static_string ("CamelPOP3Store"
), sizeof (CamelPOP3StoreClass), (GClassInitFunc)(void (*)(void
)) camel_pop3_store_class_intern_init, sizeof (CamelPOP3Store
), (GInstanceInitFunc)(void (*)(void)) camel_pop3_store_init,
(GTypeFlags) 0); { {{ CamelPOP3Store_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CamelPOP3StorePrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) camel_network_service_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (camel_network_service_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
61 camel_network_service_init))static void camel_pop3_store_init (CamelPOP3Store *self); static
void camel_pop3_store_class_init (CamelPOP3StoreClass *klass
); static GType camel_pop3_store_get_type_once (void); static
gpointer camel_pop3_store_parent_class = ((void*)0); static gint
CamelPOP3Store_private_offset; static void camel_pop3_store_class_intern_init
(gpointer klass) { camel_pop3_store_parent_class = g_type_class_peek_parent
(klass); if (CamelPOP3Store_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CamelPOP3Store_private_offset); camel_pop3_store_class_init
((CamelPOP3StoreClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer camel_pop3_store_get_instance_private
(CamelPOP3Store *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CamelPOP3Store_private_offset)))); } GType camel_pop3_store_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = camel_pop3_store_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType camel_pop3_store_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((camel_store_get_type ()), g_intern_static_string ("CamelPOP3Store"
), sizeof (CamelPOP3StoreClass), (GClassInitFunc)(void (*)(void
)) camel_pop3_store_class_intern_init, sizeof (CamelPOP3Store
), (GInstanceInitFunc)(void (*)(void)) camel_pop3_store_init,
(GTypeFlags) 0); { {{ CamelPOP3Store_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CamelPOP3StorePrivate)); } { const
GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) camel_network_service_init, ((void*)0), ((void
*)0) }; g_type_add_interface_static (g_define_type_id, (camel_network_service_get_type
()), &g_implement_interface_info); };} } return g_define_type_id
; }
62
63/* returns error message with ': ' as prefix */
64static gchar *
65get_valid_utf8_error (const gchar *text)
66{
67 gchar *tmp = camel_utf8_make_valid (text);
68 gchar *ret = NULL((void*)0);
69
70 /*TODO If the error message > size limit log it somewhere */
71 if (!tmp || g_utf8_strlen (tmp, -1) > POP3_ERROR_SIZE_LIMIT60) {
72 g_free (tmp);
73 return NULL((void*)0);
74 }
75
76 /* Translators: This is the separator between an error and an explanation */
77 ret = g_strconcat (_(": ")((char *) g_dgettext ("evolution-data-server", ": ")), tmp, NULL((void*)0));
78
79 g_free (tmp);
80 return ret;
81}
82
83static gboolean
84connect_to_server (CamelService *service,
85 GCancellable *cancellable,
86 GError **error)
87{
88 CamelPOP3Store *store = CAMEL_POP3_STORE (service)((((CamelPOP3Store*) (void *) ((service)))));
89 CamelNetworkSettings *network_settings;
90 CamelNetworkSecurityMethod method;
91 CamelSettings *settings;
92 CamelStream *stream = NULL((void*)0);
93 CamelPOP3Engine *pop3_engine = NULL((void*)0);
94 CamelPOP3Command *pc;
95 GIOStream *base_stream;
96 GIOStream *tls_stream;
97 gboolean disable_extensions;
98 gboolean success = TRUE(!(0));
99 gchar *host;
100 guint32 flags = 0;
101 gint ret;
102 GError *local_error = NULL((void*)0);
103
104 settings = camel_service_ref_settings (service);
105
106 network_settings = CAMEL_NETWORK_SETTINGS (settings)((((CamelNetworkSettings*) (void *) ((settings)))));
107 host = camel_network_settings_dup_host (network_settings);
108 method = camel_network_settings_get_security_method (network_settings);
109
110 disable_extensions = camel_pop3_settings_get_disable_extensions (
111 CAMEL_POP3_SETTINGS (settings)((((CamelPOP3Settings*) (void *) ((settings))))));
112
113 g_object_unref (settings);
114
115 base_stream = camel_network_service_connect_sync (
116 CAMEL_NETWORK_SERVICE (service)((((CamelNetworkService*) (void *) ((service))))), cancellable, error);
117
118 if (base_stream != NULL((void*)0)) {
119 stream = camel_stream_new (base_stream);
120 g_object_unref (base_stream);
121 } else {
122 success = FALSE(0);
123 goto exit;
124 }
125
126 /* parent class connect initialization */
127 if (CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class)((((CamelServiceClass*) (void *) ((camel_pop3_store_parent_class
)))))
->
128 connect_sync (service, cancellable, error) == FALSE(0)) {
129 g_object_unref (stream);
130 success = FALSE(0);
131 goto exit;
132 }
133
134 if (disable_extensions)
135 flags |= CAMEL_POP3_ENGINE_DISABLE_EXTENSIONS;
136
137 if (!(pop3_engine = camel_pop3_engine_new (stream, flags, cancellable, &local_error)) ||
138 local_error != NULL((void*)0)) {
139 if (local_error)
140 g_propagate_error (error, local_error);
141 else
142 g_set_error (
143 error, CAMEL_ERROR(camel_error_quark ()), CAMEL_ERROR_GENERIC,
144 _("Failed to read a valid greeting from POP server %s")((char *) g_dgettext ("evolution-data-server", "Failed to read a valid greeting from POP server %s"
))
,
145 host);
146 g_object_unref (stream);
147 success = FALSE(0);
148 goto exit;
149 }
150
151 if (method != CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT) {
152 g_object_unref (stream);
153 goto exit;
154 }
155
156 if (!(pop3_engine->capa & CAMEL_POP3_CAP_STLS)) {
157 g_set_error (
158 error, CAMEL_ERROR(camel_error_quark ()), CAMEL_ERROR_GENERIC,
159 _("Failed to connect to POP server %s in secure mode: %s")((char *) g_dgettext ("evolution-data-server", "Failed to connect to POP server %s in secure mode: %s"
))
,
160 host, _("STLS not supported by server")((char *) g_dgettext ("evolution-data-server", "STLS not supported by server"
))
);
161 goto stls_exception;
162 }
163
164 pc = camel_pop3_engine_command_new (
165 pop3_engine, 0, NULL((void*)0), NULL((void*)0),
166 cancellable, error, "STLS\r\n");
167 while (camel_pop3_engine_iterate (pop3_engine, NULL((void*)0), cancellable, NULL((void*)0)) > 0)
168 ;
169
170 ret = pc->state == CAMEL_POP3_COMMAND_OK;
171 camel_pop3_engine_command_free (pop3_engine, pc);
172
173 if (ret == FALSE(0)) {
174 gchar *tmp;
175
176 tmp = get_valid_utf8_error ((gchar *) pop3_engine->line);
177 g_set_error (
178 error, CAMEL_ERROR(camel_error_quark ()), CAMEL_ERROR_GENERIC,
179 /* Translators: Last %s is an optional
180 * explanation beginning with ": " separator. */
181 _("Failed to connect to POP server %s in secure mode%s")((char *) g_dgettext ("evolution-data-server", "Failed to connect to POP server %s in secure mode%s"
))
,
182 host, (tmp != NULL((void*)0)) ? tmp : "");
183 g_free (tmp);
184 goto stls_exception;
185 }
186
187 /* Okay, now toggle SSL/TLS mode */
188 base_stream = camel_stream_ref_base_stream (stream);
189 tls_stream = camel_network_service_starttls (
190 CAMEL_NETWORK_SERVICE (service)((((CamelNetworkService*) (void *) ((service))))), base_stream, error);
191 g_object_unref (base_stream);
192
193 if (tls_stream != NULL((void*)0)) {
194 camel_stream_set_base_stream (stream, tls_stream);
195 /* Truncate any left cached input from the insecure part of the session */
196 camel_pop3_stream_discard_cache (pop3_engine->stream);
197 g_object_unref (tls_stream);
198 } else {
199 g_prefix_error (
200 error,
201 _("Failed to connect to POP server %s in secure mode: ")((char *) g_dgettext ("evolution-data-server", "Failed to connect to POP server %s in secure mode: "
))
,
202 host);
203 goto stls_exception;
204 }
205
206 g_clear_object (&stream)do { _Static_assert (sizeof *((&stream)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&stream
))) _pp = ((&stream)); __typeof__ (*((&stream))) _ptr
= *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr)
; } while (0)
;
207
208 /* rfc2595, section 4 states that after a successful STLS
209 * command, the client MUST discard prior CAPA responses */
210 if (!camel_pop3_engine_reget_capabilities (pop3_engine, cancellable, error))
211 goto exception;
212
213 goto exit;
214
215stls_exception:
216 /* As soon as we send a STLS command, all hope
217 * is lost of a clean QUIT if problems arise. */
218 /* if (clean_quit) {
219 / * try to disconnect cleanly * /
220 pc = camel_pop3_engine_command_new (
221 pop3_engine, 0, NULL, NULL,
222 cancellable, NULL, "QUIT\r\n");
223 while (camel_pop3_engine_iterate (pop3_engine, NULL, cancellable, NULL) > 0)
224 ;
225 camel_pop3_engine_command_free (pop3_engine, pc);
226 }*/
227
228exception:
229 g_clear_object (&stream)do { _Static_assert (sizeof *((&stream)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&stream
))) _pp = ((&stream)); __typeof__ (*((&stream))) _ptr
= *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr)
; } while (0)
;
230 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
231
232 success = FALSE(0);
233
234exit:
235 g_free (host);
236
237 g_mutex_lock (&store->priv->property_lock);
238 if (pop3_engine != NULL((void*)0))
239 store->priv->engine = g_object_ref (pop3_engine)((__typeof__ (pop3_engine)) (g_object_ref) (pop3_engine));
240 g_mutex_unlock (&store->priv->property_lock);
241
242 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
243
244 return success;
245}
246
247static CamelAuthenticationResult
248try_sasl (CamelPOP3Store *store,
249 const gchar *mechanism,
250 GCancellable *cancellable,
251 GError **error)
252{
253 CamelPOP3Engine *pop3_engine;
254 CamelPOP3Stream *pop3_stream;
255 CamelNetworkSettings *network_settings;
256 CamelAuthenticationResult result;
257 CamelSettings *settings;
258 CamelService *service;
259 guchar *line, *resp;
260 CamelSasl *sasl = NULL((void*)0);
261 gchar *string;
262 gchar *host;
263 guint len;
264 gint ret;
265
266 service = CAMEL_SERVICE (store)((((CamelService*) (void *) ((store)))));
267
268 settings = camel_service_ref_settings (service);
269
270 network_settings = CAMEL_NETWORK_SETTINGS (settings)((((CamelNetworkSettings*) (void *) ((settings)))));
271 host = camel_network_settings_dup_host (network_settings);
272
273 g_object_unref (settings);
274
275 pop3_engine = camel_pop3_store_ref_engine (store);
276 if (!pop3_engine) {
277 g_set_error_literal (
278 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
279 CAMEL_SERVICE_ERROR_UNAVAILABLE,
280 _("You must be working online to complete this operation")((char *) g_dgettext ("evolution-data-server", "You must be working online to complete this operation"
))
);
281 result = CAMEL_AUTHENTICATION_ERROR;
282 goto exit;
283 }
284
285 pop3_stream = pop3_engine->stream;
286
287 sasl = camel_sasl_new ("pop", mechanism, service);
288 if (sasl == NULL((void*)0)) {
289 g_set_error (
290 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
291 CAMEL_SERVICE_ERROR_URL_INVALID,
292 _("No support for %s authentication")((char *) g_dgettext ("evolution-data-server", "No support for %s authentication"
))
, mechanism);
293 result = CAMEL_AUTHENTICATION_ERROR;
294 goto exit;
295 }
296
297 string = g_strdup_printf ("AUTH %s\r\n", camel_sasl_is_xoauth2_alias (mechanism) ? "XOAUTH2" : mechanism);
298 ret = camel_stream_write_string (
299 CAMEL_STREAM (pop3_stream)((((CamelStream*) (void *) ((pop3_stream))))), string, cancellable, error);
300 g_free (string);
301
302 if (ret == -1)
303 goto ioerror;
304
305 while (1) {
306 GError *local_error = NULL((void*)0);
307
308 if (camel_pop3_stream_line (pop3_stream, &line, &len, cancellable, error) == -1)
309 goto ioerror;
310
311 if (strncmp ((gchar *) line, "+OK", 3) == 0) {
312 result = CAMEL_AUTHENTICATION_ACCEPTED;
313 break;
314 }
315
316 if (strncmp ((gchar *) line, "-ERR", 4) == 0) {
317 result = CAMEL_AUTHENTICATION_REJECTED;
318 break;
319 }
320
321 /* If we don't get continuation, or the sasl object's run out
322 * of work, or we don't get a challenge, its a protocol error,
323 * so fail, and try reset the server. */
324 if (strncmp ((gchar *) line, "+ ", 2) != 0
325 || camel_sasl_get_authenticated (sasl)
326 || (resp = (guchar *) camel_sasl_challenge_base64_sync (sasl, (const gchar *) line + 2, cancellable, &local_error)) == NULL((void*)0)) {
327 if (camel_stream_write_string (CAMEL_STREAM (pop3_stream)((((CamelStream*) (void *) ((pop3_stream))))), "*\r\n", cancellable, NULL((void*)0))) {
328 /* coverity[unchecked_value] */
329 if (!camel_pop3_stream_line (pop3_stream, &line, &len, cancellable, NULL((void*)0))) {
330 ;
331 }
332 }
333
334 if (local_error) {
335 g_propagate_error (error, local_error);
336 local_error = NULL((void*)0);
337 goto ioerror;
338 }
339
340 g_set_error (
341 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
342 CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
343 _("Cannot login to POP server %s: "((char *) g_dgettext ("evolution-data-server", "Cannot login to POP server %s: "
"SASL Protocol error"))
344 "SASL Protocol error")((char *) g_dgettext ("evolution-data-server", "Cannot login to POP server %s: "
"SASL Protocol error"))
, host);
345 result = CAMEL_AUTHENTICATION_ERROR;
346 goto exit;
347 }
348
349 string = g_strdup_printf ("%s\r\n", resp);
350 ret = camel_stream_write_string (
351 CAMEL_STREAM (pop3_stream)((((CamelStream*) (void *) ((pop3_stream))))), string, cancellable, error);
352 g_free (string);
353
354 g_free (resp);
355
356 if (ret == -1)
357 goto ioerror;
358
359 }
360
361 goto exit;
362
363ioerror:
364 g_prefix_error (
365 error, _("Failed to authenticate on POP server %s: ")((char *) g_dgettext ("evolution-data-server", "Failed to authenticate on POP server %s: "
))
, host);
366 result = CAMEL_AUTHENTICATION_ERROR;
367
368exit:
369 if (sasl != NULL((void*)0))
370 g_object_unref (sasl);
371
372 g_free (host);
373
374 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
375
376 return result;
377}
378
379static void
380pop3_store_set_property (GObject *object,
381 guint property_id,
382 const GValue *value,
383 GParamSpec *pspec)
384{
385 switch (property_id) {
386 case PROP_CONNECTABLE:
387 camel_network_service_set_connectable (
388 CAMEL_NETWORK_SERVICE (object)((((CamelNetworkService*) (void *) ((object))))),
389 g_value_get_object (value));
390 return;
391 }
392
393 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "/builds/GNOME/evolution-data-server/src/camel/providers/pop3/camel-pop3-store.c"
, 393, ("property"), _glib__property_id, _glib__pspec->name
, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (_glib__pspec
))->g_class))->g_type)))), (g_type_name ((((((GTypeClass
*) (((GTypeInstance*) (_glib__object))->g_class))->g_type
)))))); } while (0)
;
394}
395
396static void
397pop3_store_get_property (GObject *object,
398 guint property_id,
399 GValue *value,
400 GParamSpec *pspec)
401{
402 switch (property_id) {
403 case PROP_CONNECTABLE:
404 g_value_take_object (
405 value,
406 camel_network_service_ref_connectable (
407 CAMEL_NETWORK_SERVICE (object)((((CamelNetworkService*) (void *) ((object)))))));
408 return;
409
410 case PROP_HOST_REACHABLE:
411 g_value_set_boolean (
412 value,
413 camel_network_service_get_host_reachable (
414 CAMEL_NETWORK_SERVICE (object)((((CamelNetworkService*) (void *) ((object)))))));
415 return;
416 }
417
418 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "/builds/GNOME/evolution-data-server/src/camel/providers/pop3/camel-pop3-store.c"
, 418, ("property"), _glib__property_id, _glib__pspec->name
, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (_glib__pspec
))->g_class))->g_type)))), (g_type_name ((((((GTypeClass
*) (((GTypeInstance*) (_glib__object))->g_class))->g_type
)))))); } while (0)
;
419}
420
421static void
422pop3_store_dispose (GObject *object)
423{
424 CamelPOP3StorePrivate *priv;
425
426 priv = CAMEL_POP3_STORE (object)((((CamelPOP3Store*) (void *) ((object)))))->priv;
427
428 /* Force disconnect so we don't have it run
429 * later, after we've cleaned up some stuff. */
430 camel_service_disconnect_sync (
431 CAMEL_SERVICE (object)((((CamelService*) (void *) ((object))))), TRUE(!(0)), NULL((void*)0), NULL((void*)0));
432
433 g_clear_object (&priv->cache)do { _Static_assert (sizeof *((&priv->cache)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&priv->cache))) _pp = ((&priv->cache)); __typeof__
(*((&priv->cache))) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_object_unref) (_ptr); } while (0)
;
434 g_clear_object (&priv->engine)do { _Static_assert (sizeof *((&priv->engine)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&priv->engine))) _pp = ((&priv->engine)); __typeof__
(*((&priv->engine))) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_object_unref) (_ptr); } while (0)
;
435
436 /* Chain up to parent's dispose() method. */
437 G_OBJECT_CLASS (camel_pop3_store_parent_class)((((GObjectClass*) (void *) ((camel_pop3_store_parent_class))
)))
->dispose (object);
438}
439
440static void
441pop3_store_finalize (GObject *object)
442{
443 CamelPOP3StorePrivate *priv;
444
445 priv = CAMEL_POP3_STORE (object)((((CamelPOP3Store*) (void *) ((object)))))->priv;
446
447 g_mutex_clear (&priv->property_lock);
448
449 /* Chain up to parent's finalize() method. */
450 G_OBJECT_CLASS (camel_pop3_store_parent_class)((((GObjectClass*) (void *) ((camel_pop3_store_parent_class))
)))
->finalize (object);
451}
452
453static gchar *
454pop3_store_get_name (CamelService *service,
455 gboolean brief)
456{
457 CamelNetworkSettings *network_settings;
458 CamelSettings *settings;
459 gchar *host;
460 gchar *user;
461 gchar *name;
462
463 settings = camel_service_ref_settings (service);
464
465 network_settings = CAMEL_NETWORK_SETTINGS (settings)((((CamelNetworkSettings*) (void *) ((settings)))));
466 host = camel_network_settings_dup_host (network_settings);
467 user = camel_network_settings_dup_user (network_settings);
468
469 g_object_unref (settings);
470
471 if (brief)
472 name = g_strdup_printf (
473 _("POP3 server %s")((char *) g_dgettext ("evolution-data-server", "POP3 server %s"
))
, host);
474 else
475 name = g_strdup_printf (
476 _("POP3 server for %s on %s")((char *) g_dgettext ("evolution-data-server", "POP3 server for %s on %s"
))
, user, host);
477
478 g_free (host);
479 g_free (user);
480
481 return name;
482}
483
484/* Called by camel_data_cache_foreach_remove() for each cache file.
485 * Returns TRUE to delete the file, FALSE to keep it. */
486static gboolean
487pop3_migrate_cache_file_cb (CamelDataCache *cdc,
488 const gchar *filename,
489 gpointer user_data)
490{
491 guchar first_byte;
492 FILE *f;
493
494 f = fopen (filename, "rb");
495 if (f
0.1
'f' is not equal to NULL
== NULL((void*)0))
1
Taking false branch
496 return FALSE(0);
497
498 if (fread (&first_byte, 1, 1, f) != 1) {
2
Taking false branch
499 fclose (f);
500 return FALSE(0);
501 }
502
503 fclose (f);
504
505 if (first_byte == '*')
3
Assuming the condition is false
4
Taking false branch
506 return TRUE(!(0)); /* incomplete old download — let foreach_remove delete it */
507
508 if (first_byte == '#') {
5
Assuming the condition is true
6
Taking true branch
509 /* Complete old download: strip the sentinel byte by rewriting via a temp file. */
510 gchar *tmp_path;
511 gint tmp_fd;
512
513 tmp_path = g_strdup_printf ("%s.XXXXXX", filename);
514 tmp_fd = g_mkstemp (tmp_path);
515 if (tmp_fd != -1) {
7
Assuming the condition is true
8
Taking true branch
516 FILE *src, *dst;
517
518 close (tmp_fd);
519 src = fopen (filename, "rb");
520 dst = fopen (tmp_path, "wb");
521 if (src
8.1
'src' is not equal to NULL
!= NULL((void*)0) && dst
8.2
'dst' is not equal to NULL
!= NULL((void*)0)) {
9
Taking true branch
522 guchar buf[4096];
523 gsize nr;
524
525 fseek (src, 1, SEEK_SET0);
526 while ((nr = fread (buf, 1, sizeof (buf), src)) > 0)
10
Assuming stream reaches end-of-file here
11
Assuming the condition is true
12
Loop condition is true. Entering loop body
13
Read function called when stream is in EOF state. Function has no effect
527 fwrite (buf, 1, nr, dst);
528 fclose (src);
529 fclose (dst);
530 g_renamerename (tmp_path, filename);
531 } else {
532 if (src != NULL((void*)0))
533 fclose (src);
534 if (dst != NULL((void*)0)) {
535 fclose (dst);
536 g_unlink (tmp_path);
537 }
538 }
539 }
540
541 g_free (tmp_path);
542 }
543
544 return FALSE(0);
545}
546
547/* One-shot migration of old POP3 cache files that carry a sentinel byte.
548 *
549 * Before the atomic write API, cache files started with either '*' (write
550 * in progress, file is incomplete) or '#' (write finished, message follows
551 * from byte 1). New files contain the raw message from byte 0. This
552 * function rewrites every old '#'-prefixed file in place (stripping the
553 * sentinel) and deletes every '*'-prefixed file. A version marker is
554 * written afterwards so the scan is skipped on future connects. */
555static void
556pop3_store_migrate_cache_format (CamelDataCache *cache)
557{
558 const gchar *base_path;
559 gchar *ver_filename;
560 gchar *ver_content = NULL((void*)0);
561
562 base_path = camel_data_cache_get_path (cache);
563 ver_filename = g_build_filename (base_path, ".cache-format-version", NULL((void*)0));
564
565 if (g_file_get_contents (ver_filename, &ver_content, NULL((void*)0), NULL((void*)0)) &&
566 atoi (ver_content) >= 2) {
567 g_free (ver_content);
568 g_free (ver_filename);
569 return;
570 }
571
572 g_free (ver_content);
573
574 camel_data_cache_foreach_remove (cache, "cache", pop3_migrate_cache_file_cb, NULL((void*)0));
575
576 g_file_set_contents (ver_filename, "2\n", -1, NULL((void*)0));
577 g_free (ver_filename);
578}
579
580static gboolean
581pop3_store_connect_sync (CamelService *service,
582 GCancellable *cancellable,
583 GError **error)
584{
585 CamelPOP3Store *store = (CamelPOP3Store *) service;
586 CamelPOP3Engine *pop3_engine;
587 CamelSettings *settings;
588 CamelSession *session;
589 const gchar *user_data_dir;
590 gboolean success = TRUE(!(0));
591 gchar *mechanism;
592
593 /* Chain up to parent's method. */
594 if (!CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class)((((CamelServiceClass*) (void *) ((camel_pop3_store_parent_class
)))))
->connect_sync (service, cancellable, error))
595 return FALSE(0);
596
597 session = camel_service_ref_session (service);
598 user_data_dir = camel_service_get_user_data_dir (service);
599
600 settings = camel_service_ref_settings (service);
601
602 mechanism = camel_network_settings_dup_auth_mechanism (
603 CAMEL_NETWORK_SETTINGS (settings)((((CamelNetworkSettings*) (void *) ((settings))))));
604
605 g_object_unref (settings);
606
607 if (!session || !camel_session_get_online (session)) {
608 g_set_error (
609 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
610 CAMEL_SERVICE_ERROR_UNAVAILABLE,
611 _("You must be working online to complete this operation")((char *) g_dgettext ("evolution-data-server", "You must be working online to complete this operation"
))
);
612 success = FALSE(0);
613 goto exit;
614 }
615
616 g_mutex_lock (&store->priv->property_lock);
617
618 if (store->priv->cache == NULL((void*)0)) {
619 CamelDataCache *cache;
620
621 cache = camel_data_cache_new (user_data_dir, error);
622 if (cache != NULL((void*)0)) {
623 /* Ensure cache will never expire, otherwise
624 * it causes redownload of messages. */
625 camel_data_cache_set_expire_age (cache, -1);
626 camel_data_cache_set_expire_access (cache, -1);
627
628 store->priv->cache = g_object_ref (cache)((__typeof__ (cache)) (g_object_ref) (cache));
629
630 pop3_store_migrate_cache_format (cache);
631
632 g_object_unref (cache);
633 }
634 }
635
636 g_mutex_unlock (&store->priv->property_lock);
637
638 success = connect_to_server (service, cancellable, error);
639
640 if (!success)
641 goto exit;
642
643 success = camel_session_authenticate_sync (
644 session, service, mechanism, cancellable, error);
645
646 if (!success)
647 goto exit;
648
649 /* Now that we are in the TRANSACTION state,
650 * try regetting the capabilities */
651 pop3_engine = camel_pop3_store_ref_engine (store);
652 if (pop3_engine) {
653 pop3_engine->state = CAMEL_POP3_ENGINE_TRANSACTION;
654 if (!camel_pop3_engine_reget_capabilities (pop3_engine, cancellable, error))
655 success = FALSE(0);
656 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
657 } else {
658 g_set_error_literal (
659 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
660 CAMEL_SERVICE_ERROR_UNAVAILABLE,
661 _("You must be working online to complete this operation")((char *) g_dgettext ("evolution-data-server", "You must be working online to complete this operation"
))
);
662 success = FALSE(0);
663 }
664
665exit:
666 g_free (mechanism);
667
668 g_object_unref (session);
669
670 if (!success) {
671 /* to not leak possible connection to the server */
672 g_mutex_lock (&store->priv->property_lock);
673 g_clear_object (&store->priv->engine)do { _Static_assert (sizeof *((&store->priv->engine
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&store->priv->engine))) _pp = ((&store->
priv->engine)); __typeof__ (*((&store->priv->engine
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
674 g_mutex_unlock (&store->priv->property_lock);
675 }
676
677 return success;
678}
679
680static gboolean
681pop3_store_disconnect_sync (CamelService *service,
682 gboolean clean,
683 GCancellable *cancellable,
684 GError **error)
685{
686 CamelServiceClass *service_class;
687 CamelPOP3Store *store = CAMEL_POP3_STORE (service)((((CamelPOP3Store*) (void *) ((service)))));
688 gboolean success;
689
690 if (clean) {
691 CamelPOP3Engine *pop3_engine;
692 CamelPOP3Command *pc;
693
694 pop3_engine = camel_pop3_store_ref_engine (store);
695
696 if (pop3_engine) {
697 if (camel_pop3_engine_busy_lock (pop3_engine, cancellable, NULL((void*)0))) {
698 pc = camel_pop3_engine_command_new (
699 pop3_engine, 0, NULL((void*)0), NULL((void*)0),
700 cancellable, error, "QUIT\r\n");
701 while (camel_pop3_engine_iterate (pop3_engine, NULL((void*)0), cancellable, NULL((void*)0)) > 0)
702 ;
703 camel_pop3_engine_command_free (pop3_engine, pc);
704 camel_pop3_engine_busy_unlock (pop3_engine);
705 }
706
707 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
708 }
709 }
710
711 /* Chain up to parent's disconnect() method. */
712 service_class = CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class)((((CamelServiceClass*) (void *) ((camel_pop3_store_parent_class
)))))
;
713
714 success = service_class->disconnect_sync (service, clean, cancellable, error);
715
716 g_mutex_lock (&store->priv->property_lock);
717 g_clear_object (&store->priv->engine)do { _Static_assert (sizeof *((&store->priv->engine
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&store->priv->engine))) _pp = ((&store->
priv->engine)); __typeof__ (*((&store->priv->engine
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
718 g_mutex_unlock (&store->priv->property_lock);
719
720 return success;
721}
722
723static CamelAuthenticationResult
724pop3_store_authenticate_sync (CamelService *service,
725 const gchar *mechanism,
726 GCancellable *cancellable,
727 GError **error)
728{
729 CamelPOP3Store *store = CAMEL_POP3_STORE (service)((((CamelPOP3Store*) (void *) ((service)))));
730 CamelNetworkSettings *network_settings;
731 CamelAuthenticationResult result;
732 CamelSettings *settings;
733 CamelPOP3Command *pcu = NULL((void*)0);
734 CamelPOP3Command *pcp = NULL((void*)0);
735 CamelPOP3Engine *pop3_engine;
736 const gchar *password;
737 gboolean enable_utf8;
738 gchar *host;
739 gchar *user;
740 gint status;
741
742 password = camel_service_get_password (service);
743
744 settings = camel_service_ref_settings (service);
745 enable_utf8 = camel_pop3_settings_get_enable_utf8 (CAMEL_POP3_SETTINGS (settings)((((CamelPOP3Settings*) (void *) ((settings))))));
746
747 network_settings = CAMEL_NETWORK_SETTINGS (settings)((((CamelNetworkSettings*) (void *) ((settings)))));
748 host = camel_network_settings_dup_host (network_settings);
749 user = camel_network_settings_dup_user (network_settings);
750
751 g_object_unref (settings);
752
753 pop3_engine = camel_pop3_store_ref_engine (store);
754 if (!pop3_engine) {
755 g_set_error_literal (
756 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
757 CAMEL_SERVICE_ERROR_UNAVAILABLE,
758 _("You must be working online to complete this operation")((char *) g_dgettext ("evolution-data-server", "You must be working online to complete this operation"
))
);
759 result = CAMEL_AUTHENTICATION_ERROR;
760 goto exit;
761 }
762
763 if (!camel_pop3_engine_busy_lock (pop3_engine, cancellable, error)) {
764 g_free (host);
765 g_free (user);
766 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
767
768 return CAMEL_AUTHENTICATION_ERROR;
769 }
770
771 if ((pop3_engine->capa & CAMEL_POP3_CAP_UTF8) != 0 && enable_utf8) {
772 pcu = camel_pop3_engine_command_new (
773 pop3_engine, 0, NULL((void*)0), NULL((void*)0), cancellable, error,
774 "UTF8\r\n");
775 if (error && *error) {
776 g_prefix_error (
777 error,
778 _("Unable to connect to POP server %s.\n"((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error enabling UTF-8 mode: "))
779 "Error enabling UTF-8 mode: ")((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error enabling UTF-8 mode: "))
, host);
780 result = CAMEL_AUTHENTICATION_ERROR;
781 goto exit;
782 }
783 while (camel_pop3_engine_iterate (pop3_engine, NULL((void*)0), cancellable, NULL((void*)0)) > 0)
784 ;
785 camel_pop3_engine_command_free (pop3_engine, pcu);
786 pcu = NULL((void*)0);
787 }
788
789 if (mechanism == NULL((void*)0)) {
790 if (password == NULL((void*)0)) {
791 g_set_error_literal (
792 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
793 CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
794 _("Authentication password not available")((char *) g_dgettext ("evolution-data-server", "Authentication password not available"
))
);
795 result = CAMEL_AUTHENTICATION_ERROR;
796 goto exit;
797 }
798
799 /* Sanitize user and password to prevent CRLF injection
800 * into POP3 protocol commands */
801 if (strchr (user, '\r') || strchr (user, '\n') ||
802 strchr (password, '\r') || strchr (password, '\n')) {
803 g_set_error_literal (
804 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
805 CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
806 _("Username or password contains invalid characters")((char *) g_dgettext ("evolution-data-server", "Username or password contains invalid characters"
))
);
807 result = CAMEL_AUTHENTICATION_ERROR;
808 goto exit;
809 }
810
811 /* pop engine will take care of pipelining ability */
812 pcu = camel_pop3_engine_command_new (
813 pop3_engine, 0, NULL((void*)0), NULL((void*)0), cancellable, error,
814 "USER %s\r\n", user);
815 if (error && *error) {
816 g_prefix_error (
817 error,
818 _("Unable to connect to POP server %s.\n"((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error sending password: "))
819 "Error sending password: ")((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error sending password: "))
, host);
820 result = CAMEL_AUTHENTICATION_ERROR;
821 goto exit;
822 }
823
824 pcp = camel_pop3_engine_command_new (
825 pop3_engine, 0, NULL((void*)0), NULL((void*)0), cancellable, error,
826 "PASS %s\r\n", password);
827
828 if (error && *error) {
829 g_prefix_error (
830 error,
831 _("Unable to connect to POP server %s.\n"((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error sending password: "))
832 "Error sending password: ")((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error sending password: "))
, host);
833 result = CAMEL_AUTHENTICATION_ERROR;
834 goto exit;
835 }
836 } else if (strcmp (mechanism, "+APOP") == 0 && pop3_engine->apop) {
837 GChecksum *checksum;
838 gchar *d;
839
840 if (password == NULL((void*)0)) {
841 g_set_error_literal (
842 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
843 CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
844 _("Authentication password not available")((char *) g_dgettext ("evolution-data-server", "Authentication password not available"
))
);
845 result = CAMEL_AUTHENTICATION_ERROR;
846 goto exit;
847 }
848
849 d = pop3_engine->apop;
850
851 while (*d != '\0') {
852 if (!isascii ((gint) * d)((((gint) * d) & ~0x7f) == 0)) {
853
854 g_set_error (
855 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
856 CAMEL_SERVICE_ERROR_URL_INVALID,
857 /* Translators: Do not translate APOP. */
858 _("Unable to connect to POP server %s: "((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s: "
"Invalid APOP ID received. Impersonation " "attack suspected. Please contact your admin."
))
859 "Invalid APOP ID received. Impersonation "((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s: "
"Invalid APOP ID received. Impersonation " "attack suspected. Please contact your admin."
))
860 "attack suspected. Please contact your admin.")((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s: "
"Invalid APOP ID received. Impersonation " "attack suspected. Please contact your admin."
))
,
861 host);
862
863 result = CAMEL_AUTHENTICATION_ERROR;
864 goto exit;
865 }
866 d++;
867 }
868
869 checksum = g_checksum_new (G_CHECKSUM_MD5);
870 g_checksum_update (checksum, (const guchar *) pop3_engine->apop, strlen (pop3_engine->apop));
871 g_checksum_update (checksum, (const guchar *) (password ? password : ""), strlen (password ? password : ""));
872
873 pcp = camel_pop3_engine_command_new (
874 pop3_engine, 0, NULL((void*)0), NULL((void*)0), cancellable, error,
875 "APOP %s %s\r\n", user, g_checksum_get_string (checksum));
876
877 g_checksum_free (checksum);
878 } else {
879 GList *link;
880 const gchar *test_mechanism = mechanism;
881
882 if (camel_sasl_is_xoauth2_alias (test_mechanism))
883 test_mechanism = "XOAUTH2";
884
885 link = pop3_engine->auth;
886 while (link != NULL((void*)0)) {
887 CamelServiceAuthType *auth = link->data;
888
889 if (g_strcmp0 (auth->authproto, test_mechanism) == 0) {
890 result = try_sasl (
891 store, mechanism,
892 cancellable, error);
893 goto exit;
894 }
895 link = g_list_next (link)((link) ? (((GList *)(link))->next) : ((void*)0));
896 }
897
898 g_set_error (
899 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
900 CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
901 _("No support for %s authentication")((char *) g_dgettext ("evolution-data-server", "No support for %s authentication"
))
, mechanism);
902 result = CAMEL_AUTHENTICATION_ERROR;
903 goto exit;
904 }
905
906 while ((status = camel_pop3_engine_iterate (pop3_engine, pcp, cancellable, error)) > 0)
907 ;
908
909 if (status == -1) {
910 g_prefix_error (
911 error,
912 _("Unable to connect to POP server %s.\n"((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error sending password: "))
913 "Error sending password: ")((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error sending password: "))
, host);
914 result = CAMEL_AUTHENTICATION_ERROR;
915
916 } else if (pcu && pcu->state != CAMEL_POP3_COMMAND_OK) {
917 gchar *tmp;
918
919 /* Abort authentication if the server rejects the user
920 * name. Reprompting for a password won't do any good. */
921 tmp = get_valid_utf8_error ((gchar *) pop3_engine->line);
922 g_set_error (
923 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
924 CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
925 /* Translators: Last %s is an optional explanation
926 * beginning with ": " separator. */
927 _("Unable to connect to POP server %s.\n"((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error sending username%s"))
928 "Error sending username%s")((char *) g_dgettext ("evolution-data-server", "Unable to connect to POP server %s.\n"
"Error sending username%s"))
,
929 host, (tmp != NULL((void*)0)) ? tmp : "");
930 g_free (tmp);
931 result = CAMEL_AUTHENTICATION_ERROR;
932
933 } else if (pcp->state != CAMEL_POP3_COMMAND_OK) {
934 result = CAMEL_AUTHENTICATION_REJECTED;
935 } else {
936 result = CAMEL_AUTHENTICATION_ACCEPTED;
937 }
938
939exit:
940 if (pcp != NULL((void*)0))
941 camel_pop3_engine_command_free (pop3_engine, pcp);
942
943 if (pcu != NULL((void*)0))
944 camel_pop3_engine_command_free (pop3_engine, pcu);
945
946 g_free (host);
947 g_free (user);
948
949 camel_pop3_engine_busy_unlock (pop3_engine);
950 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
951
952 return result;
953}
954
955static GList *
956pop3_store_query_auth_types_sync (CamelService *service,
957 GCancellable *cancellable,
958 GError **error)
959{
960 CamelServiceClass *service_class;
961 CamelPOP3Store *store = CAMEL_POP3_STORE (service)((((CamelPOP3Store*) (void *) ((service)))));
962 GList *types = NULL((void*)0);
963 GError *local_error = NULL((void*)0);
964
965 /* Chain up to parent's query_auth_types() method. */
966 service_class = CAMEL_SERVICE_CLASS (camel_pop3_store_parent_class)((((CamelServiceClass*) (void *) ((camel_pop3_store_parent_class
)))))
;
967 types = service_class->query_auth_types_sync (
968 service, cancellable, &local_error);
969
970 if (local_error != NULL((void*)0)) {
971 g_propagate_error (error, local_error);
972 return NULL((void*)0);
973 }
974
975 if (connect_to_server (service, cancellable, error)) {
976 CamelPOP3Engine *pop3_engine;
977
978 pop3_engine = camel_pop3_store_ref_engine (store);
979
980 if (pop3_engine) {
981 types = g_list_concat (types, g_list_copy (pop3_engine->auth));
982 pop3_store_disconnect_sync (service, TRUE(!(0)), cancellable, NULL((void*)0));
983
984 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
985 }
986 }
987
988 return types;
989}
990
991static gboolean
992pop3_store_can_refresh_folder (CamelStore *store,
993 CamelFolderInfo *info,
994 GError **error)
995{
996 /* any pop3 folder can be refreshed */
997 return TRUE(!(0));
998}
999
1000static CamelFolder *
1001pop3_store_get_folder_sync (CamelStore *store,
1002 const gchar *folder_name,
1003 CamelStoreGetFolderFlags flags,
1004 GCancellable *cancellable,
1005 GError **error)
1006{
1007 if (g_ascii_strcasecmp (folder_name, "inbox") != 0) {
1008 g_set_error (
1009 error, CAMEL_FOLDER_ERROR(camel_folder_error_quark ()),
1010 CAMEL_FOLDER_ERROR_INVALID,
1011 _("No such folder “%s”.")((char *) g_dgettext ("evolution-data-server", "No such folder “%s”."
))
, folder_name);
1012 return NULL((void*)0);
1013 }
1014
1015 return camel_pop3_folder_new (store, cancellable, error);
1016}
1017
1018static CamelFolderInfo *
1019pop3_store_get_folder_info_sync (CamelStore *store,
1020 const gchar *top,
1021 CamelStoreGetFolderInfoFlags flags,
1022 GCancellable *cancellable,
1023 GError **error)
1024{
1025 g_set_error (
1026 error, CAMEL_STORE_ERROR(camel_store_error_quark ()),
1027 CAMEL_STORE_ERROR_NO_FOLDER,
1028 _("POP3 stores have no folder hierarchy")((char *) g_dgettext ("evolution-data-server", "POP3 stores have no folder hierarchy"
))
);
1029
1030 return NULL((void*)0);
1031}
1032
1033static CamelFolder *
1034pop3_store_get_trash_folder_sync (CamelStore *store,
1035 GCancellable *cancellable,
1036 GError **error)
1037{
1038 /* no-op */
1039 return NULL((void*)0);
1040}
1041
1042static const gchar *
1043pop3_store_get_service_name (CamelNetworkService *service,
1044 CamelNetworkSecurityMethod method)
1045{
1046 const gchar *service_name;
1047
1048 switch (method) {
1049 case CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT:
1050 service_name = "pop3s";
1051 break;
1052
1053 default:
1054 service_name = "pop3";
1055 break;
1056 }
1057
1058 return service_name;
1059}
1060
1061static guint16
1062pop3_store_get_default_port (CamelNetworkService *service,
1063 CamelNetworkSecurityMethod method)
1064{
1065 guint16 default_port;
1066
1067 switch (method) {
1068 case CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT:
1069 default_port = POP3S_PORT995;
1070 break;
1071
1072 default:
1073 default_port = POP3_PORT110;
1074 break;
1075 }
1076
1077 return default_port;
1078}
1079
1080static void
1081camel_pop3_store_class_init (CamelPOP3StoreClass *class)
1082{
1083 GObjectClass *object_class;
1084 CamelServiceClass *service_class;
1085 CamelStoreClass *store_class;
1086
1087 object_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) ((class)))));
1088 object_class->set_property = pop3_store_set_property;
1089 object_class->get_property = pop3_store_get_property;
1090 object_class->dispose = pop3_store_dispose;
1091 object_class->finalize = pop3_store_finalize;
1092
1093 service_class = CAMEL_SERVICE_CLASS (class)((((CamelServiceClass*) (void *) ((class)))));
1094 service_class->settings_type = CAMEL_TYPE_POP3_SETTINGS(camel_pop3_settings_get_type ());
1095 service_class->get_name = pop3_store_get_name;
1096 service_class->connect_sync = pop3_store_connect_sync;
1097 service_class->disconnect_sync = pop3_store_disconnect_sync;
1098 service_class->authenticate_sync = pop3_store_authenticate_sync;
1099 service_class->query_auth_types_sync = pop3_store_query_auth_types_sync;
1100
1101 store_class = CAMEL_STORE_CLASS (class)((((CamelStoreClass*) (void *) ((class)))));
1102 store_class->can_refresh_folder = pop3_store_can_refresh_folder;
1103 store_class->get_folder_sync = pop3_store_get_folder_sync;
1104 store_class->get_folder_info_sync = pop3_store_get_folder_info_sync;
1105 store_class->get_trash_folder_sync = pop3_store_get_trash_folder_sync;
1106
1107 /* Inherited from CamelNetworkService. */
1108 g_object_class_override_property (
1109 object_class,
1110 PROP_CONNECTABLE,
1111 "connectable");
1112
1113 /* Inherited from CamelNetworkService. */
1114 g_object_class_override_property (
1115 object_class,
1116 PROP_HOST_REACHABLE,
1117 "host-reachable");
1118}
1119
1120static void
1121camel_network_service_init (CamelNetworkServiceInterface *iface)
1122{
1123 iface->get_service_name = pop3_store_get_service_name;
1124 iface->get_default_port = pop3_store_get_default_port;
1125}
1126
1127static void
1128camel_pop3_store_init (CamelPOP3Store *pop3_store)
1129{
1130 pop3_store->priv = camel_pop3_store_get_instance_private (pop3_store);
1131
1132 g_mutex_init (&pop3_store->priv->property_lock);
1133}
1134
1135/**
1136 * camel_pop3_store_ref_cache:
1137 * @store: a #CamelPOP3Store
1138 *
1139 * Returns the #CamelDataCache for @store.
1140 *
1141 * The returned #CamelDataCache is referenced for thread-safety and must be
1142 * unreferenced with g_object_unref() when finished with it.
1143 *
1144 * Returns: a #CamelDataCache
1145 **/
1146CamelDataCache *
1147camel_pop3_store_ref_cache (CamelPOP3Store *store)
1148{
1149 CamelDataCache *cache = NULL((void*)0);
1150
1151 g_return_val_if_fail (CAMEL_IS_POP3_STORE (store), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_21
= 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((store)); GType __t = ((camel_pop3_store_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_21
= 1; _g_boolean_var_21; }), 1))) { } else { g_return_if_fail_warning
("camel-pop3-provider", ((const char*) (__func__)), "CAMEL_IS_POP3_STORE (store)"
); return (((void*)0)); } } while (0)
;
1152
1153 g_mutex_lock (&store->priv->property_lock);
1154
1155 if (store->priv->cache != NULL((void*)0))
1156 cache = g_object_ref (store->priv->cache)((__typeof__ (store->priv->cache)) (g_object_ref) (store
->priv->cache))
;
1157
1158 g_mutex_unlock (&store->priv->property_lock);
1159
1160 return cache;
1161}
1162
1163/**
1164 * camel_pop3_store_ref_engine:
1165 * @store: a #CamelPOP3Store
1166 *
1167 * Returns the #CamelPOP3Engine for @store.
1168 *
1169 * The returned #CamelPOP3Engine is referenced for thread-safety and must be
1170 * unreferenced with g_object_unref() when finished with it.
1171 *
1172 * Returns: a #CamelPOP3Store
1173 **/
1174CamelPOP3Engine *
1175camel_pop3_store_ref_engine (CamelPOP3Store *store)
1176{
1177 CamelPOP3Engine *engine = NULL((void*)0);
1178
1179 g_return_val_if_fail (CAMEL_IS_POP3_STORE (store), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_22
= 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((store)); GType __t = ((camel_pop3_store_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_22
= 1; _g_boolean_var_22; }), 1))) { } else { g_return_if_fail_warning
("camel-pop3-provider", ((const char*) (__func__)), "CAMEL_IS_POP3_STORE (store)"
); return (((void*)0)); } } while (0)
;
1180
1181 g_mutex_lock (&store->priv->property_lock);
1182
1183 if (store->priv->engine != NULL((void*)0))
1184 engine = g_object_ref (store->priv->engine)((__typeof__ (store->priv->engine)) (g_object_ref) (store
->priv->engine))
;
1185
1186 g_mutex_unlock (&store->priv->property_lock);
1187
1188 return engine;
1189}
1190
1191/**
1192 * camel_pop3_store_expunge:
1193 * @store: a #CamelPOP3Store
1194 * @error: return location for a #GError, or %NULL
1195 * @cancellable: optional #GCancellable object, or %NULL
1196 *
1197 * Expunge messages from the store. This will result in the connection
1198 * being closed, which may cause later commands to fail if they can't
1199 * reconnect.
1200 **/
1201gboolean
1202camel_pop3_store_expunge (CamelPOP3Store *store,
1203 GCancellable *cancellable,
1204 GError **error)
1205{
1206 CamelPOP3Command *pc;
1207 CamelPOP3Engine *pop3_engine;
1208 CamelServiceConnectionStatus status;
1209
1210 status = camel_service_get_connection_status (CAMEL_SERVICE (store)((((CamelService*) (void *) ((store))))));
1211
1212 if (status != CAMEL_SERVICE_CONNECTED) {
1213 g_set_error (
1214 error, CAMEL_SERVICE_ERROR(camel_service_error_quark ()),
1215 CAMEL_SERVICE_ERROR_UNAVAILABLE,
1216 _("You must be working online to complete this operation")((char *) g_dgettext ("evolution-data-server", "You must be working online to complete this operation"
))
);
1217 return FALSE(0);
1218 }
1219
1220 pop3_engine = camel_pop3_store_ref_engine (store);
1221
1222 if (!camel_pop3_engine_busy_lock (pop3_engine, cancellable, error)) {
1223 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
1224 return FALSE(0);
1225 }
1226
1227 pc = camel_pop3_engine_command_new (
1228 pop3_engine, 0, NULL((void*)0), NULL((void*)0), cancellable, error, "QUIT\r\n");
1229
1230 while (camel_pop3_engine_iterate (pop3_engine, NULL((void*)0), cancellable, NULL((void*)0)) > 0)
1231 ;
1232
1233 camel_pop3_engine_command_free (pop3_engine, pc);
1234
1235 camel_pop3_engine_busy_unlock (pop3_engine);
1236 g_clear_object (&pop3_engine)do { _Static_assert (sizeof *((&pop3_engine)) == sizeof (
gpointer), "Expression evaluates to false"); __typeof__ (((&
pop3_engine))) _pp = ((&pop3_engine)); __typeof__ (*((&
pop3_engine))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
1237
1238 return TRUE(!(0));
1239}
1240
1241/**
1242 * camel_pop3_store_cache_add:
1243 * @store: a #CamelPOP3Store
1244 * @uid: a message UID
1245 * @out_io_stream: (out) (transfer full): return location for the
1246 * underlying #GIOStream opened for atomic writing
1247 * @error: return location for a #GError, or %NULL
1248 *
1249 * Creates a cache file for @uid in @store and returns a #CamelStream for
1250 * writing to it. On success the underlying atomic #GIOStream is also
1251 * returned in @out_io_stream (transfer full); the caller must pass it to
1252 * camel_data_cache_commit_atomic() on success or
1253 * camel_data_cache_discard_atomic() on failure. If an error occurs the
1254 * function sets @error and returns %NULL.
1255 *
1256 * The returned #CamelStream is referenced for thread-safety and must be
1257 * unreferenced when finished with it.
1258 *
1259 * Returns: a #CamelStream, or %NULL on error
1260 **/
1261CamelStream *
1262camel_pop3_store_cache_add (CamelPOP3Store *store,
1263 const gchar *uid,
1264 GIOStream **out_io_stream,
1265 GError **error)
1266{
1267 CamelDataCache *cache;
1268 GIOStream *base_stream;
1269 CamelStream *stream = NULL((void*)0);
1270
1271 g_return_val_if_fail (CAMEL_IS_POP3_STORE (store), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_23
= 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((store)); GType __t = ((camel_pop3_store_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_23
= 1; _g_boolean_var_23; }), 1))) { } else { g_return_if_fail_warning
("camel-pop3-provider", ((const char*) (__func__)), "CAMEL_IS_POP3_STORE (store)"
); return (((void*)0)); } } while (0)
;
1272 g_return_val_if_fail (uid != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_24
= 0; if (uid != ((void*)0)) _g_boolean_var_24 = 1; _g_boolean_var_24
; }), 1))) { } else { g_return_if_fail_warning ("camel-pop3-provider"
, ((const char*) (__func__)), "uid != NULL"); return (((void*
)0)); } } while (0)
;
1273 g_return_val_if_fail (out_io_stream != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_25
= 0; if (out_io_stream != ((void*)0)) _g_boolean_var_25 = 1;
_g_boolean_var_25; }), 1))) { } else { g_return_if_fail_warning
("camel-pop3-provider", ((const char*) (__func__)), "out_io_stream != NULL"
); return (((void*)0)); } } while (0)
;
1274
1275 *out_io_stream = NULL((void*)0);
1276
1277 cache = camel_pop3_store_ref_cache (store);
1278 g_return_val_if_fail (cache != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_26
= 0; if (cache != ((void*)0)) _g_boolean_var_26 = 1; _g_boolean_var_26
; }), 1))) { } else { g_return_if_fail_warning ("camel-pop3-provider"
, ((const char*) (__func__)), "cache != NULL"); return (((void
*)0)); } } while (0)
;
1279
1280 base_stream = camel_data_cache_add_atomic (cache, "cache", uid, error);
1281 if (base_stream != NULL((void*)0)) {
1282 stream = camel_stream_new (base_stream);
1283 *out_io_stream = base_stream;
1284 }
1285
1286 g_object_unref (cache);
1287
1288 return stream;
1289}
1290
1291/**
1292 * camel_pop3_store_cache_get:
1293 * @store: a #CamelPOP3Store
1294 * @uid: a message UID
1295 * @error: return location for a #GError, or %NULL
1296 *
1297 * Opens the cache file for @uid in @store and returns a #CamelStream for it.
1298 * If no matching cache file exists, the function returns %NULL. If an error
1299 * occurs in opening the cache file, the function sets @error and returns
1300 * %NULL.
1301 *
1302 * The returned #CamelStream is referenced for thread-safety and must be
1303 * unreferenced when finished with it.
1304 *
1305 * Returns: (nullable): a #CamelStream, or %NULL
1306 **/
1307CamelStream *
1308camel_pop3_store_cache_get (CamelPOP3Store *store,
1309 const gchar *uid,
1310 GError **error)
1311{
1312 CamelDataCache *cache;
1313 GIOStream *base_stream;
1314 CamelStream *stream = NULL((void*)0);
1315
1316 g_return_val_if_fail (CAMEL_IS_POP3_STORE (store), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_27
= 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((store)); GType __t = ((camel_pop3_store_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_27
= 1; _g_boolean_var_27; }), 1))) { } else { g_return_if_fail_warning
("camel-pop3-provider", ((const char*) (__func__)), "CAMEL_IS_POP3_STORE (store)"
); return (((void*)0)); } } while (0)
;
1317 g_return_val_if_fail (uid != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_28
= 0; if (uid != ((void*)0)) _g_boolean_var_28 = 1; _g_boolean_var_28
; }), 1))) { } else { g_return_if_fail_warning ("camel-pop3-provider"
, ((const char*) (__func__)), "uid != NULL"); return (((void*
)0)); } } while (0)
;
1318
1319 cache = camel_pop3_store_ref_cache (store);
1320 g_return_val_if_fail (cache != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_29
= 0; if (cache != ((void*)0)) _g_boolean_var_29 = 1; _g_boolean_var_29
; }), 1))) { } else { g_return_if_fail_warning ("camel-pop3-provider"
, ((const char*) (__func__)), "cache != NULL"); return (((void
*)0)); } } while (0)
;
1321
1322 base_stream = camel_data_cache_get (cache, "cache", uid, error);
1323 if (base_stream != NULL((void*)0)) {
1324 stream = camel_stream_new (base_stream);
1325 g_object_unref (base_stream);
1326 }
1327
1328 g_object_unref (cache);
1329
1330 return stream;
1331}
1332
1333/**
1334 * camel_pop3_store_cache_has:
1335 * @store: a #CamelPOP3Store
1336 * @uid: a message UID
1337 *
1338 * Returns whether @store has a cached message for @uid.
1339 *
1340 * Returns: whether @uid is cached
1341 **/
1342gboolean
1343camel_pop3_store_cache_has (CamelPOP3Store *store,
1344 const gchar *uid)
1345{
1346 CamelStream *stream;
1347 gboolean uid_is_cached;
1348
1349 g_return_val_if_fail (CAMEL_IS_POP3_STORE (store), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_30
= 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((store)); GType __t = ((camel_pop3_store_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_30
= 1; _g_boolean_var_30; }), 1))) { } else { g_return_if_fail_warning
("camel-pop3-provider", ((const char*) (__func__)), "CAMEL_IS_POP3_STORE (store)"
); return ((0)); } } while (0)
;
1350 g_return_val_if_fail (uid != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_31
= 0; if (uid != ((void*)0)) _g_boolean_var_31 = 1; _g_boolean_var_31
; }), 1))) { } else { g_return_if_fail_warning ("camel-pop3-provider"
, ((const char*) (__func__)), "uid != NULL"); return ((0)); }
} while (0)
;
1351
1352 stream = camel_pop3_store_cache_get (store, uid, NULL((void*)0));
1353 uid_is_cached = (stream != NULL((void*)0));
1354 g_clear_object (&stream)do { _Static_assert (sizeof *((&stream)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&stream
))) _pp = ((&stream)); __typeof__ (*((&stream))) _ptr
= *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr)
; } while (0)
;
1355
1356 return uid_is_cached;
1357}
1358