diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..322f372 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +SOURCES/xsane-0.999-7-autoconf.patch.bz2 +SOURCES/xsane-0.999.tar.gz +SOURCES/xsane-256x256.png diff --git a/.xsane.metadata b/.xsane.metadata new file mode 100644 index 0000000..fcafcb3 --- /dev/null +++ b/.xsane.metadata @@ -0,0 +1,3 @@ +8984dbb732b8b0f98d9bd50fdb16d3510d7d2eef SOURCES/xsane-0.999-7-autoconf.patch.bz2 +633150e4e690c1e8c18d6b82886c2fb4daba4bc9 SOURCES/xsane-0.999.tar.gz +ab0517cb7fa9a7fc30499f56f7e9aac628d9bc40 SOURCES/xsane-256x256.png diff --git a/SOURCES/xsane-0.995-close-fds.patch b/SOURCES/xsane-0.995-close-fds.patch new file mode 100644 index 0000000..917b075 --- /dev/null +++ b/SOURCES/xsane-0.995-close-fds.patch @@ -0,0 +1,101 @@ +From 6dee7eadd1b7352ec503ea04fa1639d4a93f370b Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Thu, 16 Aug 2012 11:18:31 +0200 +Subject: [PATCH] patch: close-fds + +Squashed commit of the following: + +commit 4fdedd3a8b66fb42b2d4dde62df28c78571c1c5d +Author: Nils Philippsen +Date: Fri Nov 19 12:15:58 2010 +0100 + + don't leak file descriptors to help browser process (#455450) +--- + src/xsane.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/src/xsane.c b/src/xsane.c +index 775610e..1c5d61d 100644 +--- a/src/xsane.c ++++ b/src/xsane.c +@@ -48,6 +48,8 @@ + + #include + ++#include ++ + /* ---------------------------------------------------------------------------------------------------------------------- */ + + struct option long_options[] = +@@ -3684,6 +3686,41 @@ static void xsane_show_gpl(GtkWidget *widget, gpointer data) + + /* ---------------------------------------------------------------------------------------------------------------------- */ + ++static void xsane_close_fds_for_exec(signed int first_fd_to_leave_open, ...) ++{ ++ int open_max; ++ signed int i; ++ ++ va_list ap; ++ unsigned char *close_fds; ++ ++ open_max = (int) sysconf (_SC_OPEN_MAX); ++ ++ close_fds = malloc (open_max); ++ ++ memset (close_fds, 1, open_max); ++ ++ va_start (ap, first_fd_to_leave_open); ++ ++ for (i = first_fd_to_leave_open; i >= 0; i = va_arg (ap, signed int)) { ++ if (i < open_max) ++ close_fds[i] = 0; ++ } ++ ++ va_end (ap); ++ ++ DBG(DBG_info, "closing unneeded file descriptors\n"); ++ ++ for (i = 0; i < open_max; i++) { ++ if (close_fds[i]) ++ close (i); ++ } ++ ++ free (close_fds); ++} ++ ++/* ---------------------------------------------------------------------------------------------------------------------- */ ++ + static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via netscape remote */ + { + char *name = (char *) data; +@@ -3736,6 +3773,8 @@ static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via + ipc_file = fdopen(xsane.ipc_pipefd[1], "w"); + } + ++ xsane_close_fds_for_exec (1, 2, xsane.ipc_pipefd[1], -1); ++ + DBG(DBG_info, "trying to change user id for new subprocess:\n"); + DBG(DBG_info, "old effective uid = %d\n", (int) geteuid()); + setuid(getuid()); +@@ -3778,6 +3817,8 @@ static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via + ipc_file = fdopen(xsane.ipc_pipefd[1], "w"); + } + ++ xsane_close_fds_for_exec (1, 2, xsane.ipc_pipefd[1], -1); ++ + DBG(DBG_info, "trying to change user id for new subprocess:\n"); + DBG(DBG_info, "old effective uid = %d\n", (int) geteuid()); + setuid(getuid()); +@@ -3899,6 +3940,8 @@ static void xsane_show_doc(GtkWidget *widget, gpointer data) + ipc_file = fdopen(xsane.ipc_pipefd[1], "w"); + } + ++ xsane_close_fds_for_exec (1, 2, xsane.ipc_pipefd[1], -1); ++ + DBG(DBG_info, "trying to change user id for new subprocess:\n"); + DBG(DBG_info, "old effective uid = %d\n", (int) geteuid()); + setuid(getuid()); +-- +1.7.11.4 + diff --git a/SOURCES/xsane-0.995-xdg-open.patch b/SOURCES/xsane-0.995-xdg-open.patch new file mode 100644 index 0000000..c276938 --- /dev/null +++ b/SOURCES/xsane-0.995-xdg-open.patch @@ -0,0 +1,32 @@ +From 813d7063e3d265ba7e625766a040b8ba9bb130a9 Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Thu, 16 Aug 2012 11:18:00 +0200 +Subject: [PATCH] patch: xdg-open + +Squashed commit of the following: + +commit 55380b90cece459e20d14e6da552abcf5ca54621 +Author: Nils Philippsen +Date: Fri Nov 19 12:14:17 2010 +0100 + + use "xdg-open" instead of "netscape" to launch help browser +--- + src/xsane.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/xsane.h b/src/xsane.h +index cf6111f..3d8caaa 100644 +--- a/src/xsane.h ++++ b/src/xsane.h +@@ -251,7 +251,7 @@ + # elif defined(HAVE_OS2_H) + # define DEFAULT_BROWSER "netscape" + # else +-# define DEFAULT_BROWSER "netscape" ++# define DEFAULT_BROWSER "xdg-open" + # endif + #endif + +-- +1.7.11.4 + diff --git a/SOURCES/xsane-0.996-no-eula.patch b/SOURCES/xsane-0.996-no-eula.patch new file mode 100644 index 0000000..66cd684 --- /dev/null +++ b/SOURCES/xsane-0.996-no-eula.patch @@ -0,0 +1,94 @@ +From 7018206ea45db2e8bdfeb67d33f3387c9678a407 Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Thu, 16 Aug 2012 11:19:16 +0200 +Subject: [PATCH] patch: no-eula + +Squashed commit of the following: + +commit d13f1ccfdf4c150cab91105e9b8542ecbb048a9b +Author: Nils Philippsen +Date: Fri Nov 19 12:20:52 2010 +0100 + + don't show EULA, mention bugzilla in about dialog (#504344) +--- + src/xsane-text.h | 2 ++ + src/xsane.c | 16 ++++++---------- + src/xsane.h | 3 +++ + 3 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/src/xsane-text.h b/src/xsane-text.h +index fc6bbeb..ee4a222 100644 +--- a/src/xsane-text.h ++++ b/src/xsane-text.h +@@ -230,6 +230,8 @@ + "This program is distributed in the hope that it will be useful, but\n" \ + "WITHOUT ANY WARRANTY; without even the implied warranty of\n" \ + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n") ++#define TEXT_MODIFIED_BLURB _("This package is modified from the original version.\n" \ ++ "Please contact your vendor or report problems at") + #define TEXT_EMAIL_ADR _("E-mail:") + #define TEXT_HOMEPAGE _("Homepage:") + #define TEXT_FILE _("File:") +diff --git a/src/xsane.c b/src/xsane.c +index 1c5d61d..8b24b0c 100644 +--- a/src/xsane.c ++++ b/src/xsane.c +@@ -3533,10 +3533,13 @@ static void xsane_about_dialog(GtkWidget *widget, gpointer data) + snprintf(buf, sizeof(buf), "XSane %s %s\n" + "%s %s\n" + "\n" ++ "%s\n%s" ++ "\n\n" + "%s %s\n" + "%s %s\n", + TEXT_VERSION, XSANE_VERSION, + XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT, ++ TEXT_MODIFIED_BLURB, XSANE_BUGTRACKER_URL, + TEXT_HOMEPAGE, XSANE_HOMEPAGE, + TEXT_EMAIL_ADR, XSANE_EMAIL_ADR); + +@@ -5733,6 +5736,7 @@ static int xsane_init(int argc, char **argv) + + case 'v': /* --version */ + g_print("%s-%s %s %s\n", xsane.prog_name, XSANE_VERSION, XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT); ++ g_print("\n%s\n%s\n\n", TEXT_MODIFIED_BLURB, XSANE_BUGTRACKER_URL); + g_print(" %s %s\n", TEXT_EMAIL_ADR, XSANE_EMAIL_ADR); + g_print(" %s %s\n", TEXT_PACKAGE, XSANE_PACKAGE_VERSION); + g_print(" %s%d.%d.%d\n", TEXT_GTK_VERSION, GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); +@@ -5859,17 +5863,9 @@ static int xsane_init(int argc, char **argv) + } + + +- if (xsane_pref_restore()) /* restore preferences, returns TRUE if license is not accpted yet */ ++ if (xsane_pref_restore()) /* restore preferences, returns TRUE if the version is different from the last run */ + { +- if (xsane_display_eula(1)) /* show license and ask for accept/not accept */ +- { +- DBG(DBG_info, "user did not accept eula, we abort\n"); +- return 1; /* User did not accept eula */ +- } +- else /* User did accept eula */ +- { +- xsane_pref_save(); +- } ++ xsane_pref_save(); + } + + xsane_pref_restore_media(); +diff --git a/src/xsane.h b/src/xsane.h +index 3d8caaa..6c7568e 100644 +--- a/src/xsane.h ++++ b/src/xsane.h +@@ -98,6 +98,9 @@ + #define XSANE_EMAIL_ADR "Oliver.Rauch@xsane.org" + #define XSANE_HOMEPAGE "http://www.xsane.org" + #define XSANE_COPYRIGHT_TXT XSANE_DATE " " XSANE_COPYRIGHT ++#ifndef XSANE_BUGTRACKER_URL ++#define XSANE_BUGTRACKER_URL "(no bug tracker configured)" ++#endif + + /* ---------------------------------------------------------------------------------------------------------------------- */ + +-- +1.7.11.4 + diff --git a/SOURCES/xsane-0.997-ipv6.patch b/SOURCES/xsane-0.997-ipv6.patch new file mode 100644 index 0000000..43f7af6 --- /dev/null +++ b/SOURCES/xsane-0.997-ipv6.patch @@ -0,0 +1,148 @@ +From a2ef22d59904d5e53c3d58093b561fa1ab7127a6 Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Thu, 16 Aug 2012 10:58:54 +0200 +Subject: [PATCH] patch: ipv6 + +Squashed commit of the following: + +commit 9f9d5c46fdef5ba7baccb81ab8170cfc24797de6 +Author: Nils Philippsen +Date: Fri Nov 19 12:27:42 2010 +0100 + + support IPv6 (#198422) +--- + src/xsane-save.c | 96 ++++++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 62 insertions(+), 34 deletions(-) + +diff --git a/src/xsane-save.c b/src/xsane-save.c +index 84f5d59..87ef685 100644 +--- a/src/xsane-save.c ++++ b/src/xsane-save.c +@@ -29,6 +29,8 @@ + #include + #include + ++#include ++ + /* the following test is always false */ + #ifdef _native_WIN32 + # include +@@ -7488,55 +7490,81 @@ void write_email_attach_file(int fd_socket, char *boundary, FILE *infile, char * + /* returns fd_socket if sucessfull, < 0 when error occured */ + int open_socket(char *server, int port) + { +- int fd_socket; +- struct sockaddr_in sin; +- struct hostent *he; ++ int fd_socket, e; ++ ++ struct addrinfo *ai_list, *ai; ++ struct addrinfo hints; ++ gchar *port_s; ++ gint connected; ++ ++ memset(&hints, '\0', sizeof(hints)); ++ hints.ai_flags = AI_ADDRCONFIG; ++ hints.ai_socktype = SOCK_STREAM; ++ ++ port_s = g_strdup_printf("%d", port); ++ e = getaddrinfo(server, port_s, &hints, &ai_list); ++ g_free(port_s); + +- he = gethostbyname(server); +- if (!he) ++ if (e != 0) + { +- DBG(DBG_error, "open_socket: Could not get hostname of \"%s\"\n", server); ++ DBG(DBG_error, "open_socket: Could not lookup \"%s\"\n", server); + return -1; + } +- else ++ ++ connected = 0; ++ for (ai = ai_list; ai != NULL && !connected; ai = ai->ai_next) + { +- DBG(DBG_info, "open_socket: connecting to \"%s\" = %d.%d.%d.%d\n", +- he->h_name, +- (unsigned char) he->h_addr_list[0][0], +- (unsigned char) he->h_addr_list[0][1], +- (unsigned char) he->h_addr_list[0][2], +- (unsigned char) he->h_addr_list[0][3]); +- } ++ gchar hostname[NI_MAXHOST]; ++ gchar hostaddr[NI_MAXHOST]; ++ ++ /* If all else fails */ ++ strncpy(hostname, "(unknown name)", NI_MAXHOST-1); ++ strncpy(hostaddr, "(unknown address)", NI_MAXHOST-1); ++ ++ /* Determine canonical name and IPv4/IPv6 address */ ++ (void) getnameinfo(ai->ai_addr, ai->ai_addrlen, hostname, sizeof(hostname), ++ NULL, 0, 0); ++ (void) getnameinfo(ai->ai_addr, ai->ai_addrlen, hostaddr, sizeof(hostaddr), ++ NULL, 0, NI_NUMERICHOST); ++ ++ DBG(DBG_info, "open_socket: connecting to \"%s\" (\"%s\"): %s\n", ++ server, hostname, hostaddr); + +- if (he->h_addrtype != AF_INET) +- { +- DBG(DBG_error, "open_socket: Unknown address family: %d\n", he->h_addrtype); +- return -1; +- } ++ if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) ++ { ++ DBG(DBG_error, "open_socket: Unknown address family: %d\n", ai->ai_family); ++ continue; ++ } + +- fd_socket = socket(AF_INET, SOCK_STREAM, 0); ++ fd_socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + +- if (fd_socket < 0) +- { +- DBG(DBG_error, "open_socket: Could not create socket: %s\n", strerror(errno)); +- return -1; +- } ++ if (fd_socket < 0) ++ { ++ DBG(DBG_error, "open_socket: Could not create socket: %s\n", strerror(errno)); ++ continue; ++ } + +-/* setsockopt (dev->ctl, level, TCP_NODELAY, &on, sizeof (on)); */ ++ /* setsockopt (dev->ctl, level, TCP_NODELAY, &on, sizeof (on)); */ + +- sin.sin_port = htons(port); +- sin.sin_family = AF_INET; +- memcpy(&sin.sin_addr, he->h_addr_list[0], he->h_length); ++ if (connect(fd_socket, ai->ai_addr, ai->ai_addrlen) != 0) ++ { ++ DBG(DBG_error, "open_socket: Could not connect with port %d of socket: %s\n", port, strerror(errno)); ++ continue; ++ } ++ ++ /* All went well */ ++ connected = 1; ++ } + +- if (connect(fd_socket, &sin, sizeof(sin))) ++ if (!connected) + { +- DBG(DBG_error, "open_socket: Could not connect with port %d of socket: %s\n", ntohs(sin.sin_port), strerror(errno)); +- return -1; ++ DBG(DBG_info, "open_socket: Could not connect to any address"); ++ return -1; + } + +- DBG(DBG_info, "open_socket: Connected with port %d\n", ntohs(sin.sin_port)); ++ DBG(DBG_info, "open_socket: Connected with port %d\n", port); + +- return fd_socket; ++ return fd_socket; + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ +-- +1.7.11.4 + diff --git a/SOURCES/xsane-0.997-off-root-build.patch b/SOURCES/xsane-0.997-off-root-build.patch new file mode 100644 index 0000000..02155f8 --- /dev/null +++ b/SOURCES/xsane-0.997-off-root-build.patch @@ -0,0 +1,127 @@ +From 7f43255972b741ff178f94233ffff67c9779c247 Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Thu, 16 Aug 2012 10:57:38 +0200 +Subject: [PATCH] patch: off-root-build + +Squashed commit of the following: + +commit f88d28c807667f618b3b1cf91c12b823f3853983 +Author: Nils Philippsen +Date: Fri Nov 19 12:23:57 2010 +0100 + + enable off-root builds +--- + configure.in | 2 +- + doc/Makefile.in | 12 ++++++------ + lib/Makefile.in | 4 ++-- + src/Makefile.in | 8 ++++---- + 4 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/configure.in b/configure.in +index a770253..770077b 100644 +--- a/configure.in ++++ b/configure.in +@@ -312,4 +312,4 @@ echo "* ------------------------------------------------------------ *" + echo "* ... PLEASE READ SANE DOCUMENTATION BEFORE STARTING XSANE ... *" + echo "* ------------------------------------------------------------ *" + echo "****************************************************************" +-cat xsane.NEWS ++cat ${srcdir}/xsane.NEWS +diff --git a/doc/Makefile.in b/doc/Makefile.in +index 59b022b..4038a6b 100644 +--- a/doc/Makefile.in ++++ b/doc/Makefile.in +@@ -57,14 +57,14 @@ install: $(MANPAGES) + $(MKINSTALLDIRS) $(DESTDIR)$(datadir) + + $(MKINSTALLDIRS) $(DESTDIR)$(xsanedocdir) +- @for page in *.html; do\ ++ @for page in $(notdir $(wildcard $(srcdir)/*.html)); do \ + echo installing $${page} in $(DESTDIR)$(xsanedocdir)/$${page}...; \ +- $(INSTALL_DATA) $${page} $(DESTDIR)$(xsanedocdir)/$${page} || exit 1; \ ++ $(INSTALL_DATA) $(srcdir)/$${page} $(DESTDIR)$(xsanedocdir)/$${page} || exit 1; \ + done + +- @for image in *.jpg; do\ ++ @for image in $(notdir $(wildcard $(srcdir)/*.jpg)); do \ + echo installing $${image} in $(DESTDIR)$(xsanedocdir)/$${image}...; \ +- $(INSTALL_DATA) $${image} $(DESTDIR)$(xsanedocdir)/$${image} || exit 1; \ ++ $(INSTALL_DATA) $(srcdir)/$${image} $(DESTDIR)$(xsanedocdir)/$${image} || exit 1; \ + done + + uninstall: +@@ -73,12 +73,12 @@ uninstall: + rm -f $(DESTDIR)$(mandir)/man1/$${page} || exit 1; \ + done + +- @for page in *.html; do\ ++ @for page in $(notdir $(wildcard $(srcdir)/*.html)); do \ + echo uninstalling $(DESTDIR)$(xsanedocdir)/$${page}...; \ + rm -f $(DESTDIR)$(xsanedocdir)/$${page} || exit 1; \ + done + +- @for image in *.jpg; do\ ++ @for image in $(notdir $(wildcard $(srcdir)/*.jpg)); do \ + echo uninstalling $${image} in $(DESTDIR)$(xsanedocdir)/$${image}...; \ + rm -f $(DESTDIR)$(xsanedocdir)/$${image} || exit 1; \ + done +diff --git a/lib/Makefile.in b/lib/Makefile.in +index 7567d54..6be1eeb 100644 +--- a/lib/Makefile.in ++++ b/lib/Makefile.in +@@ -30,7 +30,7 @@ RANLIB = @RANLIB@ + + CC = @CC@ + INCLUDES = -I. -I$(srcdir) \ +- -I$(top_builddir)/include/sane -I$(top_srcdir)/include ++ -I$(top_builddir)/include/sane -I$(top_builddir)/include -I$(top_srcdir)/include + CPPFLAGS = @CPPFLAGS@ + CFLAGS = @CFLAGS@ + LDFLAGS = @LDFLAGS@ +@@ -68,7 +68,7 @@ uninstall: + check: + + depend: +- makedepend -I. -I../include *.c ++ makedepend -I. -I../include $(srcdir)/*.c + + clean: + rm -f *.out *.o *.lo *~ *.a *.bak $(TESTPROGRAMS) +diff --git a/src/Makefile.in b/src/Makefile.in +index 905ef93..2b246db 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -77,10 +77,10 @@ install: $(PROGRAMS) + $(INSTALL_DATA) $(srcdir)/xsane-eula.txt $(DESTDIR)$(sanedatadir)/xsane/xsane-eula.txt + $(INSTALL_DATA) $(srcdir)/xsane.desktop $(DESTDIR)$(desktopappdir)/xsane.desktop + $(INSTALL_DATA) $(srcdir)/xsane.xpm $(DESTDIR)$(pixmapdir)/xsane.xpm +- @for logo in *-logo.xpm; do \ ++ @for logo in $(notdir $(wildcard $(srcdir)/*-logo.xpm)); do \ + echo installing $(DESTDIR)$(sanedatadir)/xsane/$${logo}; \ + $(INSTALL_DATA) $(srcdir)/$${logo} $(DESTDIR)$(sanedatadir)/xsane/$${logo}; \ +- done ++ done + + uninstall: + @for program in $(BINPROGS); do \ +@@ -99,7 +99,7 @@ uninstall: + rm -f $(DESTDIR)$(desktopappdir)/xsane.desktop + echo uninstalling $(DESTDIR)$(pixmapdir)/xsane.xpm + rm -f $(DESTDIR)$(pixmapdir)/xsane.xpm +- @for logo in *-logo.xpm; do \ ++ @for logo in $(notdir $(wildcard $(srcdir)/*-logo.xpm)); do \ + echo uninstalling $(DESTDIR)$(sanedatadir)/xsane/$${logo}; \ + rm -f $(DESTDIR)$(sanedatadir)/xsane/$${logo}; \ + done +@@ -119,7 +119,7 @@ distclean: clean + rm -f Makefile $(PROGRAMS) + + depend: +- makedepend $(INCLUDES) *.c ++ makedepend $(INCLUDES) $(srcdir)/*.c + + .PHONY: all install depend clean distclean + +-- +1.7.11.4 + diff --git a/SOURCES/xsane-0.998-desktop-file.patch b/SOURCES/xsane-0.998-desktop-file.patch new file mode 100644 index 0000000..396be67 --- /dev/null +++ b/SOURCES/xsane-0.998-desktop-file.patch @@ -0,0 +1,53 @@ +From e3f3e266249f77ff655299daeab3128347d6cb17 Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Wed, 30 Jan 2013 15:59:40 +0100 +Subject: [PATCH] patch: desktop-file + +Squashed commit of the following: + +commit e472b870c4490f41b9257c835d4c8c72a575e9e9 +Author: Nils Philippsen +Date: Wed Jan 30 15:57:57 2013 +0100 + + desktop file: use Name, GenericName, X-GNOME-FullName + +commit 9f7f6a039193f91473ded79780bd72e29d7b94fb +Author: Nils Philippsen +Date: Wed Jan 30 15:57:14 2013 +0100 + + desktop file: remove obsolete encoding key + +commit 79a444793a60bd729c72283ad1920f0ce9c65dc2 +Author: Nils Philippsen +Date: Fri Nov 19 12:41:23 2010 +0100 + + customize desktop file +--- + src/xsane.desktop | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/xsane.desktop b/src/xsane.desktop +index d5161e5..a2a4a61 100644 +--- a/src/xsane.desktop ++++ b/src/xsane.desktop +@@ -1,9 +1,14 @@ + [Desktop Entry] +-Encoding=UTF-8 +-Name=XSane - Scanning ++Version=1.0 ++#Name=XSane - Scanning ++Name=XSane ++GenericName=Scanner Tool ++X-GNOME-FullName=XSane (Scanner Tool) + Comment=Acquire images from a scanner + Exec=xsane ++TryExec=xsane + Icon=xsane + Terminal=false + Type=Application +-Categories=Application;Graphics ++Categories=Graphics;2DGraphics;RasterGraphics;Scanning;GTK; ++StartupNotify=true +-- +1.8.1 + diff --git a/SOURCES/xsane-0.998-libpng.patch b/SOURCES/xsane-0.998-libpng.patch new file mode 100644 index 0000000..c792c5a --- /dev/null +++ b/SOURCES/xsane-0.998-libpng.patch @@ -0,0 +1,41 @@ +From bd29bb933cf80f397dd28286635da2aec58e6e6c Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Thu, 16 Aug 2012 11:26:54 +0200 +Subject: [PATCH] patch: libpng + +Squashed commit of the following: + +commit 9df6d60274c95b5081faf5b398aa27cde969c649 +Author: Nils Philippsen +Date: Mon Nov 21 13:50:38 2011 +0100 + + support libpng-1.5 +--- + src/xsane-save.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/xsane-save.c b/src/xsane-save.c +index 87ef685..5461bf1 100644 +--- a/src/xsane-save.c ++++ b/src/xsane-save.c +@@ -4912,7 +4912,7 @@ int xsane_save_png(FILE *outfile, int compression, FILE *imagefile, Image_info * + return -1; /* error */ + } + +- if (setjmp(png_ptr->jmpbuf)) ++ if (setjmp(png_jmpbuf(png_ptr))) + { + snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_LIBPNG); + xsane_back_gtk_error(buf, TRUE); +@@ -5102,7 +5102,7 @@ int xsane_save_png_16(FILE *outfile, int compression, FILE *imagefile, Image_inf + return -1; /* error */ + } + +- if (setjmp(png_ptr->jmpbuf)) ++ if (setjmp(png_jmpbuf(png_ptr))) + { + snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_LIBPNG); + xsane_back_gtk_error(buf, TRUE); +-- +1.7.11.4 + diff --git a/SOURCES/xsane-0.998-preview-selection.patch b/SOURCES/xsane-0.998-preview-selection.patch new file mode 100644 index 0000000..2939818 --- /dev/null +++ b/SOURCES/xsane-0.998-preview-selection.patch @@ -0,0 +1,60 @@ +From d8bf0d3f0af16e208b52084f19a9a1287acbcea0 Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Fri, 2 Sep 2011 11:56:26 +0200 +Subject: [PATCH] patch: preview-selection +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Squashed commit of the following: + +commit e7c03a6de0c76256810b6340e0a954e88c3448e9 +Author: Reinhard Fössmeier +Date: Wed May 12 20:23:18 2010 +0200 + + fixed a problem in mouse event processing + + Fixed a problem in mouse event processing that interfered with selecting + the scan rectangle in the preview window. +--- + src/xsane-preview.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/xsane-preview.c b/src/xsane-preview.c +index f089dd1..264c775 100644 +--- a/src/xsane-preview.c ++++ b/src/xsane-preview.c +@@ -80,7 +80,6 @@ + #include "xsane-preview.h" + #include "xsane-preferences.h" + #include "xsane-gamma.h" +-#include + + + #ifndef PATH_MAX +@@ -3023,9 +3022,9 @@ static gint preview_motion_event_handler(GtkWidget *window, GdkEvent *event, gpo + preview_display_color_components(p, event->motion.x, event->motion.y); + + switch (((GdkEventMotion *)event)->state & +- GDK_Num_Lock & GDK_Caps_Lock & GDK_Shift_Lock & GDK_Scroll_Lock) /* mask all Locks */ ++ (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) /* only check for mouse buttons */ + { +- case 256: /* left button */ ++ case GDK_BUTTON1_MASK: /* left button */ + + DBG(DBG_info2, "left button\n"); + +@@ -3292,8 +3291,8 @@ static gint preview_motion_event_handler(GtkWidget *window, GdkEvent *event, gpo + } + break; + +- case 512: /* middle button */ +- case 1024: /* right button */ ++ case GDK_BUTTON2_MASK: /* middle button */ ++ case GDK_BUTTON3_MASK: /* right button */ + DBG(DBG_info2, "middle or right button\n"); + + if (p->selection_drag) +-- +1.7.11.4 + diff --git a/SOURCES/xsane-0.998-wmclass.patch b/SOURCES/xsane-0.998-wmclass.patch new file mode 100644 index 0000000..4fd84ba --- /dev/null +++ b/SOURCES/xsane-0.998-wmclass.patch @@ -0,0 +1,33 @@ +From a0b23d7e1991b23e2b9ab78bf382c55b9e24cfb9 Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Fri, 25 May 2012 11:47:39 +0200 +Subject: [PATCH] patch: wmclass + +Squashed commit of the following: + +commit d42b7a9dbe397a301373e3cbaa589540a1475a0b +Author: Nils Philippsen +Date: Fri May 25 11:45:48 2012 +0200 + + set program name -> wmclass to match desktop file name +--- + src/xsane.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/xsane.c b/src/xsane.c +index 8b24b0c..eee76ff 100644 +--- a/src/xsane.c ++++ b/src/xsane.c +@@ -6208,6 +6208,9 @@ int main(int argc, char **argv) + xsane.ipc_pipefd[1] = 0; + } + ++ /* Set program name -> wmclass to match desktop file name */ ++ g_set_prgname("xsane"); ++ + #if 0 + bindtextdomain(PACKAGE, STRINGIFY(LOCALEDIR)); + textdomain(PACKAGE); +-- +1.7.11.4 + diff --git a/SOURCES/xsane-0.999-coverity.patch b/SOURCES/xsane-0.999-coverity.patch new file mode 100644 index 0000000..f6350fe --- /dev/null +++ b/SOURCES/xsane-0.999-coverity.patch @@ -0,0 +1,2679 @@ +From 9fe09c0e0746067f9e9774229b3d0beb35c5766b Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Wed, 2 Apr 2014 14:54:05 +0200 +Subject: [PATCH] patch: coverity + +Squashed commit of the following: + +commit e26d784a5217d1609e774678d8abaeb2e1ecdadc +Author: Nils Philippsen +Date: Tue Mar 11 10:28:02 2014 +0100 + + ensure loop is run at least once while scaling + +commit e5bf8c8a659a7b03ae3eb130ebfaad292e16816d +Author: Nils Philippsen +Date: Thu Feb 27 15:07:42 2014 +0100 + + remove stray semicolon + +commit ad928333ba038051ca0a405470dadeaa0f365b95 +Author: Nils Philippsen +Date: Thu Feb 27 15:06:17 2014 +0100 + + use actual pointer type in realloc() + +commit 11dfb289d03555218318ce1a284c1165bbc58b22 +Author: Nils Philippsen +Date: Tue Feb 25 17:42:54 2014 +0100 + + don't overflow size expression for allocation + +commit 5daccfc14f129c632f8409a89903d21c5495dd2f +Author: Nils Philippsen +Date: Tue Feb 25 17:18:58 2014 +0100 + + don't leak file descriptors and other resources + +commit 034023d7aaac378b8ab02051d11392c639154842 +Author: Nils Philippsen +Date: Tue Feb 25 16:04:28 2014 +0100 + + don't overrun buffers + +commit f7454d62b5206e2100e8569e04ff4a6868cbd909 +Author: Nils Philippsen +Date: Tue Feb 25 15:56:40 2014 +0100 + + check if files actually could be opened + +commit de30cacd285c02382a32dc48cf9fe015223a57f7 +Author: Nils Philippsen +Date: Tue Feb 25 15:47:51 2014 +0100 + + handle negative return values of some calls + +commit b46a520ba85bda776b1a91de9f842ed96d97fa73 +Author: Nils Philippsen +Date: Tue Feb 25 11:54:31 2014 +0100 + + only attempt to close successfully opened files + +commit bb6a8ccab418f89fa6fb367874f84aa56195cca0 +Author: Nils Philippsen +Date: Tue Feb 25 11:54:15 2014 +0100 + + bail out early if memory can't be allocated + +commit 9b1e34c1d099c0a7acf7bd5aec8e3f0c2d2eafa8 +Author: Nils Philippsen +Date: Tue Feb 25 11:53:11 2014 +0100 + + gtk_entry_get_text() isn't supposed to return NULL + +commit bc7553caaea1955e7fa48f3a2f4c0773d40204c3 +Author: Nils Philippsen +Date: Tue Feb 25 11:00:11 2014 +0100 + + negate comparison instead of operand + +commit d1d4675a416383d808def730ade4f6b5b1a493b8 +Author: Nils Philippsen +Date: Tue Feb 25 10:55:42 2014 +0100 + + use int types for fgetc() results + +commit cbdc2df85367c27ff56fb9cdd77a61c6d82be0e1 +Author: Nils Philippsen +Date: Tue Feb 25 10:36:53 2014 +0100 + + avoid freeing static strings + +commit 0c377b9658daa5dcdbc6c260baa4e31237202f3e +Author: Nils Philippsen +Date: Wed Feb 19 16:10:35 2014 +0100 + + use guchar* for PNG profile buffer + +commit 70152131771b891fe04b3087e3b73c42e6d5ebbe +Author: Nils Philippsen +Date: Wed Feb 19 16:09:46 2014 +0100 + + cast time_t into long instead of int + +commit 0ac0683bcba7d8cf4e786abc3abe9c3e3c7d60a0 +Author: Nils Philippsen +Date: Tue Feb 18 17:55:02 2014 +0100 + + use glib macros where ints are transported in pointers + +commit 8e85947fe5a592a3f938ab5bb2dc79488b638515 +Author: Nils Philippsen +Date: Mon Feb 17 13:42:13 2014 +0100 + + handle return values of some file related system calls + +commit f4ba79f720a9a1e4a3caddc77d0de19a7d2fb75c +Author: Nils Philippsen +Date: Mon Feb 17 12:07:09 2014 +0100 + + avoid leaking resources +--- + src/xsane-back-gtk.c | 75 +++++++++++++--- + src/xsane-batch-scan.c | 41 ++++----- + src/xsane-email-project.c | 83 +++++++++--------- + src/xsane-fax-project.c | 14 ++- + src/xsane-front-gtk.c | 42 ++++----- + src/xsane-multipage-project.c | 5 ++ + src/xsane-preview.c | 34 ++++---- + src/xsane-save.c | 166 ++++++++++++++++++++++------------- + src/xsane-scan.c | 17 ++-- + src/xsane-setup.c | 70 +++++++-------- + src/xsane-text.h | 1 + + src/xsane-viewer.c | 199 +++++++++++++++++++++++------------------- + src/xsane.c | 65 ++++++++------ + 13 files changed, 478 insertions(+), 334 deletions(-) + +diff --git a/src/xsane-back-gtk.c b/src/xsane-back-gtk.c +index 6ef1506..6452f4b 100644 +--- a/src/xsane-back-gtk.c ++++ b/src/xsane-back-gtk.c +@@ -40,6 +40,7 @@ SANE_Status xsane_control_option(SANE_Handle handle, SANE_Int option, SANE_Actio + const SANE_Option_Descriptor *xsane_get_option_descriptor(SANE_Handle handle, SANE_Int option); + const char *xsane_back_gtk_unit_string(SANE_Unit unit); + void xsane_back_gtk_set_tooltip(GtkTooltips *tooltips, GtkWidget *widget, const gchar *desc); ++static int xsane_back_gtk_ensure_dir(const char *path); + int xsane_back_gtk_make_path(size_t buf_size, char *buf, const char *prog_name, const char *dir_name, + const char *prefix, const char *dev_name, const char *postfix, int location); + void xsane_back_gtk_set_option(int opt_num, void *val, SANE_Action action); +@@ -245,11 +246,47 @@ void xsane_back_gtk_set_tooltip(GtkTooltips *tooltips, GtkWidget *widget, const + + /* ----------------------------------------------------------------------------------------------------------------- */ + ++static int xsane_back_gtk_ensure_dir(const char *path) ++{ ++ struct stat statbuf; ++ ++ if (stat(path, &statbuf) < 0) ++ { ++ if (errno != ENOENT) ++ { ++ /* stat() failed and it wasn't because the file doesn't exist */ ++ return -1; ++ } ++ else ++ { ++ /* if path doesn't exist, create directory */ ++ if (mkdir(path, 0777) < 0) ++ { ++ /* mkdir() failed */ ++ return -2; ++ } ++ else ++ { ++ return 0; ++ } ++ } ++ } ++ ++ if (S_ISDIR(statbuf.st_mode)) ++ { ++ return 0; ++ } ++ ++ /* path exists and isn't a directory */ ++ return -3; ++} ++ + int xsane_back_gtk_make_path(size_t buf_size, char *buf, const char *prog_name, const char *dir_name, + const char *prefix, const char *dev_name, const char *postfix, int location) + { + size_t len, extra; + int i; ++ char msgbuf[TEXTBUFSIZE]; + + DBG(DBG_proc, "xsane_back_gtk_make_path\n"); + +@@ -263,7 +300,10 @@ int xsane_back_gtk_make_path(size_t buf_size, char *buf, const char *prog_name, + { + snprintf(buf, buf_size-2, "%s", STRINGIFY(XSANE_FIXED_APPDATA_DIR)); + } +- mkdir(buf, 0777); /* ensure ~/.sane directory exists */ ++ if (xsane_back_gtk_ensure_dir(buf)) ++ { ++ goto dir_failed; ++ } + } + else if (location == XSANE_PATH_SYSTEM) /* make path to system file */ + { +@@ -290,7 +330,10 @@ int xsane_back_gtk_make_path(size_t buf_size, char *buf, const char *prog_name, + len += extra; + + buf[len] = '\0'; +- mkdir(buf, 0777); /* ensure ~/.sane/PROG_NAME directory exists */ ++ if (xsane_back_gtk_ensure_dir(buf)) ++ { ++ goto dir_failed; ++ } + + buf[len++] = SLASH; /* OS/2 does not like slash at end of mktemp-path */ + } +@@ -314,7 +357,10 @@ int xsane_back_gtk_make_path(size_t buf_size, char *buf, const char *prog_name, + buf[len++] = SLASH; + + buf[len] = '\0'; +- mkdir(buf, 0777); /* ensure DIR_NAME directory exists */ ++ if (xsane_back_gtk_ensure_dir(buf)) ++ { ++ goto dir_failed; ++ } + } + + if (len >= buf_size) +@@ -454,6 +500,12 @@ filename_too_long: + xsane_back_gtk_error(ERR_FILENAME_TOO_LONG, FALSE); + errno = E2BIG; + return -1; ++ ++dir_failed: ++ snprintf(msgbuf, sizeof(msgbuf), "%s %s.", ERR_FAILED_CREATE_ENSURE_DIR, ++ strerror(errno)); ++ xsane_back_gtk_error(msgbuf, FALSE); ++ return -1; + } + + /* ----------------------------------------------------------------------------------------------------------------- */ +@@ -784,11 +836,15 @@ gint xsane_back_gtk_decision(gchar *title, gchar **xpm_d, gchar *message, gchar + void xsane_back_gtk_ipc_dialog_callback(gpointer data, gint source, GdkInputCondition cond) + { + char message[TEXTBUFSIZE]; +- size_t bytes; ++ ssize_t bytes; + + DBG(DBG_proc, "xsane_back_gtk_message\n"); + +- bytes = read(xsane.ipc_pipefd[0], message, sizeof(message)-1); ++ if ((bytes = read(xsane.ipc_pipefd[0], message, sizeof(message)-1)) < 0) ++ { ++ DBG(DBG_error, "xsane_back_gtk_message(): can't read from pipe\n"); ++ return; ++ } + message[bytes] = 0; + + xsane_back_gtk_decision(ERR_HEADER_CHILD_PROCESS_ERROR, (gchar **) error_xpm, message, BUTTON_CLOSE, 0 /* no reject text */, FALSE); +@@ -1980,7 +2036,7 @@ static void xsane_back_gtk_value_update(GtkAdjustment *adj_data, DialogElement * + static void xsane_back_gtk_range_display_value_right_callback(GtkAdjustment *adjust, gpointer data) + { + gchar buf[TEXTBUFSIZE]; +- int digits = (int) data; ++ int digits = GPOINTER_TO_INT(data); + GtkLabel *label; + + snprintf(buf, sizeof(buf), "%1.*f", digits, adjust->value); +@@ -2028,7 +2084,7 @@ void xsane_back_gtk_range_new(GtkWidget *parent, const char *name, gfloat val, + gtk_widget_set_size_request(value_label, 45, -1); + gtk_box_pack_end(GTK_BOX(hbox), value_label, FALSE, FALSE, 1); + +- g_signal_connect(elem->data, "value_changed", (GtkSignalFunc) xsane_back_gtk_range_display_value_right_callback, (void *) digits); ++ g_signal_connect(elem->data, "value_changed", (GtkSignalFunc) xsane_back_gtk_range_display_value_right_callback, GINT_TO_POINTER(digits)); + gtk_object_set_data(GTK_OBJECT(elem->data), "value-label", value_label); + g_signal_emit_by_name(GTK_OBJECT(elem->data), "value_changed"); /* update value */ + gtk_widget_show(value_label); +@@ -2318,10 +2374,7 @@ static void xsane_back_gtk_text_entry_callback(GtkWidget *w, gpointer data) + buf[0] = '\0'; + + text = gtk_entry_get_text(GTK_ENTRY(elem->widget)); +- if (text) +- { +- strncpy(buf, text, opt->size); +- } ++ strncpy(buf, text, opt->size); + buf[opt->size - 1] = '\0'; + + xsane_back_gtk_set_option(opt_num, buf, SANE_ACTION_SET_VALUE); +diff --git a/src/xsane-batch-scan.c b/src/xsane-batch-scan.c +index 90cc0e0..12eb1b2 100644 +--- a/src/xsane-batch-scan.c ++++ b/src/xsane-batch-scan.c +@@ -291,7 +291,7 @@ int xsane_batch_scan_load_list_from_file(char *filename) + + fd = open(filename, O_RDONLY); + +- if (fd > 0) ++ if (fd >= 0) + { + w.io.fd = fd; + w.io.read = read; +@@ -396,11 +396,11 @@ static void xsane_batch_scan_save_list(void) + sprintf(windowname, "%s %s %s", xsane.prog_name, WINDOW_SAVE_BATCH_LIST, xsane.device_text); + xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", "batch-lists", 0, "default", ".xbl", XSANE_PATH_LOCAL_SANE); + +- if (!xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, NULL, NULL, XSANE_FILE_CHOOSER_ACTION_SAVE, XSANE_GET_FILENAME_SHOW_NOTHING, XSANE_FILE_FILTER_ALL | XSANE_FILE_FILTER_BATCHLIST, XSANE_FILE_FILTER_BATCHLIST)); ++ if (!xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, NULL, NULL, XSANE_FILE_CHOOSER_ACTION_SAVE, XSANE_GET_FILENAME_SHOW_NOTHING, XSANE_FILE_FILTER_ALL | XSANE_FILE_FILTER_BATCHLIST, XSANE_FILE_FILTER_BATCHLIST)) + { + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); + +- if (fd > 0) ++ if (fd >= 0) + { + w.io.fd = fd; + w.io.read = read; +@@ -680,7 +680,6 @@ static GtkWidget *xsane_batch_scan_create_list_entry(Batch_Scan_Parameters *para + GtkWidget *list_item; + GtkWidget *hbox; + int size = 120; +- char *data; + + list_item = gtk_list_item_new(); + +@@ -688,8 +687,6 @@ static GtkWidget *xsane_batch_scan_create_list_entry(Batch_Scan_Parameters *para + gtk_container_add(GTK_CONTAINER(list_item), hbox); + gtk_widget_show(hbox); + +- data = calloc(size, size); +- + parameters->gtk_preview = gtk_preview_new(GTK_PREVIEW_COLOR); + gtk_preview_size(GTK_PREVIEW(parameters->gtk_preview), size, size); + gtk_box_pack_start(GTK_BOX(hbox), parameters->gtk_preview, FALSE, FALSE, 0); +@@ -725,13 +722,17 @@ void xsane_batch_scan_add() + + parameters = calloc(1, sizeof(Batch_Scan_Parameters)); + +- if (parameters) ++ if (!parameters) + { +- xsane_batch_scan_get_parameters(parameters); +- +- parameters->name = strdup(TEXT_BATCH_AREA_DEFAULT_NAME); ++ DBG(DBG_error, "xsane_batch_scan_add(): couldn't allocate memory for " ++ "parameters\n"); ++ return; + } + ++ xsane_batch_scan_get_parameters(parameters); ++ ++ parameters->name = strdup(TEXT_BATCH_AREA_DEFAULT_NAME); ++ + list_item = xsane_batch_scan_create_list_entry(parameters); + + /* scroll list to end */ +@@ -796,7 +797,7 @@ static void xsane_batch_scan_rotate_mirror(GtkWidget *widget, gpointer data) + GList *select; + GtkObject *list_item; + Batch_Scan_Parameters *parameters = NULL; +- int rotate_info = (int) data; ++ int rotate_info = GPOINTER_TO_INT(data); + int rotate, mirror; + + DBG(DBG_proc, "xsane_batch_scan_rotate_mirror\n"); +@@ -834,7 +835,7 @@ static void xsane_batch_scan_rename_button_callback(GtkWidget *widget, gpointer + { + DBG(DBG_proc, "xsane_batch_scan_rename\n"); + +- xsane_batch_scan_rename = (int) data; ++ xsane_batch_scan_rename = GPOINTER_TO_INT(data); + } + + +@@ -881,7 +882,7 @@ static void xsane_batch_scan_rename_callback(GtkWidget *widget, gpointer data) + gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE); + snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_BATCH_RENAME); + gtk_window_set_title(GTK_WINDOW(rename_dialog), buf); +- g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_batch_scan_rename_button_callback,(void *) -1); ++ g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_batch_scan_rename_button_callback, GINT_TO_POINTER(-1)); + gtk_widget_show(rename_dialog); + + text = gtk_entry_new(); +@@ -898,7 +899,7 @@ static void xsane_batch_scan_rename_callback(GtkWidget *widget, gpointer data) + #else + button = gtk_button_new_with_label(BUTTON_CANCEL); + #endif +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_rename_button_callback, (void *) -1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_rename_button_callback, GINT_TO_POINTER(-1)); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + +@@ -909,7 +910,7 @@ static void xsane_batch_scan_rename_callback(GtkWidget *widget, gpointer data) + button = gtk_button_new_with_label(BUTTON_OK); + #endif + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_rename_button_callback, (void *) 1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_rename_button_callback, GINT_TO_POINTER(1)); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_grab_default(button); + gtk_widget_show(button); +@@ -1000,11 +1001,11 @@ void xsane_create_batch_scan_dialog(const char *devicetext) + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, del_batch_xpm, DESC_BATCH_DEL, (GtkSignalFunc) xsane_batch_scan_delete, NULL); + + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, ascii_xpm, DESC_BATCH_RENAME, (GtkSignalFunc) xsane_batch_scan_rename_callback, NULL); +- xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, rotate90_xpm, DESC_ROTATE90, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 1); +- xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, rotate180_xpm, DESC_ROTATE180, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 2); +- xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, rotate270_xpm, DESC_ROTATE270, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 3); +- xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, mirror_x_xpm, DESC_MIRROR_X, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 4); +- xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, mirror_y_xpm, DESC_MIRROR_Y, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 6); ++ xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, rotate90_xpm, DESC_ROTATE90, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, GINT_TO_POINTER(1)); ++ xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, rotate180_xpm, DESC_ROTATE180, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, GINT_TO_POINTER(2)); ++ xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, rotate270_xpm, DESC_ROTATE270, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, GINT_TO_POINTER(3)); ++ xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, mirror_x_xpm, DESC_MIRROR_X, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, GINT_TO_POINTER(4)); ++ xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, mirror_y_xpm, DESC_MIRROR_Y, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, GINT_TO_POINTER(6)); + + + /* the scolled window with the list */ +diff --git a/src/xsane-email-project.c b/src/xsane-email-project.c +index 23fc942..413e3f7 100644 +--- a/src/xsane-email-project.c ++++ b/src/xsane-email-project.c +@@ -895,6 +895,11 @@ static void xsane_email_project_update_project_status() + + snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.email_project); + projectfile = fopen(filename, "r+b"); /* r+ = read and write, position = start of file */ ++ if (!projectfile) ++ { ++ DBG(DBG_error, "Could not open project file '%s'.\n", filename); ++ return; ++ } + + snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.email_status); /* fill 32 characters status line */ + fprintf(projectfile, "%s\n", buf); /* first line is status of email */ +@@ -931,6 +936,11 @@ void xsane_email_project_save() + } + + projectfile = fopen(filename, "wb"); /* write binary (b for win32) */ ++ if (! projectfile) ++ { ++ DBG(DBG_error, "Could not open project file '%s'.\n", filename); ++ return; ++ } + + if (xsane.email_status) + { +@@ -1271,7 +1281,7 @@ static void xsane_email_entry_rename_button_callback(GtkWidget *widget, gpointer + { + DBG(DBG_proc, "xsane_email_entry_rename\n"); + +- xsane_email_entry_rename = (int) data; ++ xsane_email_entry_rename = GPOINTER_TO_INT(data); + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ +@@ -1322,7 +1332,7 @@ static void xsane_email_entry_rename_callback(GtkWidget *widget, gpointer list) + gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE); + snprintf(filename, sizeof(filename), "%s %s", xsane.prog_name, WINDOW_EMAIL_RENAME); + gtk_window_set_title(GTK_WINDOW(rename_dialog), filename); +- g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_email_entry_rename_button_callback, (void *) -1); ++ g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_email_entry_rename_button_callback, GINT_TO_POINTER(-1)); + gtk_widget_show(rename_dialog); + + text = gtk_entry_new(); +@@ -1339,7 +1349,7 @@ static void xsane_email_entry_rename_callback(GtkWidget *widget, gpointer list) + #else + button = gtk_button_new_with_label(BUTTON_CANCEL); + #endif +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_entry_rename_button_callback,(void *) -1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_entry_rename_button_callback, GINT_TO_POINTER(-1)); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + +@@ -1348,7 +1358,7 @@ static void xsane_email_entry_rename_callback(GtkWidget *widget, gpointer list) + #else + button = gtk_button_new_with_label(BUTTON_OK); + #endif +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_entry_rename_button_callback, (void *) 1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_entry_rename_button_callback, GINT_TO_POINTER(1)); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + +@@ -1526,6 +1536,11 @@ static void xsane_create_email(int fd) + { + DBG(DBG_error, "could not open email project file %s\n", filename); + ++ if (projectfile) ++ { ++ fclose(projectfile); ++ } ++ + if (xsane.email_status) + { + free(xsane.email_status); +@@ -1766,7 +1781,7 @@ static void xsane_create_email(int fd) + + static void xsane_email_send_process() + { +- int fd_socket; ++ int fd_socket = -1; + int status; + char *password; + int i; +@@ -1787,36 +1802,20 @@ static void xsane_email_send_process() + + if (fd_socket < 0) /* could not open socket */ + { +- if (xsane.email_status) +- { +- free(xsane.email_status); +- } + xsane.email_status = strdup(TEXT_EMAIL_STATUS_POP3_CONNECTION_FAILED); +- xsane.email_progress_val = 0.0; +- xsane_front_gtk_email_project_update_lockfile_status(); +- +- free(password); +- +- return; ++ status = -1; ++ goto out; + } + + status = pop3_login(fd_socket, preferences.email_auth_user, password); + + close(fd_socket); ++ fd_socket = -1; + + if (status == -1) + { +- if (xsane.email_status) +- { +- free(xsane.email_status); +- } + xsane.email_status = strdup(TEXT_EMAIL_STATUS_POP3_LOGIN_FAILED); +- xsane.email_progress_val = 0.0; +- xsane_front_gtk_email_project_update_lockfile_status(); +- +- free(password); +- +- return; ++ goto out; + } + + DBG(DBG_info, "POP3 authentication done\n"); +@@ -1829,17 +1828,9 @@ static void xsane_email_send_process() + + if (fd_socket < 0) /* could not open socket */ + { +- if (xsane.email_status) +- { +- free(xsane.email_status); +- } + xsane.email_status = strdup(TEXT_EMAIL_STATUS_SMTP_CONNECTION_FAILED); +- xsane.email_progress_val = 0.0; +- xsane_front_gtk_email_project_update_lockfile_status(); +- +- free(password); +- +- return; ++ status = -1; ++ goto out; + } + + +@@ -1847,7 +1838,8 @@ static void xsane_email_send_process() + preferences.email_authentication, preferences.email_auth_user, password); + if (status == -1) + { +- return; ++ xsane.email_status = strdup(TEXT_EMAIL_STATUS_SMTP_ERR_DATA); ++ goto out; + } + + +@@ -1855,19 +1847,30 @@ static void xsane_email_send_process() + + write_smtp_footer(fd_socket); + +- close(fd_socket); ++out: ++ if (fd_socket >= 0) ++ { ++ close(fd_socket); ++ } + + if (xsane.email_status) + { + free(xsane.email_status); + } +- xsane.email_status = strdup(TEXT_EMAIL_STATUS_SENT); +- xsane.email_progress_val = 1.0; ++ if (status != -1) ++ { ++ xsane.email_status = strdup(TEXT_EMAIL_STATUS_SENT); ++ xsane.email_progress_val = 1.0; ++ } ++ else ++ { ++ xsane.email_progress_val = 0.0; ++ } + xsane_front_gtk_email_project_update_lockfile_status(); + + free(password); + +- _exit(0); ++ _exit(status); + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ +diff --git a/src/xsane-fax-project.c b/src/xsane-fax-project.c +index 5750b55..c08af59 100644 +--- a/src/xsane-fax-project.c ++++ b/src/xsane-fax-project.c +@@ -452,6 +452,12 @@ static void xsane_fax_project_update_project_status() + snprintf(filename, sizeof(filename), "%s/xsane-fax-list", preferences.fax_project); + projectfile = fopen(filename, "r+b"); /* r+ = read and write, position = start of file */ + ++ if (! projectfile) ++ { ++ DBG(DBG_error, "Could not open project file '%s'.\n", filename); ++ return; ++ } ++ + snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.fax_status); /* fill 32 characters status line */ + fprintf(projectfile, "%s\n", buf); /* first line is status of mail */ + +@@ -754,7 +760,7 @@ static void xsane_fax_entry_rename_button_callback(GtkWidget *widget, gpointer d + { + DBG(DBG_proc, "xsane_fax_entry_rename\n"); + +- xsane_fax_entry_rename = (int) data; ++ xsane_fax_entry_rename = GPOINTER_TO_INT(data); + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ +@@ -805,7 +811,7 @@ static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list) + gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE); + snprintf(filename, sizeof(filename), "%s %s", xsane.prog_name, WINDOW_FAX_RENAME); + gtk_window_set_title(GTK_WINDOW(rename_dialog), filename); +- g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_fax_entry_rename_button_callback,(void *) -1); ++ g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, GINT_TO_POINTER(-1)); + gtk_widget_show(rename_dialog); + + text = gtk_entry_new(); +@@ -822,7 +828,7 @@ static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list) + #else + button = gtk_button_new_with_label(BUTTON_CANCEL); + #endif +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) -1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, GINT_TO_POINTER(-1)); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + +@@ -832,7 +838,7 @@ static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list) + #else + button = gtk_button_new_with_label(BUTTON_OK); + #endif +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) 1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, GINT_TO_POINTER(1)); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + +diff --git a/src/xsane-front-gtk.c b/src/xsane-front-gtk.c +index 7bb49b0..84452f2 100644 +--- a/src/xsane-front-gtk.c ++++ b/src/xsane-front-gtk.c +@@ -598,7 +598,7 @@ gint xsane_authorization_callback(SANE_String_Const resource, + authorize_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_position(GTK_WINDOW(authorize_dialog), GTK_WIN_POS_CENTER); + gtk_window_set_resizable(GTK_WINDOW(authorize_dialog), FALSE); +- g_signal_connect(GTK_OBJECT(authorize_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_authorization_button_callback), (void *) -1); /* -1 = cancel */ ++ g_signal_connect(GTK_OBJECT(authorize_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_authorization_button_callback), GINT_TO_POINTER(-1)); /* -1 = cancel */ + snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_AUTHORIZE); + gtk_window_set_title(GTK_WINDOW(authorize_dialog), buf); + xsane_set_window_icon(authorize_dialog, 0); +@@ -667,7 +667,7 @@ gint xsane_authorization_callback(SANE_String_Const resource, + #else + button = gtk_button_new_with_label(BUTTON_CANCEL); + #endif +- g_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(xsane_authorization_button_callback), (void *) -1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(xsane_authorization_button_callback), GINT_TO_POINTER(-1)); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 10); /* x-space around cancel-button */ + gtk_widget_show(button); + +@@ -677,7 +677,7 @@ gint xsane_authorization_callback(SANE_String_Const resource, + button = gtk_button_new_with_label(BUTTON_OK); + #endif + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); +- g_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(xsane_authorization_button_callback), (void *) 1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(xsane_authorization_button_callback), GINT_TO_POINTER(1)); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 10); /* x-space around OK-button */ + gtk_widget_grab_default(button); + gtk_widget_show(button); +@@ -1107,7 +1107,7 @@ void xsane_option_menu_new_with_pixmap(GdkWindow *window, GtkBox *parent, const + static void xsane_range_display_value_right_callback(GtkAdjustment *adjust, gpointer data) + { + gchar buf[TEXTBUFSIZE]; +- int digits = (int) data; ++ int digits = GPOINTER_TO_INT(data); + GtkLabel *label; + + snprintf(buf, sizeof(buf), "%1.*f", digits, adjust->value); +@@ -1144,7 +1144,7 @@ void xsane_range_new(GtkBox *parent, char *labeltext, const char *desc, + gtk_widget_set_size_request(value_label, 35, -1); + gtk_box_pack_end(GTK_BOX(hbox), value_label, FALSE, FALSE, 1); + +- g_signal_connect(*data, "value_changed", (GtkSignalFunc) xsane_range_display_value_right_callback, (void *) digits); ++ g_signal_connect(*data, "value_changed", (GtkSignalFunc) xsane_range_display_value_right_callback, GINT_TO_POINTER(digits)); + gtk_object_set_data(GTK_OBJECT(*data), "value-label", value_label); + g_signal_emit_by_name(GTK_OBJECT(*data), "value_changed"); /* update value */ + gtk_widget_show(value_label); +@@ -1236,7 +1236,7 @@ void xsane_range_new_with_pixmap(GdkWindow *window, GtkBox *parent, const char * + gtk_widget_set_size_request(value_label, 35, -1); + gtk_box_pack_end(GTK_BOX(hbox), value_label, FALSE, FALSE, 1); + +- g_signal_connect(*data, "value_changed", (GtkSignalFunc) xsane_range_display_value_right_callback, (void *) digits); ++ g_signal_connect(*data, "value_changed", (GtkSignalFunc) xsane_range_display_value_right_callback, GINT_TO_POINTER(digits)); + gtk_object_set_data(GTK_OBJECT(*data), "value-label", value_label); + g_signal_emit_by_name(GTK_OBJECT(*data), "value_changed"); /* update value */ + gtk_widget_show(value_label); +@@ -1383,7 +1383,7 @@ static void xsane_filename_counter_step_callback(GtkWidget *widget, gpointer dat + { + DBG(DBG_proc, "xsane_filename_counter_step_callback\n"); + +- preferences.filename_counter_step = (int) data; ++ preferences.filename_counter_step = GPOINTER_TO_INT(data); + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ +@@ -1528,7 +1528,7 @@ void xsane_outputfilename_new(GtkWidget *vbox) + snprintf(buf, sizeof(buf), "%+d", j); + xsane_filename_counter_step_item = gtk_menu_item_new_with_label(buf); + gtk_container_add(GTK_CONTAINER(xsane_filename_counter_step_menu), xsane_filename_counter_step_item); +- g_signal_connect(GTK_OBJECT(xsane_filename_counter_step_item), "activate", (GtkSignalFunc) xsane_filename_counter_step_callback, (void *) j); ++ g_signal_connect(GTK_OBJECT(xsane_filename_counter_step_item), "activate", (GtkSignalFunc) xsane_filename_counter_step_callback, GINT_TO_POINTER(j)); + gtk_widget_show(xsane_filename_counter_step_item); + if (preferences.filename_counter_step == j++) + { +@@ -1895,7 +1895,7 @@ static GtkWidget *eula_dialog = NULL; + + static gboolean xsane_eula_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) + { +- eula_accept_flag = (int) data; ++ eula_accept_flag = GPOINTER_TO_INT(data); + + DBG(DBG_proc ,"xsane_eula_delete_event(%d)\n", eula_accept_flag); + eula_dialog = NULL; +@@ -1907,7 +1907,7 @@ static gboolean xsane_eula_delete_event(GtkWidget *widget, GdkEvent *event, gpoi + + static void xsane_eula_button_callback(GtkWidget *widget, gpointer data) + { +- eula_accept_flag = (int) data; ++ eula_accept_flag = GPOINTER_TO_INT(data); + + DBG(DBG_proc ,"xsane_eula_button_callback(%d)\n", eula_accept_flag); + +@@ -1937,7 +1937,7 @@ int xsane_display_eula(int ask_for_accept) + gtk_widget_set_size_request(eula_dialog, 550, 580); + gtk_window_set_position(GTK_WINDOW(eula_dialog), GTK_WIN_POS_CENTER); + gtk_window_set_resizable(GTK_WINDOW(eula_dialog), TRUE); +- g_signal_connect(GTK_OBJECT(eula_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_eula_delete_event), (void *) -1); /* -1 = cancel */ ++ g_signal_connect(GTK_OBJECT(eula_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_eula_delete_event), GINT_TO_POINTER(-1)); /* -1 = cancel */ + snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_EULA); + gtk_window_set_title(GTK_WINDOW(eula_dialog), buf); + accelerator_group = gtk_accel_group_new(); +@@ -2090,13 +2090,13 @@ int xsane_display_eula(int ask_for_accept) + button = gtk_button_new_with_label(BUTTON_NOT_ACCEPT); + gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, DEF_GTK_ACCEL_LOCKED); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_eula_button_callback, (void *) 1 /* not accept */); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_eula_button_callback, GINT_TO_POINTER(1) /* not accept */); + gtk_container_add(GTK_CONTAINER(hbox), button); + gtk_widget_grab_default(button); + gtk_widget_show(button); + + button = gtk_button_new_with_label(BUTTON_ACCEPT); +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_eula_button_callback, (void *) 0 /* accept */); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_eula_button_callback, GINT_TO_POINTER(0) /* accept */); + gtk_container_add(GTK_CONTAINER(hbox), button); + gtk_widget_show(button); + } +@@ -2109,7 +2109,7 @@ int xsane_display_eula(int ask_for_accept) + #endif + gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, DEF_GTK_ACCEL_LOCKED); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_eula_button_callback, (void *) 0 /* ok = accept */); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_eula_button_callback, GINT_TO_POINTER(0) /* ok = accept */); + gtk_container_add(GTK_CONTAINER(hbox), button); + gtk_widget_grab_default(button); + gtk_widget_show(button); +@@ -2336,7 +2336,7 @@ void xsane_display_gpl(void) + #endif + gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, DEF_GTK_ACCEL_LOCKED); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_license_dialog_callback, (void *) 0 /* ok = accept */); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_license_dialog_callback, GINT_TO_POINTER(0) /* ok = accept */); + gtk_container_add(GTK_CONTAINER(hbox), button); + gtk_widget_grab_default(button); + gtk_widget_show(button); +@@ -2414,7 +2414,7 @@ static void xsane_front_gtk_getname_button_callback(GtkWidget *widget, gpointer + { + DBG(DBG_proc, "xsane_front_gtk_getname_button_callback\n"); + +- xsane_front_gtk_getname_button = (int) data; ++ xsane_front_gtk_getname_button = GPOINTER_TO_INT(data); + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ +@@ -2438,7 +2438,7 @@ int xsane_front_gtk_getname_dialog(const char *dialog_title, const char *desc_te + gtk_window_set_resizable(GTK_WINDOW(getname_dialog), FALSE); + snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, dialog_title); + gtk_window_set_title(GTK_WINDOW(getname_dialog), buf); +- g_signal_connect(GTK_OBJECT(getname_dialog), "delete_event", (GtkSignalFunc) xsane_front_gtk_getname_button_callback, (void *) -1); ++ g_signal_connect(GTK_OBJECT(getname_dialog), "delete_event", (GtkSignalFunc) xsane_front_gtk_getname_button_callback, GINT_TO_POINTER(-1)); + gtk_widget_show(getname_dialog); + + /* set the main vbox */ +@@ -2469,7 +2469,7 @@ int xsane_front_gtk_getname_dialog(const char *dialog_title, const char *desc_te + #else + button = gtk_button_new_with_label(BUTTON_CANCEL); + #endif +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_front_gtk_getname_button_callback, (void *) -1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_front_gtk_getname_button_callback, GINT_TO_POINTER(-1)); + gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, DEF_GTK_ACCEL_LOCKED); /* ESC */ + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); +@@ -2479,7 +2479,7 @@ int xsane_front_gtk_getname_dialog(const char *dialog_title, const char *desc_te + #else + button = gtk_button_new_with_label(BUTTON_OK); + #endif +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_front_gtk_getname_button_callback, (void *) 1); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_front_gtk_getname_button_callback, GINT_TO_POINTER(1)); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); +@@ -2580,9 +2580,9 @@ void xsane_front_gtk_email_project_update_lockfile_status() + { + fprintf(lockfile, "%s\n", xsane.email_status); /* first line is status of mail */ + fprintf(lockfile, "%3d\n", (int) (xsane.email_progress_val * 100)); +- } + +- fclose(lockfile); ++ fclose(lockfile); ++ } + } + #endif + /* ---------------------------------------------------------------------------------------------------------------------- */ +diff --git a/src/xsane-multipage-project.c b/src/xsane-multipage-project.c +index f23e5f8..af3c6cc 100644 +--- a/src/xsane-multipage-project.c ++++ b/src/xsane-multipage-project.c +@@ -517,6 +517,11 @@ void xsane_multipage_project_save() + } + + projectfile = fopen(filename, "wb"); /* write binary (b for win32) */ ++ if (!projectfile) ++ { ++ DBG(DBG_error, "Could not open project file '%s'.\n", filename); ++ return; ++ } + + if (xsane.multipage_status) + { +diff --git a/src/xsane-preview.c b/src/xsane-preview.c +index 6eaf687..ef26098 100644 +--- a/src/xsane-preview.c ++++ b/src/xsane-preview.c +@@ -4112,7 +4112,7 @@ static void preview_create_preset_area_menu(Preview *p, int selection) + gtk_container_add(GTK_CONTAINER(preset_area_menu), preset_area_item); + g_signal_connect(GTK_OBJECT(preset_area_item), "button_press_event", (GtkSignalFunc) preview_preset_area_context_menu_callback, p); + g_signal_connect(GTK_OBJECT(preset_area_item), "activate", (GtkSignalFunc) preview_preset_area_callback, p); +- gtk_object_set_data(GTK_OBJECT(preset_area_item), "Selection", (void *) i); ++ gtk_object_set_data(GTK_OBJECT(preset_area_item), "Selection", GINT_TO_POINTER(i)); + gtk_object_set_data(GTK_OBJECT(preset_area_item), "Preview", (void *) p); + + gtk_widget_show(preset_area_item); +@@ -4468,7 +4468,7 @@ Preview *preview_new(void) + rotation_item = gtk_menu_item_new_with_label(buf); + gtk_container_add(GTK_CONTAINER(rotation_menu), rotation_item); + g_signal_connect(GTK_OBJECT(rotation_item), "activate", (GtkSignalFunc) preview_rotation_callback, p); +- gtk_object_set_data(GTK_OBJECT(rotation_item), "Selection", (void *) rot); ++ gtk_object_set_data(GTK_OBJECT(rotation_item), "Selection", GINT_TO_POINTER(rot)); + + gtk_widget_show(rotation_item); + } +@@ -5145,11 +5145,11 @@ static void preview_save_image_file(Preview *p, FILE *out) + /* always save it as a 16 bit PPM image: */ + fprintf(out, "P6\n" + "# surface: %g %g %g %g %u %u\n" +- "# time: %d\n" ++ "# time: %ld\n" + "%d %d\n65535\n", + dsurface[0], dsurface[1], dsurface[2], dsurface[3], + p->surface_type, p->surface_unit, +- (int) time(NULL), ++ (long) time(NULL), + p->image_width, p->image_height); + + fwrite(p->image_data_raw, 6, p->image_width*p->image_height, out); +@@ -5711,14 +5711,14 @@ static gint preview_preset_area_rename_callback(GtkWidget *widget, GtkWidget *pr + + DBG(DBG_proc, "preview_preset_area_rename_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection")); + p = (Preview *) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Preview"); + + DBG(DBG_info ,"rename %s\n", preferences.preset_area[selection]->name); + + /* set menu in correct state, is a bit strange this way but I do not have a better idea */ + old_preset_area_menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(p->preset_area_option_menu)); +- old_selection = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection"); ++ old_selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection")); + gtk_menu_popdown(GTK_MENU(old_preset_area_menu)); + gtk_option_menu_set_history(GTK_OPTION_MENU(p->preset_area_option_menu), old_selection); + +@@ -5761,12 +5761,12 @@ static gint preview_preset_area_add_callback(GtkWidget *widget, GtkWidget *prese + + DBG(DBG_proc, "preview_preset_area_add_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection")); + p = (Preview *) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Preview"); + + /* set menu in correct state, is a bit strange this way but I do not have a better idea */ + old_preset_area_menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(p->preset_area_option_menu)); +- old_selection = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection"); ++ old_selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection")); + gtk_menu_popdown(GTK_MENU(old_preset_area_menu)); + gtk_option_menu_set_history(GTK_OPTION_MENU(p->preset_area_option_menu), old_selection); + +@@ -5812,7 +5812,7 @@ static gint preview_preset_area_delete_callback(GtkWidget *widget, GtkWidget *pr + + DBG(DBG_proc, "preview_preset_area_delete_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection")); + p = (Preview *) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Preview"); + + +@@ -5832,7 +5832,7 @@ static gint preview_preset_area_delete_callback(GtkWidget *widget, GtkWidget *pr + old_preset_area_menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(p->preset_area_option_menu)); + + gtk_option_menu_remove_menu(GTK_OPTION_MENU(p->preset_area_option_menu)); +- old_selection = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection"); ++ old_selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection")); + + if (old_selection == selection) /* we are deleting the selected surface */ + { +@@ -5861,7 +5861,7 @@ static gint preview_preset_area_move_up_callback(GtkWidget *widget, GtkWidget *p + + DBG(DBG_proc, "preview_preset_area_move_up_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection")); + p = (Preview *) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Preview"); + + if (selection > 1) /* make sure "full area" stays at top */ +@@ -5877,7 +5877,7 @@ static gint preview_preset_area_move_up_callback(GtkWidget *widget, GtkWidget *p + old_preset_area_menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(p->preset_area_option_menu)); + + gtk_option_menu_remove_menu(GTK_OPTION_MENU(p->preset_area_option_menu)); +- old_selection = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection"); ++ old_selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection")); + + if (old_selection == selection) + { +@@ -5906,7 +5906,7 @@ static gint preview_preset_area_move_down_callback(GtkWidget *widget, GtkWidget + + DBG(DBG_proc, "preview_preset_area_move_down_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Selection")); + p = (Preview *) gtk_object_get_data(GTK_OBJECT(preset_area_widget), "Preview"); + + /* full size can not moved down */ +@@ -5923,7 +5923,7 @@ static gint preview_preset_area_move_down_callback(GtkWidget *widget, GtkWidget + old_preset_area_menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(p->preset_area_option_menu)); + + gtk_option_menu_remove_menu(GTK_OPTION_MENU(p->preset_area_option_menu)); +- old_selection = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection"); ++ old_selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_preset_area_menu))), "Selection")); + + if (old_selection == selection) + { +@@ -5954,7 +5954,7 @@ static gint preview_preset_area_context_menu_callback(GtkWidget *widget, GdkEven + + DBG(DBG_proc, "preview_preset_area_context_menu_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "Selection")); + + if (event->type == GDK_BUTTON_PRESS) + { +@@ -6031,7 +6031,7 @@ static void preview_preset_area_callback(GtkWidget *widget, gpointer data) + + DBG(DBG_proc, "preview_preset_area_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "Selection")); + + p->preset_surface[0] = preferences.preset_area[selection]->xoffset; + p->preset_surface[1] = preferences.preset_area[selection]->yoffset; +@@ -6055,7 +6055,7 @@ static void preview_rotation_callback(GtkWidget *widget, gpointer data) + + DBG(DBG_proc, "preview_rotation_callback\n"); + +- rot = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); ++ rot = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "Selection")); + + switch (rot) + { +diff --git a/src/xsane-save.c b/src/xsane-save.c +index 2d0e44b..31825d8 100644 +--- a/src/xsane-save.c ++++ b/src/xsane-save.c +@@ -28,6 +28,8 @@ + #include "xsane-save.h" + #include + #include ++#include ++#include + + #include + +@@ -138,7 +140,7 @@ int xsane_create_secure_file(const char *filename) + fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666); + umask(XSANE_DEFAULT_UMASK); /* define new file permissions */ + +- if (fd > 0) ++ if (fd >= 0) + { + DBG(DBG_info, "file %s is created and secure\n", filename); + close(fd); +@@ -261,22 +263,27 @@ int xsane_get_filesize(char *filename) + { + FILE *infile; + int pos; +- int size; ++ int size = -1; + + infile = fopen(filename, "rb"); /* read binary (b for win32) */ + if (infile == NULL) + { +- return 0; ++ return 0; + } + +- pos = ftell(infile); ++ if ((pos = ftell(infile)) < 0) ++ { ++ DBG(DBG_error, "xsane_get_filesize(): can't get file position\n"); ++ goto out; ++ } + fseek(infile, 0, SEEK_END); /* get size */ + size = ftell(infile); + fseek(infile, pos, SEEK_SET); /* go to previous position */ + ++out: + fclose(infile); + +- return size; ++ return size; + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ +@@ -959,7 +966,8 @@ cmsHTRANSFORM xsane_create_cms_transform(Image_info *image_info, int cms_functio + int xsane_save_grayscale_image_as_lineart(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save) + { + int x, y, bit; +- u_char bitval, packed; ++ int bitval; ++ u_char packed; + + *cancel_save = 0; + +@@ -1107,7 +1115,7 @@ int xsane_save_scaled_image(FILE *outfile, FILE *imagefile, Image_info *image_in + y_factor = 1.0; + y = 0.0; + +- while (y < original_image_height) ++ do + { + DBG(DBG_info2, "xsane_save_scaled_image: original line %d, new line %d\n", (int) y, y_new); + +@@ -1233,6 +1241,7 @@ int xsane_save_scaled_image(FILE *outfile, FILE *imagefile, Image_info *image_in + y += y_factor; + read_line = (oldy != (int) y); + } ++ while (y < original_image_height); + + if (read_line) /* we have to write one more line */ + { +@@ -3784,7 +3793,8 @@ int xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info, float + static int xsane_embed_pdf_icm_profile(FILE *outfile, struct pdf_xref *xref, char *icm_filename, int flatedecode, int icc_object) + { + FILE *icm_profile; +- size_t size, embed_len; ++ ssize_t size; ++ size_t embed_len; + unsigned char *embed_buffer; + int ret; + +@@ -3798,7 +3808,12 @@ static int xsane_embed_pdf_icm_profile(FILE *outfile, struct pdf_xref *xref, cha + } + + fseek(icm_profile, 0, SEEK_END); +- size = ftell(icm_profile); ++ if ((size = ftell(icm_profile)) < 0) ++ { ++ DBG(DBG_error, "Could not determine size of ICM profile file."); ++ fclose(icm_profile); ++ return -1; ++ } + fseek(icm_profile, 0, SEEK_SET); + + embed_buffer = malloc(size + 1); +@@ -4374,7 +4389,8 @@ static void xsane_jpeg_write_icm_profile(j_compress_ptr cinfo_ptr, const JOCTET + static void xsane_jpeg_embed_scanner_icm_profile(j_compress_ptr cinfo_ptr, const char *icm_filename) + { + FILE *icm_profile; +- size_t size, embed_len; ++ ssize_t size; ++ size_t embed_len; + cmsUInt8Number *embed_buffer; + + DBG(DBG_proc, "xsane_jpeg_embed_scanner_icm_profile(%s)\n", icm_filename); +@@ -4385,15 +4401,19 @@ static void xsane_jpeg_embed_scanner_icm_profile(j_compress_ptr cinfo_ptr, const + return; + } + +- fseek(icm_profile, 0, SEEK_END); +- size = ftell(icm_profile); +- fseek(icm_profile, 0, SEEK_SET); ++ if ((fseek(icm_profile, 0, SEEK_END) < 0) || ++ ((size = ftell(icm_profile)) < 0) || ++ (fseek(icm_profile, 0, SEEK_SET) < 0)) ++ { ++ DBG(DBG_error, "Can't determine size of ICM profile file '%s': '%s'", ++ icm_filename, strerror(errno)); ++ goto out; ++ } + + embed_buffer = (cmsUInt8Number *) malloc(size + 1); + if (embed_buffer) + { + embed_len = fread(embed_buffer, 1, size, icm_profile); +- fclose(icm_profile); + embed_buffer[embed_len] = 0; + + xsane_jpeg_write_icm_profile(cinfo_ptr, embed_buffer, embed_len); +@@ -4401,6 +4421,9 @@ static void xsane_jpeg_embed_scanner_icm_profile(j_compress_ptr cinfo_ptr, const + + DBG(DBG_info, "ICM profile %s has been embedded to jpeg file\n", icm_filename); + } ++ ++out: ++ fclose(icm_profile); + } + #endif + +@@ -4606,15 +4629,20 @@ int xsane_save_jpeg(FILE *outfile, int quality, FILE *imagefile, Image_info *ima + static void xsane_tiff_embed_scanner_icm_profile(TIFF *tiffile, const char *icm_filename) + { + FILE *icm_profile; +- size_t size; ++ ssize_t size; + char *icm_profile_buffer; + + DBG(DBG_proc, "xsane_tiff_embed_scanner_icm_profile(%s)\n", icm_filename); + if((icm_profile = fopen(icm_filename, "rb"))) + { +- fseek(icm_profile, 0, SEEK_END); +- size = ftell(icm_profile); +- fseek(icm_profile, 0, SEEK_SET); ++ if ((fseek(icm_profile, 0, SEEK_END) < 0) || ++ ((size = ftell(icm_profile)) < 0) || ++ (fseek(icm_profile, 0, SEEK_SET) < 0)) ++ { ++ DBG(DBG_error, "Can't determine size of ICM profile file '%s': '%s'", ++ icm_filename, strerror(errno)); ++ goto out; ++ } + + icm_profile_buffer = (char *) malloc(size + 1); + +@@ -4638,7 +4666,7 @@ static void xsane_tiff_embed_scanner_icm_profile(TIFF *tiffile, const char *icm_ + DBG(DBG_error, "Can not get enogh memory for ICM profile\n"); + } + +- ++out: + fclose(icm_profile); + } + else +@@ -4869,17 +4897,22 @@ int xsane_save_tiff_page(TIFF *tiffile, int page, int pages, int quality, FILE * + static void xsane_png_embed_scanner_icm_profile(png_structp png_ptr, png_infop png_info_ptr, const char *icm_filename) + { + FILE *icm_profile; +- gchar *profile_buffer; +- size_t size; ++ guchar *profile_buffer; ++ ssize_t size; + + DBG(DBG_proc, "xsane_png_embed_scanner_icm_profile(%s)\n", icm_filename); + icm_profile = fopen(icm_filename, "rb"); + + if (icm_profile) + { +- fseek(icm_profile, 0, SEEK_END); +- size = ftell(icm_profile); +- fseek(icm_profile, 0, SEEK_SET); ++ if ((fseek(icm_profile, 0, SEEK_END) < 0) || ++ ((size = ftell(icm_profile)) < 0) || ++ (fseek(icm_profile, 0, SEEK_SET) < 0)) ++ { ++ DBG(DBG_error, "Can't determine size of ICM profile file '%s': '%s'", ++ icm_filename, strerror(errno)); ++ goto out; ++ } + + profile_buffer = malloc(size); + +@@ -4901,6 +4934,7 @@ static void xsane_png_embed_scanner_icm_profile(png_structp png_ptr, png_infop p + DBG(DBG_error, "can not allocate profile_buffer\n"); + } + ++out: + fclose(icm_profile); + } + else +@@ -5416,7 +5450,7 @@ static int xsane_save_pnm_16_ascii_color(FILE *outfile, FILE *imagefile, Image_i + *cancel_save = 0; + + +- data = malloc(image_info->image_width * 6); ++ data = malloc((guint32)image_info->image_width * 6); + + if (!data) + { +@@ -5432,7 +5466,7 @@ static int xsane_save_pnm_16_ascii_color(FILE *outfile, FILE *imagefile, Image_i + { + DBG(DBG_info, "Doing CMS color conversion\n"); + +- data_raw = malloc(image_info->image_width * 6); ++ data_raw = malloc((guint32)image_info->image_width * 6); + + if (!data_raw) + { +@@ -5622,7 +5656,7 @@ static int xsane_save_pnm_16_binary_color(FILE *outfile, FILE *imagefile, Image_ + + *cancel_save = 0; + +- data = malloc(image_info->image_width * 6); ++ data = malloc((guint32)image_info->image_width * 6); + + if (!data) + { +@@ -5638,7 +5672,7 @@ static int xsane_save_pnm_16_binary_color(FILE *outfile, FILE *imagefile, Image_ + { + DBG(DBG_info, "Doing CMS color conversion\n"); + +- data_raw = malloc(image_info->image_width * 6); ++ data_raw = malloc((guint32)image_info->image_width * 6); + + if (!data_raw) + { +@@ -6159,6 +6193,8 @@ int xsane_save_image_as_text(char *output_filename, char *input_filename, GtkPro + + gtk_progress_set_format_string(GTK_PROGRESS(progress_bar), ""); + xsane_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar), 0.0); ++ ++ fclose(ocr_progress); /* close reading end of pipe */ + } + else /* no pipe available */ + { +@@ -6178,11 +6214,6 @@ int xsane_save_image_as_text(char *output_filename, char *input_filename, GtkPro + } + } + } +- +- if (pipefd[0]) +- { +- fclose(ocr_progress); /* close reading end of pipe */ +- } + + return (*cancel_save); + } +@@ -6784,11 +6815,12 @@ int xsane_transfer_to_gimp(char *input_filename, int apply_ICM_profile, int cms_ + unsigned tile_offset; + int i, x, y; + Image_info image_info; +- FILE *imagefile; ++ FILE *imagefile = NULL; + int bytes; + unsigned char *data = NULL; + guint16 *data16 = NULL; + size_t bytes_read; ++ int retval = 0; + #ifdef HAVE_LIBLCMS + unsigned char *data_raw = NULL; + cmsHTRANSFORM hTransform = NULL; +@@ -6799,13 +6831,13 @@ int xsane_transfer_to_gimp(char *input_filename, int apply_ICM_profile, int cms_ + *cancel_save = 0; + + imagefile = fopen(input_filename, "rb"); /* read binary (b for win32) */ +- if (imagefile == 0) ++ if (!imagefile) + { + char buf[TEXTBUFSIZE]; + snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, input_filename, strerror(errno)); + xsane_back_gtk_error(buf, TRUE); +- +- return -1; ++ retval = -1; ++ goto out; + } + + xsane_read_pnm_header(imagefile, &image_info); +@@ -6828,7 +6860,8 @@ int xsane_transfer_to_gimp(char *input_filename, int apply_ICM_profile, int cms_ + + snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_NO_MEM); + xsane_back_gtk_error(buf, TRUE); +- return -1; /* error */ ++ retval = -1; /* error */ ++ goto out; + } + + #ifdef HAVE_LIBLCMS +@@ -6847,11 +6880,10 @@ int xsane_transfer_to_gimp(char *input_filename, int apply_ICM_profile, int cms_ + { + char buf[TEXTBUFSIZE]; + +- free(data); +- + snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_NO_MEM); + xsane_back_gtk_error(buf, TRUE); +- return -1; /* error */ ++ retval = -1; /* error */ ++ goto out; + } + } + #endif +@@ -6892,6 +6924,11 @@ int xsane_transfer_to_gimp(char *input_filename, int apply_ICM_profile, int cms_ + { + fseek(icm_profile, 0, SEEK_END); + size = ftell(icm_profile); ++ if (size < 0) ++ { ++ DBG(DBG_error, "xsane_transfer_to_gimp(): can't tell file position"); ++ goto out; ++ } + fseek(icm_profile, 0, SEEK_SET); + + profile_buffer = malloc(size); +@@ -6949,7 +6986,7 @@ int xsane_transfer_to_gimp(char *input_filename, int apply_ICM_profile, int cms_ + case 1: /* 1 bit gray => conversion to 8 bit gray */ + for (i = 0; i < ( (image_info.image_width + 7) / 8) * image_info.image_height; ++i) + { +- u_char mask; ++ int mask; + int j; + + mask = fgetc(imagefile); +@@ -7219,7 +7256,7 @@ int xsane_transfer_to_gimp(char *input_filename, int apply_ICM_profile, int cms_ + g_free(tile); + tile = 0; + +- fclose(imagefile); ++out: + + #ifdef HAVE_LIBLCMS + if (hTransform != NULL) +@@ -7232,9 +7269,18 @@ int xsane_transfer_to_gimp(char *input_filename, int apply_ICM_profile, int cms_ + free(data_raw); + } + #endif +- free(data); + +- return 0; ++ if (imagefile) ++ { ++ fclose(imagefile); ++ } ++ ++ if (data) ++ { ++ free(data); ++ } ++ ++ return retval; + } + #endif /* HAVE_ANY_GIMP */ + +@@ -7617,7 +7663,7 @@ int pop3_login(int fd_socket, char *user, char *passwd) + int len; + ssize_t bytes_written; + +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7627,7 +7673,7 @@ int pop3_login(int fd_socket, char *user, char *passwd) + snprintf(buf, sizeof(buf), "USER %s\r\n", user); + DBG(DBG_info2, "> USER xxx\n"); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7641,7 +7687,7 @@ int pop3_login(int fd_socket, char *user, char *passwd) + snprintf(buf, sizeof(buf), "PASS %s\r\n", passwd); + DBG(DBG_info2, "> PASS xxx\n"); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7655,7 +7701,7 @@ int pop3_login(int fd_socket, char *user, char *passwd) + snprintf(buf, sizeof(buf), "QUIT\r\n"); + DBG(DBG_info2, "> QUIT\n"); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7683,7 +7729,7 @@ int asmtp_authentication(int fd_socket, int auth_type, char *user, char *passwd) + bytes_written = write(fd_socket, buf, strlen(buf)); + snprintf(buf, sizeof(buf), "%c%s%c%s", 0, user, 0, passwd); + write_string_base64(fd_socket, buf, strlen(user)+strlen(passwd)+2); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7695,7 +7741,7 @@ int asmtp_authentication(int fd_socket, int auth_type, char *user, char *passwd) + snprintf(buf, sizeof(buf), "AUTH LOGIN\r\n"); + DBG(DBG_info2, "> %s", buf); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7710,7 +7756,7 @@ int asmtp_authentication(int fd_socket, int auth_type, char *user, char *passwd) + DBG(DBG_info2, "> (USERNAME)\n"); + write_string_base64(fd_socket, user, strlen(user)); + +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7725,7 +7771,7 @@ int asmtp_authentication(int fd_socket, int auth_type, char *user, char *passwd) + DBG(DBG_info2, "> (PASSWORD)\n"); + write_string_base64(fd_socket, passwd, strlen(passwd)); + +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7743,7 +7789,7 @@ int asmtp_authentication(int fd_socket, int auth_type, char *user, char *passwd) + snprintf(buf, sizeof(buf), "AUTH CRAM-MD5\r\n"); + DBG(DBG_info2, "> %s", buf); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7773,7 +7819,7 @@ int write_smtp_header(int fd_socket, char *from, char *to, int auth_type, char * + char *pos = NULL; + ssize_t bytes_written; + +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7790,7 +7836,7 @@ int write_smtp_header(int fd_socket, char *from, char *to, int auth_type, char * + } + DBG(DBG_info2, "> %s", buf); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7824,7 +7870,7 @@ int write_smtp_header(int fd_socket, char *from, char *to, int auth_type, char * + snprintf(buf, sizeof(buf), "MAIL FROM: <%s>\r\n", from); + DBG(DBG_info2, "> %s", buf); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7864,7 +7910,7 @@ int write_smtp_header(int fd_socket, char *from, char *to, int auth_type, char * + + DBG(DBG_info2, "> %s", buf); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7897,7 +7943,7 @@ int write_smtp_header(int fd_socket, char *from, char *to, int auth_type, char * + snprintf(buf, sizeof(buf), "DATA\r\n"); + DBG(DBG_info2, "> %s", buf); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +@@ -7932,7 +7978,7 @@ int write_smtp_footer(int fd_socket) + snprintf(buf, sizeof(buf), "\r\n.\r\n"); + DBG(DBG_info2, "> %s", buf); + bytes_written = write(fd_socket, buf, strlen(buf)); +- len = read(fd_socket, buf, sizeof(buf)); ++ len = read(fd_socket, buf, sizeof(buf) - 1); + if (len >= 0) + { + buf[len] = 0; +diff --git a/src/xsane-scan.c b/src/xsane-scan.c +index 88f954a..b6a66d6 100644 +--- a/src/xsane-scan.c ++++ b/src/xsane-scan.c +@@ -394,6 +394,13 @@ static void xsane_read_image_data(gpointer data, gint source, GdkInputCondition + { + long fpos = ftell(xsane.out); + ++ if (fpos < 0) ++ { ++ DBG(DBG_error, "xsane_read_image_data(): can't tell file " ++ "position"); ++ return; ++ } ++ + fseek(xsane.out, 0, SEEK_CUR); /* sync between write and read */ + bytes_read = fread(rgbbuf, 1, bytes - 1, xsane.out); + fseek(xsane.out, fpos, SEEK_SET); +@@ -1173,6 +1180,8 @@ void xsane_scan_done(SANE_Status status) + { + abort = 1; + } ++ ++ fclose(outfile); + } + else + { +@@ -1182,8 +1191,6 @@ void xsane_scan_done(SANE_Status status) + xsane_back_gtk_error(buf, TRUE); + abort = 1; + } +- +- fclose(outfile); + } + + fclose(infile); +@@ -1452,7 +1459,7 @@ void xsane_scan_done(SANE_Status status) + } + else + { +- type = ""; ++ type = strdup(""); + } + + list_item = gtk_list_item_new_with_label(page); +@@ -1493,7 +1500,7 @@ void xsane_scan_done(SANE_Status status) + } + else + { +- type = ""; ++ type = strdup(""); + } + + list_item = gtk_list_item_new_with_label(page); +@@ -1535,7 +1542,7 @@ void xsane_scan_done(SANE_Status status) + } + else + { +- type = ""; ++ type = strdup(""); + } + + list_item = gtk_list_item_new_with_label(page); +diff --git a/src/xsane-setup.c b/src/xsane-setup.c +index a61833a..413a343 100644 +--- a/src/xsane-setup.c ++++ b/src/xsane-setup.c +@@ -111,7 +111,7 @@ void xsane_new_printer(void) + + DBG(DBG_proc, "xsane_new_printer\n"); + +- newprinters = realloc(preferences.printer, (preferences.printerdefinitions+1) * sizeof(void *)); ++ newprinters = realloc(preferences.printer, (preferences.printerdefinitions+1) * sizeof(Preferences_printer_t *)); + + if (newprinters) /* realloc returns NULL if failed, in this case the old memory keeps alive */ + { +@@ -309,7 +309,7 @@ static void xsane_setup_printer_callback(GtkWidget *widget, gpointer data) + { + DBG(DBG_proc, "xsane_setup_printer_callback\n"); + +- preferences.printernr = (int) data; ++ preferences.printernr = GPOINTER_TO_INT(data); + xsane_setup_printer_update(); + } + +@@ -328,7 +328,7 @@ static void xsane_setup_printer_menu_build(GtkWidget *option_menu) + { + printer_item = gtk_menu_item_new_with_label(preferences.printer[i]->name); + gtk_container_add(GTK_CONTAINER(printer_menu), printer_item); +- g_signal_connect(GTK_OBJECT(printer_item), "activate", (GtkSignalFunc) xsane_setup_printer_callback, (void *) i); ++ g_signal_connect(GTK_OBJECT(printer_item), "activate", (GtkSignalFunc) xsane_setup_printer_callback, GINT_TO_POINTER(i)); + gtk_widget_show(printer_item); + } + +@@ -454,7 +454,7 @@ static void xsane_setup_filename_counter_len_callback(GtkWidget *widget, gpointe + { + DBG(DBG_proc, "xsane_setup_filename_counter_len_callback\n"); + +- xsane_setup.filename_counter_len = (int) data; ++ xsane_setup.filename_counter_len = GPOINTER_TO_INT(data); + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ +@@ -464,7 +464,7 @@ static void xsane_setup_tiff_compression16_callback(GtkWidget *widget, gpointer + { + DBG(DBG_proc, "xsane_setup_tiff_compression16_callback\n"); + +- xsane_setup.tiff_compression16_nr = (int) data; ++ xsane_setup.tiff_compression16_nr = GPOINTER_TO_INT(data); + } + + /* -------------------------------------- */ +@@ -473,7 +473,7 @@ static void xsane_setup_tiff_compression8_callback(GtkWidget *widget, gpointer d + { + DBG(DBG_proc, "xsane_setup_tiff_compression8_callback\n"); + +- xsane_setup.tiff_compression8_nr = (int) data; ++ xsane_setup.tiff_compression8_nr = GPOINTER_TO_INT(data); + } + + /* -------------------------------------- */ +@@ -481,7 +481,7 @@ static void xsane_setup_tiff_compression8_callback(GtkWidget *widget, gpointer d + static void xsane_setup_tiff_compression1_callback(GtkWidget *widget, gpointer data) + { + DBG(DBG_proc, "xsane_setup_tiff_compression1_callback\n"); +- xsane_setup.tiff_compression1_nr = (int) data; ++ xsane_setup.tiff_compression1_nr = GPOINTER_TO_INT(data); + } + #endif + +@@ -569,7 +569,7 @@ static void xsane_setup_color_management_apply_changes(GtkWidget *widget, gpoint + { + DBG(DBG_proc, "xsane_setup_colormagaement_apply_changes\n"); + +- preferences.cms_intent = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(GTK_OPTION_MENU(xsane_setup.cms_intent_option_menu))))), "Selection"); ++ preferences.cms_intent = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(GTK_OPTION_MENU(xsane_setup.cms_intent_option_menu))))), "Selection")); + xsane_update_bool(xsane_setup.cms_bpc_button, &preferences.cms_bpc); + + if (xsane.scanner_default_color_icm_profile) +@@ -843,7 +843,7 @@ void xsane_close_setup_dialog_callback(GtkWidget *widget, gpointer data) + + static void xsane_permission_toggled(GtkWidget *widget, gpointer data) + { +- int mask = (int) data; ++ int mask = GPOINTER_TO_INT(data); + int *permission = 0; + const gchar *name = gtk_widget_get_name(widget); + +@@ -912,7 +912,7 @@ static void xsane_permission_box(GtkWidget *parent, gchar *name, gchar *descript + xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PERMISSION_READ); + gtk_widget_set_size_request(button, 26, -1); + gtk_widget_set_name(button, name); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, (void *) 256); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, GINT_TO_POINTER(256)); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); + gtk_widget_show(button); + gtk_widget_set_sensitive(button, user_sensitivity); +@@ -922,7 +922,7 @@ static void xsane_permission_box(GtkWidget *parent, gchar *name, gchar *descript + xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PERMISSION_WRITE); + gtk_widget_set_size_request(button, 26, -1); + gtk_widget_set_name(button, name); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, (void *) 128); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, GINT_TO_POINTER(128)); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); + gtk_widget_show(button); + gtk_widget_set_sensitive(button, user_sensitivity); +@@ -932,7 +932,7 @@ static void xsane_permission_box(GtkWidget *parent, gchar *name, gchar *descript + xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PERMISSION_SEARCH); + gtk_widget_set_size_request(button, 26, -1); + gtk_widget_set_name(button, name); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, (void *) 64); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, GINT_TO_POINTER(64)); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); + gtk_widget_show(button); + gtk_widget_set_sensitive(button, x_sensitivity & user_sensitivity); +@@ -950,7 +950,7 @@ static void xsane_permission_box(GtkWidget *parent, gchar *name, gchar *descript + xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PERMISSION_READ); + gtk_widget_set_size_request(button, 26, -1); + gtk_widget_set_name(button, name); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, (void *) 32); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, GINT_TO_POINTER(32)); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); + gtk_widget_show(button); + +@@ -959,7 +959,7 @@ static void xsane_permission_box(GtkWidget *parent, gchar *name, gchar *descript + xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PERMISSION_WRITE); + gtk_widget_set_size_request(button, 26, -1); + gtk_widget_set_name(button, name); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, (void *) 16); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, GINT_TO_POINTER(16)); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); + gtk_widget_show(button); + +@@ -968,7 +968,7 @@ static void xsane_permission_box(GtkWidget *parent, gchar *name, gchar *descript + xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PERMISSION_SEARCH); + gtk_widget_set_size_request(button, 26, -1); + gtk_widget_set_name(button, name); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, (void *) 8); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, GINT_TO_POINTER(8)); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); + gtk_widget_show(button); + gtk_widget_set_sensitive(button, x_sensitivity); +@@ -986,7 +986,7 @@ static void xsane_permission_box(GtkWidget *parent, gchar *name, gchar *descript + xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PERMISSION_READ); + gtk_widget_set_size_request(button, 26, -1); + gtk_widget_set_name(button, name); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, (void *) 4); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, GINT_TO_POINTER(4)); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); + gtk_widget_show(button); + +@@ -995,7 +995,7 @@ static void xsane_permission_box(GtkWidget *parent, gchar *name, gchar *descript + xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PERMISSION_WRITE); + gtk_widget_set_size_request(button, 26, -1); + gtk_widget_set_name(button, name); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, (void *) 2); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, GINT_TO_POINTER(2)); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); + gtk_widget_show(button); + +@@ -1004,7 +1004,7 @@ static void xsane_permission_box(GtkWidget *parent, gchar *name, gchar *descript + xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PERMISSION_SEARCH); + gtk_widget_set_size_request(button, 26, -1); + gtk_widget_set_name(button, name); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, (void *) 1); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_permission_toggled, GINT_TO_POINTER(1)); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1); + gtk_widget_show(button); + gtk_widget_set_sensitive(button, x_sensitivity); +@@ -1750,7 +1750,7 @@ static void xsane_saving_notebook(GtkWidget *notebook) + } + filename_counter_len_item = gtk_menu_item_new_with_label(buf); + gtk_container_add(GTK_CONTAINER(filename_counter_len_menu), filename_counter_len_item); +- g_signal_connect(GTK_OBJECT(filename_counter_len_item), "activate", (GtkSignalFunc) xsane_setup_filename_counter_len_callback, (void *) i); ++ g_signal_connect(GTK_OBJECT(filename_counter_len_item), "activate", (GtkSignalFunc) xsane_setup_filename_counter_len_callback, GINT_TO_POINTER(i)); + gtk_widget_show(filename_counter_len_item); + if (preferences.filename_counter_len == i) + { +@@ -1983,7 +1983,7 @@ static void xsane_filetype_notebook(GtkWidget *notebook) + { + tiff_compression_item = gtk_menu_item_new_with_label(tiff_compression16_strings[i-1].name); + gtk_container_add(GTK_CONTAINER(tiff_compression_menu), tiff_compression_item); +- g_signal_connect(GTK_OBJECT(tiff_compression_item), "activate", (GtkSignalFunc) xsane_setup_tiff_compression16_callback, (void *) tiff_compression16_strings[i-1].number); ++ g_signal_connect(GTK_OBJECT(tiff_compression_item), "activate", (GtkSignalFunc) xsane_setup_tiff_compression16_callback, GINT_TO_POINTER(tiff_compression16_strings[i-1].number)); + gtk_widget_show(tiff_compression_item); + if (tiff_compression16_strings[i-1].number == preferences.tiff_compression16_nr) + { +@@ -2019,7 +2019,7 @@ static void xsane_filetype_notebook(GtkWidget *notebook) + { + tiff_compression_item = gtk_menu_item_new_with_label(tiff_compression8_strings[i-1].name); + gtk_container_add(GTK_CONTAINER(tiff_compression_menu), tiff_compression_item); +- g_signal_connect(GTK_OBJECT(tiff_compression_item), "activate", (GtkSignalFunc) xsane_setup_tiff_compression8_callback, (void *) tiff_compression8_strings[i-1].number); ++ g_signal_connect(GTK_OBJECT(tiff_compression_item), "activate", (GtkSignalFunc) xsane_setup_tiff_compression8_callback, GINT_TO_POINTER(tiff_compression8_strings[i-1].number)); + gtk_widget_show(tiff_compression_item); + if (tiff_compression8_strings[i-1].number == preferences.tiff_compression8_nr) + { +@@ -2056,7 +2056,7 @@ static void xsane_filetype_notebook(GtkWidget *notebook) + { + tiff_compression_item = gtk_menu_item_new_with_label(tiff_compression1_strings[i-1].name); + gtk_container_add(GTK_CONTAINER(tiff_compression_menu), tiff_compression_item); +- g_signal_connect(GTK_OBJECT(tiff_compression_item), "activate", (GtkSignalFunc) xsane_setup_tiff_compression1_callback, (void *) tiff_compression1_strings[i-1].number); ++ g_signal_connect(GTK_OBJECT(tiff_compression_item), "activate", (GtkSignalFunc) xsane_setup_tiff_compression1_callback, GINT_TO_POINTER(tiff_compression1_strings[i-1].number)); + gtk_widget_show(tiff_compression_item); + if (tiff_compression1_strings[i-1].number == preferences.tiff_compression1_nr) + { +@@ -2251,7 +2251,7 @@ static void xsane_fax_notebook(GtkWidget *notebook) + for (i=0; i < sizeof(fax_program)/sizeof(fax_program_options_type); i++) + { + button = gtk_button_new_with_label(fax_program[i].identifier); +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_notebook_set_faxprogram_default_callback, (void *) i); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_notebook_set_faxprogram_default_callback, GINT_TO_POINTER(i)); + gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 10); + gtk_widget_show(button); + } +@@ -2557,7 +2557,7 @@ static void xsane_email_notebook(GtkWidget *notebook) + { + authentication_menu_item = gtk_menu_item_new_with_label(authentication_strings[i-1].name); + gtk_container_add(GTK_CONTAINER(authentication_menu), authentication_menu_item); +- g_signal_connect(GTK_OBJECT(authentication_menu_item), "activate", (GtkSignalFunc) xsane_setup_authentication_type_callback, (void *) authentication_strings[i-1].number); ++ g_signal_connect(GTK_OBJECT(authentication_menu_item), "activate", (GtkSignalFunc) xsane_setup_authentication_type_callback, GINT_TO_POINTER(authentication_strings[i-1].number)); + gtk_widget_show(authentication_menu_item); + if (authentication_strings[i-1].number == preferences.email_authentication) + { +@@ -2926,7 +2926,7 @@ static void xsane_display_notebook(GtkWidget *notebook) + { + show_range_mode_item = gtk_menu_item_new_with_label(show_range_mode_strings[i-1].name); + gtk_container_add(GTK_CONTAINER(show_range_mode_menu), show_range_mode_item); +- g_signal_connect(GTK_OBJECT(show_range_mode_item), "activate", (GtkSignalFunc) xsane_setup_show_range_mode_callback, (void *) show_range_mode_strings[i-1].number); ++ g_signal_connect(GTK_OBJECT(show_range_mode_item), "activate", (GtkSignalFunc) xsane_setup_show_range_mode_callback, GINT_TO_POINTER(show_range_mode_strings[i-1].number)); + gtk_widget_show(show_range_mode_item); + if (show_range_mode_strings[i-1].number == preferences.show_range_mode) + { +@@ -3129,7 +3129,7 @@ static void xsane_enhance_notebook_sensitivity(int lineart_mode) + + static void xsane_setup_authentication_type_callback(GtkWidget *widget, gpointer data) + { +- xsane_setup.email_authentication = (int) data; ++ xsane_setup.email_authentication = GPOINTER_TO_INT(data); + + gtk_widget_set_sensitive(xsane_setup.pop3_vbox, (xsane_setup.email_authentication == EMAIL_AUTH_POP3)); + } +@@ -3138,14 +3138,14 @@ static void xsane_setup_authentication_type_callback(GtkWidget *widget, gpointer + + static void xsane_setup_show_range_mode_callback(GtkWidget *widget, gpointer data) + { +- xsane_setup.show_range_mode = (int) data; ++ xsane_setup.show_range_mode = GPOINTER_TO_INT(data); + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ + + static void xsane_setup_lineart_mode_callback(GtkWidget *widget, gpointer data) + { +- xsane_setup.lineart_mode = (int) data; ++ xsane_setup.lineart_mode = GPOINTER_TO_INT(data); + xsane_enhance_notebook_sensitivity(xsane_setup.lineart_mode); + } + +@@ -3168,7 +3168,7 @@ static void xsane_setup_preview_pipette_range_callback(GtkWidget *widget, gpoint + { + DBG(DBG_proc, "xsane_setup_preview_pipette_range_callback\n"); + +- xsane_setup.preview_pipette_range = (int) data; ++ xsane_setup.preview_pipette_range = GPOINTER_TO_INT(data); + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ +@@ -3237,7 +3237,7 @@ static void xsane_enhance_notebook(GtkWidget *notebook) + { + lineart_mode_item = gtk_menu_item_new_with_label(lineart_mode_strings[i-1].name); + gtk_container_add(GTK_CONTAINER(lineart_mode_menu), lineart_mode_item); +- g_signal_connect(GTK_OBJECT(lineart_mode_item), "activate", (GtkSignalFunc) xsane_setup_lineart_mode_callback, (void *) lineart_mode_strings[i-1].number); ++ g_signal_connect(GTK_OBJECT(lineart_mode_item), "activate", (GtkSignalFunc) xsane_setup_lineart_mode_callback, GINT_TO_POINTER(lineart_mode_strings[i-1].number)); + gtk_widget_show(lineart_mode_item); + if (lineart_mode_strings[i-1].number == xsane.lineart_mode) + { +@@ -3461,7 +3461,7 @@ static void xsane_enhance_notebook(GtkWidget *notebook) + snprintf(buf, sizeof(buf), "%d x %d pixel", j, j); + preview_pipette_range_item = gtk_menu_item_new_with_label(buf); + gtk_container_add(GTK_CONTAINER(preview_pipette_range_menu), preview_pipette_range_item); +- g_signal_connect(GTK_OBJECT(preview_pipette_range_item), "activate", (GtkSignalFunc) xsane_setup_preview_pipette_range_callback, (void *) j); ++ g_signal_connect(GTK_OBJECT(preview_pipette_range_item), "activate", (GtkSignalFunc) xsane_setup_preview_pipette_range_callback, GINT_TO_POINTER(j)); + gtk_widget_show(preview_pipette_range_item); + if (preferences.preview_pipette_range == j) + { +@@ -3555,22 +3555,22 @@ static void xsane_color_management_notebook(GtkWidget *notebook) + menu = gtk_menu_new(); + + menu_item = gtk_menu_item_new_with_label(SUBMENU_ITEM_CMS_INTENT_PERCEPTUAL); +- gtk_object_set_data(GTK_OBJECT(menu_item), "Selection", (void *) INTENT_PERCEPTUAL); ++ gtk_object_set_data(GTK_OBJECT(menu_item), "Selection", GINT_TO_POINTER(INTENT_PERCEPTUAL)); + gtk_container_add(GTK_CONTAINER(menu), menu_item); + gtk_widget_show(menu_item); + + menu_item = gtk_menu_item_new_with_label(SUBMENU_ITEM_CMS_INTENT_RELATIVE_COLORIMETRIC); +- gtk_object_set_data(GTK_OBJECT(menu_item), "Selection", (void *) INTENT_RELATIVE_COLORIMETRIC); ++ gtk_object_set_data(GTK_OBJECT(menu_item), "Selection", GINT_TO_POINTER(INTENT_RELATIVE_COLORIMETRIC)); + gtk_container_add(GTK_CONTAINER(menu), menu_item); + gtk_widget_show(menu_item); + + menu_item = gtk_menu_item_new_with_label(SUBMENU_ITEM_CMS_INTENT_ABSOLUTE_COLORIMETRIC); +- gtk_object_set_data(GTK_OBJECT(menu_item), "Selection", (void *) INTENT_ABSOLUTE_COLORIMETRIC); ++ gtk_object_set_data(GTK_OBJECT(menu_item), "Selection", GINT_TO_POINTER(INTENT_ABSOLUTE_COLORIMETRIC)); + gtk_container_add(GTK_CONTAINER(menu), menu_item); + gtk_widget_show(menu_item); + + menu_item = gtk_menu_item_new_with_label(SUBMENU_ITEM_CMS_INTENT_SATURATION); +- gtk_object_set_data(GTK_OBJECT(menu_item), "Selection", (void *) INTENT_SATURATION); ++ gtk_object_set_data(GTK_OBJECT(menu_item), "Selection", GINT_TO_POINTER(INTENT_SATURATION)); + gtk_container_add(GTK_CONTAINER(menu), menu_item); + gtk_widget_show(menu_item); + +diff --git a/src/xsane-text.h b/src/xsane-text.h +index ee4a222..44659b9 100644 +--- a/src/xsane-text.h ++++ b/src/xsane-text.h +@@ -803,6 +803,7 @@ YOU ARE ALONE!\ + #define ERR_HEADER_CHILD_PROCESS_ERROR _("Child process error") + + #define ERR_FAILED_CREATE_FILE _("Failed to create file:") ++#define ERR_FAILED_CREATE_ENSURE_DIR _("Failed to ensure path is a directory, or to create as one:") + #define ERR_LOAD_DEVICE_SETTINGS _("Error while loading device settings:") + #define ERR_NO_DRC_FILE _("is not a device-rc-file !!!") + #define ERR_NETSCAPE_EXECUTE_FAIL _("Failed to execute netscape!") +diff --git a/src/xsane-viewer.c b/src/xsane-viewer.c +index 844c077..6786e96 100644 +--- a/src/xsane-viewer.c ++++ b/src/xsane-viewer.c +@@ -32,6 +32,8 @@ + #include "xsane-save.h" + #include + #include ++#include ++#include + + #ifndef PATH_MAX + # define PATH_MAX 1024 +@@ -506,8 +508,8 @@ static void xsane_viewer_scale_set_scale_value_and_adjustments(GtkAdjustment *ad + + *scale_val = adj_data->value; + +- image_width = (int) gtk_object_get_data(GTK_OBJECT(adj_data), "image_width"); +- image_height = (int) gtk_object_get_data(GTK_OBJECT(adj_data), "image_height"); ++ image_width = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(adj_data), "image_width")); ++ image_height = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(adj_data), "image_height")); + + adj = (GtkAdjustment*) gtk_object_get_data(GTK_OBJECT(adj_data), "size-x-adjustment"); + if ((adj) && (image_width)) +@@ -529,8 +531,8 @@ static void xsane_viewer_scale_set_size_x_value_and_adjustments(GtkAdjustment *a + GtkAdjustment *adj; + int image_width, image_height; + +- image_width = (int) gtk_object_get_data(GTK_OBJECT(adj_data), "image_width"); +- image_height = (int) gtk_object_get_data(GTK_OBJECT(adj_data), "image_height"); ++ image_width = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(adj_data), "image_width")); ++ image_height = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(adj_data), "image_height")); + + if (!image_width) + { +@@ -553,8 +555,8 @@ static void xsane_viewer_scale_set_size_y_value_and_adjustments(GtkAdjustment *a + GtkAdjustment *adj; + int image_width, image_height; + +- image_width = (int) gtk_object_get_data(GTK_OBJECT(adj_data), "image_width"); +- image_height = (int) gtk_object_get_data(GTK_OBJECT(adj_data), "image_height"); ++ image_width = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(adj_data), "image_width")); ++ image_height = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(adj_data), "image_height")); + + if (!image_height) + { +@@ -663,7 +665,7 @@ static void xsane_viewer_scale_callback(GtkWidget *window, gpointer data) + button = gtk_check_button_new_with_label(BUTTON_SCALE_BIND); + gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 5); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), v->bind_scale); +- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_viewer_button_changed, (void *) &v->bind_scale); ++ g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_viewer_button_changed, GINT_TO_POINTER(&v->bind_scale)); + g_signal_connect_after(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_viewer_scale_callback, (void *) v); + gtk_widget_show(button); + +@@ -715,20 +717,20 @@ static void xsane_viewer_scale_callback(GtkWidget *window, gpointer data) + gtk_widget_show(spinbutton); + xsane_back_gtk_set_tooltip(xsane.tooltips, spinbutton, DESC_SCALE_HEIGHT); + +- gtk_object_set_data(GTK_OBJECT(scale_widget), "size-x-adjustment", (void *) adjustment_size_x); +- gtk_object_set_data(GTK_OBJECT(scale_widget), "size-y-adjustment", (void *) adjustment_size_y); +- gtk_object_set_data(GTK_OBJECT(scale_widget), "image_width", (void *) image_info.image_width); +- gtk_object_set_data(GTK_OBJECT(scale_widget), "image_height", (void *) image_info.image_height); ++ gtk_object_set_data(GTK_OBJECT(scale_widget), "size-x-adjustment", GINT_TO_POINTER(adjustment_size_x)); ++ gtk_object_set_data(GTK_OBJECT(scale_widget), "size-y-adjustment", GINT_TO_POINTER(adjustment_size_y)); ++ gtk_object_set_data(GTK_OBJECT(scale_widget), "image_width", GINT_TO_POINTER(image_info.image_width)); ++ gtk_object_set_data(GTK_OBJECT(scale_widget), "image_height", GINT_TO_POINTER(image_info.image_height)); + +- gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "scale-adjustment", (void *) scale_widget); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "size-y-adjustment", (void *) adjustment_size_y); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "image_width", (void *) image_info.image_width); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "image_height", (void *) image_info.image_height); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "scale-adjustment", GINT_TO_POINTER(scale_widget)); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "size-y-adjustment", GINT_TO_POINTER(adjustment_size_y)); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "image_width", GINT_TO_POINTER(image_info.image_width)); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "image_height", GINT_TO_POINTER(image_info.image_height)); + +- gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "scale-adjustment", (void *) scale_widget); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "size-x-adjustment", (void *) adjustment_size_x); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "image_width", (void *) image_info.image_width); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "image_height", (void *) image_info.image_height); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "scale-adjustment", GINT_TO_POINTER(scale_widget)); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "size-x-adjustment", GINT_TO_POINTER(adjustment_size_x)); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "image_width", GINT_TO_POINTER(image_info.image_width)); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "image_height", GINT_TO_POINTER(image_info.image_height)); + } + else + { +@@ -763,12 +765,12 @@ static void xsane_viewer_scale_callback(GtkWidget *window, gpointer data) + xsane_back_gtk_set_tooltip(xsane.tooltips, spinbutton, DESC_SCALE_WIDTH); + + gtk_object_set_data(GTK_OBJECT(scalex_widget), "size-x-adjustment", (void *) adjustment_size_x); +- gtk_object_set_data(GTK_OBJECT(scalex_widget), "image_width", (void *) image_info.image_width); +- gtk_object_set_data(GTK_OBJECT(scalex_widget), "image_height", (void *) image_info.image_height); ++ gtk_object_set_data(GTK_OBJECT(scalex_widget), "image_width", GINT_TO_POINTER(image_info.image_width)); ++ gtk_object_set_data(GTK_OBJECT(scalex_widget), "image_height", GINT_TO_POINTER(image_info.image_height)); + + gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "scale-adjustment", (void *) scalex_widget); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "image_width", (void *) image_info.image_width); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "image_height", (void *) image_info.image_height); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "image_width", GINT_TO_POINTER(image_info.image_width)); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_x), "image_height", GINT_TO_POINTER(image_info.image_height)); + + + /* Y */ +@@ -802,12 +804,12 @@ static void xsane_viewer_scale_callback(GtkWidget *window, gpointer data) + xsane_back_gtk_set_tooltip(xsane.tooltips, spinbutton, DESC_SCALE_HEIGHT); + + gtk_object_set_data(GTK_OBJECT(scaley_widget), "size-y-adjustment", (void *) adjustment_size_y); +- gtk_object_set_data(GTK_OBJECT(scaley_widget), "image_width", (void *) image_info.image_width); +- gtk_object_set_data(GTK_OBJECT(scaley_widget), "image_height", (void *) image_info.image_height); ++ gtk_object_set_data(GTK_OBJECT(scaley_widget), "image_width", GINT_TO_POINTER(image_info.image_width)); ++ gtk_object_set_data(GTK_OBJECT(scaley_widget), "image_height", GINT_TO_POINTER(image_info.image_height)); + + gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "scale-adjustment", (void *) scaley_widget); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "image_width", (void *) image_info.image_width); +- gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "image_height", (void *) image_info.image_height); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "image_width", GINT_TO_POINTER(image_info.image_width)); ++ gtk_object_set_data(GTK_OBJECT(adjustment_size_y), "image_height", GINT_TO_POINTER(image_info.image_height)); + } + + /* Apply Cancel */ +@@ -1094,6 +1096,7 @@ static void xsane_viewer_scale_image(GtkWidget *window, gpointer data) + { + DBG(DBG_error, "could not save file %s\n", outfilename); + xsane_viewer_set_sensitivity(v, TRUE); ++ fclose(infile); + return; + } + +@@ -1176,6 +1179,7 @@ static void xsane_viewer_despeckle_image(GtkWidget *window, gpointer data) + { + DBG(DBG_error, "could not save file %s\n", outfilename); + xsane_viewer_set_sensitivity(v, TRUE); ++ fclose(infile); + return; + } + +@@ -1253,6 +1257,7 @@ static void xsane_viewer_blur_image(GtkWidget *window, gpointer data) + { + DBG(DBG_error, "could not save file %s\n", outfilename); + xsane_viewer_set_sensitivity(v, TRUE); ++ fclose(infile); + return; + } + +@@ -1335,6 +1340,7 @@ static void xsane_viewer_rotate(Viewer *v, int rotation) + { + DBG(DBG_error, "could not save file %s\n", outfilename); + xsane_viewer_set_sensitivity(v, TRUE); ++ fclose(infile); + + return; + } +@@ -1444,7 +1450,7 @@ static void xsane_viewer_zoom_callback(GtkWidget *widget, gpointer data) + + DBG(DBG_proc, "xsane_viewer_zoom_callback\n"); + +- val = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); ++ val = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "Selection")); + v->zoom = (float) val / 100; + DBG(DBG_info, "setting zoom factor to %f\n", v->zoom); + xsane_viewer_read_image(v); +@@ -1721,7 +1727,7 @@ static void xsane_viewer_set_cms_proofing_callback(GtkWidget *widget, gpointer d + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_proofing_widget[1]), (GtkSignalFunc) xsane_viewer_set_cms_proofing_callback, v); + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_proofing_widget[2]), (GtkSignalFunc) xsane_viewer_set_cms_proofing_callback, v); + +- val = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); ++ val = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "Selection")); + + DBG(DBG_proc, "xsane_viewer_set_cms_proofing_callback (%d)\n", val); + +@@ -1748,7 +1754,7 @@ static void xsane_viewer_set_cms_intent_callback(GtkWidget *widget, gpointer dat + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_intent_widget[2]), (GtkSignalFunc) xsane_viewer_set_cms_intent_callback, v); + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_intent_widget[3]), (GtkSignalFunc) xsane_viewer_set_cms_intent_callback, v); + +- val = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); ++ val = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "Selection")); + + DBG(DBG_proc, "xsane_viewer_set_cms_intent_callback (%d)\n", val); + +@@ -1774,7 +1780,7 @@ static void xsane_viewer_set_cms_proofing_intent_callback(GtkWidget *widget, gpo + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_proofing_intent_widget[0]), (GtkSignalFunc) xsane_viewer_set_cms_proofing_intent_callback, v); + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_proofing_intent_widget[1]), (GtkSignalFunc) xsane_viewer_set_cms_proofing_intent_callback, v); + +- val = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); ++ val = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "Selection")); + + DBG(DBG_proc, "xsane_viewer_set_cms_proofing_intent_callback (%d)\n", val); + +@@ -1806,7 +1812,7 @@ static void xsane_viewer_set_cms_gamut_alarm_color_callback(GtkWidget *widget, g + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_gamut_alarm_color_widget[4]), (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_gamut_alarm_color_widget[5]), (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); + +- val = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); ++ val = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "Selection")); + + DBG(DBG_proc, "xsane_viewer_set_cms_gamut_alarm_color_callback (%d)\n", val); + +@@ -1942,7 +1948,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_proofing_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) 0); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(0)); + gtk_widget_show(subitem); + v->cms_proofing_widget[0] = subitem; + +@@ -1953,7 +1959,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_proofing_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) 1); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(1)); + gtk_widget_show(subitem); + v->cms_proofing_widget[1] = subitem; + +@@ -1964,7 +1970,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_proofing_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) 2); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(2)); + gtk_widget_show(subitem); + v->cms_proofing_widget[2] = subitem; + +@@ -1985,7 +1991,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_intent_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) INTENT_PERCEPTUAL); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(INTENT_PERCEPTUAL)); + gtk_widget_show(subitem); + v->cms_intent_widget[INTENT_PERCEPTUAL] = subitem; + +@@ -1996,7 +2002,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_intent_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) INTENT_RELATIVE_COLORIMETRIC); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(INTENT_RELATIVE_COLORIMETRIC)); + gtk_widget_show(subitem); + v->cms_intent_widget[INTENT_RELATIVE_COLORIMETRIC] = subitem; + +@@ -2007,7 +2013,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_intent_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) INTENT_ABSOLUTE_COLORIMETRIC); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(INTENT_ABSOLUTE_COLORIMETRIC)); + gtk_widget_show(subitem); + v->cms_intent_widget[INTENT_ABSOLUTE_COLORIMETRIC] = subitem; + +@@ -2018,7 +2024,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_intent_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) INTENT_SATURATION); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(INTENT_SATURATION)); + gtk_widget_show(subitem); + v->cms_intent_widget[INTENT_SATURATION] = subitem; + +@@ -2039,7 +2045,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_proofing_intent_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) INTENT_RELATIVE_COLORIMETRIC); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(INTENT_RELATIVE_COLORIMETRIC)); + gtk_widget_show(subitem); + v->cms_proofing_intent_widget[0] = subitem; + +@@ -2050,7 +2056,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_proofing_intent_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) INTENT_ABSOLUTE_COLORIMETRIC); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(INTENT_ABSOLUTE_COLORIMETRIC)); + gtk_widget_show(subitem); + v->cms_proofing_intent_widget[1] = subitem; + +@@ -2078,7 +2084,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) 0); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(0)); + gtk_widget_show(subitem); + v->cms_gamut_alarm_color_widget[0] = subitem; + +@@ -2089,7 +2095,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) 1); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(1)); + gtk_widget_show(subitem); + v->cms_gamut_alarm_color_widget[1] = subitem; + +@@ -2100,7 +2106,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) 2); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(2)); + gtk_widget_show(subitem); + v->cms_gamut_alarm_color_widget[2] = subitem; + +@@ -2111,7 +2117,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) 3); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(3)); + gtk_widget_show(subitem); + v->cms_gamut_alarm_color_widget[3] = subitem; + +@@ -2122,7 +2128,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) 4); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(4)); + gtk_widget_show(subitem); + v->cms_gamut_alarm_color_widget[4] = subitem; + +@@ -2133,7 +2139,7 @@ static GtkWidget *xsane_viewer_color_management_build_menu(Viewer *v) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); +- gtk_object_set_data(GTK_OBJECT(subitem), "Selection", (void *) 5); ++ gtk_object_set_data(GTK_OBJECT(subitem), "Selection", GINT_TO_POINTER(5)); + gtk_widget_show(subitem); + v->cms_gamut_alarm_color_widget[5] = subitem; + +@@ -2158,7 +2164,7 @@ static int xsane_viewer_read_image_header(Viewer *v) + if (!infile) + { + DBG(DBG_error, "could not load file %s\n", v->filename); +- return -1; ++ return -1; + } + + xsane_read_pnm_header(infile, &image_info); +@@ -2200,7 +2206,7 @@ static int xsane_viewer_read_image_header(Viewer *v) + + static int xsane_viewer_read_image(Viewer *v) + { +- unsigned char *cms_row, *row, *src_row; ++ unsigned char *cms_row, *row = NULL, *src_row = NULL; + int x, y; + int last_y; + int nread; +@@ -2211,6 +2217,7 @@ static int xsane_viewer_read_image(Viewer *v) + float size; + char *size_unit; + int width, height; ++ int retval = 0; + + #ifdef HAVE_LIBLCMS + cmsHPROFILE hInProfile = NULL; +@@ -2311,7 +2318,8 @@ static int xsane_viewer_read_image(Viewer *v) + + snprintf(buf, sizeof(buf), "%s\n%s %s: %s\n", ERR_CMS_CONVERSION, ERR_CMS_OPEN_ICM_FILE, CMS_SCANNER_ICM, image_info.icm_profile); + xsane_back_gtk_error(buf, TRUE); +- return -1; ++ retval = -1; ++ goto out; + } + + hOutProfile = cmsOpenProfileFromFile(preferences.display_icm_profile, "r"); +@@ -2323,7 +2331,8 @@ static int xsane_viewer_read_image(Viewer *v) + + snprintf(buf, sizeof(buf), "%s\n%s %s: %s\n", ERR_CMS_CONVERSION, ERR_CMS_OPEN_ICM_FILE, CMS_DISPLAY_ICM, preferences.display_icm_profile); + xsane_back_gtk_error(buf, TRUE); +- return -1; ++ retval = -1; ++ goto out; + } + + +@@ -2352,7 +2361,8 @@ static int xsane_viewer_read_image(Viewer *v) + + snprintf(buf, sizeof(buf), "%s\n%s %s: %s\n", ERR_CMS_CONVERSION, ERR_CMS_OPEN_ICM_FILE, CMS_PROOF_ICM, cms_proof_icm_profile); + xsane_back_gtk_error(buf, TRUE); +- return -1; ++ retval = -1; ++ goto out; + } + + hTransform = cmsCreateProofingTransform(hInProfile, cms_input_format, +@@ -2374,7 +2384,8 @@ static int xsane_viewer_read_image(Viewer *v) + + snprintf(buf, sizeof(buf), "%s\n%s\n", ERR_CMS_CONVERSION, ERR_CMS_CREATE_TRANSFORM); + xsane_back_gtk_error(buf, TRUE); +- return -1; ++ retval = -1; ++ goto out; + } + } + #endif +@@ -2414,39 +2425,11 @@ static int xsane_viewer_read_image(Viewer *v) + row = malloc(((int) image_info.image_width * v->zoom) * image_info.channels); + } + +-#ifdef HAVE_LIBLCMS +- if ((v->enable_color_management) && (v->cms_enable)) +- { +- cms_row = malloc(((int) image_info.image_width * v->zoom) * image_info.channels); +- } +- else +-#endif ++ if (!row || !src_row) + { +- cms_row = row; +- } +- +- if (!row || !src_row || !cms_row) +- { +- if (src_row) +- { +- free(src_row); +- } +- +- if (row) +- { +- free(row); +- } +- +-#ifdef HAVE_LIBLCMS +- if ((cms_row) && (v->enable_color_management) && (v->cms_enable)) +- { +- free(cms_row); +- } +-#endif +- +- fclose(infile); +- DBG(DBG_error, "could not allocate memory\n"); +- return -1; ++ DBG(DBG_error, "could not allocate memory\n"); ++ retval = -1; ++ goto out; + } + + +@@ -2514,7 +2497,13 @@ static int xsane_viewer_read_image(Viewer *v) + guint16 *src_row16 = (guint16 *) src_row; + guint16 *dst_row16 = (guint16 *) row; + +- fseek(infile, pos0 + (((int) (y / v->zoom)) * image_info.image_width) * image_info.channels * 2, SEEK_SET); ++ if (fseek(infile, pos0 + (((int) (y / v->zoom)) * image_info.image_width) * image_info.channels * 2, SEEK_SET)) ++ { ++ DBG(DBG_error, "could not seek in file '%s': '%s'\n", v->filename, ++ strerror(errno)); ++ retval = -1; ++ goto out; ++ } + nread = fread(src_row, 2 * image_info.channels, image_info.image_width, infile); + + if (image_info.channels > 1) +@@ -2541,10 +2530,22 @@ static int xsane_viewer_read_image(Viewer *v) + #ifdef HAVE_LIBLCMS + if ((v->enable_color_management) && (v->cms_enable)) + { ++ cms_row = malloc(((int) image_info.image_width * v->zoom) * image_info.channels); ++ if (! cms_row) ++ { ++ DBG(DBG_error, "could not allocate memory\n"); ++ retval = -1; ++ goto out; ++ } + cmsDoTransform(hTransform, row, cms_row, image_info.image_width * v->zoom); ++ gtk_preview_draw_row(GTK_PREVIEW(v->window), cms_row, 0, y, image_info.image_width * v->zoom); ++ free(cms_row); + } ++ else + #endif +- gtk_preview_draw_row(GTK_PREVIEW(v->window), cms_row, 0, y, image_info.image_width * v->zoom); ++ { ++ gtk_preview_draw_row(GTK_PREVIEW(v->window), row, 0, y, image_info.image_width * v->zoom); ++ } + } + + gtk_preview_put(GTK_PREVIEW(v->window), v->window->window, v->window->style->black_gc, 0, 0, 0, 0, +@@ -2610,9 +2611,23 @@ static int xsane_viewer_read_image(Viewer *v) + gtk_window_set_default_size(GTK_WINDOW(v->top), width, height); + } + +- free(row); +- free(src_row); +- fclose(infile); ++out: ++ if (row) ++ { ++ free(row); ++ } ++ ++ if (src_row) ++ { ++ free(src_row); ++ } ++ ++ /* cms_row is freed directly after use */ ++ ++ if (infile) ++ { ++ fclose(infile); ++ } + + #ifdef HAVE_LIBLCMS + if ((v->enable_color_management) && (v->cms_enable)) +@@ -2621,7 +2636,7 @@ static int xsane_viewer_read_image(Viewer *v) + } + #endif + +- return 0; ++ return retval; + } + + #if 0 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +@@ -3066,7 +3081,7 @@ Viewer *xsane_viewer_new(char *filename, char *selection_filetype, int allow_red + zoom_menu_item = gtk_menu_item_new_with_label(buf); + gtk_menu_append(GTK_MENU(zoom_menu), zoom_menu_item); + g_signal_connect(GTK_OBJECT(zoom_menu_item), "activate", (GtkSignalFunc) xsane_viewer_zoom_callback, v); +- gtk_object_set_data(GTK_OBJECT(zoom_menu_item), "Selection", (void *) xsane_viewer_zoom[i]); ++ gtk_object_set_data(GTK_OBJECT(zoom_menu_item), "Selection", GINT_TO_POINTER(xsane_viewer_zoom[i])); + gtk_widget_show(zoom_menu_item); + if (v->zoom*100 == xsane_viewer_zoom[i]) + { +diff --git a/src/xsane.c b/src/xsane.c +index 02b4da4..a4a3f1e 100644 +--- a/src/xsane.c ++++ b/src/xsane.c +@@ -585,7 +585,7 @@ static void xsane_show_batch_scan_callback(GtkWidget * widget) + + static void xsane_paper_orientation_callback(GtkWidget *widget, gpointer data) + { +- int pos = (int) data; ++ int pos = GPOINTER_TO_INT(data); + + DBG(DBG_proc, "xsane_paper_orientation_callback\n"); + +@@ -601,7 +601,7 @@ static void xsane_printer_callback(GtkWidget *widget, gpointer data) + + DBG(DBG_proc, "xsane_printer_callback\n"); + +- preferences.printernr = (int) data; ++ preferences.printernr = GPOINTER_TO_INT(data); + + switch (xsane.param.format) + { +@@ -1165,7 +1165,7 @@ static void xsane_scanmode_menu_callback(GtkWidget *widget, gpointer data) + + static void xsane_cms_function_menu_callback(GtkWidget *widget, gpointer data) + { +- preferences.cms_function = (int) data; ++ preferences.cms_function = GPOINTER_TO_INT(data); + DBG(DBG_proc, "xsane_cms_function_menu_callback(%d)\n", preferences.cms_function); + } + +@@ -1402,7 +1402,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ + + + gtk_container_add(GTK_CONTAINER(paper_orientation_menu), paper_orientation_item); +- g_signal_connect(GTK_OBJECT(paper_orientation_item), "activate", (GtkSignalFunc) xsane_paper_orientation_callback, (void *) i); ++ g_signal_connect(GTK_OBJECT(paper_orientation_item), "activate", (GtkSignalFunc) xsane_paper_orientation_callback, GINT_TO_POINTER(i)); + + gtk_widget_show(paper_orientation_item); + } +@@ -1436,7 +1436,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ + GDK_F1+i, GDK_SHIFT_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + } + gtk_container_add(GTK_CONTAINER(xsane_printer_menu), xsane_printer_item); +- g_signal_connect(GTK_OBJECT(xsane_printer_item), "activate", (GtkSignalFunc) xsane_printer_callback, (void *) i); ++ g_signal_connect(GTK_OBJECT(xsane_printer_item), "activate", (GtkSignalFunc) xsane_printer_callback, GINT_TO_POINTER(i)); + gtk_widget_show(xsane_printer_item); + } + +@@ -1584,9 +1584,9 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ + { + xsane_medium_item = gtk_menu_item_new_with_label(preferences.medium[i]->name); + gtk_menu_append(GTK_MENU(xsane_medium_menu), xsane_medium_item); +- g_signal_connect(GTK_OBJECT(xsane_medium_item), "button_press_event", (GtkSignalFunc) xsane_medium_context_menu_callback, (void *) i); +- g_signal_connect(GTK_OBJECT(xsane_medium_item), "activate", (GtkSignalFunc) xsane_set_medium_callback, (void *) i); +- gtk_object_set_data(GTK_OBJECT(xsane_medium_item), "Selection", (void *) i); ++ g_signal_connect(GTK_OBJECT(xsane_medium_item), "button_press_event", (GtkSignalFunc) xsane_medium_context_menu_callback, GINT_TO_POINTER(i)); ++ g_signal_connect(GTK_OBJECT(xsane_medium_item), "activate", (GtkSignalFunc) xsane_set_medium_callback, GINT_TO_POINTER(i)); ++ gtk_object_set_data(GTK_OBJECT(xsane_medium_item), "Selection", GINT_TO_POINTER(i)); + + gtk_widget_show(xsane_medium_item); + } +@@ -2697,7 +2697,7 @@ static gint xsane_medium_move_up_callback(GtkWidget *widget, GtkWidget *medium_w + + DBG(DBG_proc, "xsane_medium_move_up_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection")); + + if (selection > 1) /* make sure "full range" stays at top */ + { +@@ -2732,7 +2732,7 @@ static gint xsane_medium_move_down_callback(GtkWidget *widget, GtkWidget *medium + + DBG(DBG_proc, "xsane_medium_move_up_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection")); + + if ((selection) && (selection < preferences.medium_definitions-1)) + { +@@ -2771,7 +2771,7 @@ static gint xsane_medium_rename_callback(GtkWidget *widget, GtkWidget *medium_wi + + DBG(DBG_proc, "xsane_medium_rename_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection")); + + oldname = strdup(preferences.medium[selection]->name); + +@@ -2779,7 +2779,7 @@ static gint xsane_medium_rename_callback(GtkWidget *widget, GtkWidget *medium_wi + + /* set menu in correct state, is a bit strange this way but I do not have a better idea */ + old_medium_menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(xsane.medium_widget)); +- old_selection = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_medium_menu))), "Selection"); ++ old_selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_medium_menu))), "Selection")); + gtk_menu_popdown(GTK_MENU(old_medium_menu)); + gtk_option_menu_set_history(GTK_OPTION_MENU(xsane.medium_widget), old_selection); + +@@ -2814,13 +2814,13 @@ static gint xsane_medium_add_callback(GtkWidget *widget, GtkWidget *medium_widge + DBG(DBG_proc, "xsane_medium_add_callback\n"); + + /* add new item after selected item */ +- selection = 1 + (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); ++ selection = 1 + GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection")); + + oldname = strdup(TEXT_NEW_MEDIA_NAME); + + /* set menu in correct state, is a bit strange this way but I do not have a better idea */ + old_medium_menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(xsane.medium_widget)); +- old_selection = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_medium_menu))), "Selection"); ++ old_selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_medium_menu))), "Selection")); + gtk_menu_popdown(GTK_MENU(old_medium_menu)); + gtk_option_menu_set_history(GTK_OPTION_MENU(xsane.medium_widget), old_selection); + +@@ -2895,7 +2895,7 @@ static gint xsane_medium_delete_callback(GtkWidget *widget, GtkWidget *medium_wi + + DBG(DBG_proc, "xsane_medium_delete_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection")); + + if (selection) /* full range can not be deleted */ + { +@@ -2951,7 +2951,7 @@ static gint xsane_medium_context_menu_callback(GtkWidget *widget, GdkEvent *even + + DBG(DBG_proc, "xsane_medium_context_menu_callback\n"); + +- selection = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); ++ selection = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), "Selection")); + + if (event->type == GDK_BUTTON_PRESS) + { +@@ -3022,7 +3022,7 @@ static gint xsane_medium_context_menu_callback(GtkWidget *widget, GdkEvent *even + + static void xsane_set_medium_callback(GtkWidget *widget, gpointer data) + { +- int medium_nr = (int) data; ++ int medium_nr = GPOINTER_TO_INT(data); + + if (medium_nr != preferences.medium_nr) + { +@@ -3205,11 +3205,11 @@ static void xsane_set_update_policy_callback(GtkWidget *widget, gpointer data) + DBG(DBG_proc, "xsane_set_update_policy_callback\n"); + + g_signal_handlers_block_by_func(GTK_OBJECT(xsane.update_policy_continu), (GtkSignalFunc) xsane_set_update_policy_callback, +- (void *) GTK_UPDATE_CONTINUOUS); ++ GINT_TO_POINTER(GTK_UPDATE_CONTINUOUS)); + g_signal_handlers_block_by_func(GTK_OBJECT(xsane.update_policy_discont), (GtkSignalFunc) xsane_set_update_policy_callback, +- (void *) GTK_UPDATE_DISCONTINUOUS); ++ GINT_TO_POINTER(GTK_UPDATE_DISCONTINUOUS)); + g_signal_handlers_block_by_func(GTK_OBJECT(xsane.update_policy_delayed), (GtkSignalFunc) xsane_set_update_policy_callback, +- (void *) GTK_UPDATE_DELAYED); ++ GINT_TO_POINTER(GTK_UPDATE_DELAYED)); + + if (policy == GTK_UPDATE_CONTINUOUS) + { +@@ -3231,11 +3231,11 @@ static void xsane_set_update_policy_callback(GtkWidget *widget, gpointer data) + } + + g_signal_handlers_unblock_by_func(GTK_OBJECT(xsane.update_policy_continu), (GtkSignalFunc) xsane_set_update_policy_callback, +- (void *) GTK_UPDATE_CONTINUOUS); ++ GINT_TO_POINTER(GTK_UPDATE_CONTINUOUS)); + g_signal_handlers_unblock_by_func(GTK_OBJECT(xsane.update_policy_discont), (GtkSignalFunc) xsane_set_update_policy_callback, +- (void *) GTK_UPDATE_DISCONTINUOUS); ++ GINT_TO_POINTER(GTK_UPDATE_DISCONTINUOUS)); + g_signal_handlers_unblock_by_func(GTK_OBJECT(xsane.update_policy_delayed), (GtkSignalFunc) xsane_set_update_policy_callback, +- (void *) GTK_UPDATE_DELAYED); ++ GINT_TO_POINTER(GTK_UPDATE_DELAYED)); + + preferences.gtk_update_policy = policy; + xsane_pref_save(); +@@ -3389,7 +3389,7 @@ static void xsane_info_dialog(GtkWidget *widget, gpointer data) + snprintf(buf, sizeof(buf), "%d bit", (int) (0.5 + log(opt->constraint.range->max+1.0) / log(2.0))); + label = xsane_info_table_text_new(table, buf, 1, 2); + } +- else if ((!xsane.xsane_channels > 1) && (xsane.scanner_gamma_gray)) /* gray gamma correction by scanner */ ++ else if ((!(xsane.xsane_channels > 1)) && (xsane.scanner_gamma_gray)) /* gray gamma correction by scanner */ + { + const SANE_Option_Descriptor *opt; + +@@ -3807,6 +3807,13 @@ static void xsane_close_fds_for_exec(signed int first_fd_to_leave_open, ...) + + open_max = (int) sysconf (_SC_OPEN_MAX); + ++ if (open_max < 0) ++ { ++ DBG(DBG_error, "xsane_close_fds_for_exec(): Can't determine maximum " ++ "number of open files."); ++ return; ++ } ++ + close_fds = malloc (open_max); + + memset (close_fds, 1, open_max); +@@ -4147,7 +4154,7 @@ static GtkWidget *xsane_view_build_menu(void) + { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } +- g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_CONTINUOUS); ++ g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_update_policy_callback, GINT_TO_POINTER(GTK_UPDATE_CONTINUOUS)); + gtk_widget_show(subitem); + xsane.update_policy_continu = subitem; + +@@ -4157,7 +4164,7 @@ static GtkWidget *xsane_view_build_menu(void) + { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } +- g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DISCONTINUOUS); ++ g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_update_policy_callback, GINT_TO_POINTER(GTK_UPDATE_DISCONTINUOUS)); + gtk_widget_show(subitem); + xsane.update_policy_discont = subitem; + +@@ -4167,7 +4174,7 @@ static GtkWidget *xsane_view_build_menu(void) + { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); + } +- g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DELAYED); ++ g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_update_policy_callback, GINT_TO_POINTER(GTK_UPDATE_DELAYED)); + gtk_widget_show(subitem); + xsane.update_policy_delayed = subitem; + +@@ -5709,8 +5716,8 @@ static void xsane_choose_device(void) + gtk_widget_add_accelerator(button, "clicked", device_selection_accelerator_group, GDK_F1+i, 0, DEF_GTK_ACCEL_LOCKED); + } + +- g_signal_connect(GTK_OBJECT(button), "button_press_event", (GtkSignalFunc) xsane_select_device_by_mouse_callback, (void *) (long) i); +- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_select_device_by_key_callback, (void *) (long) i); ++ g_signal_connect(GTK_OBJECT(button), "button_press_event", (GtkSignalFunc) xsane_select_device_by_mouse_callback, GINT_TO_POINTER(i)); ++ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_select_device_by_key_callback, GINT_TO_POINTER(i)); + gtk_box_pack_start(GTK_BOX(device_vbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + owner = gtk_radio_button_group(GTK_RADIO_BUTTON(button));; +-- +1.9.0 + diff --git a/SOURCES/xsane-0.999-lcms2.patch b/SOURCES/xsane-0.999-lcms2.patch new file mode 100644 index 0000000..c3d696c --- /dev/null +++ b/SOURCES/xsane-0.999-lcms2.patch @@ -0,0 +1,372 @@ +From 30af0e2edbf061b71bed9536d826894449f0390d Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Mon, 23 Sep 2013 16:11:31 +0200 +Subject: [PATCH] patch: lcms2 + +Squashed commit of the following: + +commit f975accf7e1a08438b63580ea848457d373200f5 +Author: Nils Philippsen +Date: Mon Sep 23 14:53:45 2013 +0200 + + Add support for lcms 2.x. +--- + configure.in | 22 ++++++++++++++---- + include/config.h.in | 8 ++++++- + src/xsane-preview.c | 6 +++-- + src/xsane-save.c | 38 ++++++++++++++++++++++++++----- + src/xsane-viewer.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--- + src/xsane.h | 8 ++++++- + 6 files changed, 130 insertions(+), 17 deletions(-) + +diff --git a/configure.in b/configure.in +index df7b114..3659c97 100644 +--- a/configure.in ++++ b/configure.in +@@ -130,7 +130,17 @@ if test "${USE_TIFF}" = "yes"; then + fi + + if test "${USE_LCMS}" = "yes"; then +- AC_CHECK_LIB(lcms, cmsOpenProfileFromFile) ++ AC_SEARCH_LIBS(cmsOpenProfileFromFile, [lcms2 lcms]) ++ if test "${ac_cv_search_cmsOpenProfileFromFile}" != "no"; then ++ AC_DEFINE(HAVE_LIBLCMS, 1, [Define if LCMS is to be used.]) ++ fi ++ if test "${ac_cv_search_cmsOpenProfileFromFile}" == "-llcms2"; then ++ AC_DEFINE(HAVE_LIBLCMS2, 1, [Define if you have liblcms2.]) ++ else ++ if test "${ac_cv_search_cmsOpenProfileFromFile}" == "-llcms"; then ++ AC_DEFINE(HAVE_LIBLCMS1, 1, [Define if you have liblcms.]) ++ fi ++ fi + fi + + dnl Checks for library functions. +@@ -294,10 +304,14 @@ else + echo "* - PNG support deactivated *" + fi + +-if test "${ac_cv_lib_lcms_cmsOpenProfileFromFile}" = "yes"; then +- echo "* - LCMS (color management) support activated *" ++if test "${ac_cv_search_cmsOpenProfileFromFile}" = "-llcms2"; then ++ echo "* - LCMS (color management) support activated (lcms2) *" + else +- echo "* - LCMS (color management) support deactivated *" ++ if test "${ac_cv_search_cmsOpenProfileFromFile}" = "-llcms"; then ++ echo "* - LCMS (color management) support activated (lcms) *" ++ else ++ echo "* - LCMS (color management) support deactivated *" ++ fi + fi + + echo "* *" +diff --git a/include/config.h.in b/include/config.h.in +index ecc9637..f9a3e40 100755 +--- a/include/config.h.in ++++ b/include/config.h.in +@@ -290,9 +290,15 @@ + /* Define if you have libtiff. */ + #undef HAVE_LIBTIFF + +-/* Define if you have liblcms. */ ++/* Define if LCMS is to be used. */ + #undef HAVE_LIBLCMS + ++/* Define if you have liblcms. */ ++#undef HAVE_LIBLCMS1 ++ ++/* Define if you have liblcms2. */ ++#undef HAVE_LIBLCMS2 ++ + #ifndef HAVE_STRNCASECMP + /* OS/2 needs this */ + # define strncasecmp(a, b, c) strnicmp(a, b, c) +diff --git a/src/xsane-preview.c b/src/xsane-preview.c +index 6327ca7..6eaf687 100644 +--- a/src/xsane-preview.c ++++ b/src/xsane-preview.c +@@ -6346,8 +6346,8 @@ int preview_do_color_correction(Preview *p) + cmsHPROFILE hOutProfile = NULL; + cmsHPROFILE hProofProfile = NULL; + cmsHTRANSFORM hTransform = NULL; +- DWORD input_format, output_format; +- DWORD cms_flags = 0; ++ cmsUInt32Number input_format, output_format; ++ cmsUInt32Number cms_flags = 0; + int proof = 0; + char *cms_proof_icm_profile = NULL; + int linesize = 0; +@@ -6355,7 +6355,9 @@ int preview_do_color_correction(Preview *p) + + DBG(DBG_proc, "preview_do_color_correction\n"); + ++#ifdef HAVE_LIBLCMS1 + cmsErrorAction(LCMS_ERROR_SHOW); ++#endif + + if (preferences.cms_bpc) + { +diff --git a/src/xsane-save.c b/src/xsane-save.c +index 75e0a63..2d0e44b 100644 +--- a/src/xsane-save.c ++++ b/src/xsane-save.c +@@ -832,9 +832,9 @@ cmsHTRANSFORM xsane_create_cms_transform(Image_info *image_info, int cms_functio + cmsHPROFILE hInProfile = NULL; + cmsHPROFILE hOutProfile = NULL; + cmsHTRANSFORM hTransform = NULL; +- DWORD cms_input_format; +- DWORD cms_output_format; +- DWORD cms_flags = 0; ++ cmsUInt32Number cms_input_format; ++ cmsUInt32Number cms_output_format; ++ cmsUInt32Number cms_flags = 0; + + if (cms_function == XSANE_CMS_FUNCTION_EMBED_SCANNER_ICM_PROFILE) + { +@@ -843,7 +843,9 @@ cmsHTRANSFORM xsane_create_cms_transform(Image_info *image_info, int cms_functio + + DBG(DBG_info, "Prepare CMS transform\n"); + ++#ifdef HAVE_LIBLCMS1 + cmsErrorAction(LCMS_ERROR_SHOW); ++#endif + + if (cms_bpc) + { +@@ -890,10 +892,18 @@ cmsHTRANSFORM xsane_create_cms_transform(Image_info *image_info, int cms_functio + if (image_info->channels == 1) /* == 1 (grayscale) */ + { + #if 1 /* xxx oli */ ++# ifdef HAVE_LIBLCMS2 ++ cmsToneCurve *Gamma = cmsBuildGamma(NULL, 2.2); ++# else + LPGAMMATABLE Gamma = cmsBuildGamma(256, 2.2); ++# endif + + hOutProfile = cmsCreateGrayProfile(cmsD50_xyY(), Gamma); ++# ifdef HAVE_LIBLCMS2 ++ cmsFreeToneCurve(Gamma); ++# else + cmsFreeGamma(Gamma); ++# endif + #endif + } + else +@@ -2896,7 +2906,11 @@ static int xsane_write_CSA(FILE *outfile, char *input_profile, int intent) + return -1; + } + ++#ifdef HAVE_LIBLCMS2 ++ n = cmsGetPostScriptCSA(NULL, hProfile, intent, 0, NULL, 0); ++#else + n = cmsGetPostScriptCSA(hProfile, intent, NULL, 0); ++#endif + if (n == 0) + { + return -2; +@@ -2908,7 +2922,11 @@ static int xsane_write_CSA(FILE *outfile, char *input_profile, int intent) + return -3; + } + ++#ifdef HAVE_LIBLCMS2 ++ cmsGetPostScriptCSA(NULL, hProfile, intent, 0, buffer, n); ++#else + cmsGetPostScriptCSA(hProfile, intent, buffer, n); ++#endif + buffer[n] = 0; + + fprintf(outfile, "%s", buffer); +@@ -2927,7 +2945,7 @@ static int xsane_write_CRD(FILE *outfile, char *output_profile, int intent, int + cmsHPROFILE hProfile; + size_t n; + char* buffer; +- DWORD flags = cmsFLAGS_NODEFAULTRESOURCEDEF; ++ cmsUInt32Number flags = cmsFLAGS_NODEFAULTRESOURCEDEF; + + hProfile = cmsOpenProfileFromFile(output_profile, "r"); + if (!hProfile) +@@ -2940,7 +2958,11 @@ static int xsane_write_CRD(FILE *outfile, char *output_profile, int intent, int + flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; + } + ++#ifdef HAVE_LIBLCMS2 ++ n = cmsGetPostScriptCRD(NULL, hProfile, intent, flags, NULL, 0); ++#else + n = cmsGetPostScriptCRDEx(hProfile, intent, flags, NULL, 0); ++#endif + if (n == 0) + { + return -2; +@@ -2952,7 +2974,11 @@ static int xsane_write_CRD(FILE *outfile, char *output_profile, int intent, int + return -3; + } + ++#ifdef HAVE_LIBLCMS2 ++ cmsGetPostScriptCRD(NULL, hProfile, intent, flags, buffer, n); ++#else + cmsGetPostScriptCRDEx(hProfile, intent, flags, buffer, n); ++#endif + buffer[n] = 0; + + fprintf(outfile, "%s", buffer); +@@ -4349,7 +4375,7 @@ static void xsane_jpeg_embed_scanner_icm_profile(j_compress_ptr cinfo_ptr, const + { + FILE *icm_profile; + size_t size, embed_len; +- LPBYTE embed_buffer; ++ cmsUInt8Number *embed_buffer; + + DBG(DBG_proc, "xsane_jpeg_embed_scanner_icm_profile(%s)\n", icm_filename); + +@@ -4363,7 +4389,7 @@ static void xsane_jpeg_embed_scanner_icm_profile(j_compress_ptr cinfo_ptr, const + size = ftell(icm_profile); + fseek(icm_profile, 0, SEEK_SET); + +- embed_buffer = (LPBYTE) malloc(size + 1); ++ embed_buffer = (cmsUInt8Number *) malloc(size + 1); + if (embed_buffer) + { + embed_len = fread(embed_buffer, 1, size, icm_profile); +diff --git a/src/xsane-viewer.c b/src/xsane-viewer.c +index 69a444d..844c077 100644 +--- a/src/xsane-viewer.c ++++ b/src/xsane-viewer.c +@@ -1795,6 +1795,9 @@ static void xsane_viewer_set_cms_gamut_alarm_color_callback(GtkWidget *widget, g + { + Viewer *v = (Viewer *) data; + int val; ++#ifdef HAVE_LIBLCMS2 ++ cmsUInt16Number alarm_codes[cmsMAXCHANNELS]; ++#endif + + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_gamut_alarm_color_widget[0]), (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); + g_signal_handlers_block_by_func(GTK_OBJECT(v->cms_gamut_alarm_color_widget[1]), (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); +@@ -1811,6 +1814,49 @@ static void xsane_viewer_set_cms_gamut_alarm_color_callback(GtkWidget *widget, g + v->cms_gamut_alarm_color = val; + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(v->cms_gamut_alarm_color_widget[v->cms_gamut_alarm_color]), TRUE); + ++#ifdef HAVE_LIBLCMS2 ++ switch(v->cms_gamut_alarm_color) ++ { ++ default: ++ case 0: /* black */ ++ alarm_codes[0] = (cmsUInt16Number) 0; ++ alarm_codes[1] = (cmsUInt16Number) 0; ++ alarm_codes[2] = (cmsUInt16Number) 0; ++ break; ++ ++ case 1: /* gray */ ++ alarm_codes[0] = (cmsUInt16Number) 128; ++ alarm_codes[1] = (cmsUInt16Number) 128; ++ alarm_codes[2] = (cmsUInt16Number) 128; ++ break; ++ ++ case 2: /* white */ ++ alarm_codes[0] = (cmsUInt16Number) 255; ++ alarm_codes[1] = (cmsUInt16Number) 255; ++ alarm_codes[2] = (cmsUInt16Number) 255; ++ break; ++ ++ case 3: /* red */ ++ alarm_codes[0] = (cmsUInt16Number) 255; ++ alarm_codes[1] = (cmsUInt16Number) 0; ++ alarm_codes[2] = (cmsUInt16Number) 0; ++ break; ++ ++ case 4: /* green */ ++ alarm_codes[0] = (cmsUInt16Number) 0; ++ alarm_codes[1] = (cmsUInt16Number) 255; ++ alarm_codes[2] = (cmsUInt16Number) 0; ++ break; ++ ++ case 5: /* blue */ ++ alarm_codes[0] = (cmsUInt16Number) 0; ++ alarm_codes[1] = (cmsUInt16Number) 0; ++ alarm_codes[2] = (cmsUInt16Number) 255; ++ break; ++ } ++ ++ cmsSetAlarmCodes(alarm_codes); ++#else + switch(v->cms_gamut_alarm_color) + { + default: +@@ -1838,6 +1884,7 @@ static void xsane_viewer_set_cms_gamut_alarm_color_callback(GtkWidget *widget, g + cmsSetAlarmCodes(0, 0, 255); + break; + } ++#endif + + g_signal_handlers_unblock_by_func(GTK_OBJECT(v->cms_gamut_alarm_color_widget[0]), (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); + g_signal_handlers_unblock_by_func(GTK_OBJECT(v->cms_gamut_alarm_color_widget[1]), (GtkSignalFunc) xsane_viewer_set_cms_gamut_alarm_color_callback, v); +@@ -2172,9 +2219,9 @@ static int xsane_viewer_read_image(Viewer *v) + cmsHTRANSFORM hTransform = NULL; + int proof = 0; + char *cms_proof_icm_profile = NULL; +- DWORD cms_input_format; +- DWORD cms_output_format; +- DWORD cms_flags = 0; ++ cmsUInt32Number cms_input_format; ++ cmsUInt32Number cms_output_format; ++ cmsUInt32Number cms_flags = 0; + #endif + + /* open imagefile */ +@@ -2203,7 +2250,9 @@ static int xsane_viewer_read_image(Viewer *v) + + if ((v->enable_color_management) && (v->cms_enable)) + { ++#ifdef HAVE_LIBLCMS1 + cmsErrorAction(LCMS_ERROR_SHOW); ++#endif + + if (v->cms_bpc) + { +@@ -2801,6 +2850,9 @@ Viewer *xsane_viewer_new(char *filename, char *selection_filetype, int allow_red + GtkWidget *scrolled_window; + GtkWidget *zoom_option_menu, *zoom_menu, *zoom_menu_item; + int i, selection; ++#ifdef HAVE_LIBLCMS2 ++ cmsUInt16Number alarm_codes[cmsMAXCHANNELS]; ++#endif + + DBG(DBG_proc, "viewer_new(%s)\n", filename); + +@@ -2830,8 +2882,15 @@ Viewer *xsane_viewer_new(char *filename, char *selection_filetype, int allow_red + v->cms_proofing_intent = INTENT_ABSOLUTE_COLORIMETRIC; + v->cms_gamut_check = 0; + v->cms_gamut_alarm_color = 3; /* red */ ++#ifdef HAVE_LIBLCMS2 ++ alarm_codes[0] = (cmsUInt16Number) 255; ++ alarm_codes[1] = (cmsUInt16Number) 0; ++ alarm_codes[2] = (cmsUInt16Number) 0; ++ cmsSetAlarmCodes(alarm_codes); ++#else + cmsSetAlarmCodes(255, 0, 0); + #endif ++#endif + if (selection_filetype) + { + v->selection_filetype = strdup(selection_filetype); +diff --git a/src/xsane.h b/src/xsane.h +index 4067d61..adcc0ed 100644 +--- a/src/xsane.h ++++ b/src/xsane.h +@@ -70,7 +70,13 @@ + #include + + #ifdef HAVE_LIBLCMS +-# include "lcms.h" ++# ifdef HAVE_LIBLCMS2 ++# include "lcms2.h" ++# else ++# include "lcms.h" ++typedef BYTE cmsUInt8Number; ++typedef DWORD cmsUInt32Number; ++# endif + #else + # define cmsHTRANSFORM void * + #endif +-- +1.8.3.1 + diff --git a/SOURCES/xsane-0.999-man-page.patch b/SOURCES/xsane-0.999-man-page.patch new file mode 100644 index 0000000..169dad3 --- /dev/null +++ b/SOURCES/xsane-0.999-man-page.patch @@ -0,0 +1,109 @@ +From 2dbbd80a5fb80741729c7cd5027af058b9c08c2c Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Mon, 8 Jul 2013 17:46:06 +0200 +Subject: [PATCH] patch: man-page + +Squashed commit of the following: + +commit e1915d50b677458127a8ad1c7953ee1d2e2ce250 +Author: Nils Philippsen +Date: Mon Jul 8 17:44:26 2013 +0200 + + xsane.man: update command line options +--- + doc/xsane.man | 29 ++++++++++++++++++++++++----- + 1 file changed, 24 insertions(+), 5 deletions(-) + +diff --git a/doc/xsane.man b/doc/xsane.man +index ee363a8..38b453d 100644 +--- a/doc/xsane.man ++++ b/doc/xsane.man +@@ -4,6 +4,7 @@ + xsane - scanner frontend for SANE + .SH SYNOPSIS + .B xsane ++.RB [ --help | -h ] + .RB [ --version | -v ] + .RB [ --license | -l ] + .RB [ --device-settings +@@ -13,8 +14,9 @@ xsane - scanner frontend for SANE + .RB [ --viewer | -V ] + .RB [ --save | -s ] + .RB [ --copy | -c ] ++.RB [ --multipage | -m ] + .RB [ --fax | -f ] +-.RB [ --mail | -m ] ++.RB [ --email | -e ] + .RB [ --no-mode-selection | -n ] + .RB [ --Fixed | -F ] + .RB [ --Resizable | -R ] +@@ -25,6 +27,7 @@ xsane - scanner frontend for SANE + .IR name ] + .RB [ --display + .IR d ] ++.RB [ --no-xshm ] + .RB [ --sync ] + .RI [ devicename ] + .SH DESCRIPTION +@@ -121,6 +124,12 @@ and + .SH OPTIONS + .PP + If the ++.B --help ++or ++.B -h ++flag is given xsane displays a short help message and exits. ++.PP ++If the + .B --version + or + .B -v +@@ -128,7 +137,7 @@ flag is given xsane prints a version information, some + information about gtk+ and gimp version it is compiled + against and lists the supported file formats, then it exits. + .PP +-when the ++If the + .B --license + or + .B -l +@@ -161,16 +170,22 @@ or + flag forces xsane to start in copy mode. + .PP + The ++.B --multipage ++or ++.B -m ++flag forces xsane to start in multipage mode. ++.PP ++The + .B --fax + or + .B -f + flag forces xsane to start in fax mode. + .PP + The +-.B --mail ++.B --email + or +-.B -m +-flag forces xsane to start in mail mode. ++.B -e ++flag forces xsane to start in e-mail mode. + .PP + The + .B --no-mode-selection +@@ -217,6 +232,10 @@ flag selects the X11 display used to present the graphical user-interface + for details). + .PP + The ++.B --no-xshm ++flag forces xsane not to use shared memory images. ++.PP ++The + .B --sync + flag requests a synchronous connection with the X11 server. This is for + debugging purposes only. +-- +1.8.3.1 + diff --git a/SOURCES/xsane-0.999-no-file-selected.patch b/SOURCES/xsane-0.999-no-file-selected.patch new file mode 100644 index 0000000..5550c4c --- /dev/null +++ b/SOURCES/xsane-0.999-no-file-selected.patch @@ -0,0 +1,91 @@ +From 2f7abcaa7ad39f118b2f49fdcba9c90b37b3d972 Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Fri, 5 Jul 2013 16:15:55 +0200 +Subject: [PATCH] patch: no-file-selected + +Squashed commit of the following: + +commit f887550276e324151947960292a7266c71aeb573 +Author: Pavel Polischouk +Date: Fri Nov 25 23:55:49 2011 -0500 + + fix changing working directory (#621778) + + The patch checks the value returned by xsane_back_gtk_get_filename. In + most places it will check the result properly (taking 0 for success), + except one case where it takes 0 for an error, and this happens in + xsane_browse_filename_callback (xsane-front-gtk.c). The new code would + abort copying the filename into preferences structure if 0 was returned, + and that's the OK case. I'm very curious how wonderfully it would blow + up if an actual error was returned, but that's a different story. + +commit 2c02ddd8282fa231107d8860aee4d92bdb5cb8e8 +Author: Nils Philippsen +Date: Fri Nov 19 12:25:54 2010 +0100 + + don't crash if no files are selected (#608047) +--- + src/xsane-back-gtk.c | 20 ++++++++++++++++---- + src/xsane-front-gtk.c | 6 +++++- + 2 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/src/xsane-back-gtk.c b/src/xsane-back-gtk.c +index bca9eb2..6ef1506 100644 +--- a/src/xsane-back-gtk.c ++++ b/src/xsane-back-gtk.c +@@ -1111,6 +1111,11 @@ static void xsane_back_gtk_filetype2_callback(GtkWidget *widget, gpointer data) + + chooser_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser)); + ++ if (!chooser_filename) ++ { ++ return; ++ } ++ + if ((new_filetype) && (*new_filetype)) + { + extension = strrchr(chooser_filename, '.'); +@@ -1505,12 +1510,19 @@ int xsane_back_gtk_get_filename(const char *label, const char *default_name, siz + #endif + + chooser_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser)); +- strncpy(filename, chooser_filename, max_len - 1); +- g_free(chooser_filename); ++ if (chooser_filename) ++ { ++ strncpy(filename, chooser_filename, max_len - 1); ++ g_free(chooser_filename); + +- filename[max_len - 1] = '\0'; ++ filename[max_len - 1] = '\0'; + +- ok = TRUE; ++ ok = TRUE; ++ } ++ else ++ { ++ ok = FALSE; ++ } + } + + gtk_widget_destroy(filechooser); +diff --git a/src/xsane-front-gtk.c b/src/xsane-front-gtk.c +index 4c973fb..7bb49b0 100644 +--- a/src/xsane-front-gtk.c ++++ b/src/xsane-front-gtk.c +@@ -1333,7 +1333,11 @@ static void xsane_browse_filename_callback(GtkWidget *widget, gpointer data) + snprintf(windowname, sizeof(windowname), "%s %s %s", xsane.prog_name, WINDOW_OUTPUT_FILENAME, xsane.device_text); + + umask((mode_t) preferences.directory_umask); /* define new file permissions */ +- xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, &preferences.filetype, &preferences.cms_function, XSANE_FILE_CHOOSER_ACTION_SELECT_SAVE, show_extra_widgets, XSANE_FILE_FILTER_ALL | XSANE_FILE_FILTER_IMAGES, XSANE_FILE_FILTER_IMAGES); ++ if (xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, &preferences.filetype, &preferences.cms_function, XSANE_FILE_CHOOSER_ACTION_SELECT_SAVE, show_extra_widgets, XSANE_FILE_FILTER_ALL | XSANE_FILE_FILTER_IMAGES, XSANE_FILE_FILTER_IMAGES) < 0) ++ { ++ xsane_set_sensitivity(TRUE); ++ return; ++ } + umask(XSANE_DEFAULT_UMASK); /* define new file permissions */ + + if (preferences.filename) +-- +1.8.3.1 + diff --git a/SOURCES/xsane-0.999-pdf-no-high-bpp.patch b/SOURCES/xsane-0.999-pdf-no-high-bpp.patch new file mode 100644 index 0000000..10cdbea --- /dev/null +++ b/SOURCES/xsane-0.999-pdf-no-high-bpp.patch @@ -0,0 +1,51 @@ +From c0686879ac66c1933aefbb62b69afb0c9a0db912 Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Mon, 9 Sep 2013 17:13:15 +0200 +Subject: [PATCH] patch: pdf-no-high-bpp + +Squashed commit of the following: + +commit 9f7d97e114389595481f6e9d3ac1038972f3f73b +Author: Nils Philippsen +Date: Mon Sep 9 17:08:38 2013 +0200 + + avoid producing PDFs with bpp > 8 +--- + src/xsane-save.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/xsane-save.c b/src/xsane-save.c +index 5461bf1..75e0a63 100644 +--- a/src/xsane-save.c ++++ b/src/xsane-save.c +@@ -4205,6 +4205,18 @@ int xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info, float + + *cancel_save = 0; + ++ if (image_info->depth > 8) ++ { ++ char buf[TEXTBUFSIZE]; ++ ++ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, "PDF doesn't allow bit depths > 8"); ++ DBG(DBG_error, "%s\n", buf); ++ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */); ++ *cancel_save = 1; ++ ++ goto bail_out; ++ } ++ + xsane_save_pdf_create_document_header(outfile, &xref, 1, flatedecode); + + if (apply_ICM_profile && (cms_function == XSANE_CMS_FUNCTION_EMBED_SCANNER_ICM_PROFILE)) +@@ -4232,6 +4244,8 @@ int xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info, float + *cancel_save = 1; + } + ++bail_out: ++ + return (*cancel_save); + } + +-- +1.8.3.1 + diff --git a/SOURCES/xsane-0.999-signal-handling.patch b/SOURCES/xsane-0.999-signal-handling.patch new file mode 100644 index 0000000..b9da71a --- /dev/null +++ b/SOURCES/xsane-0.999-signal-handling.patch @@ -0,0 +1,242 @@ +From 3b5d3b7e1f320b0bfbe48024a586c0a22375aa2d Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Thu, 3 Jul 2014 10:38:03 +0200 +Subject: [PATCH] patch: signal-handling + +Squashed commit of the following: + +commit 1e9e8cf5edc469114c8eadf46817cd5c1261b35c +Author: Nils Philippsen +Date: Thu Jul 3 10:14:52 2014 +0200 + + don't use g_unix_open_pipe(), g_unix_fd_add() + + These functions have only recently been added to glib. Use pipe()/ + fcntl() and g_io_channel_unix_new()/g_io_add_watch() instead which are + available in the minimum glib version needed for gtk+-2.x. + +commit acbdf3f693d3d2a78ee7490ca1bf76957daf00cf +Author: Nils Philippsen +Date: Thu Mar 13 13:38:12 2014 +0100 + + separate signal handlers in top and bottom half + + This is to avoid race-conditions occurring when a signal is received + while the signal handler is not yet finished. It also avoids calling + non-reentrant functions from a signal handler. The top half (the real + signal handler) just writes a character into a pipe which gets picked up + and serviced by the bottom half from the normal event loop, this + serializes things and makes using non-reentrant functions safe. +--- + src/xsane.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 136 insertions(+), 15 deletions(-) + +diff --git a/src/xsane.c b/src/xsane.c +index 2b9211b..fc2ebbe 100644 +--- a/src/xsane.c ++++ b/src/xsane.c +@@ -47,6 +47,7 @@ + #endif + + #include ++#include + + #include + +@@ -121,6 +122,7 @@ static const Preferences_medium_t pref_default_medium[]= + + int DBG_LEVEL = 0; + static guint xsane_resolution_timer = 0; ++static int xsane_signal_pipe[2]; + + /* ---------------------------------------------------------------------------------------------------------------------- */ + +@@ -161,8 +163,11 @@ void xsane_pref_save(void); + static int xsane_pref_restore(void); + static void xsane_pref_save_media(void); + static void xsane_pref_restore_media(void); +-static RETSIGTYPE xsane_quit_handler(int signal); +-static RETSIGTYPE xsane_sigchld_handler(int signal); ++static RETSIGTYPE xsane_signal_handler_top_half(int signal); ++static gboolean xsane_signal_handler_bottom_half(GIOChannel *source, ++ GIOCondition condition, ++ gpointer user_data); ++static void xsane_sigchld_handler(void); + static void xsane_quit(void); + static void xsane_exit(void); + static gint xsane_standard_option_win_delete(GtkWidget *widget, gpointer data); +@@ -2296,16 +2301,119 @@ static void xsane_pref_restore_media(void) + + /* ---------------------------------------------------------------------------------------------------------------------- */ + +-static RETSIGTYPE xsane_quit_handler(int signal) ++static RETSIGTYPE xsane_signal_handler_top_half(int signal) + { +- DBG(DBG_proc, "xsane_quit_handler\n"); ++ const char *msg_func = "xsane_signal_handler_top_half(): "; ++ const char *msg_short_write = "Short write() while processing signal.\n"; ++ const char *msg_err = "Error during write().\n"; ++ char sig_char; ++ ssize_t written; ++ int errno_saved = errno; + +- xsane_quit(); ++ switch (signal) ++ { ++ case SIGTERM: ++ sig_char = 't'; ++ break; ++ case SIGINT: ++ sig_char = 'i'; ++ break; ++ case SIGHUP: ++ sig_char = 'h'; ++ break; ++ case SIGCHLD: ++ sig_char = 'c'; ++ break; ++ default: ++ sig_char = '?'; ++ break; ++ } ++ ++ if ((written = write(xsane_signal_pipe[1], &sig_char, 1)) <= 0) ++ { ++ /* At this point, all bets are off. Salvage what we can. */ ++ ++ const char *msg = (written == 0) ? msg_short_write : msg_err; ++ ++ if ((write(STDERR_FILENO, msg_func, strlen(msg_func)) < 0) || ++ (write(STDERR_FILENO, msg, strlen(msg)) < 0)) ++ { ++ /* This is really a no-op, but at this point it doesn't really matter ++ * anymore if the writes succeeded or not. */ ++ goto bail_out; ++ } ++ ++bail_out: ++ /* Ignore SIGCHLD errors, zombie processes don't hurt that much. */ ++ if (signal != SIGCHLD) ++ { ++ struct SIGACTION act; ++ memset(&act, 0, sizeof(act)); ++ act.sa_handler = SIG_DFL; ++ sigaction(signal, &act, NULL); ++ raise(signal); ++ } ++ } ++ ++ errno = errno_saved; ++} ++ ++static gboolean xsane_signal_handler_bottom_half(GIOChannel *source, ++ GIOCondition condition, ++ gpointer user_data) ++{ ++ char sig_char; ++ ssize_t readlen; ++ ++ DBG(DBG_proc, "xsane_signal_handler_bottom_half\n"); ++ ++ while ((readlen = read(xsane_signal_pipe[0], &sig_char, 1)) != 0) ++ { ++ if (readlen < 0) ++ { ++ if (errno == EINTR) ++ { ++ /* if interrupted by signal, just repeat reading */ ++ continue; ++ } ++ else ++ { ++ break; ++ } ++ } ++ ++ switch (sig_char) ++ { ++ case 't': ++ case 'i': ++ case 'h': ++ xsane_quit(); ++ break; ++ case 'c': ++ xsane_sigchld_handler(); ++ break; ++ default: ++ DBG(DBG_error, ++ "Don't know how to cope with character-encoded signal: '%c'\n", ++ sig_char); ++ break; ++ } ++ } ++ ++ /* previous invocation might have read more than it should, so ignore ++ * EAGAIN/EWOULDBLOCK */ ++ if (readlen < 0 && errno != EAGAIN && errno != EWOULDBLOCK) ++ { ++ DBG(DBG_error, "Error while reading from pipe: %d '%s'\n", errno, ++ strerror(errno)); ++ } ++ ++ return TRUE; + } + + /* ---------------------------------------------------------------------------------------------------------------------- */ + +-static RETSIGTYPE xsane_sigchld_handler(int signal) ++static void xsane_sigchld_handler(void) + { + int status; + XsaneChildprocess **childprocess_listptr = &xsane.childprocess_list; +@@ -6026,6 +6134,8 @@ void xsane_interface(int argc, char **argv) + { + struct SIGACTION act; + ++ GIOChannel *gio_pipe_read; ++ + DBG(DBG_proc, "xsane_interface\n"); + + xsane.info_label = NULL; +@@ -6069,18 +6179,29 @@ void xsane_interface(int argc, char **argv) + } + } + ++ if ((pipe(xsane_signal_pipe) == -1) || ++ (fcntl(xsane_signal_pipe[0], F_SETFD, FD_CLOEXEC) == -1) || ++ (fcntl(xsane_signal_pipe[0], F_SETFL, O_NONBLOCK) == -1) || ++ (fcntl(xsane_signal_pipe[1], F_SETFD, FD_CLOEXEC) == -1) || ++ (fcntl(xsane_signal_pipe[1], F_SETFL, O_NONBLOCK) == -1) || ++ !(gio_pipe_read = g_io_channel_unix_new(xsane_signal_pipe[0])) || ++ !g_io_add_watch(gio_pipe_read, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI, ++ xsane_signal_handler_bottom_half, NULL)) ++ { ++ DBG(DBG_error, ++ "Couldn't create signal handling pipe, set flags on it or install\n" ++ "bottom half of handler.\n"); ++ exit(1); ++ } ++ + /* define SIGTERM, SIGINT, SIGHUP-handler to make sure that e.g. all temporary files are deleted */ + /* when xsane gets such a signal */ + memset(&act, 0, sizeof(act)); +- act.sa_handler = xsane_quit_handler; +- sigaction(SIGTERM, &act, 0); +- sigaction(SIGINT, &act, 0); +- sigaction(SIGHUP, &act, 0); +- +- /* add a signal handler that cleans up zombie child processes */ +- memset(&act, 0, sizeof(act)); +- act.sa_handler = xsane_sigchld_handler; +- sigaction(SIGCHLD, &act, 0); ++ act.sa_handler = xsane_signal_handler_top_half; ++ sigaction(SIGTERM, &act, NULL); ++ sigaction(SIGINT, &act, NULL); ++ sigaction(SIGHUP, &act, NULL); ++ sigaction(SIGCHLD, &act, NULL); + + gtk_main(); + sane_exit(); +-- +1.9.3 + diff --git a/SOURCES/xsane-0.999-snprintf-update.patch b/SOURCES/xsane-0.999-snprintf-update.patch new file mode 100644 index 0000000..20cf52c --- /dev/null +++ b/SOURCES/xsane-0.999-snprintf-update.patch @@ -0,0 +1,1390 @@ +diff -up xsane-0.999/lib/snprintf.c.OLD xsane-0.999/lib/snprintf.c +--- xsane-0.999/lib/snprintf.c.OLD 2014-05-29 10:42:26.795419830 -0400 ++++ xsane-0.999/lib/snprintf.c 2014-05-29 10:48:58.544431002 -0400 +@@ -2,180 +2,616 @@ + + #ifndef HAVE_SNPRINTF + +-/*************************************************************************** +- * LPRng - An Extended Print Spooler System +- * +- * Copyright 1988-1997, Patrick Powell, San Diego, CA +- * papowell@sdsu.edu +- * See below for conditions of use. +- * +- *************************************************************************** +- * MODULE: snprintf.c +- * PURPOSE: LPRng version of printf - absolutely bombproof (hopefully!) ++/************************************************************************** ++ * Copyright 1994-2003 Patrick Powell, San Diego, CA + **************************************************************************/ +-#if 0 +- +- The "Artistic License" +- +- Preamble +- +-The intent of this document is to state the conditions under which a +-Package may be copied, such that the Copyright Holder maintains some +-semblance of artistic control over the development of the package, +-while giving the users of the package the right to use and distribute +-the Package in a more-or-less customary fashion, plus the right to make +-reasonable modifications. +- +-Definitions: +- +- "Package" refers to the collection of files distributed by the +- Copyright Holder, and derivatives of that collection of files +- created through textual modification. +- +- "Standard Version" refers to such a Package if it has not been +- modified, or has been modified in accordance with the wishes +- of the Copyright Holder as specified below. +- +- "Copyright Holder" is whoever is named in the copyright or +- copyrights for the package. +- +- "You" is you, if you are thinking about copying or distributing +- this Package. +- +- "Reasonable copying fee" is whatever you can justify on the +- basis of media cost, duplication charges, time of people involved, +- and so on. (You will not be required to justify it to the +- Copyright Holder, but only to the computing community at large +- as a market that must bear the fee.) + +- "Freely Available" means that no fee is charged for the item +- itself, though there may be fees involved in handling the item. +- It also means that recipients of the item may redistribute it +- under the same conditions they received it. +- +-1. You may make and give away verbatim copies of the source form of the +-Standard Version of this Package without restriction, provided that you +-duplicate all of the original copyright notices and associated disclaimers. +- +-2. You may apply bug fixes, portability fixes and other modifications +-derived from the Public Domain or from the Copyright Holder. A Package +-modified in such a way shall still be considered the Standard Version. +- +-3. You may otherwise modify your copy of this Package in any way, provided +-that you insert a prominent notice in each changed file stating how and +-when you changed that file, and provided that you do at least ONE of the +-following: +- +- a) place your modifications in the Public Domain or otherwise make them +- Freely Available, such as by posting said modifications to Usenet or +- an equivalent medium, or placing the modifications on a major archive +- site such as uunet.uu.net, or by allowing the Copyright Holder to include +- your modifications in the Standard Version of the Package. +- +- b) use the modified Package only within your corporation or organization. +- +- c) rename any non-standard executables so the names do not conflict +- with standard executables, which must also be provided, and provide +- a separate manual page for each non-standard executable that clearly +- documents how it differs from the Standard Version. +- +- d) make other distribution arrangements with the Copyright Holder. +- +-4. You may distribute the programs of this Package in object code or +-executable form, provided that you do at least ONE of the following: ++/* ++ Overview: + +- a) distribute a Standard Version of the executables and library files, +- together with instructions (in the manual page or equivalent) on where +- to get the Standard Version. ++ snprintf( char *buffer, int len, const char *format,...) ++ plp_unsafe_snprintf( char *buffer, int len, const char *format,...) ++ its horribly unsafe companion that does NOT protect you from ++ the printing of evil control characters, but may be necessary ++ See the man page documentation below ++ ++ This version of snprintf was developed originally for printing ++ on a motley collection of specialized hardware that had NO IO ++ library. Due to contractual restrictions, a clean room implementation ++ of the printf() code had to be developed. ++ ++ The method chosen for printf was to be as paranoid as possible, ++ as these platforms had NO memory protection, and very small ++ address spaces. This made it possible to try to print ++ very long strings, i.e. - all of memory, very easily. To guard ++ against this, all printing was done via a buffer, generous enough ++ to hold strings, but small enough to protect against overruns, ++ etc. ++ ++ Strangely enough, this proved to be of immense importance when ++ SPRINTFing to a buffer on a stack... The rest, of course, is ++ well known, as buffer overruns in the stack are a common way to ++ do horrible things to operating systems, security, etc etc. ++ ++ This version of snprintf is VERY limited by modern standards. ++ ++ Revision History: ++ First Released Version - 1994. This version had NO comments. ++ First Released Version - 1994. This version had NO comments. ++ Second Major Released Version - Tue May 23 10:43:44 PDT 2000 ++ Configuration and other items changed. Read this doc. ++ Treat this as a new version. ++ Minor Revision - Mon Apr 1 09:41:28 PST 2002 ++ - fixed up some constants and casts ++ ++ COPYRIGHT AND TERMS OF USE: ++ ++ You may use, copy, distribute, or otherwise incorporate this software ++ and documentation into any product or other item, provided that ++ the copyright in the documentation and source code as well as the ++ source code generated constant strings in the object, executable ++ or other code remain in place and are present in executable modules ++ or objects. ++ ++ You may modify this code as appropriate to your usage; however the ++ modified version must be identified by changing the various source ++ and object code identification strings as is appropriately noted ++ in the source code. ++ ++ You can use this with the GNU CONFIGURE utility. ++ This should define the following macros appropriately: ++ ++ HAVE_STDARG_H - if the include file is available ++ HAVE_VARARG_H - if the include file is available ++ ++ HAVE_STRERROR - if the strerror() routine is available. ++ If it is not available, then examine the lines containing ++ the tests below. ++ ++ HAVE_SYS_ERRLIST - have sys_errlist available ++ HAVE_DECL_SYS_ERRLIST - sys_errlist declaration in include files ++ HAVE_SYS_NERR - have sys_nerr available ++ HAVE_DECL_SYS_NERR - sys_nerr declaration in include files ++ ++ HAVE_QUAD_T - if the quad_t type is defined ++ HAVE_LONG_LONG - if the long long type is defined ++ HAVE_LONG_DOUBLE - if the long double type is defined ++ ++ If you are using the GNU configure (autoconf) facility, add the ++ following line to the configure.in file, to force checking for the ++ quad_t and long long data types: ++ ++ ++ AC_CHECK_HEADERS(stdlib.h,stdio.h,unistd.h,errno.h) ++ AC_CHECK_FUNCS(strerror) ++ AC_CACHE_CHECK(for errno, ++ ac_cv_errno, ++ [ ++ AC_TRY_LINK(,[extern int errno; return (errno);], ++ ac_cv_errno=yes, ac_cv_errno=no) ++ ]) ++ if test "$ac_cv_errno" = yes; then ++ AC_DEFINE(HAVE_ERRNO) ++ AC_CACHE_CHECK(for errno declaration, ++ ac_cv_decl_errno, ++ [ ++ AC_TRY_COMPILE([ ++ #include ++ #ifdef HAVE_STDLIB_H ++ #include ++ #endif ++ #ifdef HAVE_UNISTD_H ++ #include ++ #endif ++ #ifdef HAVE_ERRNO_H ++ #include ++ ],[return(sys_nerr);], ++ ac_cv_decl_errno=yes, ac_cv_decl_errno=no) ++ ]) ++ if test "$ac_cv_decl_errno" = yes; then ++ AC_DEFINE(HAVE_DECL_ERRNO) ++ fi; ++ fi ++ ++ AC_CACHE_CHECK(for sys_nerr, ++ ac_cv_sys_nerr, ++ [ ++ AC_TRY_LINK(,[extern int sys_nerr; return (sys_nerr);], ++ ac_cv_sys_nerr=yes, ac_cv_sys_nerr=no) ++ ]) ++ if test "$ac_cv_sys_nerr" = yes; then ++ AC_DEFINE(HAVE_SYS_NERR) ++ AC_CACHE_CHECK(for sys_nerr declaration, ++ ac_cv_decl_sys_nerr, ++ [ ++ AC_TRY_COMPILE([ ++ #include ++ #ifdef HAVE_STDLIB_H ++ #include ++ #endif ++ #ifdef HAVE_UNISTD_H ++ #include ++ #endif],[return(sys_nerr);], ++ ac_cv_decl_sys_nerr_def=yes, ac_cv_decl_sys_nerr_def=no) ++ ]) ++ if test "$ac_cv_decl_sys_nerr" = yes; then ++ AC_DEFINE(HAVE_DECL_SYS_NERR) ++ fi ++ fi ++ ++ ++ AC_CACHE_CHECK(for sys_errlist array, ++ ac_cv_sys_errlist, ++ [AC_TRY_LINK(,[extern char *sys_errlist[]; ++ sys_errlist[0];], ++ ac_cv_sys_errlist=yes, ac_cv_sys_errlist=no) ++ ]) ++ if test "$ac_cv_sys_errlist" = yes; then ++ AC_DEFINE(HAVE_SYS_ERRLIST) ++ AC_CACHE_CHECK(for sys_errlist declaration, ++ ac_cv_sys_errlist_def, ++ [AC_TRY_COMPILE([ ++ #include ++ #include ++ #ifdef HAVE_STDLIB_H ++ #include ++ #endif ++ #ifdef HAVE_UNISTD_H ++ #include ++ #endif],[char *s = sys_errlist[0]; return(*s);], ++ ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no) ++ ]) ++ if test "$ac_cv_decl_sys_errlist" = yes; then ++ AC_DEFINE(HAVE_DECL_SYS_ERRLIST) ++ fi ++ fi ++ ++ ++ ++ AC_CACHE_CHECK(checking for long long, ++ ac_cv_long_long, ++ [ ++ AC_TRY_COMPILE([ ++ #include ++ #include ++ ], [printf("%d",sizeof(long long));], ++ ac_cv_long_long=yes, ac_cv_long_long=no) ++ ]) ++ if test $ac_cv_long_long = yes; then ++ AC_DEFINE(HAVE_LONG_LONG) ++ fi ++ ++ AC_CACHE_CHECK(checking for long double, ++ ac_cv_long_double, ++ [ ++ AC_TRY_COMPILE([ ++ #include ++ #include ++ ], [printf("%d",sizeof(long double));], ++ ac_cv_long_double=yes, ac_cv_long_double=no) ++ ]) ++ if test $ac_cv_long_double = yes; then ++ AC_DEFINE(HAVE_LONG_DOUBLE) ++ fi ++ ++ AC_CACHE_CHECK(checking for quad_t, ++ ac_cv_quad_t, ++ [ ++ AC_TRY_COMPILE([ ++ #include ++ #include ++ ], [printf("%d",sizeof(quad_t));], ++ ac_cv_quad_t=yes, ac_cv_quad_t=no) ++ ]) ++ if test $ac_cv_quad_t = yes; then ++ AC_DEFINE(HAVE_QUAD_T) ++ fi ++ ++ ++ ++ NAME ++ snprintf, plp_vsnprintf - formatted output conversion ++ ++ SYNOPSIS ++ #include ++ #include ++ ++ int ++ snprintf(const char *format, size_t size, va_list ap); ++ int ++ plp_unsafe_snprintf(const char *format, size_t size, va_list ap); ++ ++ AKA snprintf and unsafe_snprintf in the documentation below ++ ++ int ++ vsnprintf(char *str, size_t size, const char *format, va_list ap); ++ int ++ unsafe_vsnprintf(char *str, size_t size, const char *format, va_list ap); ++ ++ AKA vsnprintf and unsafe_vsnprintf in the documentation below ++ ++ (Multithreaded Safe) ++ ++ DESCRIPTION ++ The printf() family of functions produces output according to ++ a format as described below. Snprintf(), and vsnprintf() ++ write to the character string str. These functions write the ++ output under the control of a format string that specifies ++ how subsequent arguments (or arguments accessed via the ++ variable-length argument facilities of stdarg(3)) are converted ++ for output. These functions return the number of characters ++ printed (not including the trailing `\0' used to end output ++ to strings). Snprintf() and vsnprintf() will write at most ++ size-1 of the characters printed into the output string (the ++ size'th character then gets the terminating `\0'); if the ++ return value is greater than or equal to the size argument, ++ the string was too short and some of the printed characters ++ were discarded. The size or str may be given as zero to find ++ out how many characters are needed; in this case, the str ++ argument is ignored. ++ ++ By default, the snprintf function will not format control ++ characters (except new line and tab) in strings. This is a ++ safety feature that has proven to be extremely critical when ++ using snprintf for secure applications and when debugging. ++ If you MUST have control characters formatted or printed, ++ then use the unsafe_snprintf() and unsafe_vsnprintf() and on ++ your own head be the consequences. You have been warned. ++ ++ There is one exception to the comments above, and that is ++ the "%c" (character) format. It brutally assumes that the ++ user will have performed the necessary 'isprint()' or other ++ checks and uses the integer value as a character. ++ ++ The format string is composed of zero or more directives: ++ ordinary characters (not %), which are copied unchanged to ++ the output stream; and conversion specifications, each ++ of which results in fetching zero or more subsequent arguments. ++ Each conversion specification is introduced by the character ++ %. The arguments must correspond properly (after type promotion) ++ with the conversion specifier. After the %, the following ++ appear in sequence: ++ ++ o Zero or more of the following flags: ++ ++ - A zero `0' character specifying zero padding. For ++ all conversions except n, the converted value is padded ++ on the left with zeros rather than blanks. If a ++ precision is given with a numeric conversion (d, i, ++ o, u, i, x, and X), the `0' flag is ignored. ++ ++ - A negative field width flag `-' indicates the converted ++ value is to be left adjusted on the field boundary. Except ++ for n conversions, the converted value is padded on ++ the right with blanks, rather than on the left with ++ blanks or zeros. A `-' overrides a `0' if both are ++ given. ++ ++ - A space, specifying that a blank should be left before ++ a positive number produced by a signed conversion (d, e, E, f, ++ g, G, or i). ++ ++ - A `+' character specifying that a sign always be placed ++ before a number produced by a signed conversion. A `+' overrides ++ a space if both are used. ++ ++ o An optional decimal digit string specifying a minimum ++ field width. If the converted value has fewer ++ characters than the field width, it will be padded ++ with spaces on the left (or right, if the ++ left-adjustment flag has been given) to fill out ++ the field width. ++ ++ o An optional precision, in the form of a period `.' followed ++ by an optional digit string. If the digit string ++ is omitted, the precision is taken as zero. This ++ gives the minimum number of digits to appear for ++ d, i, o, u, x, and X conversions, the number of ++ digits to appear after the decimal-point for e, ++ E, and f conversions, the maximum number of ++ significant digits for g and G conversions, or ++ the maximum number of characters to be printed ++ from a string for s conversions. ++ ++ o The optional character h, specifying that a following d, ++ i, o, u, x, or X conversion corresponds to a short ++ int or unsigned short int argument, or that a ++ following n conversion corresponds to a pointer ++ to a short int argument. ++ ++ o The optional character l (ell) specifying that a following ++ d, i, o, u, x, or X conversion applies to a pointer ++ to a long int or unsigned long int argument, or ++ that a following n conversion corresponds to a ++ pointer to a long int argument. ++ ++ o The optional character q, specifying that a following d, ++ i, o, u, x, or X conversion corresponds to a quad_t ++ or u_quad_t argument, or that a following n ++ conversion corresponds to a quad_t argument. ++ This value is always printed in HEX notation. Tough. ++ quad_t's are an OS system implementation, and should ++ not be allowed. ++ ++ o The character L specifying that a following e, E, f, g, ++ or G conversion corresponds to a long double ++ argument. ++ ++ o A character that specifies the type of conversion to be applied. ++ ++ ++ A field width or precision, or both, may be indicated by an asterisk `*' ++ instead of a digit string. In this case, an int argument supplies the ++ field width or precision. A negative field width is treated as a left ++ adjustment flag followed by a positive field width; a negative precision ++ is treated as though it were missing. ++ ++ The conversion specifiers and their meanings are: ++ ++ diouxX The int (or appropriate variant) argument is converted to signed ++ decimal (d and i), unsigned octal (o), unsigned decimal ++ (u), or unsigned hexadecimal (x and X) notation. The ++ letters abcdef are used for x conversions; the letters ++ ABCDEF are used for X conversions. The precision, if ++ any, gives the minimum number of digits that must ++ appear; if the converted value requires fewer digits, ++ it is padded on the left with zeros. ++ ++ eE The double argument is rounded and converted in the style ++ [-]d.ddde+-dd where there is one digit before the decimal-point ++ character and the number of digits after it is equal ++ to the precision; if the precision is missing, it is ++ taken as 6; if the precision is zero, no decimal-point ++ character appears. An E conversion uses the letter ++ E (rather than e) to introduce the exponent. ++ The exponent always contains at least two digits; if ++ the value is zero, the exponent is 00. ++ ++ f The double argument is rounded and converted to decimal notation ++ in the style [-]ddd.ddd, where the number of digits after the ++ decimal-point character is equal to the precision specification. ++ If the precision is missing, it is taken as 6; if the precision ++ is explicitly zero, no decimal-point character appears. If a ++ decimal point appears, at least one digit appears before it. ++ ++ g The double argument is converted in style f or e (or ++ E for G conversions). The precision specifies the ++ number of significant digits. If the precision is ++ missing, 6 digits are given; if the precision is zero, ++ it is treated as 1. Style e is used if the exponent ++ from its conversion is less than -4 or greater than ++ or equal to the precision. Trailing zeros are removed ++ from the fractional part of the result; a decimal ++ point appears only if it is followed by at least one ++ digit. ++ ++ c The int argument is converted to an unsigned char, ++ and the resulting character is written. ++ ++ s The ``char *'' argument is expected to be a pointer to an array ++ of character type (pointer to a string). Characters ++ from the array are written up to (but not including) ++ a terminating NUL character; if a precision is ++ specified, no more than the number specified are ++ written. If a precision is given, no null character ++ need be present; if the precision is not specified, ++ or is greater than the size of the array, the array ++ must contain a terminating NUL character. ++ ++ % A `%' is written. No argument is converted. The complete ++ conversion specification is `%%'. ++ ++ In no case does a non-existent or small field width cause truncation of a ++ field; if the result of a conversion is wider than the field width, the ++ field is expanded to contain the conversion result. ++ ++ EXAMPLES ++ To print a date and time in the form `Sunday, July 3, 10:02', where ++ weekday and month are pointers to strings: ++ ++ #include ++ fprintf(stdout, "%s, %s %d, %.2d:%.2d\n", ++ weekday, month, day, hour, min); ++ ++ To print pi to five decimal places: ++ ++ #include ++ #include ++ fprintf(stdout, "pi = %.5f\n", 4 * atan(1.0)); ++ ++ To allocate a 128 byte string and print into it: ++ ++ #include ++ #include ++ #include ++ char *newfmt(const char *fmt, ...) ++ { ++ char *p; ++ va_list ap; ++ if ((p = malloc(128)) == NULL) ++ return (NULL); ++ va_start(ap, fmt); ++ (void) vsnprintf(p, 128, fmt, ap); ++ va_end(ap); ++ return (p); ++ } ++ ++ SEE ALSO ++ printf(1), scanf(3) ++ ++ STANDARDS ++ Turkey C Standardization and wimpy POSIX folks did not define ++ snprintf or vsnprintf(). ++ ++ BUGS ++ The conversion formats %D, %O, and %U are not standard and are provided ++ only for backward compatibility. The effect of padding the %p format ++ with zeros (either by the `0' flag or by specifying a precision), and the ++ benign effect (i.e., none) of the `#' flag on %n and %p conversions, as ++ well as other nonsensical combinations such as %Ld, are not standard; ++ such combinations should be avoided. + +- b) accompany the distribution with the machine-readable source of +- the Package with your modifications. ++ The typedef names quad_t and u_quad_t are infelicitous. + +- c) give non-standard executables non-standard names, and clearly +- document the differences in manual pages (or equivalent), together +- with instructions on where to get the Standard Version. ++*/ + +- d) make other distribution arrangements with the Copyright Holder. + +-5. You may charge a reasonable copying fee for any distribution of this +-Package. You may charge any fee you choose for support of this +-Package. You may not charge a fee for this Package itself. However, +-you may distribute this Package in aggregate with other (possibly +-commercial) programs as part of a larger (possibly commercial) software +-distribution provided that you do not advertise this Package as a +-product of your own. ++#include ++#include ++#include ++#include ++#if defined(HAVE_STRING_H) ++# include ++#endif ++#if defined(HAVE_STRINGS_H) ++# include ++#endif ++#if defined(HAVE_ERRNO_H) ++#include ++#endif + +-6. The name of the Copyright Holder may not be used to endorse or promote +-products derived from this software without specific prior written permission. ++/* ++ * For testing, define these values ++ */ ++#if 0 ++#define HAVE_STDARG_H 1 ++#define TEST 1 ++#define HAVE_QUAD_T 1 ++#endif + +-7. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +-IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +-WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ++/**** ENDINCLUDE ****/ + +- The End +-#include "lp.h" ++/************************************************* ++ * KEEP THIS STRING - MODIFY AT THE END WITH YOUR REVISIONS ++ * i.e. - the LOCAL REVISIONS part is for your use ++ *************************************************/ ++ ++ ++ static char *const _id = "plp_snprintf V2000.08.18 Copyright Patrick Powell 1988-2000 " ++ "$Id: plp_snprintf.c,v 1.4 2005/04/14 20:05:19 papowell Exp $" ++ " LOCAL REVISIONS: renamed plp_snprintf to snprintf, conditionalized everything on HAVE_SNPRINTF"; ++ ++/* varargs declarations: */ ++ ++# undef HAVE_STDARGS /* let's hope that works everywhere (mj) */ ++# undef VA_LOCAL_DECL ++# undef VA_START ++# undef VA_SHIFT ++# undef VA_END ++ ++#if defined(HAVE_STDARG_H) ++# include ++# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ ++# define VA_LOCAL_DECL va_list ap; ++# define VA_START(f) va_start(ap, f) ++# define VA_SHIFT(v,t) ; /* no-op for ANSI */ ++# define VA_END va_end(ap) ++#else ++# if defined(HAVE_VARARGS_H) ++# include ++# undef HAVE_STDARGS ++# define VA_LOCAL_DECL va_list ap; ++# define VA_START(f) va_start(ap) /* f is ignored! */ ++# define VA_SHIFT(v,t) v = va_arg(ap,t) ++# define VA_END va_end(ap) ++# else ++ XX ** NO VARARGS ** XX ++# endif + #endif + +-#include +-#include +-#include +-#define HAVE_STDARGS /* let's hope that works everywhere (mj) */ +-#define VA_LOCAL_DECL va_list ap; +-#define VA_START(f) va_start(ap, f) +-#define VA_SHIFT(v,t) ; /* no-op for ANSI */ +-#define VA_END va_end(ap) +- +-/**** ENDINCLUDE ****/ ++ union value { ++#if defined(HAVE_QUAD_T) ++ quad_t qvalue; ++#endif ++#if defined(HAVE_LONG_LONG) ++ long long value; ++#else ++ long value; ++#endif ++ double dvalue; ++}; + +-static char *const _id = "$Id: snprintf.c,v 3.2 1997/01/19 14:34:56 papowell Exp $"; ++#undef CVAL ++#define CVAL(s) (*((unsigned char *)s)) ++#define safestrlen(s) ((s)?strlen(s):0) + +-/* +- * dopr(): poor man's version of doprintf +- */ + +-static char * plp_Errormsg ( int err ); +-static void dopr( char *buffer, const char *format, va_list args ); +-static void fmtstr( char *value, int ljust, int len, int zpad, int precision ); +-static void fmtnum( long value, int base, int dosign, ++ static char * plp_Errormsg ( int err, char *buffer ); ++ static void dopr( int visible_control, char **buffer, int *left, ++ const char *format, va_list args ); ++ static void fmtstr( int visible_control, char **buffer, int *left, ++ char *value, int ljust, int len, int zpad, int precision ); ++ static void fmtnum( char **buffer, int *left, ++ union value *value, int base, int dosign, ++ int ljust, int len, int zpad, int precision ); ++#if defined(HAVE_QUAD_T) ++ static void fmtquad( char **buffer, int *left, ++ union value *value, int base, int dosign, + int ljust, int len, int zpad, int precision ); +-static void fmtdouble( int fmt, double value, ++#endif ++ static void fmtdouble( char **bufer, int *left, ++ int fmt, double value, + int ljust, int len, int zpad, int precision ); +-static void dostr( char * ); +-static char *output; +-static void dopr_outch( int c ); +-static char *end; +-int visible_control = 1; +- +-/************************************************************** +- * Original: +- * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 +- * A bombproof version of doprnt (dopr) included. +- * Sigh. This sort of thing is always nasty do deal with. Note that +- * the version here does not include floating point... +- * +- * plp_snprintf() is used instead of sprintf() as it does limit checks +- * for string length. This covers a nasty loophole. +- * +- * The other functions are there to prevent NULL pointers from +- * causing nast effects. +- **************************************************************/ +- +-int vsnprintf(char *str, size_t count, const char *fmt, va_list args) +-{ +- str[0] = 0; +- end = str+count-1; +- dopr( str, fmt, args ); +- if( count>0 ){ +- end[0] = 0; ++ static void dostr( char **buffer, int *left, char *str ); ++ static void dopr_outch( char **buffer, int *left, int c ); ++/* VARARGS3 */ ++#ifdef HAVE_STDARGS ++ int plp_vsnprintf(char *str, size_t count, const char *fmt, va_list args) ++#else ++ int plp_vsnprintf(char *str, size_t count, const char *fmt, va_list args) ++#endif ++ ++{ ++ int left; ++ char *buffer; ++ if( (int)count < 0 ) count = 0; ++ left = count; ++ if( count == 0 ) str = 0; ++ buffer = str; ++ dopr( 1, &buffer, &left, fmt, args ); ++ /* fprintf(stderr,"str 0x%x, buffer 0x%x, count %d, left %d\n", ++ (int)str, (int)buffer, count, left ); */ ++ if( str && count > 0 ){ ++ if( left > 0 ){ ++ str[count-left] = 0; ++ } else { ++ str[count-1] = 0; ++ } ++ } ++ return(count - left); ++} ++ ++/* VARARGS3 */ ++#ifdef HAVE_STDARGS ++ int plp_unsafe_vsnprintf(char *str, size_t count, const char *fmt, va_list args) ++#else ++ int plp_unsafe_vsnprintf(char *str, size_t count, const char *fmt, va_list args) ++#endif ++{ ++ int left; ++ char *buffer; ++ if( (int)count < 0 ) count = 0; ++ left = count; ++ if( count == 0 ) str = 0; ++ buffer = str; ++ dopr( 0, &buffer, &left, fmt, args ); ++ /* fprintf(stderr,"str 0x%x, buffer 0x%x, count %d, left %d\n", ++ (int)str, (int)buffer, count, left ); */ ++ if( str && count > 0 ){ ++ if( left > 0 ){ ++ str[count-left] = 0; ++ } else { ++ str[count-1] = 0; ++ } + } +- return(strlen(str)); ++ return(count - left); + } + + /* VARARGS3 */ + #ifdef HAVE_STDARGS +-int snprintf (char *str,size_t count,const char *fmt,...) ++ int snprintf (char *str,size_t count,const char *fmt,...) + #else +-int snprintf (va_alist) va_dcl ++ int snprintf (va_alist) va_dcl + #endif + { + #ifndef HAVE_STDARGS +@@ -183,22 +619,48 @@ int snprintf (va_alist) va_dcl + size_t count; + char *fmt; + #endif ++ int n = 0; + VA_LOCAL_DECL + + VA_START (fmt); + VA_SHIFT (str, char *); + VA_SHIFT (count, size_t ); + VA_SHIFT (fmt, char *); +- (void) vsnprintf ( str, count, fmt, ap); ++ n = plp_vsnprintf ( str, count, fmt, ap); + VA_END; +- return( strlen( str ) ); ++ return( n ); + } + +-static void dopr( char *buffer, const char *format, va_list args ) ++ ++/* VARARGS3 */ ++#ifdef HAVE_STDARGS ++ int plp_unsafe_snprintf (char *str,size_t count,const char *fmt,...) ++#else ++ int plp_unsafe_snprintf (va_alist) va_dcl ++#endif ++{ ++#ifndef HAVE_STDARGS ++ char *str; ++ size_t count; ++ char *fmt; ++#endif ++ int n = 0; ++ VA_LOCAL_DECL ++ ++ VA_START (fmt); ++ VA_SHIFT (str, char *); ++ VA_SHIFT (count, size_t ); ++ VA_SHIFT (fmt, char *); ++ n = plp_unsafe_vsnprintf ( str, count, fmt, ap); ++ VA_END; ++ return( n ); ++} ++ static void dopr( int visible_control, char **buffer, int *left, const char *format, va_list args ) + { + int ch; +- long value; ++ union value value; + int longflag = 0; ++ int quadflag = 0; + char *strvalue; + int ljust; + int len; +@@ -207,22 +669,30 @@ static void dopr( char *buffer, const ch + int set_precision; + double dval; + int err = errno; ++ int base = 0; ++ int signed_val = 0; + +- output = buffer; + while( (ch = *format++) ){ + switch( ch ){ + case '%': +- ljust = len = zpad = 0; ++ longflag = quadflag = ++ ljust = len = zpad = base = signed_val = 0; + precision = -1; set_precision = 0; + nextch: + ch = *format++; + switch( ch ){ + case 0: +- dostr( "**end of format**" ); ++ dostr( buffer, left, "**end of format**" ); + return; + case '-': ljust = 1; goto nextch; + case '.': set_precision = 1; precision = 0; goto nextch; +- case '*': len = va_arg( args, int ); goto nextch; ++ case '*': ++ if( set_precision ){ ++ precision = va_arg( args, int ); ++ } else { ++ len = va_arg( args, int ); ++ } ++ goto nextch; + case '0': /* set zero padding if len not set */ + if(len==0 && set_precision == 0 ) zpad = '0'; + case '1': case '2': case '3': +@@ -234,76 +704,91 @@ static void dopr( char *buffer, const ch + len = len*10 + ch - '0'; + } + goto nextch; +- case 'l': longflag = 1; goto nextch; ++ case 'l': ++longflag; goto nextch; ++ case 'q': ++#if !defined( HAVE_QUAD_T ) ++ dostr( buffer, left, "*no quad_t support *"); ++ return; ++#endif ++ quadflag = 1; ++ goto nextch; + case 'u': case 'U': +- /*fmtnum(value,base,dosign,ljust,len, zpad, precision) */ +- if( longflag ){ +- value = va_arg( args, long ); +- } else { +- value = va_arg( args, int ); +- } +- fmtnum( value, 10,0, ljust, len, zpad, precision ); break; ++ if( base == 0 ){ base = 10; signed_val = 0; } + case 'o': case 'O': +- /*fmtnum(value,base,dosign,ljust,len, zpad, precision) */ +- if( longflag ){ +- value = va_arg( args, long ); +- } else { +- value = va_arg( args, int ); +- } +- fmtnum( value, 8,0, ljust, len, zpad, precision ); break; ++ if( base == 0 ){ base = 8; signed_val = 0; } + case 'd': case 'D': +- if( longflag ){ +- value = va_arg( args, long ); +- } else { +- value = va_arg( args, int ); +- } +- fmtnum( value, 10,1, ljust, len, zpad, precision ); break; ++ if( base == 0 ){ base = 10; signed_val = 1; } + case 'x': +- if( longflag ){ +- value = va_arg( args, long ); +- } else { +- value = va_arg( args, int ); +- } +- fmtnum( value, 16,0, ljust, len, zpad, precision ); break; ++ if( base == 0 ){ base = 16; signed_val = 0; } + case 'X': +- if( longflag ){ +- value = va_arg( args, long ); ++ if( base == 0 ){ base = -16; signed_val = 0; } ++#if defined( HAVE_QUAD_T ) ++ if( quadflag ){ ++ value.qvalue = va_arg( args, quad_t ); ++ fmtquad( buffer, left, &value,base,signed_val, ljust, len, zpad, precision ); ++ break; ++ } else ++#endif ++ if( longflag > 1 ){ ++#if defined(HAVE_LONG_LONG) ++ if( signed_val ){ ++ value.value = va_arg( args, long long ); ++ } else { ++ value.value = va_arg( args, unsigned long long ); ++ } ++#else ++ if( signed_val ){ ++ value.value = va_arg( args, long ); ++ } else { ++ value.value = va_arg( args, unsigned long ); ++ } ++#endif ++ } else if( longflag ){ ++ if( signed_val ){ ++ value.value = va_arg( args, long ); ++ } else { ++ value.value = va_arg( args, unsigned long ); ++ } + } else { +- value = va_arg( args, int ); ++ if( signed_val ){ ++ value.value = va_arg( args, int ); ++ } else { ++ value.value = va_arg( args, unsigned int ); ++ } + } +- fmtnum( value,-16,0, ljust, len, zpad, precision ); break; ++ fmtnum( buffer, left, &value,base,signed_val, ljust, len, zpad, precision ); break; + case 's': + strvalue = va_arg( args, char *); +- fmtstr( strvalue,ljust,len, zpad, precision ); ++ fmtstr( visible_control, buffer, left, strvalue,ljust,len, zpad, precision ); + break; + case 'c': + ch = va_arg( args, int ); + { char b[2]; +- int vsb = visible_control; + b[0] = ch; + b[1] = 0; +- visible_control = 0; +- fmtstr( b,ljust,len, zpad, precision ); +- visible_control = vsb; ++ fmtstr( 0, buffer, left, b,ljust,len, zpad, precision ); + } + break; +- case 'f': case 'g': ++ case 'f': case 'g': case 'e': + dval = va_arg( args, double ); +- fmtdouble( ch, dval,ljust,len, zpad, precision ); break; ++ fmtdouble( buffer, left, ch, dval,ljust,len, zpad, precision ); break; + case 'm': +- fmtstr( plp_Errormsg(err),ljust,len, zpad, precision ); break; +- case '%': dopr_outch( ch ); continue; ++ { char shortbuffer[32]; ++ fmtstr( visible_control, buffer, left, ++ plp_Errormsg(err, shortbuffer),ljust,len, zpad, precision ); ++ } ++ break; ++ case '%': dopr_outch( buffer, left, ch ); continue; + default: +- dostr( "???????" ); ++ dostr( buffer, left, "???????" ); + } + longflag = 0; + break; + default: +- dopr_outch( ch ); ++ dopr_outch( buffer, left, ch ); + break; + } + } +- *output = 0; + } + + /* +@@ -312,63 +797,69 @@ static void dopr( char *buffer, const ch + * len = minimum length + * precision = numbers of chars in string to use + */ +-static void +-fmtstr( char *value, int ljust, int len, int zpad, int precision ) ++ static void ++ fmtstr( int visible_control, char **buffer, int *left, ++ char *value, int ljust, int len, int zpad, int precision ) + { +- int padlen, strlen, i, c; /* amount to pad */ ++ int padlen, strlenv, i, c; /* amount to pad */ + + if( value == 0 ){ + value = ""; + } +- if( precision > 0 ){ +- strlen = precision; +- } else { +- /* cheap strlen so you do not have library call */ +- for( strlen = 0; (c=value[strlen]); ++ strlen ){ +- if( visible_control && iscntrl( c ) && !isspace( c ) ){ +- ++strlen; +- } ++ /* cheap strlen so you do not have library call */ ++ for( strlenv = i = 0; (c=CVAL(value+i)); ++i ){ ++ if( visible_control && iscntrl( c ) && c != '\t' && c != '\n' ){ ++ ++strlenv; + } ++ ++strlenv; + } +- padlen = len - strlen; ++ if( precision > 0 && strlenv > precision ){ ++ strlenv = precision; ++ } ++ padlen = len - strlenv; + if( padlen < 0 ) padlen = 0; + if( ljust ) padlen = -padlen; + while( padlen > 0 ) { +- dopr_outch( ' ' ); ++ dopr_outch( buffer, left, ' ' ); + --padlen; + } + /* output characters */ +- for( i = 0; (c = value[i]); ++i ){ +- if( visible_control && iscntrl( c ) && !isspace( c ) ){ +- dopr_outch('^'); ++ for( i = 0; i < strlenv && (c = CVAL(value+i)); ++i ){ ++ if( visible_control && iscntrl( c ) && c != '\t' && c != '\n' ){ ++ dopr_outch(buffer, left, '^'); + c = ('@' | (c & 0x1F)); + } +- dopr_outch(c); ++ dopr_outch(buffer, left, c); + } + while( padlen < 0 ) { +- dopr_outch( ' ' ); ++ dopr_outch( buffer, left, ' ' ); + ++padlen; + } + } + +-static void +-fmtnum( long value, int base, int dosign, int ljust, ++ static void ++ fmtnum( char **buffer, int *left, ++ union value *value, int base, int dosign, int ljust, + int len, int zpad, int precision ) + { + int signvalue = 0; ++#if defined(HAVE_LONG_LONG) ++ unsigned long long uvalue; ++#else + unsigned long uvalue; +- char convert[20]; ++#endif ++ char convert[sizeof( union value) * 8 + 16]; + int place = 0; + int padlen = 0; /* amount to pad */ + int caps = 0; + +- /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", +- value, base, dosign, ljust, len, zpad )); */ +- uvalue = value; ++ /* fprintf(stderr,"value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", ++ value, base, dosign, ljust, len, zpad );/ **/ ++ uvalue = value->value; + if( dosign ){ +- if( value < 0 ) { ++ if( value->value < 0 ) { + signvalue = '-'; +- uvalue = -value; ++ uvalue = -value->value; + } + } + if( base < 0 ){ +@@ -385,71 +876,148 @@ fmtnum( long value, int base, int dosig + padlen = len - place; + if( padlen < 0 ) padlen = 0; + if( ljust ) padlen = -padlen; +- /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n", +- convert,place,signvalue,padlen)); */ ++ /* fprintf( stderr, "str '%s', place %d, sign %c, padlen %d\n", ++ convert,place,signvalue,padlen); / **/ + if( zpad && padlen > 0 ){ + if( signvalue ){ +- dopr_outch( signvalue ); ++ dopr_outch( buffer, left, signvalue ); + --padlen; + signvalue = 0; + } + while( padlen > 0 ){ +- dopr_outch( zpad ); ++ dopr_outch( buffer, left, zpad ); + --padlen; + } + } + while( padlen > 0 ) { +- dopr_outch( ' ' ); ++ dopr_outch( buffer, left, ' ' ); + --padlen; + } +- if( signvalue ) dopr_outch( signvalue ); +- while( place > 0 ) dopr_outch( convert[--place] ); ++ if( signvalue ) dopr_outch( buffer, left, signvalue ); ++ while( place > 0 ) dopr_outch( buffer, left, convert[--place] ); + while( padlen < 0 ){ +- dopr_outch( ' ' ); ++ dopr_outch( buffer, left, ' ' ); + ++padlen; + } + } + +-static void +-fmtdouble( int fmt, double value, int ljust, int len, int zpad, int precision ) ++#if defined(HAVE_QUAD_T) ++ ++ static void ++ fmtquad( char **buffer, int *left, ++ union value *value, int base, int dosign, int ljust, ++ int len, int zpad, int precision ) + { +- char convert[128]; +- char fmtstr[128]; +- int l; ++ int signvalue = 0; ++ int place = 0; ++ int padlen = 0; /* amount to pad */ ++ int caps = 0; ++ int i, c; ++ union { ++ quad_t qvalue; ++ unsigned char qconvert[sizeof(quad_t)]; ++ } vvalue; ++ char convert[2*sizeof(quad_t)+1]; ++ ++ /* fprintf(stderr,"value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", ++ value, base, dosign, ljust, len, zpad );/ **/ ++ vvalue.qvalue = value->qvalue; + +- if( len == 0 ) len = 10; +- if( len > sizeof(convert) - 10 ){ +- len = sizeof(convert) - 10; ++ if( base < 0 ){ ++ caps = 1; + } +- if( precision > sizeof(convert) - 10 ){ +- precision = sizeof(convert) - 10; ++ ++ for( i = 0; i < (int)sizeof(quad_t); ++i ){ ++ c = vvalue.qconvert[i]; ++ convert[2*i] = ++ (caps? "0123456789ABCDEF":"0123456789abcdef")[ (c >> 4) & 0xF]; ++ convert[2*i+1] = ++ (caps? "0123456789ABCDEF":"0123456789abcdef")[ c & 0xF]; + } +- if( precision > len ) precision = len; +- strcpy( fmtstr, "%" ); +- if( ljust ) strcat(fmtstr, "-" ); +- if( len ){ +- sprintf( fmtstr+strlen(fmtstr), "%d", len ); ++ convert[2*i] = 0; ++ ++ place = strlen(convert); ++ padlen = len - place; ++ if( padlen < 0 ) padlen = 0; ++ if( ljust ) padlen = -padlen; ++ /* fprintf( stderr, "str '%s', place %d, sign %c, padlen %d\n", ++ convert,place,signvalue,padlen); / **/ ++ if( zpad && padlen > 0 ){ ++ if( signvalue ){ ++ dopr_outch( buffer, left, signvalue ); ++ --padlen; ++ signvalue = 0; ++ } ++ while( padlen > 0 ){ ++ dopr_outch( buffer, left, zpad ); ++ --padlen; ++ } ++ } ++ while( padlen > 0 ) { ++ dopr_outch( buffer, left, ' ' ); ++ --padlen; ++ } ++ if( signvalue ) dopr_outch( buffer, left, signvalue ); ++ while( place > 0 ) dopr_outch( buffer, left, convert[--place] ); ++ while( padlen < 0 ){ ++ dopr_outch( buffer, left, ' ' ); ++ ++padlen; ++ } ++} ++ ++#endif ++ ++ static void mystrcat(char *dest, char *src ) ++{ ++ if( dest && src ){ ++ dest += safestrlen(dest); ++ strcpy(dest,src); ++ } ++} ++ ++ static void ++ fmtdouble( char **buffer, int *left, ++ int fmt, double value, int ljust, int len, int zpad, int precision ) ++{ ++ char convert[sizeof( union value) * 8 + 512]; ++ char formatstr[128]; ++ ++ /* fprintf(stderr,"len %d, precision %d\n", len, precision ); */ ++ if( len > 255 ){ ++ len = 255; ++ } ++ if( precision > 255 ){ ++ precision = 255; ++ } ++ if( precision >= 0 && len > 0 && precision > len ) precision = len; ++ strcpy( formatstr, "%" ); /* 1 */ ++ if( ljust ) mystrcat(formatstr, "-" ); /* 1 */ ++ if( zpad ) mystrcat(formatstr, "0" ); /* 1 */ ++ if( len >= 0 ){ ++ sprintf( formatstr+strlen(formatstr), "%d", len ); /* 3 */ + } +- if( precision > 0 ){ +- sprintf( fmtstr+strlen(fmtstr), ".%d", precision ); ++ if( precision >= 0 ){ ++ sprintf( formatstr+strlen(formatstr), ".%d", precision ); /* 3 */ + } +- l = strlen( fmtstr ); +- fmtstr[l] = fmt; +- fmtstr[l+1] = 0; +- sprintf( convert, fmtstr, value ); +- dostr( convert ); ++ /* format string will be at most 10 chars long ... */ ++ sprintf( formatstr+strlen(formatstr), "%c", fmt ); ++ /* this is easier than trying to do the portable dtostr */ ++ /* fprintf(stderr,"format string '%s'\n", formatstr); */ ++ sprintf( convert, formatstr, value ); ++ dostr( buffer, left, convert ); + } + +-static void dostr( char *str ) ++ static void dostr( char **buffer, int *left, char *str ) + { +- while(*str) dopr_outch(*str++); ++ if(str)while(*str) dopr_outch( buffer, left, *str++ ); + } + +-static void dopr_outch( int c ) ++ static void dopr_outch( char **buffer, int *left, int c ) + { +- if( end == 0 || output < end ){ +- *output++ = c; ++ if( *left > 0 ){ ++ *(*buffer)++ = c; + } ++ *left -= 1; + } + + +@@ -461,29 +1029,26 @@ static void dopr_outch( int c ) + * Patrick Powell Tue Apr 11 08:05:05 PDT 1995 + ****************************************************************************/ + /****************************************************************************/ +-#if !defined(HAVE_STRERROR) +- +-# if defined(HAVE_SYS_NERR) +-# if !defined(HAVE_SYS_NERR_DEF) +- extern int sys_nerr; +-# endif +-# define num_errors (sys_nerr) +-# else +-# define num_errors (-1) /* always use "errno=%d" */ +-# endif + ++#if !defined(HAVE_STRERROR) ++# undef num_errors + # if defined(HAVE_SYS_ERRLIST) +-# if !defined(HAVE_SYS_ERRLIST_DEF) ++# if !defined(HAVE_DECL_SYS_ERRLIST) + extern const char *const sys_errlist[]; + # endif +-# else +-# undef num_errors +-# define num_errors (-1) /* always use "errno=%d" */ ++# if defined(HAVE_SYS_NERR) ++# if !defined(HAVE_DECL_SYS_NERR) ++ extern int sys_nerr; ++# endif ++# define num_errors (sys_nerr) ++# endif ++# endif ++# if !defined(num_errors) ++# define num_errors (-1) /* always use "errno=%d" */ + # endif +- + #endif + +-static char * plp_Errormsg ( int err ) ++ static char * plp_Errormsg ( int err, char *buffer /* int maxlen = 32 */) + { + char *cp; + +@@ -496,10 +1061,8 @@ static char * plp_Errormsg ( int err ) + } else + # endif + { +- static char msgbuf[32]; /* holds "errno=%d". */ +- /* SAFE use of sprintf */ +- (void) sprintf (msgbuf, "errno=%d", err); +- cp = msgbuf; ++ (void) sprintf (buffer, "errno=%d", err); ++ cp = buffer; + } + #endif + return (cp); +@@ -507,23 +1070,47 @@ static char * plp_Errormsg ( int err ) + + #if defined(TEST) + #include +-int main( void ) ++ int main( void ) + { + char buffer[128]; + char *t; + char *test1 = "01234"; ++ int n; + errno = 1; +- plp_snprintf( buffer, sizeof(buffer), (t="errno '%m'")); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%s"), test1 ); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%12s"), test1 ); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%-12s"), test1 ); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%12.2s"), test1 ); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%-12.2s"), test1 ); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%g"), 1.25 ); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%g"), 1.2345 ); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%12g"), 1.25 ); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%12.2g"), 1.25 ); printf( "%s = '%s'\n", t, buffer ); +- plp_snprintf( buffer, sizeof(buffer), (t = "%0*d"), 6, 1 ); printf( "%s = '%s'\n", t, buffer ); ++ buffer[0] = 0; ++ n = snprintf( buffer, 0, (t="test")); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t="errno '%m'")); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%12s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%-12s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%12.2s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%-12.2s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%g"), 1.2345 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%12g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%12.1g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%12.2g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%12.3g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%0*d"), 6, 1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++#if defined(HAVE_LONG_LONG) ++ n = snprintf( buffer, sizeof(buffer), (t = "%llx"), 1, 2, 3, 4 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%llx"), (long long)1, (long long)2 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%qx"), 1, 2, 3, 4 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%qx"), (quad_t)1, (quad_t)2 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++#endif ++ n = snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), (char *)(0x01234567), (char *)0, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), (char *)(0x01234567), (char *)0x89ABCDEF, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), t, 0, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%f"), 1.2345 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%12f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%12.2f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%0.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%1.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%1.5f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); ++ n = snprintf( buffer, sizeof(buffer), (t = "%5.5f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); + return(0); + } + #endif diff --git a/SPECS/xsane.spec b/SPECS/xsane.spec new file mode 100644 index 0000000..33f9241 --- /dev/null +++ b/SPECS/xsane.spec @@ -0,0 +1,799 @@ +# if you rebuild, please change bugtracker_url accordingly: +%global bugtracker_url http://bugzilla.redhat.com + +%global gimpplugindir %(gimptool --gimpplugindir 2>/dev/null || echo INVALID)/plug-ins +%global iconrootdir %{_datadir}/icons/hicolor + +# needed for off-root building +%global _configure ../configure + +Name: xsane +Summary: X Window System front-end for the SANE scanner interface +Version: 0.999 +Release: 30%{?dist} +Source0: http://www.xsane.org/download/%{name}-%{version}.tar.gz +Source1: xsane-256x256.png +# use "xdg-open" instead of "netscape" to launch help browser +# submitted to upstream (Oliver Rauch) via email, 2013-06-04 +Patch0: xsane-0.995-xdg-open.patch +# submitted to upstream (Oliver Rauch) via email, 2009-08-18 +Patch1: xsane-0.995-close-fds.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=504344 +# distro-specific(?), upstream won't accept it: "don't show license dialog" +# submitted to upstream (Oliver Rauch) anyway via email, 2013-06-04 +Patch2: xsane-0.996-no-eula.patch +# enable off-root building +# submitted to upstream (Oliver Rauch) via email, 2010-06-23 +Patch3: xsane-0.997-off-root-build.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=608047 +# https://bugzilla.redhat.com/show_bug.cgi?id=621778 +# submitted to upstream (Oliver Rauch) via email, 2013-07-05 +Patch4: xsane-0.999-no-file-selected.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=198422 +# submitted to upstream (Oliver Rauch) via email, 2010-06-29 +Patch5: xsane-0.997-ipv6.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=624190 +# fix from: https://bugs.launchpad.net/ubuntu/+source/xsane/+bug/370818 +# submitted to upstream (Oliver Rauch) via email, 2011-06-01 +Patch6: xsane-0.998-preview-selection.patch +# fix building with libpng >= 1.5 +# submitted to upstream (Oliver Rauch) via email, 2011-11-21 +Patch7: xsane-0.998-libpng.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=795085 +# set program name/wmclass so GNOME shell picks appropriate high resolution +# icon file +# submitted to upstream (Oliver Rauch) via email, 2013-06-04 +Patch8: xsane-0.998-wmclass.patch +# partly distro-specific: customize desktop file +# submitted to upstream (Oliver Rauch) via email, 2013-06-04 +Patch9: xsane-0.998-desktop-file.patch +# man page: update command line options +# submitted to upstream (Oliver Rauch) via email, 2013-07-08 +Patch10: xsane-0.999-man-page.patch +# avoid producing PDFs with bpp > 8 +# submitted to upstream (Oliver Rauch) via email, 2013-09-09 +Patch11: xsane-0.999-pdf-no-high-bpp.patch +# build against lcms 2.x +# submitted to upstream (Oliver Rauch) via email, 2013-09-23 +Patch12: xsane-0.999-lcms2.patch +# fix issues found during static analysis that don't require far-reaching +# refactoring +# submitted to upstream (Oliver Rauch) via email, 2014-04-02 +Patch13: xsane-0.999-coverity.patch +# update lib/snprintf.c to the latest version from LPRng that has a Free license +# submitted to upstream (Oliver Rauch) via email, 2014-05-29 +Patch14: xsane-0.999-snprintf-update.patch +# fix signal handling (#1073698) +# submitted to upstream (Oliver Rauch) via email, 2014-07-03 +Patch15: xsane-0.999-signal-handling.patch + +# autoconf-generated files +Patch100: xsane-0.999-7-autoconf.patch.bz2 +License: GPLv2+ and LGPLv2+ +URL: http://www.xsane.org/ + +# gcc is no longer in buildroot by default +BuildRequires: gcc +BuildRequires: gimp-devel +BuildRequires: lcms2-devel +BuildRequires: libjpeg-devel +BuildRequires: libpng-devel +BuildRequires: sane-backends-devel >= 1.0.19-15 +BuildRequires: desktop-file-utils >= 0.2.92 +BuildRequires: libtiff-devel +BuildRequires: gettext-devel +Requires: xsane-common +Requires: hicolor-icon-theme + +%description +XSane is an X based interface for the SANE (Scanner Access Now Easy) +library, which provides access to scanners, digital cameras, and other +capture devices. XSane is written in GTK+ and provides control for +performing the scan and then manipulating the captured image. + +%package gimp +Summary: GIMP plug-in providing the SANE scanner interface +Requires: gimp >= 2:2.2.12-4 +Requires: xsane-common + +%description gimp +This package provides the regular XSane frontend for the SANE scanner +interface, but it works as a GIMP plug-in. You must have GIMP +installed to use this package. + +%package common +Summary: Common files for xsane packages + +%description common +This package contains common files needed by other xsane packages. + +%prep +%setup -q + +# convert some files to UTF-8 +for doc in xsane.{CHANGES,PROBLEMS,INSTALL}; do + iconv -f ISO-8859-1 -t utf8 "$doc" -o "$doc.new" && \ + touch -r "$doc" "$doc.new" && \ + mv "$doc.new" "$doc" +done + +%patch0 -p1 -b .xdg-open +%patch1 -p1 -b .close-fds +%patch2 -p1 -b .no-eula +%patch3 -p1 -b .off-root-build +%patch4 -p1 -b .no-file-selected +%patch5 -p1 -b .ipv6 +%patch6 -p1 -b .preview-selection.patch +%patch7 -p1 -b .libpng +%patch8 -p1 -b .wmclass +%patch9 -p1 -b .desktop-file +%patch10 -p1 -b .man-page +%patch11 -p1 -b .pdf-no-high-bpp +%patch12 -p1 -b .lcms2 +%patch13 -p1 -b .coverity +%patch14 -p1 -b .snprintf-update +%patch15 -p1 -b .signal-handling + +%patch100 -p1 -b .autoconf + +# in-root config.h breaks off-root building +rm include/config.h + +mkdir build-with-gimp +mkdir build-without-gimp + +%build +CFLAGS='%optflags -fno-strict-aliasing -DXSANE_BUGTRACKER_URL=\"%{bugtracker_url}\"' +export CFLAGS + +pushd build-with-gimp +%configure --enable-gimp +make %{?_smp_mflags} +popd + +pushd build-without-gimp +%configure --disable-gimp +make +popd + +cp %{SOURCE1} src/ + +%install + +pushd build-without-gimp +make DESTDIR=%{buildroot} install +popd + +# install GIMP plugin +install -m 0755 -d %{buildroot}%{gimpplugindir} +install -m 0755 build-with-gimp/src/xsane %{buildroot}%{gimpplugindir} + +# install customized desktop file +rm %{buildroot}%{_datadir}/applications/xsane.desktop +desktop-file-install \ + --dir %{buildroot}%{_datadir}/applications \ + src/xsane.desktop + +# icon files in multiple resolutions +for res in 16 32 48 256; do + tdir="%{buildroot}%{iconrootdir}/${res}x${res}/apps" + install -m 0755 -d "$tdir" + install -m 0644 src/xsane-${res}x${res}.png "${tdir}/xsane.png" +done + +# Register as an application to be visible in the software center +# +# NOTE: It would be *awesome* if this file was maintained by the upstream +# project, translated and installed into the right place during `make install`. +# +# See http://www.freedesktop.org/software/appstream/docs/ for more details. +# +mkdir -p $RPM_BUILD_ROOT%{_datadir}/appdata +cat > $RPM_BUILD_ROOT%{_datadir}/appdata/%{name}.appdata.xml < + + + + xsane.desktop + CC0-1.0 + Scan images with a scanner + +

+ XSane is an application to scan images using a hardware scanner attached + to your computer. + It is able to save in a variety of image formats, including TIFF and JPEG + and can even save your scan as a PDF. + XSane also has support for scanning multiple pages and merging them into + a single document. +

+
+ http://www.xsane.org/ + + http://www.xsane.org/doc/xsane-save.jpg + +
+EOF + +%find_lang %{name} XSANE.lang + +%pre gimp +# remove obsolete gimp-plugin-mgr managed symlink +if [ -L "%{gimpplugindir}/xsane" ]; then + rm -f "%{gimpplugindir}/xsane" +fi + +%files -f XSANE.lang +%doc xsane.ACCELKEYS xsane.AUTHOR xsane.BEGINNERS-INFO xsane.BUGS xsane.CHANGES xsane.FAQ xsane.LANGUAGES xsane.LOGO xsane.NEWS xsane.ONLINEHELP xsane.PROBLEMS xsane.ROOT xsane.TODO +%license xsane.COPYING +%{_bindir}/xsane +%{_mandir}/man1/* +%if %{with desktop_vendor_tag} +%{_datadir}/appdata/%{name}.appdata.xml +%{_datadir}/applications/fedora-xsane.desktop +%else +%{_datadir}/appdata/%{name}.appdata.xml +%{_datadir}/applications/xsane.desktop +%endif +%{_datadir}/pixmaps/xsane.xpm +%{iconrootdir}/*/apps/%{name}.png + +%files gimp +%{gimpplugindir}/xsane + +%files common +%doc xsane.AUTHOR +%license xsane.COPYING +%dir %{_datadir}/sane +%{_datadir}/sane/xsane + +%changelog +* Thu Aug 16 2018 Josef Ridky - 0.999-30 +- rebuild for new GIMP module + +* Tue Jul 24 2018 Zdenek Dohnal - 0.999-29 +- correcting license + +* Mon Apr 09 2018 Zdenek Dohnal - 0.999-28 +- remove dependency on ImageMagick and netpbm-progs, because they were needed for + tests during %%build phase, which were removed in commit SHA 0595c15da29 + +* Mon Apr 09 2018 Zdenek Dohnal - 0.999-27 +- remove vendor tag, license needs to be in %%license (FPG) + +* Mon Feb 19 2018 Zdenek Dohnal - 0.999-26 +- remove old stuff +- gcc is no longer in buildroot by default + +* Fri Feb 09 2018 Fedora Release Engineering - 0.999-25 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Jan 18 2018 Igor Gnatenko - 0.999-24 +- Remove obsolete scriptlets + +* Thu Aug 03 2017 Fedora Release Engineering - 0.999-23 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 0.999-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Sat Feb 11 2017 Fedora Release Engineering - 0.999-21 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Feb 05 2016 Fedora Release Engineering - 0.999-20 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Fri Jun 19 2015 Fedora Release Engineering - 0.999-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Thu Mar 26 2015 Richard Hughes - 0.999-18 +- Add an AppData file for the software center + +* Mon Dec 08 2014 David King - 0.999-17 +- Depend on hicolor-icon-theme for icon directories (#1171826) + +* Mon Aug 18 2014 Fedora Release Engineering - 0.999-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Thu Jul 03 2014 Nils Philippsen - 0.999-15 +- make signal-handling patch work with older glib versions +- use consistent name for snprintf patch + +* Sun Jun 08 2014 Fedora Release Engineering - 0.999-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu May 29 2014 Tom Callaway - 0.999-13 +- update to newer snprintf implementation from LPRng that resolves license + issue (#1102523) + +* Thu Apr 03 2014 Nils Philippsen - 0.999-12 +- don't unnecessarily recreate 32px icon (#966301) +- ship 16px icon + +* Wed Apr 02 2014 Nils Philippsen - 0.999-11 +- fix coverity patch: ensure directories exist instead of indiscriminately + attempting to create them (#1079586) + +* Wed Mar 19 2014 Nils Philippsen - 0.999-10 +- fix signal handling (#1073698) +- fix issues found during static analysis that don't require far-reaching + refactoring + +* Mon Sep 23 2013 Nils Philippsen - 0.999-7 +- get rid of ancient compat cruft +- build against lcms2 + +* Mon Sep 09 2013 Nils Philippsen - 0.999-6 +- avoid producing PDFs with bpp > 8 + +* Sun Aug 04 2013 Fedora Release Engineering - 0.999-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Mon Jul 08 2013 Nils Philippsen - 0.999-4 +- man page: update command line options + +* Fri Jul 05 2013 Nils Philippsen - 0.999-3 +- fix no-file-selected patch: change working directories (#621778, fix by Pavel + Polischouk) + +* Thu Jun 27 2013 Nils Philippsen - 0.999-2 +- ensure correct autoconf patch is used + +* Tue Jun 04 2013 Nils Philippsen - 0.999-1 +- version 0.999 +- remove obsolete patches +- update/fix patch comments +- fix changelog dates + +* Fri May 17 2013 Nils Philippsen - 0.998-21 +- don't dereference NULL preview objects when quitting (#963696) +- fix vendor tag logic in a prettier way + +* Tue May 14 2013 Jon Ciesla - 0.998-20 +- Re-fix vendor tag logic. + +* Fri Mar 08 2013 Nils Philippsen - 0.998-19 +- fix vendor tag retaining logic (thanks to Toshio Kuratomi) + +* Thu Mar 07 2013 Nils Philippsen - 0.998-18 +- retain vendor tag up to Fedora 18 + +* Mon Feb 11 2013 Parag Nemade - 0.998-17 +- Add BR: ImageMagick for identify + +* Sun Feb 10 2013 Parag Nemade - 0.998-16 +- Remove vendor tag from desktop file as per https://fedorahosted.org/fesco/ticket/1077 + +* Wed Jan 30 2013 Nils Philippsen - 0.998-15 +- build with -fno-strict-aliasing +- tidy up desktop file +- catch errors when determining the %%gimpplugindir macro +- use netpbm pipeline to create 32px PNG icon instead of convert (which embeds + timestamps in the resulting file) + +* Mon Jan 21 2013 Adam Tkac - 0.998-14 +- rebuild due to "jpeg8-ABI" feature drop + +* Fri Dec 21 2012 Adam Tkac - 0.998-13 +- rebuild against new libjpeg + +* Mon Sep 03 2012 Nils Philippsen - 0.998-12 +- calculate minimum window size better for multi-head setups +- correct man page (#675437) + +* Sun Jul 22 2012 Fedora Release Engineering - 0.998-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sat May 26 2012 Nils Philippsen - 0.998-10 +- add icon cache update scriptlets + +* Fri May 25 2012 Nils Philippsen - 0.998-9 +- install and use higher resolution icons (#795085) + +* Tue Apr 03 2012 Nils Philippsen - 0.998-8 +- rebuild against gimp 2.8.0 release candidate + +* Tue Jan 10 2012 Nils Philippsen - 0.998-7 +- rebuild for gcc 4.7 + +* Fri Dec 16 2011 Nils Philippsen - 0.998-6 +- rebuild for GIMP 2.7 + +* Mon Nov 21 2011 Nils Philippsen - 0.998-5 +- patch and rebuild for libpng-1.5 + +* Wed Jun 01 2011 Nils Philippsen - 0.998-4 +- fix a problem in mouse event processing that interferes with selecting the + scan rectangle in the preview window (#624190, patch by Reinhard Fössmeier) + +* Mon Apr 04 2011 Nils Philippsen - 0.998-3 +- don't dereference unset xsane.preview (#693224) + +* Tue Feb 08 2011 Fedora Release Engineering - 0.998-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Nov 19 2010 Nils Philippsen - 0.998-1 +- version 0.998 +- patch desktop file instead of copying it over + +* Tue Jul 13 2010 Nils Philippsen - 0.997-10 +- don't crash if no files are selected, take two + +* Mon Jul 12 2010 Nils Philippsen - 0.997-9 +- distribute license and other documentation with xsane-common + +* Tue Jun 29 2010 Nils Philippsen 0.997-8 +- support IPv6 (#198422) + +* Mon Jun 28 2010 Nils Philippsen 0.997-7 +- work around old %%configure macro + +* Mon Jun 28 2010 Nils Philippsen 0.997-6 +- don't crash if no files are selected (#608047) + +* Wed Jun 23 2010 Nils Philippsen 0.997-5 +- don't use gimp-plugin-mgr anymore +- use off-root builds + +* Thu Feb 25 2010 Nils Philippsen 0.997-4 +- quote RPM macros in changelog + +* Tue Aug 18 2009 Nils Philippsen +- explain patches + +* Wed Aug 05 2009 Nils Philippsen 0.997-3 +- Merge Review (#226658): + - replace %%desktop_vendor macro with "fedora" + - fix xsane-gimp requirements + - move EULA and documentation into -common subpackage + +* Mon Aug 03 2009 Nils Philippsen 0.997-2 +- remove ExcludeArch: s390 s390x + +* Fri Jul 31 2009 Nils Philippsen 0.997-1 +- version 0.997 +- drop obsolete sane-backends-1.0.20 patch + +* Mon Jul 27 2009 Fedora Release Engineering - 0.996-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Jul 21 2009 Nils Philippsen 0.996-9 +- don't show EULA, mention bugzilla in about dialog (#504344) + +* Mon Jul 20 2009 Nils Philippsen 0.996-8 +- don't use obsolete SANE_CAP_ALWAYS_SETTABLE macro (#507823) + +* Tue Jul 7 2009 Tom "spot" Callaway 0.996-7 +- don't own %%{_datadir}/applications/ (filesystem package owns it) + +* Fri May 29 2009 Nils Philippsen +- Merge review (#226658): + - convert documentation files to UTF-8 + - don't BR: sed + - don't own %%{_datadir}/applications, %%{_sysconfdir}/gimp, + %%{_sysconfdir}/gimp/plugins.d + - don't package unnecessary documentation + +* Mon Mar 02 2009 Nils Philippsen - 0.996-6 +- rebuild against new sane-backends (just in case) + +* Thu Feb 26 2009 Fedora Release Engineering - 0.996-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Tue Jan 20 2009 Nils Philippsen - 0.996-3 +- pickup changed desktop file, close-fds patch in F9, F10 + +* Tue Jan 20 2009 Nils Philippsen - 0.996-2 +- BR: lcms-devel + +* Sun Jan 18 2009 Nils Philippsen - 0.996-1 +- version 0.996 +- don't use %%makeinstall +- use shipped xsane.xpm as application icon + +* Fri Jul 18 2008 Nils Philippsen - 0.995-5 +- fix fd leak prevention (#455450) + +* Tue Jul 15 2008 Nils Philippsen - 0.995-4 +- don't leak file descriptors to help browser process (#455450) + +* Tue Feb 19 2008 Fedora Release Engineering - 0.995-3 +- Autorebuild for GCC 4.3 + +* Thu Nov 29 2007 Nils Philippsen - 0.995-2 +- make EULA, license dialogs be viewable on 800x600 displays + +* Fri Nov 23 2007 Nils Philippsen - 0.995-1 +- version 0.995 +- remove obsolete gimp2.0, medium-definitions, showeulaonce patches + +* Thu Nov 15 2007 Nils Philippsen +- explicitely enable building the gimp plugin in configure call +- reorder spec file sections + +* Wed Sep 05 2007 Nils Philippsen - 0.994-4 +- fix "Category" entries in desktop file + +* Wed Sep 05 2007 Nils Philippsen +- change license to GPLv2+ + +* Tue Apr 24 2007 Nils Philippsen - 0.994-3 +- don't include obsolete Application category in desktop file (#226658) + +* Wed Apr 04 2007 Nils Philippsen - 0.994-2 +- save prefs when EULA is accepted to ensure that EULA is only shown once at + startup (#233645) + +* Tue Apr 03 2007 Nils Philippsen - 0.994-1 +- version 0.994 (#235038) + +* Fri Mar 30 2007 Nils Philippsen - 0.993-2 +- fix summaries and buildroot, don't remove buildroot on %%prep, mark dirs and + config files, don't reference %%buildroot in %%build, use double-%% in + changelog entries (#226658) + +* Fri Mar 02 2007 Nils Philippsen - 0.993-1 +- version 0.993 (#230706) + +* Wed Oct 25 2006 Nils Philippsen - 0.991-4 +- fix typo in scriptlet (#212063) + +* Mon Oct 23 2006 Nils Philippsen - 0.991-3 +- really don't barf on missing gimp-plugin-mgr when updating (#208159) + +* Mon Oct 02 2006 Nils Philippsen - 0.991-2 +- don't barf on missing gimp-plugin-mgr when updating (#208159) + +* Mon Aug 28 2006 Nils Philippsen - 0.991-1 +- version 0.991 +- remove obsolete buffer patch + +* Wed Aug 16 2006 Nils Philippsen - 0.99-6 +- revamp scheme for integrating external GIMP plugins (#202545) +- use disttag + +* Wed Jul 12 2006 Jesse Keating - 0.99-5.1 +- rebuild + +* Thu Jun 08 2006 Nils Philippsen - 0.99-5 +- re-add desktop file (#170835) +- use %%buildroot consistently +- add automake, autoconf build requirements + +* Wed Apr 05 2006 Nils Philippsen - 0.99-4 +- use XSANE.lang instead of xsane.lang to avoid %%doc multilib regression + +* Tue Apr 04 2006 Nils Philippsen - 0.99-3 +- fix medium-definitions patch to not barf on obsolete options in config file + (#185269, by Aldy Hernandez) + +* Fri Feb 10 2006 Jesse Keating - 0.99-2.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 0.99-2.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Mon Jan 16 2006 Nils Philippsen 0.99-2 +- fix buffer overflow + +* Fri Jan 13 2006 Nils Philippsen 0.99-1 +- version 0.99 + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Thu Nov 24 2005 Nils Philippsen 0.98a-1 +- version 0.98a + +* Tue Oct 04 2005 Nils Philippsen 0.97-1 +- version 0.97 + +* Mon Jun 20 2005 Tim Waugh 0.95-4 +- Build requires gettext-devel (bug #160994). + +* Wed Mar 2 2005 Tim Waugh 0.95-3 +- Rebuild for new GCC. + +* Wed Dec 8 2004 Tim Waugh 0.95-2 +- Fix crash on start (bug #142148). + +* Fri Dec 3 2004 Tim Waugh 0.95-1 +- 0.95. +- No longer need badcode patch. +- Enable translations again. +- New method of installing GIMP plug-in due to Nils Philippsen. + +* Mon Jun 28 2004 Tim Waugh 0.92-13 +- Build requires libtiff-devel (bug #126564). + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Fri Jun 4 2004 Tim Waugh 0.92-11 +- Fix GIMP plug-in package (bug #125254). + +* Wed Apr 21 2004 Seth Nickell 0.92-10 +- Remove .desktop file + +* Wed Mar 31 2004 Tim Waugh 0.92-9 +- Rebuilt. + +* Thu Mar 18 2004 Nils Philippsen 0.92-8 +- Rebuild against new gimp. + +* Tue Mar 9 2004 Tim Waugh 0.92-7 +- Fix desktop file Name (bug #117370). + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Fri Feb 13 2004 Tim Waugh 0.92-5 +- Fixed %%post scriptlet. + +* Sun Jan 25 2004 Tim Waugh 0.92-4 +- Gimp patch updated. + +* Fri Jan 23 2004 Tim Waugh 0.92-3 +- Translations are broken -- turn them off for the time being. +- Really apply the patch this time. +- Fix up post/postun scriptlets. + +* Fri Jan 23 2004 Tim Waugh 0.92-2 +- Apply patch for building against new gimp. + +* Mon Dec 15 2003 Tim Waugh 0.92-1 +- 0.92. + +* Thu Nov 27 2003 Thomas Woerner 0.91-2 +- removed rpath + +* Wed Oct 8 2003 Tim Waugh +- Avoid undefined behaviour in xsane-preview.c (bug #106314). + +* Thu Jul 24 2003 Tim Waugh 0.91-1 +- 0.91. + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Wed Apr 9 2003 Tim Waugh 0.90-2 +- Set default HTML viewer to htmlview (bug #88318). + +* Thu Mar 20 2003 Tim Waugh 0.90-1 +- 0.90. + +* Sat Feb 1 2003 Matt Wilson 0.89-3 +- use %%{_libdir} for gimp plugin path + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Fri Oct 25 2002 Tim Waugh 0.89-1 +- 0.89. +- Use %%find_lang. + +* Fri Aug 30 2002 Tim Waugh 0.84-8 +- Don't require gimp-devel (cf. bug #70754). + +* Tue Jul 23 2002 Tim Waugh 0.84-7 +- Desktop file fixes (bug #69555). + +* Mon Jul 15 2002 Tim Waugh 0.84-6 +- Use desktop-file-install. + +* Fri Jun 21 2002 Tim Powers 0.84-5 +- automated rebuild + +* Wed Jun 12 2002 Tim Waugh 0.84-4 +- Rebuild to fix bug #66132. + +* Thu May 23 2002 Tim Powers 0.84-3 +- automated rebuild + +* Thu Feb 21 2002 Tim Waugh 0.84-2 +- Rebuild in new environment. + +* Wed Jan 23 2002 Tim Waugh 0.84-1 +- 0.84. +- Remove explicit sane-backends dependency, since it is automatically + found by rpm. + +* Wed Jan 09 2002 Tim Powers 0.83-2 +- automated rebuild + +* Tue Jan 8 2002 Tim Waugh 0.83-1 +- 0.83. + +* Tue Dec 11 2001 Tim Waugh 0.82-3.1 +- 0.82. +- Some extra patches from Oliver Rauch. +- Require sane not sane-backends since it's available throughout 7.x. +- Built for Red Hat Linux 7.1, 7.2. + +* Tue Jul 24 2001 Tim Waugh 0.77-4 +- Build requires libpng-devel, libjpeg-devel (#bug 49760). + +* Tue Jul 17 2001 Preston Brown 0.77-3 +- add an icon to the desktop entry + +* Tue Jun 19 2001 Florian La Roche +- add ExcludeArch: s390 s390x + +* Mon Jun 11 2001 Tim Waugh 0.77-1 +- 0.77. + +* Sun Jun 3 2001 Tim Waugh 0.76-2 +- Require sane-backends, not all of sane. + +* Wed May 23 2001 Tim Waugh 0.76-1 +- 0.76. + +* Thu May 3 2001 Tim Waugh 0.75-1 +- 0.75 +- Fix summary/description to match specspo. + +* Mon Jan 8 2001 Matt Wilson +- fix post script of gimp subpackage to install into the correct location + +* Mon Dec 25 2000 Matt Wilson +- rebuilt against gimp 1.2.0 + +* Thu Dec 21 2000 Matt Wilson +- rebuilt against gimp 1.1.32 +- use -DGIMP_ENABLE_COMPAT_CRUFT=1 to build with compat macros + +* Thu Oct 12 2000 Than Ngo +- 0.62 + +* Wed Aug 23 2000 Matt Wilson +- rebuilt against gimp-1.1.25 + +* Mon Aug 07 2000 Than Ngo +- added swedish translation (Bug #15316) + +* Fri Aug 4 2000 Than Ngo +- fix, shows error dialogbox if no scanner exists (Bug #15445) +- update to 0.61 + +* Wed Aug 2 2000 Matt Wilson +- rebuilt against new libpng + +* Thu Jul 13 2000 Prospector +- automatic rebuild + +* Mon Jul 3 2000 Matt Wilson +- rebuilt against gimp 1.1.24 +- make clean before building non gimp version + +* Fri Jun 30 2000 Preston Brown +- made gimp subpkg + +* Wed Jun 14 2000 Preston Brown +- desktop entry added + +* Tue Jun 13 2000 Preston Brown +- fixed gimp link +- FHS paths + +* Tue May 30 2000 Karsten Hopp +- update to 0.59 + +* Sat Jan 29 2000 TIm Powers +- fixed bug 8948 + +* Thu Dec 2 1999 Tim Powers +- updated to 0.47 +- gzip man pages + +* Mon Aug 30 1999 Tim Powers +- changed group + +* Mon Jul 26 1999 Tim Powers +- update to 0.30 +- added %%defattr +- built for 6.1 + +* Thu Apr 22 1999 Preston Brown +- initial RPM for PowerTools 6.0