/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* camel-disco-diary.c: class for a disconnected operation log */ /* * Authors: Dan Winship * * Copyright (C) 2001 Ximian, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #ifdef HAVE_CONFIG_H #include #endif #include "camel-disco-diary.h" #include "camel-disco-folder.h" #include "camel-disco-store.h" #include "camel-exception.h" #include "camel-file-utils.h" #include "camel-folder.h" #include "camel-operation.h" #include "camel-session.h" #include "camel-store.h" #include static void camel_disco_diary_class_init (CamelDiscoDiaryClass *camel_disco_diary_class) { /* virtual method definition */ } static void camel_disco_diary_init (CamelDiscoDiary *diary) { diary->folders = g_hash_table_new (g_str_hash, g_str_equal); diary->uidmap = g_hash_table_new (g_str_hash, g_str_equal); } static void unref_folder (gpointer key, gpointer value, gpointer data) { camel_object_unref (value); } static void free_uid (gpointer key, gpointer value, gpointer data) { g_free (key); g_free (value); } static void camel_disco_diary_finalize (CamelDiscoDiary *diary) { if (diary->file) fclose (diary->file); if (diary->folders) { g_hash_table_foreach (diary->folders, unref_folder, NULL); g_hash_table_destroy (diary->folders); } if (diary->uidmap) { g_hash_table_foreach (diary->uidmap, free_uid, NULL); g_hash_table_destroy (diary->uidmap); } } CamelType camel_disco_diary_get_type (void) { static CamelType camel_disco_diary_type = CAMEL_INVALID_TYPE; if (camel_disco_diary_type == CAMEL_INVALID_TYPE) { camel_disco_diary_type = camel_type_register ( CAMEL_OBJECT_TYPE, "CamelDiscoDiary", sizeof (CamelDiscoDiary), sizeof (CamelDiscoDiaryClass), (CamelObjectClassInitFunc) camel_disco_diary_class_init, NULL, (CamelObjectInitFunc) camel_disco_diary_init, (CamelObjectFinalizeFunc) camel_disco_diary_finalize); } return camel_disco_diary_type; } static int diary_encode_uids (CamelDiscoDiary *diary, GPtrArray *uids) { int i, status; status = camel_file_util_encode_uint32 (diary->file, uids->len); for (i = 0; status != -1 && i < uids->len; i++) status = camel_file_util_encode_string (diary->file, uids->pdata[i]); return status; } void camel_disco_diary_log (CamelDiscoDiary *diary, CamelDiscoDiaryAction action, ...) { va_list ap; int status; /* You may already be a loser. */ if (!diary->file) return; status = camel_file_util_encode_uint32 (diary->file, action); if (status == -1) goto lose; va_start (ap, action); switch (action) { case CAMEL_DISCO_DIARY_FOLDER_EXPUNGE: { CamelFolder *folder = va_arg (ap, CamelFolder *); GPtrArray *uids = va_arg (ap, GPtrArray *); status = camel_file_util_encode_string (diary->file, folder->full_name); if (status != -1) status = diary_encode_uids (diary, uids); break; } case CAMEL_DISCO_DIARY_FOLDER_APPEND: { CamelFolder *folder = va_arg (ap, CamelFolder *); char *uid = va_arg (ap, char *); status = camel_file_util_encode_string (diary->file, folder->full_name); if (status != -1) status = camel_file_util_encode_string (diary->file, uid); break; } case CAMEL_DISCO_DIARY_FOLDER_TRANSFER: { CamelFolder *source = va_arg (ap, CamelFolder *); CamelFolder *destination = va_arg (ap, CamelFolder *); GPtrArray *uids = va_arg (ap, GPtrArray *); gboolean delete_originals = va_arg (ap, gboolean); status = camel_file_util_encode_string (diary->file, source->full_name); if (status == -1) break; status = camel_file_util_encode_string (diary->file, destination->full_name); if (status == -1) break; status = diary_encode_uids (diary, uids); if (status == -1) break; status = camel_file_util_encode_uint32 (diary->file, delete_originals); break; } default: g_assert_not_reached (); break; } va_end (ap); lose: if (status == -1) { char *msg; msg = g_strdup_printf (_("Could not write log entry: %s\n" "Further operations on this server " "will not be replayed when you\n" "reconnect to the network."), g_strerror (errno)); camel_session_alert_user (camel_service_get_session (CAMEL_SERVICE (diary->store)), CAMEL_SESSION_ALERT_ERROR, msg, FALSE); g_free (msg); fclose (diary->file); diary->file = NULL; } } static void free_uids (GPtrArray *array) { while (array->len--) g_free (array->pdata[array->len]); g_ptr_array_free (array, TRUE); } static GPtrArray * diary_decode_uids (CamelDiscoDiary *diary) { GPtrArray *uids; char *uid; guint32 i; if (camel_file_util_decode_uint32 (diary->file, &i) == -1) return NULL; uids = g_ptr_array_new (); while (i--) { if (camel_file_util_decode_string (diary->file, &uid) == -1) { free_uids (uids); return NULL; } g_ptr_array_add (uids, uid); } return uids; } static CamelFolder * diary_decode_folder (CamelDiscoDiary *diary) { CamelFolder *folder; char *name; if (camel_file_util_decode_string (diary->file, &name) == -1) return NULL; folder = g_hash_table_lookup (diary->folders, name); if (!folder) { CamelException ex; char *msg; camel_exception_init (&ex); folder = camel_store_get_folder (CAMEL_STORE (diary->store), name, 0, &ex); if (folder) g_hash_table_insert (diary->folders, name, folder); else { msg = g_strdup_printf (_("Could not open `%s':\n%s\nChanges made to this folder will not be resynchronized."), name, camel_exception_get_description (&ex)); camel_exception_clear (&ex); camel_session_alert_user (camel_service_get_session (CAMEL_SERVICE (diary->store)), CAMEL_SESSION_ALERT_WARNING, msg, FALSE); g_free (msg); g_free (name); } } else g_free (name); return folder; } static void close_folder (gpointer name, gpointer folder, gpointer data) { g_free (name); camel_folder_sync (folder, FALSE, NULL); camel_object_unref (folder); } void camel_disco_diary_replay (CamelDiscoDiary *diary, CamelException *ex) { guint32 action; off_t size; double pc; fseek (diary->file, 0, SEEK_END); size = ftell (diary->file); g_return_if_fail (size != 0); rewind (diary->file); camel_operation_start (NULL, _("Resynchronizing with server")); while (!camel_exception_is_set (ex)) { pc = ftell (diary->file) / size; camel_operation_progress (NULL, pc * 100); if (camel_file_util_decode_uint32 (diary->file, &action) == -1) break; if (action == CAMEL_DISCO_DIARY_END) break; switch (action) { case CAMEL_DISCO_DIARY_FOLDER_EXPUNGE: { CamelFolder *folder; GPtrArray *uids; folder = diary_decode_folder (diary); uids = diary_decode_uids (diary); if (!uids) goto lose; if (folder) camel_disco_folder_expunge_uids (folder, uids, ex); free_uids (uids); break; } case CAMEL_DISCO_DIARY_FOLDER_APPEND: { CamelFolder *folder; char *uid, *ret_uid; CamelMimeMessage *message; CamelMessageInfo *info; folder = diary_decode_folder (diary); if (camel_file_util_decode_string (diary->file, &uid) == -1) goto lose; if (!folder) { g_free (uid); continue; } message = camel_folder_get_message (folder, uid, NULL); if (!message) { /* The message was appended and then deleted. */ g_free (uid); continue; } info = camel_folder_get_message_info (folder, uid); camel_folder_append_message (folder, message, info, &ret_uid, ex); camel_folder_free_message_info (folder, info); if (ret_uid) { camel_disco_diary_uidmap_add (diary, uid, ret_uid); g_free (ret_uid); } g_free (uid); break; } case CAMEL_DISCO_DIARY_FOLDER_TRANSFER: { CamelFolder *source, *destination; GPtrArray *uids, *ret_uids; guint32 delete_originals; int i; source = diary_decode_folder (diary); destination = diary_decode_folder (diary); uids = diary_decode_uids (diary); if (!uids) goto lose; if (camel_file_util_decode_uint32 (diary->file, &delete_originals) == -1) goto lose; if (!source || !destination) { free_uids (uids); continue; } camel_folder_transfer_messages_to (source, uids, destination, &ret_uids, delete_originals, ex); if (ret_uids) { for (i = 0; i < uids->len; i++) { if (!ret_uids->pdata[i]) continue; camel_disco_diary_uidmap_add (diary, uids->pdata[i], ret_uids->pdata[i]); g_free (ret_uids->pdata[i]); } g_ptr_array_free (ret_uids, TRUE); } free_uids (uids); break; } } } lose: camel_operation_end (NULL); /* Close folders */ g_hash_table_foreach (diary->folders, close_folder, diary); g_hash_table_destroy (diary->folders); diary->folders = NULL; /* Truncate the log */ ftruncate (fileno (diary->file), 0); } CamelDiscoDiary * camel_disco_diary_new (CamelDiscoStore *store, const char *filename, CamelException *ex) { CamelDiscoDiary *diary; g_return_val_if_fail (CAMEL_IS_DISCO_STORE (store), NULL); g_return_val_if_fail (filename != NULL, NULL); diary = CAMEL_DISCO_DIARY (camel_object_new (CAMEL_DISCO_DIARY_TYPE)); diary->store = store; diary->file = fopen (filename, "a+"); if (!diary->file) { camel_object_unref (CAMEL_OBJECT (diary)); camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, "Could not open journal file: %s", g_strerror (errno)); return NULL; } return diary; } gboolean camel_disco_diary_empty (CamelDiscoDiary *diary) { return ftell (diary->file) == 0; } void camel_disco_diary_uidmap_add (CamelDiscoDiary *diary, const char *old_uid, const char *new_uid) { g_hash_table_insert (diary->uidmap, g_strdup (old_uid), g_strdup (new_uid)); } const char * camel_disco_diary_uidmap_lookup (CamelDiscoDiary *diary, const char *uid) { return g_hash_table_lookup (diary->uidmap, uid); } iv class='alt'>
09e2eb771492
1
2
3
4
5
6
7
8
9
                                                     

                                                                           
 
           

 
                             
                      
                 
                      







                                                                
                                          
 
                                   
                                                
 
                                                    
                                                
 
                   
                   
                            
                   
                   
                   
                                                                        

                                                                        


                                                             
 


                                                        
                                      

      


                                                
 
             










                                                                     
 
                           
# New ports collection makefile for:    enlightenment
# Date created:         10 June 1997
# Whom:             Yukihiro Nakai <Nakai@Mlab.t.u-tokyo.ac.jp>
#
# $FreeBSD$
#

PORTNAME=   enlightenment
PORTVERSION=    0.16.6
PORTREVISION=   1
CATEGORIES= x11-wm
MASTER_SITES=   ${MASTER_SITE_SOURCEFORGE:S/$/:enlightenment/} \
        ftp://freebsd.sinica.edu.tw/pub/clive/:ethemes
MASTER_SITE_SUBDIR= ${PORTNAME}/:enlightenment
DISTFILES=  ${DISTNAME}${EXTRACT_SUFX}:enlightenment \
        Marble.etheme:ethemes \
        BlueSteel.etheme.zh_TW.Big5:ethemes \
        BrushedMetal-Tigert.etheme.zh_TW.Big5:ethemes \
        ShinyMetal.etheme.zh_TW.Big5:ethemes
EXTRACT_ONLY=   ${DISTNAME}${EXTRACT_SUFX}

MAINTAINER= vanilla@FreeBSD.org
COMMENT=    A very artistic X window manager

LIB_DEPENDS=    Fnlib.0:${PORTSDIR}/graphics/fnlib \
        ghttp.1:${PORTSDIR}/www/libghttp

USE_REINPLACE=  yes
USE_X_PREFIX=   yes
USE_GNOME=  esound imlib
USE_FREETYPE=   yes
USE_GMAKE=  yes
GNU_CONFIGURE=  yes
CONFIGURE_ARGS= --enable-fsstd --disable-hints-gnome --disable-hints-kde
CONFIGURE_ENV=  CPPFLAGS="-I${LOCALBASE}/include/freetype1 \
              -I${LOCALBASE}/include -I${X11BASE}/include" \
        LDFLAGS="-L${LOCALBASE}/lib -L${X11BASE}/lib"

MAN1=       enlightenment.1

.include <bsd.port.pre.mk>

.if (${MACHINE} == "alpha") && (${XFREE86_VERSION} == 3)
CONFIGURE_ARGS+=    --disable-zoom
.endif

post-patch:
    @${REINPLACE_CMD} -e 's| wctype.h||g ; \
         s|-ldl||g' ${WRKSRC}/configure

post-install:
    ${MKDIR} ${DATADIR}/themes/Marble
    ${TAR} -C ${DATADIR}/themes/Marble \
        -xzf ${DISTDIR}/Marble.etheme
    ${TAR} -C ${DATADIR}/themes/BlueSteel \
        -xzf ${DISTDIR}/BlueSteel.etheme.zh_TW.Big5
    ${TAR} -C ${DATADIR}/themes/BrushedMetal-Tigert \
        -xzf ${DISTDIR}/BrushedMetal-Tigert.etheme.zh_TW.Big5
    ${TAR} -C ${DATADIR}/themes/ShinyMetal \
        -xzf ${DISTDIR}/ShinyMetal.etheme.zh_TW.Big5
    ${CHOWN} -R ${SHAREOWN}:${SHAREGRP} ${DATADIR}/themes
    ${CHMOD} -R a+rX ${DATADIR}/themes

.include <bsd.port.post.mk>