Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37657513
en ru br
Репозитории ALT
S:3.7.0-alt0.6
4.1: 2.2.9-alt1.1
4.0: 2.2.9-alt1.1
3.0: 1.0.4-alt1
www.altlinux.org/Changes

Группа :: Сети/Почта
Пакет: sylpheed

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: sylpheed-2.2.4-alt-mboxlock.patch
Скачать


--- sylpheed/src/inc.c.alt-mboxlock	2006-03-09 09:37:55 +0300
+++ sylpheed/src/inc.c	2006-05-27 23:10:03 +0400
@@ -1257,7 +1257,7 @@ static gint inc_spool(void)
 static gint get_spool(FolderItem *dest, const gchar *mbox)
 {
 	gint msgs, size;
-	gint lockfd;
+	FILE *mbox_fp;
 	gchar tmp_mbox[MAXPATHLEN + 1];
 	GHashTable *folder_table = NULL;
 
@@ -1270,14 +1270,14 @@ static gint get_spool(FolderItem *dest, 
 	} else if (size < 0)
 		return -1;
 
-	if ((lockfd = lock_mbox(mbox, LOCK_FLOCK)) < 0)
+	if ((mbox_fp = open_and_lock_mbox(mbox, LOCK_FLOCK)) == NULL)
 		return -1;
 
 	g_snprintf(tmp_mbox, sizeof(tmp_mbox), "%s%ctmpmbox.%p",
 		   get_tmp_dir(), G_DIR_SEPARATOR, mbox);
 
-	if (copy_mbox(mbox, tmp_mbox) < 0) {
-		unlock_mbox(mbox, lockfd, LOCK_FLOCK);
+	if (copy_mbox(mbox, mbox_fp, tmp_mbox) < 0) {
+		unlock_and_close_mbox(mbox, mbox_fp, LOCK_FLOCK);
 		return -1;
 	}
 
@@ -1289,8 +1289,8 @@ static gint get_spool(FolderItem *dest, 
 	msgs = proc_mbox(dest, tmp_mbox, folder_table);
 
 	g_unlink(tmp_mbox);
-	if (msgs >= 0) empty_mbox(mbox);
-	unlock_mbox(mbox, lockfd, LOCK_FLOCK);
+	if (msgs >= 0) empty_mbox(mbox, mbox_fp);
+	unlock_and_close_mbox(mbox, mbox_fp, LOCK_FLOCK);
 
 	if (folder_table) {
 		if (!prefs_common.scan_all_after_inc) {
--- sylpheed/configure.in.alt-mboxlock	2006-05-26 13:19:30 +0400
+++ sylpheed/configure.in	2006-05-27 23:10:58 +0400
@@ -343,6 +343,14 @@ if test $ac_cv_dirent_d_type = yes; then
 fi
 
 
+dnl Select spool locking type
+AC_ARG_ENABLE(flock,
+	[  --enable-flock          Lock spool mailbox with flock],
+	[ac_cv_enable_flock=$enableval], [ac_cv_enable_flock=maybe])
+AC_ARG_ENABLE(fcntl,
+	[  --enable-fcntl          Lock spool mailbox with fcntl],
+	[ac_cv_enable_fcntl=$enableval], [ac_cv_enable_fcntl=maybe])
+
 dnl Checks for header files.
 AC_HEADER_DIRENT
 AC_HEADER_STDC
@@ -370,7 +378,40 @@ dnl Checks for library functions.
 AC_FUNC_ALLOCA
 AC_CHECK_FUNCS(gethostname mkdir mktime socket strstr strchr \
 	       uname flock lockf inet_aton inet_addr \
-	       fchmod truncate getuid regcomp mlock)
+	       fchmod truncate ftruncate getuid regcomp mlock)
+
+dnl Finish locking decision
+
+dnl Turn off unavailable methods
+if test x"$ac_cv_have_flock" = xno; then
+	ac_cv_enable_flock=no
+fi
+if test x"$ac_cv_have_fcntl" = xno; then
+	ac_cv_enable_fcntl=no
+fi
+
+dnl If no --enable-... is given, prefer flock to fcntl
+dnl (compatible with the previous behavior)
+if test x"$ac_cv_enable_flock" = xmaybe; then
+	ac_cv_enable_flock=yes
+fi
+if test x"$ac_cv_enable_fcntl" = xmaybe; then
+	if test x"$ac_cv_enable_flock" = xno; then
+		ac_cv_enable_fcntl=yes
+	else
+		ac_cv_enable_fcntl=no
+	fi
+fi
+
+dnl Define the macros
+if test x"$ac_cv_enable_flock" = xyes; then
+	AC_DEFINE(LOCK_WITH_FLOCK, 1,
+		 [Define to use the flock function for mailbox locking])
+fi
+if test x"$ac_cv_enable_fcntl" = xyes; then
+	AC_DEFINE(LOCK_WITH_FCNTL, 1,
+		 [Define to use the fcntl function for mailbox locking])
+fi
 
 AC_OUTPUT([
 Makefile
@@ -403,6 +444,8 @@ echo "OpenSSL       : $ac_cv_enable_ssl"
 echo "iconv         : $am_cv_func_iconv"
 echo "compface      : $ac_cv_enable_compface"
 echo "IPv6          : $ac_cv_enable_ipv6"
+echo "flock locking : $ac_cv_enable_flock"
+echo "fcntl locking : $ac_cv_enable_fcntl"
 echo "GtkSpell      : $ac_cv_enable_gtkspell"
 echo ""
 echo "The binary will be installed in $prefix/bin"
--- sylpheed/libsylph/mbox.h.alt-mboxlock	2005-09-13 12:18:44 +0400
+++ sylpheed/libsylph/mbox.h	2006-05-27 22:56:39 +0400
@@ -21,6 +21,7 @@
 #define __MBOX_H__
 
 #include <glib.h>
+#include <stdio.h>
 
 #include "folder.h"
 
@@ -29,19 +30,21 @@ typedef enum {
 	LOCK_FLOCK
 } LockType;
 
-gint proc_mbox		(FolderItem	*dest,
-			 const gchar	*mbox,
-			 GHashTable	*folder_table);
-gint lock_mbox		(const gchar	*base,
-			 LockType	 type);
-gint unlock_mbox	(const gchar	*base,
-			 gint		 fd,
-			 LockType	 type);
-gint copy_mbox		(const gchar	*src,
-			 const gchar	*dest);
-void empty_mbox		(const gchar	*mbox);
+gint   proc_mbox		(FolderItem	*dest,
+				 const gchar	*mbox,
+				 GHashTable	*folder_table);
+FILE * open_and_lock_mbox	(const gchar	*base,
+				 LockType	 type);
+gint   unlock_and_close_mbox	(const gchar	*base,
+				 FILE		*fp,
+				 LockType	 type);
+gint   copy_mbox		(const gchar	*src,
+				 FILE		*src_fp,
+				 const gchar	*dest);
+void   empty_mbox		(const gchar	*mbox,
+				 FILE		*mbox_fp);
 
-gint export_to_mbox	(FolderItem	*src,
-			 const gchar	*mbox);
+gint   export_to_mbox		(FolderItem	*src,
+				 const gchar	*mbox);
 
 #endif /* __MBOX_H__ */
--- sylpheed/libsylph/utils.h.alt-mboxlock	2006-03-27 12:19:53 +0400
+++ sylpheed/libsylph/utils.h	2006-05-27 23:03:14 +0400
@@ -407,6 +407,10 @@ gint remove_expired_files	(const gchar	*
 gint remove_dir_recursive	(const gchar	*dir);
 gint rename_force		(const gchar	*oldpath,
 				 const gchar	*newpath);
+gint copy_open_file		(const gchar	*src,
+				 FILE 		*src_fp,
+				 const gchar	*dest,
+				 gboolean	 keep_backup);
 gint copy_file			(const gchar	*src,
 				 const gchar	*dest,
 				 gboolean	 keep_backup);
--- sylpheed/libsylph/mbox.c.alt-mboxlock	2005-11-14 13:00:00 +0300
+++ sylpheed/libsylph/mbox.c	2006-05-27 23:29:15 +0400
@@ -252,142 +252,206 @@ gint proc_mbox(FolderItem *dest, const g
 	return msgs;
 }
 
-gint lock_mbox(const gchar *base, LockType type)
+static gint lock_dotlock(const gchar *base)
 {
-#ifdef G_OS_UNIX
-	gint retval = 0;
+#ifdef LOCK_WITH_DOTLOCK
+	gchar *lockfile, *locklink;
+	gint retry = 0;
+	FILE *lockfp;
+
+	lockfile = g_strdup_printf("%s.%d", base, getpid());
+	if ((lockfp = g_fopen(lockfile, "wb")) == NULL) {
+		FILE_OP_ERROR(lockfile, "fopen");
+		g_warning(_("can't create lock file %s\n"), lockfile);
+		g_warning(_("use 'flock' instead of 'file' if possible.\n"));
+		g_free(lockfile);
+		return NULL;
+	}
 
-	if (type == LOCK_FILE) {
-		gchar *lockfile, *locklink;
-		gint retry = 0;
-		FILE *lockfp;
-
-		lockfile = g_strdup_printf("%s.%d", base, getpid());
-		if ((lockfp = g_fopen(lockfile, "wb")) == NULL) {
-			FILE_OP_ERROR(lockfile, "fopen");
-			g_warning(_("can't create lock file %s\n"), lockfile);
-			g_warning(_("use 'flock' instead of 'file' if possible.\n"));
+	fprintf(lockfp, "%d\n", getpid());
+	fclose(lockfp);
+
+	locklink = g_strconcat(base, ".lock", NULL);
+	while (link(lockfile, locklink) < 0) {
+		FILE_OP_ERROR(lockfile, "link");
+		if (retry >= 5) {
+			g_warning(_("can't create %s\n"), lockfile);
+			g_unlink(lockfile);
 			g_free(lockfile);
 			return -1;
 		}
+		if (retry == 0)
+			g_warning(_("mailbox is owned by another"
+				    " process, waiting...\n"));
+		retry++;
+		sleep(5);
+	}
+	g_unlink(lockfile);
+	g_free(lockfile);
+#endif /* LOCK_WITH_DOTLOCK */
 
-		fprintf(lockfp, "%d\n", getpid());
-		fclose(lockfp);
+	return 0;
+}
 
-		locklink = g_strconcat(base, ".lock", NULL);
-		while (link(lockfile, locklink) < 0) {
-			FILE_OP_ERROR(lockfile, "link");
-			if (retry >= 5) {
-				g_warning(_("can't create %s\n"), lockfile);
-				g_unlink(lockfile);
-				g_free(lockfile);
-				return -1;
-			}
-			if (retry == 0)
-				g_warning(_("mailbox is owned by another"
-					    " process, waiting...\n"));
-			retry++;
-			sleep(5);
-		}
-		g_unlink(lockfile);
+static gint unlock_dotlock(const gchar *base)
+{
+#ifdef LOCK_WITH_DOTLOCK
+	gchar *lockfile;
+
+	lockfile = g_strconcat(base, ".lock", NULL);
+	if (g_unlink(lockfile) < 0) {
+		FILE_OP_ERROR(lockfile, "unlink");
 		g_free(lockfile);
-	} else if (type == LOCK_FLOCK) {
-		gint lockfd;
+		return -1;
+	}
+	g_free(lockfile);
+#endif /* LOCK_WITH_DOTLOCK */
 
-#if HAVE_FLOCK
-		if ((lockfd = open(base, O_RDONLY)) < 0) {
-#else
-		if ((lockfd = open(base, O_RDWR)) < 0) {
-#endif
-			FILE_OP_ERROR(base, "open");
+	return 0;
+}
+
+static gint lock_fcntl(const gchar *base, gint fd)
+{
+#ifdef LOCK_WITH_FCNTL
+	struct flock lck;
+
+	memset(&lck, 0, sizeof (struct flock));
+	lck.l_type = F_WRLCK;
+	lck.l_whence = SEEK_SET;
+
+	if (fcntl(fd, F_SETLK, &lck) == -1) {
+		if (errno != EAGAIN && errno != EACCES) {
+			FILE_OP_ERROR(base, "fcntl lock");
 			return -1;
 		}
-#if HAVE_FLOCK
-		if (flock(lockfd, LOCK_EX|LOCK_NB) < 0) {
-			perror("flock");
-#else
-#if HAVE_LOCKF
-		if (lockf(lockfd, F_TLOCK, 0) < 0) {
-			perror("lockf");
-#else
-		{
-#endif
-#endif /* HAVE_FLOCK */
-			g_warning(_("can't lock %s\n"), base);
-			if (close(lockfd) < 0)
-				perror("close");
+
+		g_warning(_("can't lock %s with fcntl\n"), base);
+		return -1;
+	}
+#endif /* LOCK_WITH_FCNTL */
+
+	return 0;
+}
+
+static gint unlock_fcntl(const gchar *base, gint fd)
+{
+#ifdef LOCK_WITH_FCNTL
+      	struct flock lck;
+
+	memset(&lck, 0, sizeof (struct flock));
+	lck.l_type = F_UNLCK;
+	lck.l_whence = SEEK_SET;
+	if (fcntl(fd, F_SETLK, &lck) == -1) {
+		FILE_OP_ERROR(base, "fcntl unlock");
+		return -1;
+	}
+#endif /* LOCK_WITH_FCNTL */
+
+	return 0;
+}
+
+static gint lock_flock(const gchar *base, gint fd)
+{
+#ifdef LOCK_WITH_FLOCK
+	if (flock(fd, LOCK_EX | LOCK_NB) == -1)
+	{
+		if (errno != EWOULDBLOCK) {
+			FILE_OP_ERROR(base, "flock lock");
 			return -1;
 		}
-		retval = lockfd;
-	} else {
-		g_warning(_("invalid lock type\n"));
+
+		g_warning(_("can't lock %s with flock\n"), base);
 		return -1;
 	}
+#endif /* LOCK_WITH_FLOCK */
 
-	return retval;
-#else
-	return -1;
-#endif /* G_OS_UNIX */
+	return 0;
 }
 
-gint unlock_mbox(const gchar *base, gint fd, LockType type)
+static gint unlock_flock(const gchar *base, gint fd)
 {
-	if (type == LOCK_FILE) {
-		gchar *lockfile;
+#ifdef LOCK_WITH_FLOCK
+	if (flock(fd, LOCK_UN) == -1) {
+		FILE_OP_ERROR(base, "flock unlock");
+		return -1;
+	}
+#endif /* LOCK_WITH_FLOCK */
 
-		lockfile = g_strconcat(base, ".lock", NULL);
-		if (g_unlink(lockfile) < 0) {
-			FILE_OP_ERROR(lockfile, "unlink");
-			g_free(lockfile);
-			return -1;
+	return 0;
+}
+
+FILE *open_and_lock_mbox(const gchar *base, LockType type)
+{
+#ifdef G_OS_UNIX
+	FILE *mbox_fp;
+	gint fd;
+
+	mbox_fp = g_fopen(base, "rb+");
+	if (mbox_fp == NULL) {
+		FILE_OP_ERROR(base, "fopen");
+		return NULL;
+	}
+	fd = fileno(mbox_fp);
+
+	if (lock_fcntl(base, fd) == -1) {
+		fclose(mbox_fp);
+		return NULL;
+	}
+
+	if (lock_flock(base, fd) == -1) {
+		unlock_fcntl(base, fd);
+		fclose(mbox_fp);
+		return NULL;
+	}
+
+	if (type == LOCK_FILE) {
+		if (lock_dotlock(base) == -1) {
+			unlock_flock(base, fd);
+			unlock_fcntl(base, fd);
+			fclose(mbox_fp);
+			return NULL;
 		}
-		g_free(lockfile);
+	}
 
-		return 0;
-	} else if (type == LOCK_FLOCK) {
-#if HAVE_FLOCK
-		if (flock(fd, LOCK_UN) < 0) {
-			perror("flock");
-#else
-#if HAVE_LOCKF
-		if (lockf(fd, F_ULOCK, 0) < 0) {
-			perror("lockf");
+	return mbox_fp;
 #else
-		{
-#endif
-#endif /* HAVE_FLOCK */
-			g_warning(_("can't unlock %s\n"), base);
-			if (close(fd) < 0)
-				perror("close");
-			return -1;
-		}
+	return NULL;
+#endif  /* G_OS_UNIX */
+}
 
-		if (close(fd) < 0) {
-			perror("close");
-			return -1;
-		}
+gint unlock_and_close_mbox(const gchar *base, FILE *mbox_fp, LockType type)
+{
+	gint fd = fileno(mbox_fp);
 
-		return 0;
+	unlock_fcntl(base, fd);
+	unlock_flock(base, fd);
+	if (type == LOCK_FILE)
+		unlock_dotlock(base);
+
+	if (fclose(mbox_fp) == EOF) {
+		FILE_OP_ERROR(base, "fclose");
+		return -1;
 	}
 
-	g_warning(_("invalid lock type\n"));
-	return -1;
+	return 0;
 }
 
-gint copy_mbox(const gchar *src, const gchar *dest)
+gint copy_mbox(const gchar *src, FILE *src_fp, const gchar *dest)
 {
-	return copy_file(src, dest, TRUE);
+	return copy_open_file(src, src_fp, dest, TRUE);
 }
 
-void empty_mbox(const gchar *mbox)
+void empty_mbox(const gchar *mbox, FILE *mbox_fp)
 {
-#if HAVE_TRUNCATE
-	if (truncate(mbox, 0) < 0) {
+#if HAVE_FTRUNCATE
+	int fd = fileno(mbox_fp);
+
+	if (ftruncate(fd, 0) < 0) {
 #endif
 		FILE *fp;
 
-#if HAVE_TRUNCATE
-		FILE_OP_ERROR(mbox, "truncate");
+#if HAVE_FTRUNCATE
+		FILE_OP_ERROR(mbox, "ftruncate");
 #endif
 		if ((fp = g_fopen(mbox, "wb")) == NULL) {
 			FILE_OP_ERROR(mbox, "fopen");
@@ -395,7 +459,7 @@ void empty_mbox(const gchar *mbox)
 			return;
 		}
 		fclose(fp);
-#if HAVE_TRUNCATE
+#if HAVE_FTRUNCATE
 	}
 #endif
 }
--- sylpheed/libsylph/utils.c.alt-mboxlock	2006-03-27 12:19:53 +0400
+++ sylpheed/libsylph/utils.c	2006-05-27 23:08:03 +0400
@@ -2423,23 +2423,19 @@ gint rename_force(const gchar *oldpath, 
 	return g_rename(oldpath, newpath);
 }
 
-gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup)
+gint copy_open_file(const gchar *src, FILE *src_fp, const gchar *dest,
+		    gboolean keep_backup)
 {
-	FILE *src_fp, *dest_fp;
+	FILE *dest_fp;
 	gint n_read;
 	gchar buf[BUFSIZ];
 	gchar *dest_bak = NULL;
 	gboolean err = FALSE;
 
-	if ((src_fp = g_fopen(src, "rb")) == NULL) {
-		FILE_OP_ERROR(src, "fopen");
-		return -1;
-	}
 	if (is_file_exist(dest)) {
 		dest_bak = g_strconcat(dest, ".bak", NULL);
 		if (rename_force(dest, dest_bak) < 0) {
 			FILE_OP_ERROR(dest, "rename");
-			fclose(src_fp);
 			g_free(dest_bak);
 			return -1;
 		}
@@ -2447,7 +2443,6 @@ gint copy_file(const gchar *src, const g
 
 	if ((dest_fp = g_fopen(dest, "wb")) == NULL) {
 		FILE_OP_ERROR(dest, "fopen");
-		fclose(src_fp);
 		if (dest_bak) {
 			if (rename_force(dest_bak, dest) < 0)
 				FILE_OP_ERROR(dest_bak, "rename");
@@ -2467,7 +2462,6 @@ gint copy_file(const gchar *src, const g
 		if (fwrite(buf, n_read, 1, dest_fp) < 1) {
 			g_warning(_("writing to %s failed.\n"), dest);
 			fclose(dest_fp);
-			fclose(src_fp);
 			g_unlink(dest);
 			if (dest_bak) {
 				if (rename_force(dest_bak, dest) < 0)
@@ -2482,7 +2476,6 @@ gint copy_file(const gchar *src, const g
 		FILE_OP_ERROR(src, "fread");
 		err = TRUE;
 	}
-	fclose(src_fp);
 	if (fclose(dest_fp) == EOF) {
 		FILE_OP_ERROR(dest, "fclose");
 		err = TRUE;
@@ -2506,6 +2499,20 @@ gint copy_file(const gchar *src, const g
 	return 0;
 }
 
+gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup)
+{
+	FILE *src_fp;
+	gint result;
+
+	if ((src_fp = g_fopen(src, "rb")) == NULL) {
+		FILE_OP_ERROR(src, "fopen");
+		return -1;
+	}
+	result = copy_open_file(src, src_fp, dest, keep_backup);
+	fclose(src_fp);
+	return result;
+}
+
 gint copy_dir(const gchar *src, const gchar *dest)
 {
 	GDir *dir;
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin