aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am18
-rw-r--r--src/base64.c168
-rw-r--r--src/base64.h46
-rw-r--r--src/codeconv.c1982
-rw-r--r--src/codeconv.h239
-rw-r--r--src/prefs.c465
-rw-r--r--src/prefs.h80
-rw-r--r--src/quoted-printable.c232
-rw-r--r--src/quoted-printable.h36
-rw-r--r--src/session.c793
-rw-r--r--src/session.h205
-rw-r--r--src/socket.c1397
-rw-r--r--src/socket.h124
-rw-r--r--src/ssl.c175
-rw-r--r--src/ssl.h58
-rw-r--r--src/stringtable.c163
-rw-r--r--src/stringtable.h38
-rw-r--r--src/unmime.c134
-rw-r--r--src/unmime.h27
-rw-r--r--src/utils.c3436
-rw-r--r--src/utils.h493
-rw-r--r--src/uuencode.c101
-rw-r--r--src/uuencode.h24
-rw-r--r--src/xml.c656
-rw-r--r--src/xml.h108
25 files changed, 4 insertions, 11194 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 5da41db1..b81e23cf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,7 +26,6 @@ sylpheed_SOURCES = \
gtkshruler.c gtkshruler.h \
menu.c menu.h \
stock_pixmap.c stock_pixmap.h \
- prefs.c prefs.h \
prefs_ui.c prefs_ui.h \
prefs_common.c prefs_common.h \
prefs_filter.c prefs_filter.h \
@@ -76,17 +75,8 @@ sylpheed_SOURCES = \
grouplistdialog.c grouplistdialog.h \
about.c about.h \
setup.c setup.h \
- utils.c utils.h \
gtkutils.c gtkutils.h \
- codeconv.c codeconv.h \
- unmime.c unmime.h \
- base64.c base64.h \
- quoted-printable.c quoted-printable.h \
- uuencode.c uuencode.h \
md5.c md5.h \
- socket.c socket.h \
- ssl.c ssl.h \
- session.c session.h \
smtp.c smtp.h \
pop.c pop.h \
mh.c mh.h \
@@ -99,7 +89,6 @@ sylpheed_SOURCES = \
nntp.c nntp.h \
news.c news.h \
imap.c imap.h \
- xml.c xml.h \
html.c html.h \
procmime.c procmime.h \
rfc2015.c rfc2015.h \
@@ -108,7 +97,6 @@ sylpheed_SOURCES = \
sigstatus.c sigstatus.h \
simple-gettext.c \
manual.c manual.h \
- stringtable.c stringtable.h \
eggtrayicon.c eggtrayicon.h \
trayicon.c trayicon.h \
quote_fmt_lex.l quote_fmt_lex.h \
@@ -132,14 +120,16 @@ INCLUDES = \
$(GTK_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \
$(GPGME_CFLAGS) \
- -I$(includedir)
+ -I$(includedir) \
+ -I$(top_srcdir)/libsylph
sylpheed_LDADD = \
$(INTLLIBS) \
$(GTK_LIBS) \
$(GPGME_LIBS) \
$(LDAP_LIBS) \
- $(LIBICONV)
+ $(LIBICONV) \
+ ../libsylph/libsylph.la
AM_CPPFLAGS = \
-DLOCALEDIR=\""$(localedir)"\" \
diff --git a/src/base64.c b/src/base64.c
deleted file mode 100644
index 484cd286..00000000
--- a/src/base64.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <glib.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "base64.h"
-
-static const gchar base64char[64] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-static const gchar base64val[128] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
-};
-
-#define BASE64VAL(c) (isascii((guchar)c) ? base64val[(gint)(c)] : -1)
-
-void base64_encode(gchar *out, const guchar *in, gint inlen)
-{
- const guchar *inp = in;
- gchar *outp = out;
-
- while (inlen >= 3) {
- *outp++ = base64char[(inp[0] >> 2) & 0x3f];
- *outp++ = base64char[((inp[0] & 0x03) << 4) |
- ((inp[1] >> 4) & 0x0f)];
- *outp++ = base64char[((inp[1] & 0x0f) << 2) |
- ((inp[2] >> 6) & 0x03)];
- *outp++ = base64char[inp[2] & 0x3f];
-
- inp += 3;
- inlen -= 3;
- }
-
- if (inlen > 0) {
- *outp++ = base64char[(inp[0] >> 2) & 0x3f];
- if (inlen == 1) {
- *outp++ = base64char[(inp[0] & 0x03) << 4];
- *outp++ = '=';
- } else {
- *outp++ = base64char[((inp[0] & 0x03) << 4) |
- ((inp[1] >> 4) & 0x0f)];
- *outp++ = base64char[((inp[1] & 0x0f) << 2)];
- }
- *outp++ = '=';
- }
-
- *outp = '\0';
-}
-
-gint base64_decode(guchar *out, const gchar *in, gint inlen)
-{
- const gchar *inp = in;
- guchar *outp = out;
- gchar buf[4];
-
- if (inlen < 0)
- inlen = G_MAXINT;
-
- while (inlen >= 4 && *inp != '\0') {
- buf[0] = *inp++;
- inlen--;
- if (BASE64VAL(buf[0]) == -1) break;
-
- buf[1] = *inp++;
- inlen--;
- if (BASE64VAL(buf[1]) == -1) break;
-
- buf[2] = *inp++;
- inlen--;
- if (buf[2] != '=' && BASE64VAL(buf[2]) == -1) break;
-
- buf[3] = *inp++;
- inlen--;
- if (buf[3] != '=' && BASE64VAL(buf[3]) == -1) break;
-
- *outp++ = ((BASE64VAL(buf[0]) << 2) & 0xfc) |
- ((BASE64VAL(buf[1]) >> 4) & 0x03);
- if (buf[2] != '=') {
- *outp++ = ((BASE64VAL(buf[1]) & 0x0f) << 4) |
- ((BASE64VAL(buf[2]) >> 2) & 0x0f);
- if (buf[3] != '=') {
- *outp++ = ((BASE64VAL(buf[2]) & 0x03) << 6) |
- (BASE64VAL(buf[3]) & 0x3f);
- }
- }
- }
-
- return outp - out;
-}
-
-Base64Decoder *base64_decoder_new(void)
-{
- Base64Decoder *decoder;
-
- decoder = g_new0(Base64Decoder, 1);
- return decoder;
-}
-
-void base64_decoder_free(Base64Decoder *decoder)
-{
- g_free(decoder);
-}
-
-gint base64_decoder_decode(Base64Decoder *decoder,
- const gchar *in, guchar *out)
-{
- gint len, total_len = 0;
- gint buf_len;
- gchar buf[4];
-
- g_return_val_if_fail(decoder != NULL, -1);
- g_return_val_if_fail(in != NULL, -1);
- g_return_val_if_fail(out != NULL, -1);
-
- buf_len = decoder->buf_len;
- memcpy(buf, decoder->buf, sizeof(buf));
-
- for (;;) {
- while (buf_len < 4) {
- gchar c = *in;
-
- in++;
- if (c == '\0') break;
- if (c == '\r' || c == '\n') continue;
- if (c != '=' && BASE64VAL(c) == -1)
- return -1;
- buf[buf_len++] = c;
- }
- if (buf_len < 4 || buf[0] == '=' || buf[1] == '=') {
- decoder->buf_len = buf_len;
- memcpy(decoder->buf, buf, sizeof(buf));
- return total_len;
- }
- len = base64_decode(out, buf, 4);
- out += len;
- total_len += len;
- buf_len = 0;
- if (len < 3) {
- decoder->buf_len = 0;
- return total_len;
- }
- }
-}
diff --git a/src/base64.h b/src/base64.h
deleted file mode 100644
index 4aa55758..00000000
--- a/src/base64.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __BASE64_H__
-#define __BASE64_H__
-
-#include <glib.h>
-
-typedef struct _Base64Decoder Base64Decoder;
-
-struct _Base64Decoder
-{
- gint buf_len;
- gchar buf[4];
-};
-
-void base64_encode (gchar *out,
- const guchar *in,
- gint inlen);
-gint base64_decode (guchar *out,
- const gchar *in,
- gint inlen);
-
-Base64Decoder *base64_decoder_new (void);
-void base64_decoder_free (Base64Decoder *decoder);
-gint base64_decoder_decode (Base64Decoder *decoder,
- const gchar *in,
- guchar *out);
-
-#endif /* __BASE64_H__ */
diff --git a/src/codeconv.c b/src/codeconv.c
deleted file mode 100644
index 4eb68b78..00000000
--- a/src/codeconv.c
+++ /dev/null
@@ -1,1982 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#if HAVE_LOCALE_H
-# include <locale.h>
-#endif
-
-#include <iconv.h>
-
-#include "codeconv.h"
-#include "unmime.h"
-#include "base64.h"
-#include "quoted-printable.h"
-#include "utils.h"
-#include "prefs_common.h"
-
-typedef enum
-{
- JIS_ASCII,
- JIS_KANJI,
- JIS_HWKANA,
- JIS_AUXKANJI
-} JISState;
-
-#define SUBST_CHAR '_'
-#define ESC '\033'
-
-#define iseuckanji(c) \
- (((c) & 0xff) >= 0xa1 && ((c) & 0xff) <= 0xfe)
-#define iseuchwkana1(c) \
- (((c) & 0xff) == 0x8e)
-#define iseuchwkana2(c) \
- (((c) & 0xff) >= 0xa1 && ((c) & 0xff) <= 0xdf)
-#define iseucaux(c) \
- (((c) & 0xff) == 0x8f)
-#define issjiskanji1(c) \
- ((((c) & 0xff) >= 0x81 && ((c) & 0xff) <= 0x9f) || \
- (((c) & 0xff) >= 0xe0 && ((c) & 0xff) <= 0xfc))
-#define issjiskanji2(c) \
- ((((c) & 0xff) >= 0x40 && ((c) & 0xff) <= 0x7e) || \
- (((c) & 0xff) >= 0x80 && ((c) & 0xff) <= 0xfc))
-#define issjishwkana(c) \
- (((c) & 0xff) >= 0xa1 && ((c) & 0xff) <= 0xdf)
-
-#define K_IN() \
- if (state != JIS_KANJI) { \
- *out++ = ESC; \
- *out++ = '$'; \
- *out++ = 'B'; \
- state = JIS_KANJI; \
- }
-
-#define K_OUT() \
- if (state != JIS_ASCII) { \
- *out++ = ESC; \
- *out++ = '('; \
- *out++ = 'B'; \
- state = JIS_ASCII; \
- }
-
-#define HW_IN() \
- if (state != JIS_HWKANA) { \
- *out++ = ESC; \
- *out++ = '('; \
- *out++ = 'I'; \
- state = JIS_HWKANA; \
- }
-
-#define AUX_IN() \
- if (state != JIS_AUXKANJI) { \
- *out++ = ESC; \
- *out++ = '$'; \
- *out++ = '('; \
- *out++ = 'D'; \
- state = JIS_AUXKANJI; \
- }
-
-static gchar *conv_jistoeuc(const gchar *inbuf, gint *error);
-static gchar *conv_euctojis(const gchar *inbuf, gint *error);
-static gchar *conv_sjistoeuc(const gchar *inbuf, gint *error);
-
-static gchar *conv_jistoutf8(const gchar *inbuf, gint *error);
-static gchar *conv_sjistoutf8(const gchar *inbuf, gint *error);
-static gchar *conv_euctoutf8(const gchar *inbuf, gint *error);
-static gchar *conv_anytoutf8(const gchar *inbuf, gint *error);
-
-static gchar *conv_utf8toeuc(const gchar *inbuf, gint *error);
-static gchar *conv_utf8tojis(const gchar *inbuf, gint *error);
-
-/* static void conv_unreadable_eucjp(gchar *str); */
-static void conv_unreadable_8bit(gchar *str);
-/* static void conv_unreadable_latin(gchar *str); */
-
-static gchar *conv_jistodisp(const gchar *inbuf, gint *error);
-static gchar *conv_sjistodisp(const gchar *inbuf, gint *error);
-static gchar *conv_euctodisp(const gchar *inbuf, gint *error);
-
-static gchar *conv_anytodisp(const gchar *inbuf, gint *error);
-static gchar *conv_ustodisp(const gchar *inbuf, gint *error);
-static gchar *conv_noconv(const gchar *inbuf, gint *error);
-
-static gchar *conv_jistoeuc(const gchar *inbuf, gint *error)
-{
- gchar *outbuf;
- const guchar *in = (guchar *)inbuf;
- guchar *out;
- JISState state = JIS_ASCII;
- gint error_ = 0;
-
- outbuf = g_malloc(strlen(inbuf) * 2 + 1);
- out = (guchar *)outbuf;
-
- while (*in != '\0') {
- if (*in == ESC) {
- in++;
- if (*in == '$') {
- if (*(in + 1) == '@' || *(in + 1) == 'B') {
- state = JIS_KANJI;
- in += 2;
- } else if (*(in + 1) == '(' &&
- *(in + 2) == 'D') {
- state = JIS_AUXKANJI;
- in += 3;
- } else {
- /* unknown escape sequence */
- error_ = -1;
- state = JIS_ASCII;
- }
- } else if (*in == '(') {
- if (*(in + 1) == 'B' || *(in + 1) == 'J') {
- state = JIS_ASCII;
- in += 2;
- } else if (*(in + 1) == 'I') {
- state = JIS_HWKANA;
- in += 2;
- } else {
- /* unknown escape sequence */
- error_ = -1;
- state = JIS_ASCII;
- }
- } else {
- /* unknown escape sequence */
- error_ = -1;
- state = JIS_ASCII;
- }
- } else if (*in == 0x0e) {
- state = JIS_HWKANA;
- in++;
- } else if (*in == 0x0f) {
- state = JIS_ASCII;
- in++;
- } else {
- switch (state) {
- case JIS_ASCII:
- *out++ = *in++;
- break;
- case JIS_KANJI:
- *out++ = *in++ | 0x80;
- if (*in == '\0') break;
- *out++ = *in++ | 0x80;
- break;
- case JIS_HWKANA:
- *out++ = 0x8e;
- *out++ = *in++ | 0x80;
- break;
- case JIS_AUXKANJI:
- *out++ = 0x8f;
- *out++ = *in++ | 0x80;
- if (*in == '\0') break;
- *out++ = *in++ | 0x80;
- break;
- }
- }
- }
-
- *out = '\0';
-
- if (error)
- *error = error_;
-
- return outbuf;
-}
-
-#define JIS_HWDAKUTEN 0x5e
-#define JIS_HWHANDAKUTEN 0x5f
-
-static gint conv_jis_hantozen(guchar *outbuf, guchar jis_code, guchar sound_sym)
-{
- static guint16 h2z_tbl[] = {
- /* 0x20 - 0x2f */
- 0x0000, 0x2123, 0x2156, 0x2157, 0x2122, 0x2126, 0x2572, 0x2521,
- 0x2523, 0x2525, 0x2527, 0x2529, 0x2563, 0x2565, 0x2567, 0x2543,
- /* 0x30 - 0x3f */
- 0x213c, 0x2522, 0x2524, 0x2526, 0x2528, 0x252a, 0x252b, 0x252d,
- 0x252f, 0x2531, 0x2533, 0x2535, 0x2537, 0x2539, 0x253b, 0x253d,
- /* 0x40 - 0x4f */
- 0x253f, 0x2541, 0x2544, 0x2546, 0x2548, 0x254a, 0x254b, 0x254c,
- 0x254d, 0x254e, 0x254f, 0x2552, 0x2555, 0x2558, 0x255b, 0x255e,
- /* 0x50 - 0x5f */
- 0x255f, 0x2560, 0x2561, 0x2562, 0x2564, 0x2566, 0x2568, 0x2569,
- 0x256a, 0x256b, 0x256c, 0x256d, 0x256f, 0x2573, 0x212b, 0x212c
- };
-
- static guint16 dakuten_tbl[] = {
- /* 0x30 - 0x3f */
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x252c, 0x252e,
- 0x2530, 0x2532, 0x2534, 0x2536, 0x2538, 0x253a, 0x253c, 0x253e,
- /* 0x40 - 0x4f */
- 0x2540, 0x2542, 0x2545, 0x2547, 0x2549, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x2550, 0x2553, 0x2556, 0x2559, 0x255c, 0x0000
- };
-
- static guint16 handakuten_tbl[] = {
- /* 0x4a - 0x4e */
- 0x2551, 0x2554, 0x2557, 0x255a, 0x255d
- };
-
- guint16 out_code;
-
- jis_code &= 0x7f;
- sound_sym &= 0x7f;
-
- if (jis_code < 0x21 || jis_code > 0x5f)
- return 0;
-
- if (sound_sym == JIS_HWDAKUTEN &&
- jis_code >= 0x36 && jis_code <= 0x4e) {
- out_code = dakuten_tbl[jis_code - 0x30];
- if (out_code != 0) {
- *outbuf = out_code >> 8;
- *(outbuf + 1) = out_code & 0xff;
- return 2;
- }
- }
-
- if (sound_sym == JIS_HWHANDAKUTEN &&
- jis_code >= 0x4a && jis_code <= 0x4e) {
- out_code = handakuten_tbl[jis_code - 0x4a];
- *outbuf = out_code >> 8;
- *(outbuf + 1) = out_code & 0xff;
- return 2;
- }
-
- out_code = h2z_tbl[jis_code - 0x20];
- *outbuf = out_code >> 8;
- *(outbuf + 1) = out_code & 0xff;
- return 1;
-}
-
-static gchar *conv_euctojis(const gchar *inbuf, gint *error)
-{
- gchar *outbuf;
- const guchar *in = (guchar *)inbuf;
- guchar *out;
- JISState state = JIS_ASCII;
- gint error_ = 0;
-
- outbuf = g_malloc(strlen(inbuf) * 3 + 4);
- out = (guchar *)outbuf;
-
- while (*in != '\0') {
- if (isascii(*in)) {
- K_OUT();
- *out++ = *in++;
- } else if (iseuckanji(*in)) {
- if (iseuckanji(*(in + 1))) {
- K_IN();
- *out++ = *in++ & 0x7f;
- *out++ = *in++ & 0x7f;
- } else {
- error_ = -1;
- K_OUT();
- *out++ = SUBST_CHAR;
- in++;
- if (*in != '\0' && !isascii(*in)) {
- *out++ = SUBST_CHAR;
- in++;
- }
- }
- } else if (iseuchwkana1(*in)) {
- if (iseuchwkana2(*(in + 1))) {
- if (prefs_common.allow_jisx0201_kana) {
- HW_IN();
- in++;
- *out++ = *in++ & 0x7f;
- } else {
- guchar jis_ch[2];
- gint len;
-
- if (iseuchwkana1(*(in + 2)) &&
- iseuchwkana2(*(in + 3)))
- len = conv_jis_hantozen
- (jis_ch,
- *(in + 1), *(in + 3));
- else
- len = conv_jis_hantozen
- (jis_ch,
- *(in + 1), '\0');
- if (len == 0)
- in += 2;
- else {
- K_IN();
- in += len * 2;
- *out++ = jis_ch[0];
- *out++ = jis_ch[1];
- }
- }
- } else {
- error_ = -1;
- K_OUT();
- in++;
- if (*in != '\0' && !isascii(*in)) {
- *out++ = SUBST_CHAR;
- in++;
- }
- }
- } else if (iseucaux(*in)) {
- in++;
- if (iseuckanji(*in) && iseuckanji(*(in + 1))) {
- AUX_IN();
- *out++ = *in++ & 0x7f;
- *out++ = *in++ & 0x7f;
- } else {
- error_ = -1;
- K_OUT();
- if (*in != '\0' && !isascii(*in)) {
- *out++ = SUBST_CHAR;
- in++;
- if (*in != '\0' && !isascii(*in)) {
- *out++ = SUBST_CHAR;
- in++;
- }
- }
- }
- } else {
- error_ = -1;
- K_OUT();
- *out++ = SUBST_CHAR;
- in++;
- }
- }
-
- K_OUT();
- *out = '\0';
-
- if (error)
- *error = error_;
-
- return outbuf;
-}
-
-static gchar *conv_sjistoeuc(const gchar *inbuf, gint *error)
-{
- gchar *outbuf;
- const guchar *in = (guchar *)inbuf;
- guchar *out;
- gint error_ = 0;
-
- outbuf = g_malloc(strlen(inbuf) * 2 + 1);
- out = (guchar *)outbuf;
-
- while (*in != '\0') {
- if (isascii(*in)) {
- *out++ = *in++;
- } else if (issjiskanji1(*in)) {
- if (issjiskanji2(*(in + 1))) {
- guchar out1 = *in;
- guchar out2 = *(in + 1);
- guchar row;
-
- row = out1 < 0xa0 ? 0x70 : 0xb0;
- if (out2 < 0x9f) {
- out1 = (out1 - row) * 2 - 1;
- out2 -= out2 > 0x7f ? 0x20 : 0x1f;
- } else {
- out1 = (out1 - row) * 2;
- out2 -= 0x7e;
- }
-
- *out++ = out1 | 0x80;
- *out++ = out2 | 0x80;
- in += 2;
- } else {
- error_ = -1;
- *out++ = SUBST_CHAR;
- in++;
- if (*in != '\0' && !isascii(*in)) {
- *out++ = SUBST_CHAR;
- in++;
- }
- }
- } else if (issjishwkana(*in)) {
- *out++ = 0x8e;
- *out++ = *in++;
- } else {
- error_ = -1;
- *out++ = SUBST_CHAR;
- in++;
- }
- }
-
- *out = '\0';
-
- if (error)
- *error = error_;
-
- return outbuf;
-}
-
-static gchar *conv_jistoutf8(const gchar *inbuf, gint *error)
-{
- gchar *eucstr, *utf8str;
- gint e_error = 0, u_error = 0;
-
- eucstr = conv_jistoeuc(inbuf, &e_error);
- utf8str = conv_euctoutf8(eucstr, &u_error);
- g_free(eucstr);
-
- if (error)
- *error = (e_error | u_error);
-
- return utf8str;
-}
-
-static gchar *conv_sjistoutf8(const gchar *inbuf, gint *error)
-{
- gchar *utf8str;
-
- utf8str = conv_iconv_strdup(inbuf, CS_SHIFT_JIS, CS_UTF_8, error);
- if (!utf8str)
- utf8str = g_strdup(inbuf);
-
- return utf8str;
-}
-
-static gchar *conv_euctoutf8(const gchar *inbuf, gint *error)
-{
- static iconv_t cd = (iconv_t)-1;
- static gboolean iconv_ok = TRUE;
-
- if (cd == (iconv_t)-1) {
- if (!iconv_ok) {
- if (error)
- *error = -1;
- return g_strdup(inbuf);
- }
-
- cd = iconv_open(CS_UTF_8, CS_EUC_JP_MS);
- if (cd == (iconv_t)-1) {
- cd = iconv_open(CS_UTF_8, CS_EUC_JP);
- if (cd == (iconv_t)-1) {
- g_warning("conv_euctoutf8(): %s\n",
- g_strerror(errno));
- iconv_ok = FALSE;
- if (error)
- *error = -1;
- return g_strdup(inbuf);
- }
- }
- }
-
- return conv_iconv_strdup_with_cd(inbuf, cd, error);
-}
-
-static gchar *conv_anytoutf8(const gchar *inbuf, gint *error)
-{
- switch (conv_guess_ja_encoding(inbuf)) {
- case C_ISO_2022_JP:
- return conv_jistoutf8(inbuf, error);
- case C_SHIFT_JIS:
- return conv_sjistoutf8(inbuf, error);
- case C_EUC_JP:
- return conv_euctoutf8(inbuf, error);
- default:
- if (error)
- *error = 0;
- return g_strdup(inbuf);
- }
-}
-
-static gchar *conv_utf8toeuc(const gchar *inbuf, gint *error)
-{
- static iconv_t cd = (iconv_t)-1;
- static gboolean iconv_ok = TRUE;
-
- if (cd == (iconv_t)-1) {
- if (!iconv_ok) {
- if (error)
- *error = -1;
- return g_strdup(inbuf);
- }
-
- cd = iconv_open(CS_EUC_JP_MS, CS_UTF_8);
- if (cd == (iconv_t)-1) {
- cd = iconv_open(CS_EUC_JP, CS_UTF_8);
- if (cd == (iconv_t)-1) {
- g_warning("conv_utf8toeuc(): %s\n",
- g_strerror(errno));
- iconv_ok = FALSE;
- if (error)
- *error = -1;
- return g_strdup(inbuf);
- }
- }
- }
-
- return conv_iconv_strdup_with_cd(inbuf, cd, error);
-}
-
-static gchar *conv_utf8tojis(const gchar *inbuf, gint *error)
-{
- gchar *eucstr, *jisstr;
- gint e_error = 0, j_error = 0;
-
- eucstr = conv_utf8toeuc(inbuf, &e_error);
- jisstr = conv_euctojis(eucstr, &j_error);
- g_free(eucstr);
-
- if (error)
- *error = (e_error | j_error);
-
- return jisstr;
-}
-
-#if 0
-static gchar valid_eucjp_tbl[][96] = {
- /* 0xa2a0 - 0xa2ff */
- { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0 },
-
- /* 0xa3a0 - 0xa3ff */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
-
- /* 0xa4a0 - 0xa4ff */
- { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-
- /* 0xa5a0 - 0xa5ff */
- { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-
- /* 0xa6a0 - 0xa6ff */
- { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-
- /* 0xa7a0 - 0xa7ff */
- { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-
- /* 0xa8a0 - 0xa8ff */
- { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-};
-
-static gboolean isprintableeuckanji(guchar c1, guchar c2)
-{
- if (c1 <= 0xa0 || c1 >= 0xf5)
- return FALSE;
- if (c2 <= 0xa0 || c2 == 0xff)
- return FALSE;
-
- if (c1 >= 0xa9 && c1 <= 0xaf)
- return FALSE;
-
- if (c1 >= 0xa2 && c1 <= 0xa8)
- return (gboolean)valid_eucjp_tbl[c1 - 0xa2][c2 - 0xa0];
-
- if (c1 == 0xcf) {
- if (c2 >= 0xd4 && c2 <= 0xfe)
- return FALSE;
- } else if (c1 == 0xf4) {
- if (c2 >= 0xa7 && c2 <= 0xfe)
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void conv_unreadable_eucjp(gchar *str)
-{
- register guchar *p = str;
-
- while (*p != '\0') {
- if (isascii(*p)) {
- /* convert CR+LF -> LF */
- if (*p == '\r' && *(p + 1) == '\n')
- memmove(p, p + 1, strlen(p));
- /* printable 7 bit code */
- p++;
- } else if (iseuckanji(*p)) {
- if (isprintableeuckanji(*p, *(p + 1))) {
- /* printable euc-jp code */
- p += 2;
- } else {
- /* substitute unprintable code */
- *p++ = SUBST_CHAR;
- if (*p != '\0') {
- if (isascii(*p))
- p++;
- else
- *p++ = SUBST_CHAR;
- }
- }
- } else if (iseuchwkana1(*p)) {
- if (iseuchwkana2(*(p + 1)))
- /* euc-jp hankaku kana */
- p += 2;
- else
- *p++ = SUBST_CHAR;
- } else if (iseucaux(*p)) {
- if (iseuckanji(*(p + 1)) && iseuckanji(*(p + 2))) {
- /* auxiliary kanji */
- p += 3;
- } else
- *p++ = SUBST_CHAR;
- } else
- /* substitute unprintable 1 byte code */
- *p++ = SUBST_CHAR;
- }
-}
-#endif
-
-static void conv_unreadable_8bit(gchar *str)
-{
- register gchar *p = str;
-
- while (*p != '\0') {
- /* convert CR+LF -> LF */
- if (*p == '\r' && *(p + 1) == '\n')
- memmove(p, p + 1, strlen(p));
- else if (!isascii(*(guchar *)p)) *p = SUBST_CHAR;
- p++;
- }
-}
-
-#if 0
-static void conv_unreadable_latin(gchar *str)
-{
- register guchar *p = str;
-
- while (*p != '\0') {
- /* convert CR+LF -> LF */
- if (*p == '\r' && *(p + 1) == '\n')
- memmove(p, p + 1, strlen(p));
- else if ((*p & 0xff) >= 0x7f && (*p & 0xff) <= 0x9f)
- *p = SUBST_CHAR;
- p++;
- }
-}
-#endif
-
-#define NCV '\0'
-
-void conv_mb_alnum(gchar *str)
-{
- static guchar char_tbl[] = {
- /* 0xa0 - 0xaf */
- NCV, ' ', NCV, NCV, ',', '.', NCV, ':',
- ';', '?', '!', NCV, NCV, NCV, NCV, NCV,
- /* 0xb0 - 0xbf */
- NCV, NCV, NCV, NCV, NCV, NCV, NCV, NCV,
- NCV, NCV, NCV, NCV, NCV, NCV, NCV, NCV,
- /* 0xc0 - 0xcf */
- NCV, NCV, NCV, NCV, NCV, NCV, NCV, NCV,
- NCV, NCV, '(', ')', NCV, NCV, '[', ']',
- /* 0xd0 - 0xdf */
- '{', '}', NCV, NCV, NCV, NCV, NCV, NCV,
- NCV, NCV, NCV, NCV, '+', '-', NCV, NCV,
- /* 0xe0 - 0xef */
- NCV, '=', NCV, '<', '>', NCV, NCV, NCV,
- NCV, NCV, NCV, NCV, NCV, NCV, NCV, NCV
- };
-
- register guchar *p = (guchar *)str;
- register gint len;
-
- len = strlen(str);
-
- while (len > 1) {
- if (*p == 0xa3) {
- register guchar ch = *(p + 1);
-
- if (ch >= 0xb0 && ch <= 0xfa) {
- /* [a-zA-Z] */
- *p = ch & 0x7f;
- p++;
- len--;
- memmove(p, p + 1, len);
- len--;
- } else {
- p += 2;
- len -= 2;
- }
- } else if (*p == 0xa1) {
- register guchar ch = *(p + 1);
-
- if (ch >= 0xa0 && ch <= 0xef &&
- NCV != char_tbl[ch - 0xa0]) {
- *p = char_tbl[ch - 0xa0];
- p++;
- len--;
- memmove(p, p + 1, len);
- len--;
- } else {
- p += 2;
- len -= 2;
- }
- } else if (iseuckanji(*p)) {
- p += 2;
- len -= 2;
- } else {
- p++;
- len--;
- }
- }
-}
-
-CharSet conv_guess_ja_encoding(const gchar *str)
-{
- const guchar *p = (const guchar *)str;
- CharSet guessed = C_US_ASCII;
-
- while (*p != '\0') {
- if (*p == ESC && (*(p + 1) == '$' || *(p + 1) == '(')) {
- if (guessed == C_US_ASCII)
- return C_ISO_2022_JP;
- p += 2;
- } else if (isascii(*p)) {
- p++;
- } else if (iseuckanji(*p) && iseuckanji(*(p + 1))) {
- if (*p >= 0xfd && *p <= 0xfe)
- return C_EUC_JP;
- else if (guessed == C_SHIFT_JIS) {
- if ((issjiskanji1(*p) &&
- issjiskanji2(*(p + 1))) ||
- issjishwkana(*p))
- guessed = C_SHIFT_JIS;
- else
- guessed = C_EUC_JP;
- } else
- guessed = C_EUC_JP;
- p += 2;
- } else if (issjiskanji1(*p) && issjiskanji2(*(p + 1))) {
- if (iseuchwkana1(*p) && iseuchwkana2(*(p + 1)))
- guessed = C_SHIFT_JIS;
- else
- return C_SHIFT_JIS;
- p += 2;
- } else if (issjishwkana(*p)) {
- guessed = C_SHIFT_JIS;
- p++;
- } else {
- p++;
- }
- }
-
- return guessed;
-}
-
-static gchar *conv_jistodisp(const gchar *inbuf, gint *error)
-{
- return conv_jistoutf8(inbuf, error);
-}
-
-static gchar *conv_sjistodisp(const gchar *inbuf, gint *error)
-{
- return conv_sjistoutf8(inbuf, error);
-}
-
-static gchar *conv_euctodisp(const gchar *inbuf, gint *error)
-{
- return conv_euctoutf8(inbuf, error);
-}
-
-gchar *conv_utf8todisp(const gchar *inbuf, gint *error)
-{
- if (g_utf8_validate(inbuf, -1, NULL) == TRUE) {
- if (error)
- *error = 0;
- return g_strdup(inbuf);
- } else
- return conv_ustodisp(inbuf, error);
-}
-
-static gchar *conv_anytodisp(const gchar *inbuf, gint *error)
-{
- gchar *outbuf;
-
- outbuf = conv_anytoutf8(inbuf, error);
- if (g_utf8_validate(outbuf, -1, NULL) != TRUE) {
- if (error)
- *error = -1;
- conv_unreadable_8bit(outbuf);
- }
-
- return outbuf;
-}
-
-static gchar *conv_ustodisp(const gchar *inbuf, gint *error)
-{
- gchar *outbuf;
-
- outbuf = g_strdup(inbuf);
- conv_unreadable_8bit(outbuf);
- if (error)
- *error = 0;
-
- return outbuf;
-}
-
-gchar *conv_localetodisp(const gchar *inbuf, gint *error)
-{
- gchar *str;
-
- str = conv_iconv_strdup(inbuf, conv_get_locale_charset_str(),
- CS_INTERNAL, error);
- if (!str)
- str = conv_utf8todisp(inbuf, NULL);
-
- return str;
-}
-
-static gchar *conv_noconv(const gchar *inbuf, gint *error)
-{
- if (error)
- *error = 0;
- return g_strdup(inbuf);
-}
-
-static const gchar *
-conv_get_fallback_for_private_encoding(const gchar *encoding)
-{
- if (encoding && (encoding[0] == 'X' || encoding[0] == 'x') &&
- encoding[1] == '-') {
- if (!g_ascii_strcasecmp(encoding, CS_X_GBK))
- return CS_GBK;
- }
-
- return encoding;
-}
-
-CodeConverter *conv_code_converter_new(const gchar *src_encoding,
- const gchar *dest_encoding)
-{
- CodeConverter *conv;
-
- src_encoding = conv_get_fallback_for_private_encoding(src_encoding);
-
- conv = g_new0(CodeConverter, 1);
- conv->code_conv_func =
- conv_get_code_conv_func(src_encoding, dest_encoding);
- conv->src_encoding = g_strdup(src_encoding);
- conv->dest_encoding = g_strdup(dest_encoding);
-
- return conv;
-}
-
-void conv_code_converter_destroy(CodeConverter *conv)
-{
- g_free(conv->src_encoding);
- g_free(conv->dest_encoding);
- g_free(conv);
-}
-
-gchar *conv_convert(CodeConverter *conv, const gchar *inbuf)
-{
- if (conv->code_conv_func != conv_noconv)
- return conv->code_conv_func(inbuf, NULL);
- else
- return conv_iconv_strdup
- (inbuf, conv->src_encoding, conv->dest_encoding, NULL);
-}
-
-gchar *conv_codeset_strdup_full(const gchar *inbuf,
- const gchar *src_encoding,
- const gchar *dest_encoding,
- gint *error)
-{
- CodeConvFunc conv_func;
-
- src_encoding = conv_get_fallback_for_private_encoding(src_encoding);
-
- conv_func = conv_get_code_conv_func(src_encoding, dest_encoding);
- if (conv_func != conv_noconv)
- return conv_func(inbuf, error);
-
- return conv_iconv_strdup(inbuf, src_encoding, dest_encoding, error);
-}
-
-CodeConvFunc conv_get_code_conv_func(const gchar *src_encoding,
- const gchar *dest_encoding)
-{
- CodeConvFunc code_conv = conv_noconv;
- CharSet src_charset;
- CharSet dest_charset;
-
- if (!src_encoding)
- src_charset = conv_get_locale_charset();
- else
- src_charset = conv_get_charset_from_str(src_encoding);
-
- /* auto detection mode */
- if (!src_encoding && !dest_encoding) {
- if (conv_is_ja_locale())
- return conv_anytodisp;
- else
- return conv_noconv;
- }
-
- dest_charset = conv_get_charset_from_str(dest_encoding);
-
- if (dest_charset == C_US_ASCII)
- return conv_ustodisp;
-
- switch (src_charset) {
- case C_US_ASCII:
- case C_ISO_8859_1:
- case C_ISO_8859_2:
- case C_ISO_8859_3:
- case C_ISO_8859_4:
- case C_ISO_8859_5:
- case C_ISO_8859_6:
- case C_ISO_8859_7:
- case C_ISO_8859_8:
- case C_ISO_8859_9:
- case C_ISO_8859_10:
- case C_ISO_8859_11:
- case C_ISO_8859_13:
- case C_ISO_8859_14:
- case C_ISO_8859_15:
- break;
- case C_ISO_2022_JP:
- case C_ISO_2022_JP_2:
- case C_ISO_2022_JP_3:
- if (dest_charset == C_AUTO)
- code_conv = conv_jistodisp;
- else if (dest_charset == C_EUC_JP)
- code_conv = conv_jistoeuc;
- else if (dest_charset == C_UTF_8)
- code_conv = conv_jistoutf8;
- break;
- case C_SHIFT_JIS:
- if (dest_charset == C_AUTO)
- code_conv = conv_sjistodisp;
- else if (dest_charset == C_EUC_JP)
- code_conv = conv_sjistoeuc;
- else if (dest_charset == C_UTF_8)
- code_conv = conv_sjistoutf8;
- break;
- case C_EUC_JP:
- if (dest_charset == C_AUTO)
- code_conv = conv_euctodisp;
- else if (dest_charset == C_ISO_2022_JP ||
- dest_charset == C_ISO_2022_JP_2 ||
- dest_charset == C_ISO_2022_JP_3)
- code_conv = conv_euctojis;
- else if (dest_charset == C_UTF_8)
- code_conv = conv_euctoutf8;
- break;
- case C_UTF_8:
- if (dest_charset == C_EUC_JP)
- code_conv = conv_utf8toeuc;
- else if (dest_charset == C_ISO_2022_JP ||
- dest_charset == C_ISO_2022_JP_2 ||
- dest_charset == C_ISO_2022_JP_3)
- code_conv = conv_utf8tojis;
- break;
- default:
- break;
- }
-
- return code_conv;
-}
-
-gchar *conv_iconv_strdup(const gchar *inbuf,
- const gchar *src_code, const gchar *dest_code,
- gint *error)
-{
- iconv_t cd;
- gchar *outbuf;
-
- if (!src_code)
- src_code = conv_get_locale_charset_str();
- if (!dest_code)
- dest_code = CS_INTERNAL;
-
- cd = iconv_open(dest_code, src_code);
- if (cd == (iconv_t)-1) {
- if (error)
- *error = -1;
- return NULL;
- }
-
- outbuf = conv_iconv_strdup_with_cd(inbuf, cd, error);
-
- iconv_close(cd);
-
- return outbuf;
-}
-
-gchar *conv_iconv_strdup_with_cd(const gchar *inbuf, iconv_t cd, gint *error)
-{
- const gchar *inbuf_p;
- gchar *outbuf;
- gchar *outbuf_p;
- size_t in_size;
- size_t in_left;
- size_t out_size;
- size_t out_left;
- size_t n_conv;
- size_t len;
- gint error_ = 0;
-
- inbuf_p = inbuf;
- in_size = strlen(inbuf);
- in_left = in_size;
- out_size = (in_size + 1) * 2;
- outbuf = g_malloc(out_size);
- outbuf_p = outbuf;
- out_left = out_size;
-
-#define EXPAND_BUF() \
-{ \
- len = outbuf_p - outbuf; \
- out_size *= 2; \
- outbuf = g_realloc(outbuf, out_size); \
- outbuf_p = outbuf + len; \
- out_left = out_size - len; \
-}
-
- while ((n_conv = iconv(cd, (ICONV_CONST gchar **)&inbuf_p, &in_left,
- &outbuf_p, &out_left)) == (size_t)-1) {
- if (EILSEQ == errno) {
- /* g_print("iconv(): at %d: %s\n", in_size - in_left, g_strerror(errno)); */
- error_ = -1;
- inbuf_p++;
- in_left--;
- if (out_left == 0) {
- EXPAND_BUF();
- }
- *outbuf_p++ = SUBST_CHAR;
- out_left--;
- } else if (EINVAL == errno) {
- error_ = -1;
- break;
- } else if (E2BIG == errno) {
- EXPAND_BUF();
- } else {
- g_warning("conv_iconv_strdup(): %s\n",
- g_strerror(errno));
- error_ = -1;
- break;
- }
- }
-
- while ((n_conv = iconv(cd, NULL, NULL, &outbuf_p, &out_left)) ==
- (size_t)-1) {
- if (E2BIG == errno) {
- EXPAND_BUF();
- } else {
- g_warning("conv_iconv_strdup(): %s\n",
- g_strerror(errno));
- error_ = -1;
- break;
- }
- }
-
-#undef EXPAND_BUF
-
- len = outbuf_p - outbuf;
- outbuf = g_realloc(outbuf, len + 1);
- outbuf[len] = '\0';
-
- if (error)
- *error = error_;
-
- return outbuf;
-}
-
-static const struct {
- CharSet charset;
- gchar *const name;
-} charsets[] = {
- {C_US_ASCII, CS_US_ASCII},
- {C_US_ASCII, CS_ANSI_X3_4_1968},
- {C_UTF_8, CS_UTF_8},
- {C_UTF_7, CS_UTF_7},
- {C_ISO_8859_1, CS_ISO_8859_1},
- {C_ISO_8859_2, CS_ISO_8859_2},
- {C_ISO_8859_3, CS_ISO_8859_3},
- {C_ISO_8859_4, CS_ISO_8859_4},
- {C_ISO_8859_5, CS_ISO_8859_5},
- {C_ISO_8859_6, CS_ISO_8859_6},
- {C_ISO_8859_7, CS_ISO_8859_7},
- {C_ISO_8859_8, CS_ISO_8859_8},
- {C_ISO_8859_9, CS_ISO_8859_9},
- {C_ISO_8859_10, CS_ISO_8859_10},
- {C_ISO_8859_11, CS_ISO_8859_11},
- {C_ISO_8859_13, CS_ISO_8859_13},
- {C_ISO_8859_14, CS_ISO_8859_14},
- {C_ISO_8859_15, CS_ISO_8859_15},
- {C_BALTIC, CS_BALTIC},
- {C_CP1250, CS_CP1250},
- {C_CP1251, CS_CP1251},
- {C_CP1252, CS_CP1252},
- {C_CP1253, CS_CP1253},
- {C_CP1254, CS_CP1254},
- {C_CP1255, CS_CP1255},
- {C_CP1256, CS_CP1256},
- {C_CP1257, CS_CP1257},
- {C_CP1258, CS_CP1258},
- {C_WINDOWS_1250, CS_WINDOWS_1250},
- {C_WINDOWS_1251, CS_WINDOWS_1251},
- {C_WINDOWS_1252, CS_WINDOWS_1252},
- {C_WINDOWS_1253, CS_WINDOWS_1253},
- {C_WINDOWS_1254, CS_WINDOWS_1254},
- {C_WINDOWS_1255, CS_WINDOWS_1255},
- {C_WINDOWS_1256, CS_WINDOWS_1256},
- {C_WINDOWS_1257, CS_WINDOWS_1257},
- {C_WINDOWS_1258, CS_WINDOWS_1258},
- {C_KOI8_R, CS_KOI8_R},
- {C_KOI8_T, CS_KOI8_T},
- {C_KOI8_U, CS_KOI8_U},
- {C_ISO_2022_JP, CS_ISO_2022_JP},
- {C_ISO_2022_JP_2, CS_ISO_2022_JP_2},
- {C_ISO_2022_JP_3, CS_ISO_2022_JP_3},
- {C_EUC_JP, CS_EUC_JP},
- {C_EUC_JP, CS_EUCJP},
- {C_EUC_JP_MS, CS_EUC_JP_MS},
- {C_SHIFT_JIS, CS_SHIFT_JIS},
- {C_SHIFT_JIS, CS_SHIFT__JIS},
- {C_SHIFT_JIS, CS_SJIS},
- {C_ISO_2022_KR, CS_ISO_2022_KR},
- {C_EUC_KR, CS_EUC_KR},
- {C_ISO_2022_CN, CS_ISO_2022_CN},
- {C_EUC_CN, CS_EUC_CN},
- {C_GB2312, CS_GB2312},
- {C_GBK, CS_GBK},
- {C_EUC_TW, CS_EUC_TW},
- {C_BIG5, CS_BIG5},
- {C_BIG5_HKSCS, CS_BIG5_HKSCS},
- {C_TIS_620, CS_TIS_620},
- {C_WINDOWS_874, CS_WINDOWS_874},
- {C_GEORGIAN_PS, CS_GEORGIAN_PS},
- {C_TCVN5712_1, CS_TCVN5712_1},
-};
-
-static const struct {
- gchar *const locale;
- CharSet charset;
- CharSet out_charset;
-} locale_table[] = {
- {"ja_JP.eucJP" , C_EUC_JP , C_ISO_2022_JP},
- {"ja_JP.EUC-JP" , C_EUC_JP , C_ISO_2022_JP},
- {"ja_JP.EUC" , C_EUC_JP , C_ISO_2022_JP},
- {"ja_JP.ujis" , C_EUC_JP , C_ISO_2022_JP},
- {"ja_JP.SJIS" , C_SHIFT_JIS , C_ISO_2022_JP},
- {"ja_JP.JIS" , C_ISO_2022_JP , C_ISO_2022_JP},
-#ifdef G_OS_WIN32
- {"ja_JP" , C_SHIFT_JIS , C_ISO_2022_JP},
-#else
- {"ja_JP" , C_EUC_JP , C_ISO_2022_JP},
-#endif
- {"ko_KR.EUC-KR" , C_EUC_KR , C_EUC_KR},
- {"ko_KR" , C_EUC_KR , C_EUC_KR},
- {"zh_CN.GB2312" , C_GB2312 , C_GB2312},
- {"zh_CN.GBK" , C_GBK , C_GBK},
- {"zh_CN" , C_GB2312 , C_GB2312},
- {"zh_HK" , C_BIG5_HKSCS , C_BIG5_HKSCS},
- {"zh_TW.eucTW" , C_EUC_TW , C_BIG5},
- {"zh_TW.EUC-TW" , C_EUC_TW , C_BIG5},
- {"zh_TW.Big5" , C_BIG5 , C_BIG5},
- {"zh_TW" , C_BIG5 , C_BIG5},
-
- {"ru_RU.KOI8-R" , C_KOI8_R , C_KOI8_R},
- {"ru_RU.KOI8R" , C_KOI8_R , C_KOI8_R},
- {"ru_RU.CP1251" , C_WINDOWS_1251, C_KOI8_R},
- {"ru_RU" , C_ISO_8859_5 , C_KOI8_R},
- {"tg_TJ" , C_KOI8_T , C_KOI8_T},
- {"ru_UA" , C_KOI8_U , C_KOI8_U},
- {"uk_UA.CP1251" , C_WINDOWS_1251, C_KOI8_U},
- {"uk_UA" , C_KOI8_U , C_KOI8_U},
-
- {"be_BY" , C_WINDOWS_1251, C_WINDOWS_1251},
- {"bg_BG" , C_WINDOWS_1251, C_WINDOWS_1251},
-
- {"yi_US" , C_WINDOWS_1255, C_WINDOWS_1255},
-
- {"af_ZA" , C_ISO_8859_1 , C_ISO_8859_1},
- {"br_FR" , C_ISO_8859_1 , C_ISO_8859_1},
- {"ca_ES" , C_ISO_8859_1 , C_ISO_8859_1},
- {"da_DK" , C_ISO_8859_1 , C_ISO_8859_1},
- {"de_AT" , C_ISO_8859_1 , C_ISO_8859_1},
- {"de_BE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"de_CH" , C_ISO_8859_1 , C_ISO_8859_1},
- {"de_DE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"de_LU" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_AU" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_BW" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_CA" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_DK" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_GB" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_HK" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_IE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_NZ" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_PH" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_SG" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_US" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_ZA" , C_ISO_8859_1 , C_ISO_8859_1},
- {"en_ZW" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_AR" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_BO" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_CL" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_CO" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_CR" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_DO" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_EC" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_ES" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_GT" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_HN" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_MX" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_NI" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_PA" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_PE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_PR" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_PY" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_SV" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_US" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_UY" , C_ISO_8859_1 , C_ISO_8859_1},
- {"es_VE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"et_EE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"eu_ES" , C_ISO_8859_1 , C_ISO_8859_1},
- {"fi_FI" , C_ISO_8859_1 , C_ISO_8859_1},
- {"fo_FO" , C_ISO_8859_1 , C_ISO_8859_1},
- {"fr_BE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"fr_CA" , C_ISO_8859_1 , C_ISO_8859_1},
- {"fr_CH" , C_ISO_8859_1 , C_ISO_8859_1},
- {"fr_FR" , C_ISO_8859_1 , C_ISO_8859_1},
- {"fr_LU" , C_ISO_8859_1 , C_ISO_8859_1},
- {"ga_IE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"gl_ES" , C_ISO_8859_1 , C_ISO_8859_1},
- {"gv_GB" , C_ISO_8859_1 , C_ISO_8859_1},
- {"id_ID" , C_ISO_8859_1 , C_ISO_8859_1},
- {"is_IS" , C_ISO_8859_1 , C_ISO_8859_1},
- {"it_CH" , C_ISO_8859_1 , C_ISO_8859_1},
- {"it_IT" , C_ISO_8859_1 , C_ISO_8859_1},
- {"kl_GL" , C_ISO_8859_1 , C_ISO_8859_1},
- {"kw_GB" , C_ISO_8859_1 , C_ISO_8859_1},
- {"ms_MY" , C_ISO_8859_1 , C_ISO_8859_1},
- {"nl_BE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"nl_NL" , C_ISO_8859_1 , C_ISO_8859_1},
- {"nn_NO" , C_ISO_8859_1 , C_ISO_8859_1},
- {"no_NO" , C_ISO_8859_1 , C_ISO_8859_1},
- {"oc_FR" , C_ISO_8859_1 , C_ISO_8859_1},
- {"pt_BR" , C_ISO_8859_1 , C_ISO_8859_1},
- {"pt_PT" , C_ISO_8859_1 , C_ISO_8859_1},
- {"sq_AL" , C_ISO_8859_1 , C_ISO_8859_1},
- {"sv_FI" , C_ISO_8859_1 , C_ISO_8859_1},
- {"sv_SE" , C_ISO_8859_1 , C_ISO_8859_1},
- {"tl_PH" , C_ISO_8859_1 , C_ISO_8859_1},
- {"uz_UZ" , C_ISO_8859_1 , C_ISO_8859_1},
- {"wa_BE" , C_ISO_8859_1 , C_ISO_8859_1},
-
- {"bs_BA" , C_ISO_8859_2 , C_ISO_8859_2},
- {"cs_CZ" , C_ISO_8859_2 , C_ISO_8859_2},
- {"hr_HR" , C_ISO_8859_2 , C_ISO_8859_2},
- {"hu_HU" , C_ISO_8859_2 , C_ISO_8859_2},
- {"pl_PL" , C_ISO_8859_2 , C_ISO_8859_2},
- {"ro_RO" , C_ISO_8859_2 , C_ISO_8859_2},
- {"sk_SK" , C_ISO_8859_2 , C_ISO_8859_2},
- {"sl_SI" , C_ISO_8859_2 , C_ISO_8859_2},
-
- {"sr_YU@cyrillic" , C_ISO_8859_5 , C_ISO_8859_5},
- {"sr_YU" , C_ISO_8859_2 , C_ISO_8859_2},
-
- {"mt_MT" , C_ISO_8859_3 , C_ISO_8859_3},
-
- {"lt_LT.iso88594" , C_ISO_8859_4 , C_ISO_8859_4},
- {"lt_LT.ISO8859-4" , C_ISO_8859_4 , C_ISO_8859_4},
- {"lt_LT.ISO_8859-4" , C_ISO_8859_4 , C_ISO_8859_4},
- {"lt_LT" , C_ISO_8859_13 , C_ISO_8859_13},
-
- {"mk_MK" , C_ISO_8859_5 , C_ISO_8859_5},
-
- {"ar_AE" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_BH" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_DZ" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_EG" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_IQ" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_JO" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_KW" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_LB" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_LY" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_MA" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_OM" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_QA" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_SA" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_SD" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_SY" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_TN" , C_ISO_8859_6 , C_ISO_8859_6},
- {"ar_YE" , C_ISO_8859_6 , C_ISO_8859_6},
-
- {"el_GR" , C_ISO_8859_7 , C_ISO_8859_7},
- {"he_IL" , C_ISO_8859_8 , C_ISO_8859_8},
- {"iw_IL" , C_ISO_8859_8 , C_ISO_8859_8},
- {"tr_TR" , C_ISO_8859_9 , C_ISO_8859_9},
-
- {"lv_LV" , C_ISO_8859_13 , C_ISO_8859_13},
- {"mi_NZ" , C_ISO_8859_13 , C_ISO_8859_13},
-
- {"cy_GB" , C_ISO_8859_14 , C_ISO_8859_14},
-
- {"ar_IN" , C_UTF_8 , C_UTF_8},
- {"en_IN" , C_UTF_8 , C_UTF_8},
- {"se_NO" , C_UTF_8 , C_UTF_8},
- {"ta_IN" , C_UTF_8 , C_UTF_8},
- {"te_IN" , C_UTF_8 , C_UTF_8},
- {"ur_PK" , C_UTF_8 , C_UTF_8},
-
- {"th_TH" , C_TIS_620 , C_TIS_620},
- /* {"th_TH" , C_WINDOWS_874}, */
- /* {"th_TH" , C_ISO_8859_11}, */
-
- {"ka_GE" , C_GEORGIAN_PS , C_GEORGIAN_PS},
- {"vi_VN.TCVN" , C_TCVN5712_1 , C_TCVN5712_1},
-
- {"C" , C_US_ASCII , C_US_ASCII},
- {"POSIX" , C_US_ASCII , C_US_ASCII},
- {"ANSI_X3.4-1968" , C_US_ASCII , C_US_ASCII},
-};
-
-static GHashTable *conv_get_charset_to_str_table(void)
-{
- static GHashTable *table;
- gint i;
-
- if (table)
- return table;
-
- table = g_hash_table_new(NULL, g_direct_equal);
-
- for (i = 0; i < sizeof(charsets) / sizeof(charsets[0]); i++) {
- if (g_hash_table_lookup(table, GUINT_TO_POINTER(charsets[i].charset))
- == NULL) {
- g_hash_table_insert
- (table, GUINT_TO_POINTER(charsets[i].charset),
- charsets[i].name);
- }
- }
-
- return table;
-}
-
-static GHashTable *conv_get_charset_from_str_table(void)
-{
- static GHashTable *table;
- gint i;
-
- if (table)
- return table;
-
- table = g_hash_table_new(str_case_hash, str_case_equal);
-
- for (i = 0; i < sizeof(charsets) / sizeof(charsets[0]); i++) {
- g_hash_table_insert(table, charsets[i].name,
- GUINT_TO_POINTER(charsets[i].charset));
- }
-
- return table;
-}
-
-const gchar *conv_get_charset_str(CharSet charset)
-{
- GHashTable *table;
-
- table = conv_get_charset_to_str_table();
- return g_hash_table_lookup(table, GUINT_TO_POINTER(charset));
-}
-
-CharSet conv_get_charset_from_str(const gchar *charset)
-{
- GHashTable *table;
-
- if (!charset) return C_AUTO;
-
- table = conv_get_charset_from_str_table();
- return GPOINTER_TO_UINT(g_hash_table_lookup(table, charset));
-}
-
-CharSet conv_get_locale_charset(void)
-{
- static CharSet cur_charset = -1;
- const gchar *cur_locale;
- const gchar *p;
- gint i;
-
- if (cur_charset != -1)
- return cur_charset;
-
- cur_locale = conv_get_current_locale();
- if (!cur_locale) {
- cur_charset = C_US_ASCII;
- return cur_charset;
- }
-
- if (strcasestr(cur_locale, "UTF-8")) {
- cur_charset = C_UTF_8;
- return cur_charset;
- }
-
- if ((p = strcasestr(cur_locale, "@euro")) && p[5] == '\0') {
- cur_charset = C_ISO_8859_15;
- return cur_charset;
- }
-
- for (i = 0; i < sizeof(locale_table) / sizeof(locale_table[0]); i++) {
- const gchar *p;
-
- /* "ja_JP.EUC" matches with "ja_JP.eucJP", "ja_JP.EUC" and
- "ja_JP". "ja_JP" matches with "ja_JP.xxxx" and "ja" */
- if (!g_ascii_strncasecmp(cur_locale, locale_table[i].locale,
- strlen(locale_table[i].locale))) {
- cur_charset = locale_table[i].charset;
- return cur_charset;
- } else if ((p = strchr(locale_table[i].locale, '_')) &&
- !strchr(p + 1, '.')) {
- if (strlen(cur_locale) == 2 &&
- !g_ascii_strncasecmp(cur_locale,
- locale_table[i].locale, 2)) {
- cur_charset = locale_table[i].charset;
- return cur_charset;
- }
- }
- }
-
- cur_charset = C_AUTO;
- return cur_charset;
-}
-
-const gchar *conv_get_locale_charset_str(void)
-{
- static const gchar *codeset = NULL;
-
- if (!codeset)
- codeset = conv_get_charset_str(conv_get_locale_charset());
-
- return codeset ? codeset : CS_INTERNAL;
-}
-
-CharSet conv_get_internal_charset(void)
-{
- return C_INTERNAL;
-}
-
-const gchar *conv_get_internal_charset_str(void)
-{
- return CS_INTERNAL;
-}
-
-CharSet conv_get_outgoing_charset(void)
-{
- static CharSet out_charset = -1;
- const gchar *cur_locale;
- const gchar *p;
- gint i;
-
- if (out_charset != -1)
- return out_charset;
-
- cur_locale = conv_get_current_locale();
- if (!cur_locale) {
- out_charset = C_AUTO;
- return out_charset;
- }
-
- if ((p = strcasestr(cur_locale, "@euro")) && p[5] == '\0') {
- out_charset = C_ISO_8859_15;
- return out_charset;
- }
-
- for (i = 0; i < sizeof(locale_table) / sizeof(locale_table[0]); i++) {
- const gchar *p;
-
- if (!g_ascii_strncasecmp(cur_locale, locale_table[i].locale,
- strlen(locale_table[i].locale))) {
- out_charset = locale_table[i].out_charset;
- break;
- } else if ((p = strchr(locale_table[i].locale, '_')) &&
- !strchr(p + 1, '.')) {
- if (strlen(cur_locale) == 2 &&
- !g_ascii_strncasecmp(cur_locale,
- locale_table[i].locale, 2)) {
- out_charset = locale_table[i].out_charset;
- break;
- }
- }
- }
-
- return out_charset;
-}
-
-const gchar *conv_get_outgoing_charset_str(void)
-{
- CharSet out_charset;
- const gchar *str;
-
- out_charset = conv_get_outgoing_charset();
- str = conv_get_charset_str(out_charset);
-
- return str ? str : CS_UTF_8;
-}
-
-gboolean conv_is_multibyte_encoding(CharSet encoding)
-{
- switch (encoding) {
- case C_EUC_JP:
- case C_EUC_JP_MS:
- case C_EUC_KR:
- case C_EUC_TW:
- case C_EUC_CN:
- case C_ISO_2022_JP:
- case C_ISO_2022_JP_2:
- case C_ISO_2022_JP_3:
- case C_ISO_2022_KR:
- case C_ISO_2022_CN:
- case C_SHIFT_JIS:
- case C_GB2312:
- case C_GBK:
- case C_BIG5:
- case C_UTF_8:
- case C_UTF_7:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-const gchar *conv_get_current_locale(void)
-{
- static const gchar *cur_locale;
-
- if (!cur_locale) {
-#ifdef G_OS_WIN32
- cur_locale = g_win32_getlocale();
-#else
- cur_locale = g_getenv("LC_ALL");
- if (!cur_locale) cur_locale = g_getenv("LC_CTYPE");
- if (!cur_locale) cur_locale = g_getenv("LANG");
- if (!cur_locale) cur_locale = setlocale(LC_CTYPE, NULL);
-#endif /* G_OS_WIN32 */
-
- debug_print("current locale: %s\n",
- cur_locale ? cur_locale : "(none)");
- }
-
- return cur_locale;
-}
-
-gboolean conv_is_ja_locale(void)
-{
- static gint is_ja_locale = -1;
- const gchar *cur_locale;
-
- if (is_ja_locale != -1)
- return is_ja_locale != 0;
-
- is_ja_locale = 0;
- cur_locale = conv_get_current_locale();
- if (cur_locale) {
- if (g_ascii_strncasecmp(cur_locale, "ja", 2) == 0)
- is_ja_locale = 1;
- }
-
- return is_ja_locale != 0;
-}
-
-gchar *conv_unmime_header(const gchar *str, const gchar *default_encoding)
-{
- gchar *buf;
- gchar *decoded_str;
-
- if (is_ascii_str(str))
- return unmime_header(str);
-
- if (default_encoding) {
- buf = conv_codeset_strdup
- (str, default_encoding, CS_INTERNAL);
- if (buf) {
- decoded_str = unmime_header(buf);
- g_free(buf);
- return decoded_str;
- }
- }
-
- if (conv_is_ja_locale())
- buf = conv_anytodisp(str, NULL);
- else
- buf = conv_localetodisp(str, NULL);
-
- decoded_str = unmime_header(buf);
- g_free(buf);
-
- return decoded_str;
-}
-
-#define MAX_LINELEN 76
-#define MAX_HARD_LINELEN 996
-#define MIMESEP_BEGIN "=?"
-#define MIMESEP_END "?="
-
-#define B64LEN(len) ((len) / 3 * 4 + ((len) % 3 ? 4 : 0))
-
-#define LBREAK_IF_REQUIRED(cond, is_plain_text) \
-{ \
- if (len - (destp - dest) < MAX_LINELEN + 2) { \
- *destp = '\0'; \
- return; \
- } \
- \
- if ((cond) && *srcp) { \
- if (destp > dest && left < MAX_LINELEN - 1) { \
- if (g_ascii_isspace(*(destp - 1))) \
- destp--; \
- else if (is_plain_text && \
- g_ascii_isspace(*srcp)) \
- srcp++; \
- if (*srcp) { \
- *destp++ = '\n'; \
- *destp++ = ' '; \
- left = MAX_LINELEN - 1; \
- } \
- } \
- } \
-}
-
-void conv_encode_header(gchar *dest, gint len, const gchar *src,
- gint header_len, gboolean addr_field,
- const gchar *out_encoding)
-{
- const gchar *cur_encoding;
- gint mimestr_len;
- gchar *mimesep_enc;
- gint left;
- const gchar *srcp = src;
- gchar *destp = dest;
- gboolean use_base64;
-
- g_return_if_fail(g_utf8_validate(src, -1, NULL) == TRUE);
-
- if (MB_CUR_MAX > 1) {
- use_base64 = TRUE;
- mimesep_enc = "?B?";
- } else {
- use_base64 = FALSE;
- mimesep_enc = "?Q?";
- }
-
- cur_encoding = CS_INTERNAL;
- if (!out_encoding)
- out_encoding = conv_get_outgoing_charset_str();
- if (!strcmp(out_encoding, CS_US_ASCII))
- out_encoding = CS_ISO_8859_1;
-
- mimestr_len = strlen(MIMESEP_BEGIN) + strlen(out_encoding) +
- strlen(mimesep_enc) + strlen(MIMESEP_END);
-
- left = MAX_LINELEN - header_len;
-
- while (*srcp) {
- LBREAK_IF_REQUIRED(left <= 0, TRUE);
-
- while (g_ascii_isspace(*srcp)) {
- *destp++ = *srcp++;
- left--;
- LBREAK_IF_REQUIRED(left <= 0, TRUE);
- }
-
- /* output as it is if the next word is ASCII string */
- if (!is_next_nonascii(srcp)) {
- gint word_len;
-
- word_len = get_next_word_len(srcp);
- LBREAK_IF_REQUIRED(left < word_len, TRUE);
- while (word_len > 0) {
- LBREAK_IF_REQUIRED(left + (MAX_HARD_LINELEN - MAX_LINELEN) <= 0, TRUE)
- *destp++ = *srcp++;
- left--;
- word_len--;
- }
-
- continue;
- }
-
- /* don't include parentheses in encoded strings */
- if (addr_field && (*srcp == '(' || *srcp == ')')) {
- LBREAK_IF_REQUIRED(left < 2, FALSE);
- *destp++ = *srcp++;
- left--;
- }
-
- while (1) {
- gint mb_len = 0;
- gint cur_len = 0;
- gchar *part_str;
- gchar *out_str;
- gchar *enc_str;
- const gchar *p = srcp;
- gint out_str_len;
- gint out_enc_str_len;
- gint mime_block_len;
- gboolean cont = FALSE;
-
- while (*p != '\0') {
- if (g_ascii_isspace(*p) &&
- !is_next_nonascii(p + 1))
- break;
- /* don't include parentheses in encoded
- strings */
- if (addr_field && (*p == '(' || *p == ')'))
- break;
-
- mb_len = g_utf8_skip[*(guchar *)p];
-
- Xstrndup_a(part_str, srcp, cur_len + mb_len, );
- out_str = conv_codeset_strdup
- (part_str, cur_encoding, out_encoding);
- if (!out_str) {
- g_warning("conv_encode_header(): code conversion failed\n");
- conv_unreadable_8bit(part_str);
- out_str = g_strdup(part_str);
- }
- out_str_len = strlen(out_str);
-
- if (use_base64)
- out_enc_str_len = B64LEN(out_str_len);
- else
- out_enc_str_len =
- qp_get_q_encoding_len
- ((guchar *)out_str);
-
- g_free(out_str);
-
- if (mimestr_len + out_enc_str_len <= left) {
- cur_len += mb_len;
- p += mb_len;
- } else if (cur_len == 0) {
- LBREAK_IF_REQUIRED(1, FALSE);
- continue;
- } else {
- cont = TRUE;
- break;
- }
- }
-
- if (cur_len > 0) {
- Xstrndup_a(part_str, srcp, cur_len, );
- out_str = conv_codeset_strdup
- (part_str, cur_encoding, out_encoding);
- if (!out_str) {
- g_warning("conv_encode_header(): code conversion failed\n");
- conv_unreadable_8bit(part_str);
- out_str = g_strdup(part_str);
- }
- out_str_len = strlen(out_str);
-
- if (use_base64)
- out_enc_str_len = B64LEN(out_str_len);
- else
- out_enc_str_len =
- qp_get_q_encoding_len
- ((guchar *)out_str);
-
- Xalloca(enc_str, out_enc_str_len + 1, );
- if (use_base64)
- base64_encode(enc_str,
- (guchar *)out_str,
- out_str_len);
- else
- qp_q_encode(enc_str, (guchar *)out_str);
-
- g_free(out_str);
-
- /* output MIME-encoded string block */
- mime_block_len = mimestr_len + strlen(enc_str);
- g_snprintf(destp, mime_block_len + 1,
- MIMESEP_BEGIN "%s%s%s" MIMESEP_END,
- out_encoding, mimesep_enc, enc_str);
- destp += mime_block_len;
- srcp += cur_len;
-
- left -= mime_block_len;
- }
-
- LBREAK_IF_REQUIRED(cont, FALSE);
-
- if (cur_len == 0)
- break;
- }
- }
-
- *destp = '\0';
-}
-
-#undef LBREAK_IF_REQUIRED
-
-gint conv_copy_file(const gchar *src, const gchar *dest, const gchar *encoding)
-{
- FILE *src_fp, *dest_fp;
- gchar buf[BUFFSIZE];
- CodeConverter *conv;
- gboolean err = FALSE;
-
- if ((src_fp = g_fopen(src, "rb")) == NULL) {
- FILE_OP_ERROR(src, "fopen");
- return -1;
- }
- if ((dest_fp = g_fopen(dest, "wb")) == NULL) {
- FILE_OP_ERROR(dest, "fopen");
- fclose(src_fp);
- return -1;
- }
-
- if (change_file_mode_rw(dest_fp, dest) < 0) {
- FILE_OP_ERROR(dest, "chmod");
- g_warning("can't change file mode\n");
- }
-
- conv = conv_code_converter_new(encoding, NULL);
-
- while (fgets(buf, sizeof(buf), src_fp) != NULL) {
- gchar *outbuf;
-
- outbuf = conv_convert(conv, buf);
- if (outbuf) {
- fputs(outbuf, dest_fp);
- g_free(outbuf);
- } else
- fputs(buf, dest_fp);
- }
-
- conv_code_converter_destroy(conv);
-
- if (ferror(src_fp)) {
- FILE_OP_ERROR(src, "fgets");
- err = TRUE;
- }
- fclose(src_fp);
- if (fclose(dest_fp) == EOF) {
- FILE_OP_ERROR(dest, "fclose");
- err = TRUE;
- }
- if (err) {
- g_unlink(dest);
- return -1;
- }
-
- return 0;
-}
-
-gint conv_copy_dir(const gchar *src, const gchar *dest, const gchar *encoding)
-{
- GDir *dir;
- const gchar *dir_name;
- gchar *src_file;
- gchar *dest_file;
-
- if ((dir = g_dir_open(src, 0, NULL)) == NULL) {
- g_warning("failed to open directory: %s\n", src);
- return -1;
- }
-
- if (make_dir_hier(dest) < 0) {
- g_dir_close(dir);
- return -1;
- }
-
- while ((dir_name = g_dir_read_name(dir)) != NULL) {
- src_file = g_strconcat(src, G_DIR_SEPARATOR_S, dir_name, NULL);
- dest_file = g_strconcat(dest, G_DIR_SEPARATOR_S, dir_name,
- NULL);
- if (is_file_exist(src_file))
- conv_copy_file(src_file, dest_file, encoding);
- g_free(dest_file);
- g_free(src_file);
- }
-
- g_dir_close(dir);
-
- return 0;
-}
-
-gchar *conv_filename_from_utf8(const gchar *utf8_file)
-{
- gchar *fs_file;
- GError *error = NULL;
-
- fs_file = g_filename_from_utf8(utf8_file, -1, NULL, NULL, &error);
- if (error) {
- g_warning("failed to convert encoding of file name: %s\n",
- error->message);
- g_error_free(error);
- }
- if (!fs_file)
- fs_file = g_strdup(utf8_file);
-
- return fs_file;
-}
-
-gchar *conv_filename_to_utf8(const gchar *fs_file)
-{
- gchar *utf8_file;
- GError *error = NULL;
-
- utf8_file = g_filename_to_utf8(fs_file, -1, NULL, NULL, &error);
- if (error) {
- g_warning("failed to convert encoding of file name: %s\n",
- error->message);
- g_error_free(error);
- }
- if (!utf8_file)
- utf8_file = g_strdup(fs_file);
-
- return utf8_file;
-}
diff --git a/src/codeconv.h b/src/codeconv.h
deleted file mode 100644
index 833b1402..00000000
--- a/src/codeconv.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __CODECONV_H__
-#define __CODECONV_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <iconv.h>
-
-typedef struct _CodeConverter CodeConverter;
-
-typedef enum
-{
- C_AUTO,
- C_US_ASCII,
- C_UTF_8,
- C_UTF_7,
- C_ISO_8859_1,
- C_ISO_8859_2,
- C_ISO_8859_3,
- C_ISO_8859_4,
- C_ISO_8859_5,
- C_ISO_8859_6,
- C_ISO_8859_7,
- C_ISO_8859_8,
- C_ISO_8859_9,
- C_ISO_8859_10,
- C_ISO_8859_11,
- C_ISO_8859_13,
- C_ISO_8859_14,
- C_ISO_8859_15,
- C_BALTIC,
- C_CP1250,
- C_CP1251,
- C_CP1252,
- C_CP1253,
- C_CP1254,
- C_CP1255,
- C_CP1256,
- C_CP1257,
- C_CP1258,
- C_WINDOWS_1250,
- C_WINDOWS_1251,
- C_WINDOWS_1252,
- C_WINDOWS_1253,
- C_WINDOWS_1254,
- C_WINDOWS_1255,
- C_WINDOWS_1256,
- C_WINDOWS_1257,
- C_WINDOWS_1258,
- C_KOI8_R,
- C_KOI8_T,
- C_KOI8_U,
- C_ISO_2022_JP,
- C_ISO_2022_JP_2,
- C_ISO_2022_JP_3,
- C_EUC_JP,
- C_EUC_JP_MS,
- C_SHIFT_JIS,
- C_ISO_2022_KR,
- C_EUC_KR,
- C_ISO_2022_CN,
- C_EUC_CN,
- C_GB2312,
- C_GBK,
- C_EUC_TW,
- C_BIG5,
- C_BIG5_HKSCS,
- C_TIS_620,
- C_WINDOWS_874,
- C_GEORGIAN_PS,
- C_TCVN5712_1
-} CharSet;
-
-typedef gchar *(*CodeConvFunc) (const gchar *inbuf, gint *error);
-
-struct _CodeConverter
-{
- CodeConvFunc code_conv_func;
- gchar *src_encoding;
- gchar *dest_encoding;
-};
-
-#define CS_AUTO "AUTO"
-#define CS_US_ASCII "US-ASCII"
-#define CS_ANSI_X3_4_1968 "ANSI_X3.4-1968"
-#define CS_UTF_8 "UTF-8"
-#define CS_UTF_7 "UTF-7"
-#define CS_ISO_8859_1 "ISO-8859-1"
-#define CS_ISO_8859_2 "ISO-8859-2"
-#define CS_ISO_8859_3 "ISO-8859-3"
-#define CS_ISO_8859_4 "ISO-8859-4"
-#define CS_ISO_8859_5 "ISO-8859-5"
-#define CS_ISO_8859_6 "ISO-8859-6"
-#define CS_ISO_8859_7 "ISO-8859-7"
-#define CS_ISO_8859_8 "ISO-8859-8"
-#define CS_ISO_8859_9 "ISO-8859-9"
-#define CS_ISO_8859_10 "ISO-8859-10"
-#define CS_ISO_8859_11 "ISO-8859-11"
-#define CS_ISO_8859_13 "ISO-8859-13"
-#define CS_ISO_8859_14 "ISO-8859-14"
-#define CS_ISO_8859_15 "ISO-8859-15"
-#define CS_BALTIC "BALTIC"
-#define CS_CP1250 "CP1250"
-#define CS_CP1251 "CP1251"
-#define CS_CP1252 "CP1252"
-#define CS_CP1253 "CP1253"
-#define CS_CP1254 "CP1254"
-#define CS_CP1255 "CP1255"
-#define CS_CP1256 "CP1256"
-#define CS_CP1257 "CP1257"
-#define CS_CP1258 "CP1258"
-#define CS_WINDOWS_1250 "Windows-1250"
-#define CS_WINDOWS_1251 "Windows-1251"
-#define CS_WINDOWS_1252 "Windows-1252"
-#define CS_WINDOWS_1253 "Windows-1253"
-#define CS_WINDOWS_1254 "Windows-1254"
-#define CS_WINDOWS_1255 "Windows-1255"
-#define CS_WINDOWS_1256 "Windows-1256"
-#define CS_WINDOWS_1257 "Windows-1257"
-#define CS_WINDOWS_1258 "Windows-1258"
-#define CS_KOI8_R "KOI8-R"
-#define CS_KOI8_T "KOI8-T"
-#define CS_KOI8_U "KOI8-U"
-#define CS_ISO_2022_JP "ISO-2022-JP"
-#define CS_ISO_2022_JP_2 "ISO-2022-JP-2"
-#define CS_ISO_2022_JP_3 "ISO-2022-JP-3"
-#define CS_EUC_JP "EUC-JP"
-#define CS_EUCJP "EUCJP"
-#define CS_EUC_JP_MS "EUC-JP-MS"
-#define CS_SHIFT_JIS "Shift_JIS"
-#define CS_SHIFT__JIS "SHIFT-JIS"
-#define CS_SJIS "SJIS"
-#define CS_X_SJIS "X-SJIS"
-#define CS_ISO_2022_KR "ISO-2022-KR"
-#define CS_EUC_KR "EUC-KR"
-#define CS_ISO_2022_CN "ISO-2022-CN"
-#define CS_EUC_CN "EUC-CN"
-#define CS_GB2312 "GB2312"
-#define CS_GBK "GBK"
-#define CS_X_GBK "X-GBK"
-#define CS_EUC_TW "EUC-TW"
-#define CS_BIG5 "Big5"
-#define CS_BIG5_HKSCS "BIG5-HKSCS"
-#define CS_TIS_620 "TIS-620"
-#define CS_WINDOWS_874 "Windows-874"
-#define CS_GEORGIAN_PS "GEORGIAN-PS"
-#define CS_TCVN5712_1 "TCVN5712-1"
-
-#define C_INTERNAL C_UTF_8
-#define CS_INTERNAL CS_UTF_8
-
-//void conv_mb_alnum(gchar *str);
-
-CharSet conv_guess_ja_encoding (const gchar *str);
-
-gchar *conv_utf8todisp (const gchar *inbuf,
- gint *error);
-gchar *conv_localetodisp (const gchar *inbuf,
- gint *error);
-
-CodeConverter *conv_code_converter_new (const gchar *src_encoding,
- const gchar *dest_encoding);
-void conv_code_converter_destroy (CodeConverter *conv);
-gchar *conv_convert (CodeConverter *conv,
- const gchar *inbuf);
-
-#define conv_codeset_strdup(inbuf, src_code, dest_code) \
- (conv_codeset_strdup_full(inbuf, src_code, dest_code, NULL))
-
-gchar *conv_codeset_strdup_full (const gchar *inbuf,
- const gchar *src_encoding,
- const gchar *dest_encoding,
- gint *error);
-
-CodeConvFunc conv_get_code_conv_func (const gchar *src_encoding,
- const gchar *dest_encoding);
-
-gchar *conv_iconv_strdup (const gchar *inbuf,
- const gchar *src_encoding,
- const gchar *dest_encoding,
- gint *error);
-gchar *conv_iconv_strdup_with_cd (const gchar *inbuf,
- iconv_t cd,
- gint *error);
-
-const gchar *conv_get_charset_str (CharSet charset);
-CharSet conv_get_charset_from_str (const gchar *charset);
-CharSet conv_get_locale_charset (void);
-const gchar *conv_get_locale_charset_str (void);
-CharSet conv_get_internal_charset (void);
-const gchar *conv_get_internal_charset_str (void);
-CharSet conv_get_outgoing_charset (void);
-const gchar *conv_get_outgoing_charset_str (void);
-gboolean conv_is_multibyte_encoding (CharSet encoding);
-
-const gchar *conv_get_current_locale (void);
-gboolean conv_is_ja_locale (void);
-
-gchar *conv_unmime_header (const gchar *str,
- const gchar *default_encoding);
-void conv_encode_header (gchar *dest,
- gint len,
- const gchar *src,
- gint header_len,
- gboolean addr_field,
- const gchar *out_encoding);
-
-gint conv_copy_file (const gchar *src,
- const gchar *dest,
- const gchar *src_encoding);
-gint conv_copy_dir (const gchar *src,
- const gchar *dest,
- const gchar *src_encoding);
-
-gchar *conv_filename_from_utf8 (const gchar *utf8_file);
-gchar *conv_filename_to_utf8 (const gchar *fs_file);
-
-#endif /* __CODECONV_H__ */
diff --git a/src/prefs.c b/src/prefs.c
deleted file mode 100644
index 4579df4f..00000000
--- a/src/prefs.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "prefs.h"
-#include "codeconv.h"
-#include "utils.h"
-
-typedef enum
-{
- DUMMY_PARAM
-} DummyEnum;
-
-void prefs_read_config(PrefParam *param, const gchar *label,
- const gchar *rcfile, const gchar *encoding)
-{
- FILE *fp;
- gchar buf[PREFSBUFSIZE];
- gchar *block_label;
-
- g_return_if_fail(param != NULL);
- g_return_if_fail(label != NULL);
- g_return_if_fail(rcfile != NULL);
-
- debug_print("Reading configuration...\n");
-
- prefs_set_default(param);
-
- if ((fp = g_fopen(rcfile, "rb")) == NULL) {
- if (ENOENT != errno) FILE_OP_ERROR(rcfile, "fopen");
- return;
- }
-
- block_label = g_strdup_printf("[%s]", label);
-
- /* search aiming block */
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- gint val;
-
- if (encoding) {
- gchar *conv_str;
-
- conv_str = conv_codeset_strdup
- (buf, encoding, CS_INTERNAL);
- if (!conv_str)
- conv_str = g_strdup(buf);
- val = strncmp
- (conv_str, block_label, strlen(block_label));
- g_free(conv_str);
- } else
- val = strncmp(buf, block_label, strlen(block_label));
- if (val == 0) {
- debug_print("Found %s\n", block_label);
- break;
- }
- }
- g_free(block_label);
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- strretchomp(buf);
- /* reached next block */
- if (buf[0] == '[') break;
-
- if (encoding) {
- gchar *conv_str;
-
- conv_str = conv_codeset_strdup
- (buf, encoding, CS_INTERNAL);
- if (!conv_str)
- conv_str = g_strdup(buf);
- prefs_config_parse_one_line(param, conv_str);
- g_free(conv_str);
- } else
- prefs_config_parse_one_line(param, buf);
- }
-
- debug_print("Finished reading configuration.\n");
- fclose(fp);
-}
-
-void prefs_config_parse_one_line(PrefParam *param, const gchar *buf)
-{
- gint i;
- gint name_len;
- const gchar *value;
-
- for (i = 0; param[i].name != NULL; i++) {
- name_len = strlen(param[i].name);
- if (g_ascii_strncasecmp(buf, param[i].name, name_len))
- continue;
- if (buf[name_len] != '=')
- continue;
- value = buf + name_len + 1;
- /* debug_print("%s = %s\n", param[i].name, value); */
-
- switch (param[i].type) {
- case P_STRING:
- g_free(*((gchar **)param[i].data));
- *((gchar **)param[i].data) =
- *value ? g_strdup(value) : NULL;
- break;
- case P_INT:
- *((gint *)param[i].data) =
- (gint)atoi(value);
- break;
- case P_BOOL:
- *((gboolean *)param[i].data) =
- (*value == '0' || *value == '\0')
- ? FALSE : TRUE;
- break;
- case P_ENUM:
- *((DummyEnum *)param[i].data) =
- (DummyEnum)atoi(value);
- break;
- case P_USHORT:
- *((gushort *)param[i].data) =
- (gushort)atoi(value);
- break;
- default:
- break;
- }
- }
-}
-
-#define TRY(func) \
-if (!(func)) \
-{ \
- g_warning(_("failed to write configuration to file\n")); \
- if (orig_fp) fclose(orig_fp); \
- prefs_file_close_revert(pfile); \
- g_free(rcpath); \
- g_free(block_label); \
- return; \
-} \
-
-void prefs_write_config(PrefParam *param, const gchar *label,
- const gchar *rcfile)
-{
- FILE *orig_fp;
- PrefFile *pfile;
- gchar *rcpath;
- gchar buf[PREFSBUFSIZE];
- gchar *block_label = NULL;
- gboolean block_matched = FALSE;
-
- g_return_if_fail(param != NULL);
- g_return_if_fail(label != NULL);
- g_return_if_fail(rcfile != NULL);
-
- rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, rcfile, NULL);
- if ((orig_fp = g_fopen(rcpath, "rb")) == NULL) {
- if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
- }
-
- if ((pfile = prefs_file_open(rcpath)) == NULL) {
- g_warning(_("failed to write configuration to file\n"));
- if (orig_fp) fclose(orig_fp);
- g_free(rcpath);
- return;
- }
-
- block_label = g_strdup_printf("[%s]", label);
-
- /* search aiming block */
- if (orig_fp) {
- while (fgets(buf, sizeof(buf), orig_fp) != NULL) {
- gint val;
-
- val = strncmp(buf, block_label, strlen(block_label));
- if (val == 0) {
- debug_print(_("Found %s\n"), block_label);
- block_matched = TRUE;
- break;
- } else
- TRY(fputs(buf, pfile->fp) != EOF);
- }
- }
-
- TRY(fprintf(pfile->fp, "%s\n", block_label) > 0);
- g_free(block_label);
- block_label = NULL;
-
- /* write all param data to file */
- TRY(prefs_file_write_param(pfile, param) == 0);
-
- if (block_matched) {
- while (fgets(buf, sizeof(buf), orig_fp) != NULL) {
- /* next block */
- if (buf[0] == '[') {
- TRY(fputc('\n', pfile->fp) != EOF &&
- fputs(buf, pfile->fp) != EOF);
- break;
- }
- }
- while (fgets(buf, sizeof(buf), orig_fp) != NULL)
- TRY(fputs(buf, pfile->fp) != EOF);
- }
-
- if (orig_fp) fclose(orig_fp);
- if (prefs_file_close(pfile) < 0)
- g_warning(_("failed to write configuration to file\n"));
- g_free(rcpath);
-
- debug_print(_("Configuration is saved.\n"));
-}
-
-gint prefs_file_write_param(PrefFile *pfile, PrefParam *param)
-{
- gint i;
- gchar buf[PREFSBUFSIZE];
-
- for (i = 0; param[i].name != NULL; i++) {
- switch (param[i].type) {
- case P_STRING:
- g_snprintf(buf, sizeof(buf), "%s=%s\n", param[i].name,
- *((gchar **)param[i].data) ?
- *((gchar **)param[i].data) : "");
- break;
- case P_INT:
- g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
- *((gint *)param[i].data));
- break;
- case P_BOOL:
- g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
- *((gboolean *)param[i].data));
- break;
- case P_ENUM:
- g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
- *((DummyEnum *)param[i].data));
- break;
- case P_USHORT:
- g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
- *((gushort *)param[i].data));
- break;
- default:
- buf[0] = '\0';
- }
-
- if (buf[0] != '\0') {
- if (fputs(buf, pfile->fp) == EOF) {
- perror("fputs");
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-PrefFile *prefs_file_open(const gchar *path)
-{
- PrefFile *pfile;
- gchar *tmppath;
- FILE *fp;
-
- g_return_val_if_fail(path != NULL, NULL);
-
- tmppath = g_strconcat(path, ".tmp", NULL);
- if ((fp = g_fopen(tmppath, "wb")) == NULL) {
- FILE_OP_ERROR(tmppath, "fopen");
- g_free(tmppath);
- return NULL;
- }
-
- if (change_file_mode_rw(fp, tmppath) < 0)
- FILE_OP_ERROR(tmppath, "chmod");
-
- g_free(tmppath);
-
- pfile = g_new(PrefFile, 1);
- pfile->fp = fp;
- pfile->path = g_strdup(path);
-
- return pfile;
-}
-
-gint prefs_file_close(PrefFile *pfile)
-{
- FILE *fp;
- gchar *path;
- gchar *tmppath;
- gchar *bakpath = NULL;
-
- g_return_val_if_fail(pfile != NULL, -1);
-
- fp = pfile->fp;
- path = pfile->path;
- g_free(pfile);
-
- tmppath = g_strconcat(path, ".tmp", NULL);
- if (fclose(fp) == EOF) {
- FILE_OP_ERROR(tmppath, "fclose");
- g_unlink(tmppath);
- g_free(path);
- g_free(tmppath);
- return -1;
- }
-
- if (is_file_exist(path)) {
- bakpath = g_strconcat(path, ".bak", NULL);
- if (rename_force(path, bakpath) < 0) {
- FILE_OP_ERROR(path, "rename");
- g_unlink(tmppath);
- g_free(path);
- g_free(tmppath);
- g_free(bakpath);
- return -1;
- }
- }
-
- if (rename_force(tmppath, path) < 0) {
- FILE_OP_ERROR(tmppath, "rename");
- g_unlink(tmppath);
- g_free(path);
- g_free(tmppath);
- g_free(bakpath);
- return -1;
- }
-
- g_free(path);
- g_free(tmppath);
- g_free(bakpath);
- return 0;
-}
-
-gint prefs_file_close_revert(PrefFile *pfile)
-{
- gchar *tmppath;
-
- g_return_val_if_fail(pfile != NULL, -1);
-
- tmppath = g_strconcat(pfile->path, ".tmp", NULL);
- fclose(pfile->fp);
- if (g_unlink(tmppath) < 0)
- FILE_OP_ERROR(tmppath, "unlink");
- g_free(tmppath);
- g_free(pfile->path);
- g_free(pfile);
-
- return 0;
-}
-
-void prefs_set_default(PrefParam *param)
-{
- gint i;
-
- g_return_if_fail(param != NULL);
-
- for (i = 0; param[i].name != NULL; i++) {
- if (!param[i].data) continue;
-
- switch (param[i].type) {
- case P_STRING:
- if (param[i].defval != NULL) {
- if (!g_ascii_strncasecmp(param[i].defval, "ENV_", 4)) {
- const gchar *envstr;
- gchar *tmp = NULL;
-
- envstr = g_getenv(param[i].defval + 4);
- if (envstr) {
- tmp = conv_codeset_strdup
- (envstr,
- conv_get_locale_charset_str(),
- CS_UTF_8);
- if (!tmp) {
- g_warning("failed to convert character set.");
- tmp = g_strdup(envstr);
- }
- }
- *((gchar **)param[i].data) = tmp;
- } else if (param[i].defval[0] == '~')
- *((gchar **)param[i].data) =
- g_strconcat(get_home_dir(),
- param[i].defval + 1,
- NULL);
- else if (param[i].defval[0] != '\0')
- *((gchar **)param[i].data) =
- g_strdup(param[i].defval);
- else
- *((gchar **)param[i].data) = NULL;
- } else
- *((gchar **)param[i].data) = NULL;
- break;
- case P_INT:
- if (param[i].defval != NULL)
- *((gint *)param[i].data) =
- (gint)atoi(param[i].defval);
- else
- *((gint *)param[i].data) = 0;
- break;
- case P_BOOL:
- if (param[i].defval != NULL) {
- if (!g_ascii_strcasecmp(param[i].defval, "TRUE"))
- *((gboolean *)param[i].data) = TRUE;
- else
- *((gboolean *)param[i].data) =
- atoi(param[i].defval) ? TRUE : FALSE;
- } else
- *((gboolean *)param[i].data) = FALSE;
- break;
- case P_ENUM:
- if (param[i].defval != NULL)
- *((DummyEnum*)param[i].data) =
- (DummyEnum)atoi(param[i].defval);
- else
- *((DummyEnum *)param[i].data) = 0;
- break;
- case P_USHORT:
- if (param[i].defval != NULL)
- *((gushort *)param[i].data) =
- (gushort)atoi(param[i].defval);
- else
- *((gushort *)param[i].data) = 0;
- break;
- default:
- break;
- }
- }
-}
-
-void prefs_free(PrefParam *param)
-{
- gint i;
-
- g_return_if_fail(param != NULL);
-
- for (i = 0; param[i].name != NULL; i++) {
- if (!param[i].data) continue;
-
- switch (param[i].type) {
- case P_STRING:
- g_free(*((gchar **)param[i].data));
- break;
- default:
- break;
- }
- }
-}
diff --git a/src/prefs.h b/src/prefs.h
deleted file mode 100644
index f062d1eb..00000000
--- a/src/prefs.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __PREFS_H__
-#define __PREFS_H__
-
-#include <glib.h>
-#include <stdio.h>
-
-typedef struct _PrefParam PrefParam;
-typedef struct _PrefFile PrefFile;
-
-#define PREFSBUFSIZE 1024
-
-#define P_WID(wid) ((gpointer *)(wid))
-
-typedef enum
-{
- P_STRING,
- P_INT,
- P_BOOL,
- P_ENUM,
- P_USHORT,
- P_OTHER
-} PrefType;
-
-typedef void (*DataSetFunc) (PrefParam *pparam);
-typedef void (*WidgetSetFunc) (PrefParam *pparam);
-
-struct _PrefParam {
- gchar *name;
- gchar *defval;
- gpointer data;
- PrefType type;
- gpointer *widget;
- DataSetFunc data_set_func;
- WidgetSetFunc widget_set_func;
-};
-
-struct _PrefFile {
- FILE *fp;
- gchar *path;
-};
-
-void prefs_read_config (PrefParam *param,
- const gchar *label,
- const gchar *rcfile,
- const gchar *encoding);
-void prefs_config_parse_one_line(PrefParam *param,
- const gchar *buf);
-void prefs_write_config (PrefParam *param,
- const gchar *label,
- const gchar *rcfile);
-
-PrefFile *prefs_file_open (const gchar *path);
-gint prefs_file_write_param (PrefFile *pfile,
- PrefParam *param);
-gint prefs_file_close (PrefFile *pfile);
-gint prefs_file_close_revert (PrefFile *pfile);
-
-void prefs_set_default (PrefParam *param);
-void prefs_free (PrefParam *param);
-
-#endif /* __PREFS_H__ */
diff --git a/src/quoted-printable.c b/src/quoted-printable.c
deleted file mode 100644
index cea0b704..00000000
--- a/src/quoted-printable.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <glib.h>
-#include <ctype.h>
-
-static gboolean get_hex_value(guchar *out, gchar c1, gchar c2);
-static void get_hex_str(gchar *out, guchar ch);
-
-#define MAX_LINELEN 76
-
-#define IS_LBREAK(p) \
- (*(p) == '\0' || *(p) == '\n' || (*(p) == '\r' && *((p) + 1) == '\n'))
-
-#define SOFT_LBREAK_IF_REQUIRED(n) \
- if (len + (n) > MAX_LINELEN || \
- (len + (n) == MAX_LINELEN && (!IS_LBREAK(inp + 1)))) { \
- *outp++ = '='; \
- *outp++ = '\n'; \
- len = 0; \
- }
-
-void qp_encode_line(gchar *out, const guchar *in)
-{
- const guchar *inp = in;
- gchar *outp = out;
- guchar ch;
- gint len = 0;
-
- while (*inp != '\0') {
- ch = *inp;
-
- if (IS_LBREAK(inp)) {
- *outp++ = '\n';
- len = 0;
- if (*inp == '\r')
- inp++;
- inp++;
- } else if (ch == '\t' || ch == ' ') {
- if (IS_LBREAK(inp + 1)) {
- SOFT_LBREAK_IF_REQUIRED(3);
- *outp++ = '=';
- get_hex_str(outp, ch);
- outp += 2;
- len += 3;
- inp++;
- } else {
- SOFT_LBREAK_IF_REQUIRED(1);
- *outp++ = *inp++;
- len++;
- }
- } else if ((ch >= 33 && ch <= 60) || (ch >= 62 && ch <= 126)) {
- SOFT_LBREAK_IF_REQUIRED(1);
- *outp++ = *inp++;
- len++;
- } else {
- SOFT_LBREAK_IF_REQUIRED(3);
- *outp++ = '=';
- get_hex_str(outp, ch);
- outp += 2;
- len += 3;
- inp++;
- }
- }
-
- if (len > 0)
- *outp++ = '\n';
-
- *outp = '\0';
-}
-
-gint qp_decode_line(gchar *str)
-{
- gchar *inp = str, *outp = str;
-
- while (*inp != '\0') {
- if (*inp == '=') {
- if (inp[1] && inp[2] &&
- get_hex_value((guchar *)outp, inp[1], inp[2])
- == TRUE) {
- inp += 3;
- } else if (inp[1] == '\0' || g_ascii_isspace(inp[1])) {
- /* soft line break */
- break;
- } else {
- /* broken QP string */
- *outp = *inp++;
- }
- } else {
- *outp = *inp++;
- }
- outp++;
- }
-
- *outp = '\0';
-
- return outp - str;
-}
-
-gint qp_decode_q_encoding(guchar *out, const gchar *in, gint inlen)
-{
- const gchar *inp = in;
- guchar *outp = out;
-
- if (inlen < 0)
- inlen = G_MAXINT;
-
- while (inp - in < inlen && *inp != '\0') {
- if (*inp == '=' && inp + 3 - in <= inlen) {
- if (get_hex_value(outp, inp[1], inp[2]) == TRUE) {
- inp += 3;
- } else {
- *outp = *inp++;
- }
- } else if (*inp == '_') {
- *outp = ' ';
- inp++;
- } else {
- *outp = *inp++;
- }
- outp++;
- }
-
- *outp = '\0';
-
- return outp - out;
-}
-
-gint qp_get_q_encoding_len(const guchar *str)
-{
- const guchar *inp = str;
- gint len = 0;
-
- while (*inp != '\0') {
- if (*inp == 0x20)
- len++;
- else if (*inp == '=' || *inp == '?' || *inp == '_' ||
- *inp < 32 || *inp > 127 || g_ascii_isspace(*inp))
- len += 3;
- else
- len++;
-
- inp++;
- }
-
- return len;
-}
-
-void qp_q_encode(gchar *out, const guchar *in)
-{
- const guchar *inp = in;
- gchar *outp = out;
-
- while (*inp != '\0') {
- if (*inp == 0x20)
- *outp++ = '_';
- else if (*inp == '=' || *inp == '?' || *inp == '_' ||
- *inp < 32 || *inp > 127 || g_ascii_isspace(*inp)) {
- *outp++ = '=';
- get_hex_str(outp, *inp);
- outp += 2;
- } else
- *outp++ = *inp;
-
- inp++;
- }
-
- *outp = '\0';
-}
-
-#define HEX_TO_INT(val, hex) \
-{ \
- gchar c = hex; \
- \
- if ('0' <= c && c <= '9') { \
- val = c - '0'; \
- } else if ('a' <= c && c <= 'f') { \
- val = c - 'a' + 10; \
- } else if ('A' <= c && c <= 'F') { \
- val = c - 'A' + 10; \
- } else { \
- val = -1; \
- } \
-}
-
-static gboolean get_hex_value(guchar *out, gchar c1, gchar c2)
-{
- gint hi, lo;
-
- HEX_TO_INT(hi, c1);
- HEX_TO_INT(lo, c2);
-
- if (hi == -1 || lo == -1)
- return FALSE;
-
- *out = (hi << 4) + lo;
- return TRUE;
-}
-
-#define INT_TO_HEX(hex, val) \
-{ \
- if ((val) < 10) \
- hex = '0' + (val); \
- else \
- hex = 'A' + (val) - 10; \
-}
-
-static void get_hex_str(gchar *out, guchar ch)
-{
- gchar hex;
-
- INT_TO_HEX(hex, ch >> 4);
- *out++ = hex;
- INT_TO_HEX(hex, ch & 0x0f);
- *out++ = hex;
-}
diff --git a/src/quoted-printable.h b/src/quoted-printable.h
deleted file mode 100644
index e5abf4f7..00000000
--- a/src/quoted-printable.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __QUOTED_PRINTABLE_H__
-#define __QUOTED_PRINTABLE_H__
-
-#include <glib.h>
-
-void qp_encode_line (gchar *out,
- const guchar *in);
-gint qp_decode_line (gchar *str);
-
-gint qp_decode_q_encoding (guchar *out,
- const gchar *in,
- gint inlen);
-gint qp_get_q_encoding_len (const guchar *str);
-void qp_q_encode (gchar *out,
- const guchar *in);
-
-#endif /* __QUOTED_PRINTABLE_H__ */
diff --git a/src/session.c b/src/session.c
deleted file mode 100644
index 6e7fa4e9..00000000
--- a/src/session.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-#include <errno.h>
-
-#include "session.h"
-#include "utils.h"
-
-static gint session_connect_cb (SockInfo *sock,
- gpointer data);
-static gint session_close (Session *session);
-
-static gboolean session_timeout_cb (gpointer data);
-
-static gboolean session_recv_msg_idle_cb (gpointer data);
-static gboolean session_recv_data_idle_cb (gpointer data);
-
-static gboolean session_read_msg_cb (SockInfo *source,
- GIOCondition condition,
- gpointer data);
-static gboolean session_read_data_cb (SockInfo *source,
- GIOCondition condition,
- gpointer data);
-static gboolean session_write_msg_cb (SockInfo *source,
- GIOCondition condition,
- gpointer data);
-static gboolean session_write_data_cb (SockInfo *source,
- GIOCondition condition,
- gpointer data);
-
-
-void session_init(Session *session)
-{
- session->type = SESSION_UNKNOWN;
- session->sock = NULL;
- session->server = NULL;
- session->port = 0;
-#if USE_SSL
- session->ssl_type = SSL_NONE;
-#endif
- session->nonblocking = TRUE;
- session->state = SESSION_READY;
- session->last_access_time = time(NULL);
-
- g_get_current_time(&session->tv_prev);
-
- session->conn_id = 0;
-
- session->io_tag = 0;
-
- session->read_buf_p = session->read_buf;
- session->read_buf_len = 0;
-
- session->read_msg_buf = g_string_sized_new(1024);
- session->read_data_buf = g_byte_array_new();
-
- session->write_buf = NULL;
- session->write_buf_p = NULL;
- session->write_buf_len = 0;
-
- session->write_data = NULL;
- session->write_data_p = NULL;
- session->write_data_len = 0;
-
- session->timeout_tag = 0;
- session->timeout_interval = 0;
-
- session->data = NULL;
-}
-
-gint session_connect(Session *session, const gchar *server, gushort port)
-{
-#ifdef G_OS_UNIX
- session->server = g_strdup(server);
- session->port = port;
-
- session->conn_id = sock_connect_async(server, port, session_connect_cb,
- session);
- if (session->conn_id < 0) {
- g_warning("can't connect to server.");
- session_close(session);
- return -1;
- }
-
- return 0;
-#else
- SockInfo *sock;
-
- session->server = g_strdup(server);
- session->port = port;
-
- sock = sock_connect(server, port);
- if (sock == NULL) {
- g_warning("can't connect to server.");
- session_close(session);
- return -1;
- }
-
- return session_connect_cb(sock, session);
-#endif
-}
-
-static gint session_connect_cb(SockInfo *sock, gpointer data)
-{
- Session *session = SESSION(data);
-
- session->conn_id = 0;
-
- if (!sock) {
- g_warning("can't connect to server.");
- session->state = SESSION_ERROR;
- return -1;
- }
-
- session->sock = sock;
-
-#if USE_SSL
- if (session->ssl_type == SSL_TUNNEL) {
- sock_set_nonblocking_mode(sock, FALSE);
- if (!ssl_init_socket(sock)) {
- g_warning("can't initialize SSL.");
- session->state = SESSION_ERROR;
- return -1;
- }
- }
-#endif
-
- sock_set_nonblocking_mode(sock, session->nonblocking);
-
- debug_print("session (%p): connected\n", session);
-
- session->state = SESSION_RECV;
- session->io_tag = sock_add_watch(session->sock, G_IO_IN,
- session_read_msg_cb,
- session);
-
- return 0;
-}
-
-gint session_disconnect(Session *session)
-{
- session_close(session);
- return 0;
-}
-
-void session_destroy(Session *session)
-{
- g_return_if_fail(session != NULL);
- g_return_if_fail(session->destroy != NULL);
-
- session_close(session);
- session->destroy(session);
- g_free(session->server);
- g_string_free(session->read_msg_buf, TRUE);
- g_byte_array_free(session->read_data_buf, TRUE);
- g_free(session->read_data_terminator);
- g_free(session->write_buf);
-
- debug_print("session (%p): destroyed\n", session);
-
- g_free(session);
-}
-
-gboolean session_is_connected(Session *session)
-{
- return (session->state == SESSION_READY ||
- session->state == SESSION_SEND ||
- session->state == SESSION_RECV);
-}
-
-void session_set_access_time(Session *session)
-{
- session->last_access_time = time(NULL);
-}
-
-void session_set_timeout(Session *session, guint interval)
-{
- if (session->timeout_tag > 0)
- g_source_remove(session->timeout_tag);
-
- session->timeout_interval = interval;
- if (interval > 0)
- session->timeout_tag =
- g_timeout_add(interval, session_timeout_cb, session);
- else
- session->timeout_tag = 0;
-}
-
-static gboolean session_timeout_cb(gpointer data)
-{
- Session *session = SESSION(data);
-
- g_warning("session timeout.\n");
-
- if (session->io_tag > 0) {
- g_source_remove(session->io_tag);
- session->io_tag = 0;
- }
-
- session->timeout_tag = 0;
- session->state = SESSION_TIMEOUT;
-
- return FALSE;
-}
-
-void session_set_recv_message_notify(Session *session,
- RecvMsgNotify notify_func, gpointer data)
-{
- session->recv_msg_notify = notify_func;
- session->recv_msg_notify_data = data;
-}
-
-void session_set_recv_data_progressive_notify
- (Session *session,
- RecvDataProgressiveNotify notify_func,
- gpointer data)
-{
- session->recv_data_progressive_notify = notify_func,
- session->recv_data_progressive_notify_data = data;
-}
-
-void session_set_recv_data_notify(Session *session, RecvDataNotify notify_func,
- gpointer data)
-{
- session->recv_data_notify = notify_func;
- session->recv_data_notify_data = data;
-}
-
-void session_set_send_data_progressive_notify
- (Session *session,
- SendDataProgressiveNotify notify_func,
- gpointer data)
-{
- session->send_data_progressive_notify = notify_func;
- session->send_data_progressive_notify_data = data;
-}
-
-void session_set_send_data_notify(Session *session, SendDataNotify notify_func,
- gpointer data)
-{
- session->send_data_notify = notify_func;
- session->send_data_notify_data = data;
-}
-
-static gint session_close(Session *session)
-{
- g_return_val_if_fail(session != NULL, -1);
-
-#ifdef G_OS_UNIX
- if (session->conn_id > 0) {
- sock_connect_async_cancel(session->conn_id);
- session->conn_id = 0;
- debug_print("session (%p): connection cancelled\n", session);
- }
-#endif
-
- session_set_timeout(session, 0);
-
- if (session->io_tag > 0) {
- g_source_remove(session->io_tag);
- session->io_tag = 0;
- }
-
- if (session->sock) {
- sock_close(session->sock);
- session->sock = NULL;
- session->state = SESSION_DISCONNECTED;
- debug_print("session (%p): closed\n", session);
- }
-
- return 0;
-}
-
-#if USE_SSL
-gint session_start_tls(Session *session)
-{
- gboolean nb_mode;
-
- nb_mode = sock_is_nonblocking_mode(session->sock);
-
- if (nb_mode)
- sock_set_nonblocking_mode(session->sock, FALSE);
-
- if (!ssl_init_socket_with_method(session->sock, SSL_METHOD_TLSv1)) {
- g_warning("can't start TLS session.\n");
- if (nb_mode)
- sock_set_nonblocking_mode(session->sock, TRUE);
- return -1;
- }
-
- if (nb_mode)
- sock_set_nonblocking_mode(session->sock, session->nonblocking);
-
- return 0;
-}
-#endif
-
-gint session_send_msg(Session *session, SessionMsgType type, const gchar *msg)
-{
- gboolean ret;
-
- g_return_val_if_fail(session->write_buf == NULL, -1);
- g_return_val_if_fail(msg != NULL, -1);
- g_return_val_if_fail(msg[0] != '\0', -1);
-
- session->state = SESSION_SEND;
- session->write_buf = g_strconcat(msg, "\r\n", NULL);
- session->write_buf_p = session->write_buf;
- session->write_buf_len = strlen(msg) + 2;
-
- ret = session_write_msg_cb(session->sock, G_IO_OUT, session);
-
- if (ret == TRUE)
- session->io_tag = sock_add_watch(session->sock, G_IO_OUT,
- session_write_msg_cb, session);
- else if (session->state == SESSION_ERROR)
- return -1;
-
- return 0;
-}
-
-gint session_recv_msg(Session *session)
-{
- g_return_val_if_fail(session->read_msg_buf->len == 0, -1);
-
- session->state = SESSION_RECV;
-
- if (session->read_buf_len > 0)
- g_idle_add(session_recv_msg_idle_cb, session);
- else
- session->io_tag = sock_add_watch(session->sock, G_IO_IN,
- session_read_msg_cb, session);
-
- return 0;
-}
-
-static gboolean session_recv_msg_idle_cb(gpointer data)
-{
- Session *session = SESSION(data);
- gboolean ret;
-
- ret = session_read_msg_cb(session->sock, G_IO_IN, session);
-
- if (ret == TRUE)
- session->io_tag = sock_add_watch(session->sock, G_IO_IN,
- session_read_msg_cb, session);
-
- return FALSE;
-}
-
-gint session_send_data(Session *session, const guchar *data, guint size)
-{
- gboolean ret;
-
- g_return_val_if_fail(session->write_data == NULL, -1);
- g_return_val_if_fail(data != NULL, -1);
- g_return_val_if_fail(size != 0, -1);
-
- session->state = SESSION_SEND;
-
- session->write_data = data;
- session->write_data_p = session->write_data;
- session->write_data_len = size;
- g_get_current_time(&session->tv_prev);
-
- ret = session_write_data_cb(session->sock, G_IO_OUT, session);
-
- if (ret == TRUE)
- session->io_tag = sock_add_watch(session->sock, G_IO_OUT,
- session_write_data_cb,
- session);
- else if (session->state == SESSION_ERROR)
- return -1;
-
- return 0;
-}
-
-gint session_recv_data(Session *session, guint size, const gchar *terminator)
-{
- g_return_val_if_fail(session->read_data_buf->len == 0, -1);
-
- session->state = SESSION_RECV;
-
- g_free(session->read_data_terminator);
- session->read_data_terminator = g_strdup(terminator);
- g_get_current_time(&session->tv_prev);
-
- if (session->read_buf_len > 0)
- g_idle_add(session_recv_data_idle_cb, session);
- else
- session->io_tag = sock_add_watch(session->sock, G_IO_IN,
- session_read_data_cb, session);
-
- return 0;
-}
-
-static gboolean session_recv_data_idle_cb(gpointer data)
-{
- Session *session = SESSION(data);
- gboolean ret;
-
- ret = session_read_data_cb(session->sock, G_IO_IN, session);
-
- if (ret == TRUE)
- session->io_tag = sock_add_watch(session->sock, G_IO_IN,
- session_read_data_cb, session);
-
- return FALSE;
-}
-
-static gboolean session_read_msg_cb(SockInfo *source, GIOCondition condition,
- gpointer data)
-{
- Session *session = SESSION(data);
- gchar buf[SESSION_BUFFSIZE];
- gint line_len;
- gchar *newline;
- gchar *msg;
- gint ret;
-
- g_return_val_if_fail(condition == G_IO_IN, FALSE);
-
- session_set_timeout(session, session->timeout_interval);
-
- if (session->read_buf_len == 0) {
- gint read_len;
-
- read_len = sock_read(session->sock, session->read_buf,
- SESSION_BUFFSIZE - 1);
-
- if (read_len == 0) {
- g_warning("sock_read: received EOF\n");
- session->state = SESSION_EOF;
- return FALSE;
- }
-
- if (read_len < 0) {
- switch (errno) {
- case EAGAIN:
- return TRUE;
- default:
- g_warning("sock_read: %s\n", g_strerror(errno));
- session->state = SESSION_ERROR;
- return FALSE;
- }
- }
-
- session->read_buf_len = read_len;
- }
-
- if ((newline = memchr(session->read_buf_p, '\n', session->read_buf_len))
- != NULL)
- line_len = newline - session->read_buf_p + 1;
- else
- line_len = session->read_buf_len;
-
- if (line_len == 0)
- return TRUE;
-
- memcpy(buf, session->read_buf_p, line_len);
- buf[line_len] = '\0';
-
- g_string_append(session->read_msg_buf, buf);
-
- session->read_buf_len -= line_len;
- if (session->read_buf_len == 0)
- session->read_buf_p = session->read_buf;
- else
- session->read_buf_p += line_len;
-
- /* incomplete read */
- if (buf[line_len - 1] != '\n')
- return TRUE;
-
- /* complete */
- if (session->io_tag > 0) {
- g_source_remove(session->io_tag);
- session->io_tag = 0;
- }
-
- /* callback */
- msg = g_strdup(session->read_msg_buf->str);
- strretchomp(msg);
- g_string_truncate(session->read_msg_buf, 0);
-
- ret = session->recv_msg(session, msg);
- session->recv_msg_notify(session, msg, session->recv_msg_notify_data);
-
- g_free(msg);
-
- if (ret < 0)
- session->state = SESSION_ERROR;
-
- return FALSE;
-}
-
-static gboolean session_read_data_cb(SockInfo *source, GIOCondition condition,
- gpointer data)
-{
- Session *session = SESSION(data);
- GByteArray *data_buf;
- gint terminator_len;
- gboolean complete = FALSE;
- guint data_len;
- gint ret;
-
- g_return_val_if_fail(condition == G_IO_IN, FALSE);
-
- session_set_timeout(session, session->timeout_interval);
-
- if (session->read_buf_len == 0) {
- gint read_len;
-
- read_len = sock_read(session->sock, session->read_buf,
- SESSION_BUFFSIZE);
-
- if (read_len == 0) {
- g_warning("sock_read: received EOF\n");
- session->state = SESSION_EOF;
- return FALSE;
- }
-
- if (read_len < 0) {
- switch (errno) {
- case EAGAIN:
- return TRUE;
- default:
- g_warning("sock_read: %s\n", g_strerror(errno));
- session->state = SESSION_ERROR;
- return FALSE;
- }
- }
-
- session->read_buf_len = read_len;
- }
-
- data_buf = session->read_data_buf;
- terminator_len = strlen(session->read_data_terminator);
-
- if (session->read_buf_len == 0)
- return TRUE;
-
- g_byte_array_append(data_buf, session->read_buf_p,
- session->read_buf_len);
-
- session->read_buf_len = 0;
- session->read_buf_p = session->read_buf;
-
- /* check if data is terminated */
- if (data_buf->len >= terminator_len) {
- if (memcmp(data_buf->data, session->read_data_terminator,
- terminator_len) == 0)
- complete = TRUE;
- else if (data_buf->len >= terminator_len + 2 &&
- memcmp(data_buf->data + data_buf->len -
- (terminator_len + 2), "\r\n", 2) == 0 &&
- memcmp(data_buf->data + data_buf->len -
- terminator_len, session->read_data_terminator,
- terminator_len) == 0)
- complete = TRUE;
- }
-
- /* incomplete read */
- if (!complete) {
- GTimeVal tv_cur;
-
- g_get_current_time(&tv_cur);
- if (tv_cur.tv_sec - session->tv_prev.tv_sec > 0 ||
- tv_cur.tv_usec - session->tv_prev.tv_usec >
- UI_REFRESH_INTERVAL) {
- session->recv_data_progressive_notify
- (session, data_buf->len, 0,
- session->recv_data_progressive_notify_data);
- g_get_current_time(&session->tv_prev);
- }
- return TRUE;
- }
-
- /* complete */
- if (session->io_tag > 0) {
- g_source_remove(session->io_tag);
- session->io_tag = 0;
- }
-
- data_len = data_buf->len - terminator_len;
-
- /* callback */
- ret = session->recv_data_finished(session, (gchar *)data_buf->data,
- data_len);
-
- g_byte_array_set_size(data_buf, 0);
-
- session->recv_data_notify(session, data_len,
- session->recv_data_notify_data);
-
- if (ret < 0)
- session->state = SESSION_ERROR;
-
- return FALSE;
-}
-
-static gint session_write_buf(Session *session)
-{
- gint write_len;
- gint to_write_len;
-
- g_return_val_if_fail(session->write_buf != NULL, -1);
- g_return_val_if_fail(session->write_buf_p != NULL, -1);
- g_return_val_if_fail(session->write_buf_len > 0, -1);
-
- to_write_len = session->write_buf_len -
- (session->write_buf_p - session->write_buf);
- to_write_len = MIN(to_write_len, SESSION_BUFFSIZE);
-
- write_len = sock_write(session->sock, session->write_buf_p,
- to_write_len);
-
- if (write_len < 0) {
- switch (errno) {
- case EAGAIN:
- write_len = 0;
- break;
- default:
- g_warning("sock_write: %s\n", g_strerror(errno));
- session->state = SESSION_ERROR;
- return -1;
- }
- }
-
- /* incomplete write */
- if (session->write_buf_p - session->write_buf + write_len <
- session->write_buf_len) {
- session->write_buf_p += write_len;
- return 1;
- }
-
- g_free(session->write_buf);
- session->write_buf = NULL;
- session->write_buf_p = NULL;
- session->write_buf_len = 0;
-
- return 0;
-}
-
-static gint session_write_data(Session *session)
-{
- gint write_len;
- gint to_write_len;
-
- g_return_val_if_fail(session->write_data != NULL, -1);
- g_return_val_if_fail(session->write_data_p != NULL, -1);
- g_return_val_if_fail(session->write_data_len > 0, -1);
-
- to_write_len = session->write_data_len -
- (session->write_data_p - session->write_data);
- to_write_len = MIN(to_write_len, SESSION_BUFFSIZE);
-
- write_len = sock_write(session->sock, session->write_data_p,
- to_write_len);
-
- if (write_len < 0) {
- switch (errno) {
- case EAGAIN:
- write_len = 0;
- break;
- default:
- g_warning("sock_write: %s\n", g_strerror(errno));
- session->state = SESSION_ERROR;
- return -1;
- }
- }
-
- /* incomplete write */
- if (session->write_data_p - session->write_data + write_len <
- session->write_data_len) {
- session->write_data_p += write_len;
- return 1;
- }
-
- session->write_data = NULL;
- session->write_data_p = NULL;
- session->write_data_len = 0;
-
- return 0;
-}
-
-static gboolean session_write_msg_cb(SockInfo *source, GIOCondition condition,
- gpointer data)
-{
- Session *session = SESSION(data);
- gint ret;
-
- g_return_val_if_fail(condition == G_IO_OUT, FALSE);
- g_return_val_if_fail(session->write_buf != NULL, FALSE);
- g_return_val_if_fail(session->write_buf_p != NULL, FALSE);
- g_return_val_if_fail(session->write_buf_len > 0, FALSE);
-
- ret = session_write_buf(session);
-
- if (ret < 0) {
- session->state = SESSION_ERROR;
- return FALSE;
- } else if (ret > 0)
- return TRUE;
-
- if (session->io_tag > 0) {
- g_source_remove(session->io_tag);
- session->io_tag = 0;
- }
-
- session_recv_msg(session);
-
- return FALSE;
-}
-
-static gboolean session_write_data_cb(SockInfo *source,
- GIOCondition condition, gpointer data)
-{
- Session *session = SESSION(data);
- guint write_data_len;
- gint ret;
-
- g_return_val_if_fail(condition == G_IO_OUT, FALSE);
- g_return_val_if_fail(session->write_data != NULL, FALSE);
- g_return_val_if_fail(session->write_data_p != NULL, FALSE);
- g_return_val_if_fail(session->write_data_len > 0, FALSE);
-
- write_data_len = session->write_data_len;
-
- ret = session_write_data(session);
-
- if (ret < 0) {
- session->state = SESSION_ERROR;
- return FALSE;
- } else if (ret > 0) {
- GTimeVal tv_cur;
-
- g_get_current_time(&tv_cur);
- if (tv_cur.tv_sec - session->tv_prev.tv_sec > 0 ||
- tv_cur.tv_usec - session->tv_prev.tv_usec >
- UI_REFRESH_INTERVAL) {
- session_set_timeout(session, session->timeout_interval);
- session->send_data_progressive_notify
- (session,
- session->write_data_p - session->write_data,
- write_data_len,
- session->send_data_progressive_notify_data);
- g_get_current_time(&session->tv_prev);
- }
- return TRUE;
- }
-
- if (session->io_tag > 0) {
- g_source_remove(session->io_tag);
- session->io_tag = 0;
- }
-
- /* callback */
- ret = session->send_data_finished(session, write_data_len);
- session->send_data_notify(session, write_data_len,
- session->send_data_notify_data);
-
- return FALSE;
-}
diff --git a/src/session.h b/src/session.h
deleted file mode 100644
index 9ed0eaf4..00000000
--- a/src/session.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __SESSION_H__
-#define __SESSION_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-
-#include <time.h>
-#include <unistd.h>
-
-#include "socket.h"
-
-#define SESSION_BUFFSIZE 4096
-
-typedef struct _Session Session;
-
-#define SESSION(obj) ((Session *)obj)
-
-typedef enum {
- SESSION_UNKNOWN,
- SESSION_IMAP,
- SESSION_NEWS,
- SESSION_SMTP,
- SESSION_POP3
-} SessionType;
-
-typedef enum {
- SESSION_READY,
- SESSION_SEND,
- SESSION_RECV,
- SESSION_EOF,
- SESSION_TIMEOUT,
- SESSION_ERROR,
- SESSION_DISCONNECTED
-} SessionState;
-
-typedef enum
-{
- SESSION_MSG_NORMAL,
- SESSION_MSG_SEND_DATA,
- SESSION_MSG_RECV_DATA,
- SESSION_MSG_CONTROL,
- SESSION_MSG_ERROR,
- SESSION_MSG_UNKNOWN
-} SessionMsgType;
-
-typedef gint (*RecvMsgNotify) (Session *session,
- const gchar *msg,
- gpointer user_data);
-typedef gint (*RecvDataProgressiveNotify) (Session *session,
- guint cur_len,
- guint total_len,
- gpointer user_data);
-typedef gint (*RecvDataNotify) (Session *session,
- guint len,
- gpointer user_data);
-typedef gint (*SendDataProgressiveNotify) (Session *session,
- guint cur_len,
- guint total_len,
- gpointer user_data);
-typedef gint (*SendDataNotify) (Session *session,
- guint len,
- gpointer user_data);
-
-struct _Session
-{
- SessionType type;
-
- SockInfo *sock;
-
- gchar *server;
- gushort port;
-
-#if USE_SSL
- SSLType ssl_type;
-#endif
-
- gboolean nonblocking;
-
- SessionState state;
-
- time_t last_access_time;
- GTimeVal tv_prev;
-
- gint conn_id;
-
- gint io_tag;
-
- gchar read_buf[SESSION_BUFFSIZE];
- gchar *read_buf_p;
- gint read_buf_len;
-
- GString *read_msg_buf;
- GByteArray *read_data_buf;
- gchar *read_data_terminator;
-
- /* buffer for short messages */
- gchar *write_buf;
- gchar *write_buf_p;
- gint write_buf_len;
-
- /* buffer for large data */
- const guchar *write_data;
- const guchar *write_data_p;
- gint write_data_len;
-
- guint timeout_tag;
- guint timeout_interval;
-
- gpointer data;
-
- /* virtual methods to parse server responses */
- gint (*recv_msg) (Session *session,
- const gchar *msg);
-
- gint (*send_data_finished) (Session *session,
- guint len);
- gint (*recv_data_finished) (Session *session,
- guchar *data,
- guint len);
-
- void (*destroy) (Session *session);
-
- /* notification functions */
- RecvMsgNotify recv_msg_notify;
- RecvDataProgressiveNotify recv_data_progressive_notify;
- RecvDataNotify recv_data_notify;
- SendDataProgressiveNotify send_data_progressive_notify;
- SendDataNotify send_data_notify;
-
- gpointer recv_msg_notify_data;
- gpointer recv_data_progressive_notify_data;
- gpointer recv_data_notify_data;
- gpointer send_data_progressive_notify_data;
- gpointer send_data_notify_data;
-};
-
-void session_init (Session *session);
-gint session_connect (Session *session,
- const gchar *server,
- gushort port);
-gint session_disconnect (Session *session);
-void session_destroy (Session *session);
-gboolean session_is_connected (Session *session);
-
-void session_set_access_time (Session *session);
-
-void session_set_timeout (Session *session,
- guint interval);
-
-void session_set_recv_message_notify (Session *session,
- RecvMsgNotify notify_func,
- gpointer data);
-void session_set_recv_data_progressive_notify
- (Session *session,
- RecvDataProgressiveNotify notify_func,
- gpointer data);
-void session_set_recv_data_notify (Session *session,
- RecvDataNotify notify_func,
- gpointer data);
-void session_set_send_data_progressive_notify
- (Session *session,
- SendDataProgressiveNotify notify_func,
- gpointer data);
-void session_set_send_data_notify (Session *session,
- SendDataNotify notify_func,
- gpointer data);
-
-#if USE_SSL
-gint session_start_tls (Session *session);
-#endif
-
-gint session_send_msg (Session *session,
- SessionMsgType type,
- const gchar *msg);
-gint session_recv_msg (Session *session);
-gint session_send_data (Session *session,
- const guchar *data,
- guint size);
-gint session_recv_data (Session *session,
- guint size,
- const gchar *terminator);
-
-#endif /* __SESSION_H__ */
diff --git a/src/socket.c b/src/socket.c
deleted file mode 100644
index 17063ab1..00000000
--- a/src/socket.c
+++ /dev/null
@@ -1,1397 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#ifdef G_OS_WIN32
-# include <winsock2.h>
-#else
-# if HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-# endif
-# include <sys/socket.h>
-# include <sys/un.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# include <netdb.h>
-#endif /* G_OS_WIN32 */
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <setjmp.h>
-#if HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-
-#include "socket.h"
-#if USE_SSL
-# include "ssl.h"
-#endif
-
-#define BUFFSIZE 8192
-
-typedef gint (*SockAddrFunc) (GList *addr_list,
- gpointer data);
-
-typedef struct _SockConnectData SockConnectData;
-typedef struct _SockLookupData SockLookupData;
-typedef struct _SockAddrData SockAddrData;
-typedef struct _SockSource SockSource;
-
-struct _SockConnectData {
- gint id;
- gchar *hostname;
- gushort port;
- GList *addr_list;
- GList *cur_addr;
- SockLookupData *lookup_data;
- GIOChannel *channel;
- guint io_tag;
- SockConnectFunc func;
- gpointer data;
-};
-
-struct _SockLookupData {
- gchar *hostname;
- pid_t child_pid;
- GIOChannel *channel;
- guint io_tag;
- SockAddrFunc func;
- gpointer data;
-};
-
-struct _SockAddrData {
- gint family;
- gint socktype;
- gint protocol;
- gint addr_len;
- struct sockaddr *addr;
-};
-
-struct _SockSource {
- GSource parent;
- SockInfo *sock;
-};
-
-static guint io_timeout = 60;
-
-static GList *sock_connect_data_list = NULL;
-
-static gboolean sock_prepare (GSource *source,
- gint *timeout);
-static gboolean sock_check (GSource *source);
-static gboolean sock_dispatch (GSource *source,
- GSourceFunc callback,
- gpointer user_data);
-
-GSourceFuncs sock_watch_funcs = {
- sock_prepare,
- sock_check,
- sock_dispatch,
- NULL
-};
-
-static gint sock_connect_with_timeout (gint sock,
- const struct sockaddr *serv_addr,
- gint addrlen,
- guint timeout_secs);
-
-#ifndef INET6
-static gint sock_connect_by_hostname (gint sock,
- const gchar *hostname,
- gushort port);
-#else
-static gint sock_connect_by_getaddrinfo (const gchar *hostname,
- gushort port);
-#endif
-
-#ifdef G_OS_UNIX
-static void sock_address_list_free (GList *addr_list);
-
-static gboolean sock_connect_async_cb (GIOChannel *source,
- GIOCondition condition,
- gpointer data);
-static gint sock_connect_async_get_address_info_cb
- (GList *addr_list,
- gpointer data);
-
-static gint sock_connect_address_list_async (SockConnectData *conn_data);
-
-static gboolean sock_get_address_info_async_cb (GIOChannel *source,
- GIOCondition condition,
- gpointer data);
-static SockLookupData *sock_get_address_info_async
- (const gchar *hostname,
- gushort port,
- SockAddrFunc func,
- gpointer data);
-static gint sock_get_address_info_async_cancel (SockLookupData *lookup_data);
-#endif /* G_OS_UNIX */
-
-
-gint sock_init(void)
-{
-#ifdef G_OS_WIN32
- WSADATA wsadata;
- gint result;
-
- result = WSAStartup(MAKEWORD(2, 2), &wsadata);
- if (result != NO_ERROR) {
- g_warning("WSAStartup() failed\n");
- return -1;
- }
-#endif
- return 0;
-}
-
-gint sock_cleanup(void)
-{
-#ifdef G_OS_WIN32
- WSACleanup();
-#endif
- return 0;
-}
-
-gint sock_set_io_timeout(guint sec)
-{
- io_timeout = sec;
- return 0;
-}
-
-gint fd_connect_unix(const gchar *path)
-{
-#ifdef G_OS_UNIX
- gint sock;
- struct sockaddr_un addr;
-
- sock = socket(PF_UNIX, SOCK_STREAM, 0);
- if (sock < 0) {
- perror("sock_connect_unix(): socket");
- return -1;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
-
- if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- fd_close(sock);
- return -1;
- }
-
- return sock;
-#else
- return -1;
-#endif
-}
-
-gint fd_open_unix(const gchar *path)
-{
-#ifdef G_OS_UNIX
- gint sock;
- struct sockaddr_un addr;
-
- sock = socket(PF_UNIX, SOCK_STREAM, 0);
-
- if (sock < 0) {
- perror("sock_open_unix(): socket");
- return -1;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
-
- if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- perror("bind");
- fd_close(sock);
- return -1;
- }
-
- if (listen(sock, 1) < 0) {
- perror("listen");
- fd_close(sock);
- return -1;
- }
-
- return sock;
-#else
- return -1;
-#endif
-}
-
-gint fd_accept(gint sock)
-{
-#ifdef G_OS_UNIX
- struct sockaddr_in caddr;
- guint caddr_len;
-
- caddr_len = sizeof(caddr);
- return accept(sock, (struct sockaddr *)&caddr, &caddr_len);
-#else
- return -1;
-#endif
-}
-
-
-static gint set_nonblocking_mode(gint fd, gboolean nonblock)
-{
-#ifdef G_OS_UNIX
- gint flags;
-
- flags = fcntl(fd, F_GETFL, 0);
- if (flags < 0) {
- perror("fcntl");
- return -1;
- }
-
- if (nonblock)
- flags |= O_NONBLOCK;
- else
- flags &= ~O_NONBLOCK;
-
- return fcntl(fd, F_SETFL, flags);
-#else
- return -1;
-#endif
-}
-
-gint sock_set_nonblocking_mode(SockInfo *sock, gboolean nonblock)
-{
- g_return_val_if_fail(sock != NULL, -1);
-
- return set_nonblocking_mode(sock->sock, nonblock);
-}
-
-static gboolean is_nonblocking_mode(gint fd)
-{
-#ifdef G_OS_UNIX
- gint flags;
-
- flags = fcntl(fd, F_GETFL, 0);
- if (flags < 0) {
- perror("fcntl");
- return FALSE;
- }
-
- return ((flags & O_NONBLOCK) != 0);
-#else
- return FALSE;
-#endif
-}
-
-gboolean sock_is_nonblocking_mode(SockInfo *sock)
-{
- g_return_val_if_fail(sock != NULL, FALSE);
-
- return is_nonblocking_mode(sock->sock);
-}
-
-
-static gboolean sock_prepare(GSource *source, gint *timeout)
-{
- *timeout = 1;
- return FALSE;
-}
-
-static gboolean sock_check(GSource *source)
-{
- SockInfo *sock = ((SockSource *)source)->sock;
- struct timeval timeout = {0, 0};
- fd_set fds;
- GIOCondition condition = sock->condition;
-
-#if USE_SSL
- if (sock->ssl) {
- if (condition & G_IO_IN) {
- if (SSL_pending(sock->ssl) > 0)
- return TRUE;
- if (SSL_want_write(sock->ssl))
- condition |= G_IO_OUT;
- }
-
- if (condition & G_IO_OUT) {
- if (SSL_want_read(sock->ssl))
- condition |= G_IO_IN;
- }
- }
-#endif
-
- FD_ZERO(&fds);
- FD_SET(sock->sock, &fds);
-
- select(sock->sock + 1,
- (condition & G_IO_IN) ? &fds : NULL,
- (condition & G_IO_OUT) ? &fds : NULL,
- NULL, &timeout);
-
- return FD_ISSET(sock->sock, &fds) != 0;
-}
-
-static gboolean sock_dispatch(GSource *source, GSourceFunc callback,
- gpointer user_data)
-{
- SockInfo *sock = ((SockSource *)source)->sock;
-
- return sock->callback(sock, sock->condition, sock->data);
-}
-
-static gboolean sock_watch_cb(GIOChannel *source, GIOCondition condition,
- gpointer data)
-{
- SockInfo *sock = (SockInfo *)data;
-
- if ((condition & sock->condition) == 0)
- return TRUE;
-
- return sock->callback(sock, sock->condition, sock->data);
-}
-
-guint sock_add_watch(SockInfo *sock, GIOCondition condition, SockFunc func,
- gpointer data)
-{
- sock->callback = func;
- sock->condition = condition;
- sock->data = data;
-
-#if USE_SSL
- if (sock->ssl) {
- GSource *source;
-
- source = g_source_new(&sock_watch_funcs, sizeof(SockSource));
- ((SockSource *)source)->sock = sock;
- g_source_set_priority(source, G_PRIORITY_DEFAULT);
- g_source_set_can_recurse(source, FALSE);
- return g_source_attach(source, NULL);
- }
-#endif
-
- return g_io_add_watch(sock->sock_ch, condition, sock_watch_cb, sock);
-}
-
-static gint fd_check_io(gint fd, GIOCondition cond)
-{
- struct timeval timeout;
- fd_set fds;
-
- if (is_nonblocking_mode(fd))
- return 0;
-
- timeout.tv_sec = io_timeout;
- timeout.tv_usec = 0;
-
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
-
- if (cond == G_IO_IN) {
- select(fd + 1, &fds, NULL, NULL,
- io_timeout > 0 ? &timeout : NULL);
- } else {
- select(fd + 1, NULL, &fds, NULL,
- io_timeout > 0 ? &timeout : NULL);
- }
-
- if (FD_ISSET(fd, &fds)) {
- return 0;
- } else {
- g_warning("Socket IO timeout\n");
- return -1;
- }
-}
-
-#ifdef G_OS_UNIX
-static sigjmp_buf jmpenv;
-
-static void timeout_handler(gint sig)
-{
- siglongjmp(jmpenv, 1);
-}
-#endif
-
-static gint sock_connect_with_timeout(gint sock,
- const struct sockaddr *serv_addr,
- gint addrlen,
- guint timeout_secs)
-{
- gint ret;
-#ifdef G_OS_UNIX
- void (*prev_handler)(gint);
-
- alarm(0);
- prev_handler = signal(SIGALRM, timeout_handler);
- if (sigsetjmp(jmpenv, 1)) {
- alarm(0);
- signal(SIGALRM, prev_handler);
- errno = ETIMEDOUT;
- return -1;
- }
- alarm(timeout_secs);
-#endif
-
- ret = connect(sock, serv_addr, addrlen);
-
-#ifdef G_OS_UNIX
- alarm(0);
- signal(SIGALRM, prev_handler);
-#endif
-
- return ret;
-}
-
-struct hostent *my_gethostbyname(const gchar *hostname)
-{
- struct hostent *hp;
-#ifdef G_OS_UNIX
- void (*prev_handler)(gint);
-
- alarm(0);
- prev_handler = signal(SIGALRM, timeout_handler);
- if (sigsetjmp(jmpenv, 1)) {
- alarm(0);
- signal(SIGALRM, prev_handler);
- fprintf(stderr, "%s: host lookup timed out.\n", hostname);
- errno = 0;
- return NULL;
- }
- alarm(io_timeout);
-#endif
-
- if ((hp = gethostbyname(hostname)) == NULL) {
-#ifdef G_OS_UNIX
- alarm(0);
- signal(SIGALRM, prev_handler);
-#endif
- fprintf(stderr, "%s: unknown host.\n", hostname);
- errno = 0;
- return NULL;
- }
-
-#ifdef G_OS_UNIX
- alarm(0);
- signal(SIGALRM, prev_handler);
-#endif
-
- return hp;
-}
-
-#ifndef INET6
-static gint my_inet_aton(const gchar *hostname, struct in_addr *inp)
-{
-#if HAVE_INET_ATON
- return inet_aton(hostname, inp);
-#else
-#if HAVE_INET_ADDR
- guint32 inaddr;
-
- inaddr = inet_addr(hostname);
- if (inaddr != -1) {
- memcpy(inp, &inaddr, sizeof(inaddr));
- return 1;
- } else
- return 0;
-#else
- return 0;
-#endif
-#endif /* HAVE_INET_ATON */
-}
-
-static gint sock_connect_by_hostname(gint sock, const gchar *hostname,
- gushort port)
-{
- struct hostent *hp;
- struct sockaddr_in ad;
-
- memset(&ad, 0, sizeof(ad));
- ad.sin_family = AF_INET;
- ad.sin_port = htons(port);
-
- if (!my_inet_aton(hostname, &ad.sin_addr)) {
- if ((hp = my_gethostbyname(hostname)) == NULL) {
- fprintf(stderr, "%s: unknown host.\n", hostname);
- errno = 0;
- return -1;
- }
-
- if (hp->h_length != 4 && hp->h_length != 8) {
- fprintf(stderr, "illegal address length received for host %s\n", hostname);
- errno = 0;
- return -1;
- }
-
- memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
- }
-
- return sock_connect_with_timeout(sock, (struct sockaddr *)&ad,
- sizeof(ad), io_timeout);
-}
-
-#else /* INET6 */
-static gint sock_connect_by_getaddrinfo(const gchar *hostname, gushort port)
-{
- gint sock = -1, gai_error;
- struct addrinfo hints, *res, *ai;
- gchar port_str[6];
-
- memset(&hints, 0, sizeof(hints));
- /* hints.ai_flags = AI_CANONNAME; */
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
-
- /* convert port from integer to string. */
- g_snprintf(port_str, sizeof(port_str), "%d", port);
-
- if ((gai_error = getaddrinfo(hostname, port_str, &hints, &res)) != 0) {
- fprintf(stderr, "getaddrinfo for %s:%s failed: %s\n",
- hostname, port_str, gai_strerror(gai_error));
- return -1;
- }
-
- for (ai = res; ai != NULL; ai = ai->ai_next) {
- sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (sock < 0)
- continue;
-
- if (sock_connect_with_timeout
- (sock, ai->ai_addr, ai->ai_addrlen, io_timeout) == 0)
- break;
-
- fd_close(sock);
- }
-
- if (res != NULL)
- freeaddrinfo(res);
-
- if (ai == NULL)
- return -1;
-
- return sock;
-}
-#endif /* !INET6 */
-
-SockInfo *sock_connect(const gchar *hostname, gushort port)
-{
-#ifdef G_OS_WIN32
- SOCKET sock;
-#else
- gint sock;
-#endif
- SockInfo *sockinfo;
-
-#ifdef INET6
- if ((sock = sock_connect_by_getaddrinfo(hostname, port)) < 0)
- return NULL;
-#else
-#ifdef G_OS_WIN32
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
- g_warning("socket() failed: %ld\n", WSAGetLastError());
-#else
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("socket");
-#endif /* G_OS_WIN32 */
- return NULL;
- }
-
- if (sock_connect_by_hostname(sock, hostname, port) < 0) {
- if (errno != 0) perror("connect");
- fd_close(sock);
- return NULL;
- }
-#endif /* INET6 */
-
- sockinfo = g_new0(SockInfo, 1);
- sockinfo->sock = sock;
- sockinfo->sock_ch = g_io_channel_unix_new(sock);
- sockinfo->hostname = g_strdup(hostname);
- sockinfo->port = port;
- sockinfo->state = CONN_ESTABLISHED;
-
- g_usleep(100000);
-
- return sockinfo;
-}
-
-#ifdef G_OS_UNIX
-static void sock_address_list_free(GList *addr_list)
-{
- GList *cur;
-
- for (cur = addr_list; cur != NULL; cur = cur->next) {
- SockAddrData *addr_data = (SockAddrData *)cur->data;
- g_free(addr_data->addr);
- g_free(addr_data);
- }
-
- g_list_free(addr_list);
-}
-
-/* asynchronous TCP connection */
-
-static gboolean sock_connect_async_cb(GIOChannel *source,
- GIOCondition condition, gpointer data)
-{
- SockConnectData *conn_data = (SockConnectData *)data;
- gint fd;
- gint val;
- guint len;
- SockInfo *sockinfo;
-
- fd = g_io_channel_unix_get_fd(source);
-
- conn_data->io_tag = 0;
- conn_data->channel = NULL;
- g_io_channel_unref(source);
-
- len = sizeof(val);
- if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &val, &len) < 0) {
- perror("getsockopt");
- fd_close(fd);
- sock_connect_address_list_async(conn_data);
- return FALSE;
- }
-
- if (val != 0) {
- fd_close(fd);
- sock_connect_address_list_async(conn_data);
- return FALSE;
- }
-
- sockinfo = g_new0(SockInfo, 1);
- sockinfo->sock = fd;
- sockinfo->sock_ch = g_io_channel_unix_new(fd);
- sockinfo->hostname = g_strdup(conn_data->hostname);
- sockinfo->port = conn_data->port;
- sockinfo->state = CONN_ESTABLISHED;
-
- conn_data->func(sockinfo, conn_data->data);
-
- sock_connect_async_cancel(conn_data->id);
-
- return FALSE;
-}
-
-static gint sock_connect_async_get_address_info_cb(GList *addr_list,
- gpointer data)
-{
- SockConnectData *conn_data = (SockConnectData *)data;
-
- conn_data->addr_list = addr_list;
- conn_data->cur_addr = addr_list;
- conn_data->lookup_data = NULL;
-
- return sock_connect_address_list_async(conn_data);
-}
-
-gint sock_connect_async(const gchar *hostname, gushort port,
- SockConnectFunc func, gpointer data)
-{
- static gint id = 1;
- SockConnectData *conn_data;
-
- conn_data = g_new0(SockConnectData, 1);
- conn_data->id = id++;
- conn_data->hostname = g_strdup(hostname);
- conn_data->port = port;
- conn_data->addr_list = NULL;
- conn_data->cur_addr = NULL;
- conn_data->io_tag = 0;
- conn_data->func = func;
- conn_data->data = data;
-
- conn_data->lookup_data = sock_get_address_info_async
- (hostname, port, sock_connect_async_get_address_info_cb,
- conn_data);
-
- if (conn_data->lookup_data == NULL) {
- g_free(conn_data->hostname);
- g_free(conn_data);
- return -1;
- }
-
- sock_connect_data_list = g_list_append(sock_connect_data_list,
- conn_data);
-
- return conn_data->id;
-}
-
-gint sock_connect_async_cancel(gint id)
-{
- SockConnectData *conn_data = NULL;
- GList *cur;
-
- for (cur = sock_connect_data_list; cur != NULL; cur = cur->next) {
- if (((SockConnectData *)cur->data)->id == id) {
- conn_data = (SockConnectData *)cur->data;
- break;
- }
- }
-
- if (conn_data) {
- sock_connect_data_list = g_list_remove(sock_connect_data_list,
- conn_data);
-
- if (conn_data->lookup_data)
- sock_get_address_info_async_cancel
- (conn_data->lookup_data);
-
- if (conn_data->io_tag > 0)
- g_source_remove(conn_data->io_tag);
- if (conn_data->channel) {
- g_io_channel_shutdown(conn_data->channel, FALSE, NULL);
- g_io_channel_unref(conn_data->channel);
- }
-
- sock_address_list_free(conn_data->addr_list);
- g_free(conn_data->hostname);
- g_free(conn_data);
- } else {
- g_warning("sock_connect_async_cancel: id %d not found.\n", id);
- return -1;
- }
-
- return 0;
-}
-
-static gint sock_connect_address_list_async(SockConnectData *conn_data)
-{
- SockAddrData *addr_data;
- gint sock = -1;
-
- for (; conn_data->cur_addr != NULL;
- conn_data->cur_addr = conn_data->cur_addr->next) {
- addr_data = (SockAddrData *)conn_data->cur_addr->data;
-
- if ((sock = socket(addr_data->family, addr_data->socktype,
- addr_data->protocol)) < 0) {
- perror("socket");
- continue;
- }
-
- set_nonblocking_mode(sock, TRUE);
-
- if (connect(sock, addr_data->addr, addr_data->addr_len) < 0) {
- if (EINPROGRESS == errno) {
- break;
- } else {
- perror("connect");
- fd_close(sock);
- }
- } else
- break;
- }
-
- if (conn_data->cur_addr == NULL) {
- g_warning("sock_connect_address_list_async: "
- "connection to %s:%d failed\n",
- conn_data->hostname, conn_data->port);
- conn_data->func(NULL, conn_data->data);
- sock_connect_async_cancel(conn_data->id);
- return -1;
- }
-
- conn_data->cur_addr = conn_data->cur_addr->next;
-
- conn_data->channel = g_io_channel_unix_new(sock);
- conn_data->io_tag = g_io_add_watch(conn_data->channel, G_IO_OUT,
- sock_connect_async_cb, conn_data);
-
- return 0;
-}
-
-/* asynchronous DNS lookup */
-
-static gboolean sock_get_address_info_async_cb(GIOChannel *source,
- GIOCondition condition,
- gpointer data)
-{
- SockLookupData *lookup_data = (SockLookupData *)data;
- GList *addr_list = NULL;
- SockAddrData *addr_data;
- gsize bytes_read;
- gint ai_member[4];
- struct sockaddr *addr;
-
- for (;;) {
- if (g_io_channel_read(source, (gchar *)ai_member,
- sizeof(ai_member), &bytes_read)
- != G_IO_ERROR_NONE) {
- g_warning("sock_get_address_info_async_cb: "
- "address length read error\n");
- break;
- }
-
- if (bytes_read == 0 || bytes_read != sizeof(ai_member))
- break;
-
- if (ai_member[0] == AF_UNSPEC) {
- g_warning("DNS lookup failed\n");
- break;
- }
-
- addr = g_malloc(ai_member[3]);
- if (g_io_channel_read(source, (gchar *)addr, ai_member[3],
- &bytes_read)
- != G_IO_ERROR_NONE) {
- g_warning("sock_get_address_info_async_cb: "
- "address data read error\n");
- g_free(addr);
- break;
- }
-
- if (bytes_read != ai_member[3]) {
- g_warning("sock_get_address_info_async_cb: "
- "incomplete address data\n");
- g_free(addr);
- break;
- }
-
- addr_data = g_new0(SockAddrData, 1);
- addr_data->family = ai_member[0];
- addr_data->socktype = ai_member[1];
- addr_data->protocol = ai_member[2];
- addr_data->addr_len = ai_member[3];
- addr_data->addr = addr;
-
- addr_list = g_list_append(addr_list, addr_data);
- }
-
- g_io_channel_shutdown(source, FALSE, NULL);
- g_io_channel_unref(source);
-
- kill(lookup_data->child_pid, SIGKILL);
- waitpid(lookup_data->child_pid, NULL, 0);
-
- lookup_data->func(addr_list, lookup_data->data);
-
- g_free(lookup_data->hostname);
- g_free(lookup_data);
-
- return FALSE;
-}
-
-static SockLookupData *sock_get_address_info_async(const gchar *hostname,
- gushort port,
- SockAddrFunc func,
- gpointer data)
-{
- SockLookupData *lookup_data = NULL;
- gint pipe_fds[2];
- pid_t pid;
-
- if (pipe(pipe_fds) < 0) {
- perror("pipe");
- func(NULL, data);
- return NULL;
- }
-
- if ((pid = fork()) < 0) {
- perror("fork");
- func(NULL, data);
- return NULL;
- }
-
- /* child process */
- if (pid == 0) {
-#ifdef INET6
- gint gai_err;
- struct addrinfo hints, *res, *ai;
- gchar port_str[6];
-#else /* !INET6 */
- struct hostent *hp;
- gchar **addr_list_p;
- struct sockaddr_in ad;
-#endif /* INET6 */
- gint ai_member[4] = {AF_UNSPEC, 0, 0, 0};
-
- close(pipe_fds[0]);
-
-#ifdef INET6
- memset(&hints, 0, sizeof(hints));
- /* hints.ai_flags = AI_CANONNAME; */
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
-
- g_snprintf(port_str, sizeof(port_str), "%d", port);
-
- gai_err = getaddrinfo(hostname, port_str, &hints, &res);
- if (gai_err != 0) {
- g_warning("getaddrinfo for %s:%s failed: %s\n",
- hostname, port_str, gai_strerror(gai_err));
- fd_write_all(pipe_fds[1], (gchar *)ai_member,
- sizeof(ai_member));
- close(pipe_fds[1]);
- _exit(1);
- }
-
- for (ai = res; ai != NULL; ai = ai->ai_next) {
- ai_member[0] = ai->ai_family;
- ai_member[1] = ai->ai_socktype;
- ai_member[2] = ai->ai_protocol;
- ai_member[3] = ai->ai_addrlen;
-
- fd_write_all(pipe_fds[1], (gchar *)ai_member,
- sizeof(ai_member));
- fd_write_all(pipe_fds[1], (gchar *)ai->ai_addr,
- ai->ai_addrlen);
- }
-
- if (res != NULL)
- freeaddrinfo(res);
-#else /* !INET6 */
- hp = my_gethostbyname(hostname);
- if (hp == NULL || hp->h_addrtype != AF_INET) {
- fd_write_all(pipe_fds[1], (gchar *)ai_member,
- sizeof(ai_member));
- close(pipe_fds[1]);
- _exit(1);
- }
-
- ai_member[0] = AF_INET;
- ai_member[1] = SOCK_STREAM;
- ai_member[2] = IPPROTO_TCP;
- ai_member[3] = sizeof(ad);
-
- memset(&ad, 0, sizeof(ad));
- ad.sin_family = AF_INET;
- ad.sin_port = htons(port);
-
- for (addr_list_p = hp->h_addr_list; *addr_list_p != NULL;
- addr_list_p++) {
- memcpy(&ad.sin_addr, *addr_list_p, hp->h_length);
- fd_write_all(pipe_fds[1], (gchar *)ai_member,
- sizeof(ai_member));
- fd_write_all(pipe_fds[1], (gchar *)&ad, sizeof(ad));
- }
-#endif /* INET6 */
-
- close(pipe_fds[1]);
-
- _exit(0);
- } else {
- close(pipe_fds[1]);
-
- lookup_data = g_new0(SockLookupData, 1);
- lookup_data->hostname = g_strdup(hostname);
- lookup_data->child_pid = pid;
- lookup_data->func = func;
- lookup_data->data = data;
-
- lookup_data->channel = g_io_channel_unix_new(pipe_fds[0]);
- lookup_data->io_tag = g_io_add_watch
- (lookup_data->channel, G_IO_IN,
- sock_get_address_info_async_cb, lookup_data);
- }
-
- return lookup_data;
-}
-
-static gint sock_get_address_info_async_cancel(SockLookupData *lookup_data)
-{
- if (lookup_data->io_tag > 0)
- g_source_remove(lookup_data->io_tag);
- if (lookup_data->channel) {
- g_io_channel_shutdown(lookup_data->channel, FALSE, NULL);
- g_io_channel_unref(lookup_data->channel);
- }
-
- if (lookup_data->child_pid > 0) {
- kill(lookup_data->child_pid, SIGKILL);
- waitpid(lookup_data->child_pid, NULL, 0);
- }
-
- g_free(lookup_data->hostname);
- g_free(lookup_data);
-
- return 0;
-}
-#endif /* G_OS_UNIX */
-
-
-gint sock_printf(SockInfo *sock, const gchar *format, ...)
-{
- va_list args;
- gchar buf[BUFFSIZE];
-
- va_start(args, format);
- g_vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
-
- return sock_write_all(sock, buf, strlen(buf));
-}
-
-gint sock_read(SockInfo *sock, gchar *buf, gint len)
-{
- g_return_val_if_fail(sock != NULL, -1);
-
-#if USE_SSL
- if (sock->ssl)
- return ssl_read(sock->ssl, buf, len);
-#endif
- return fd_read(sock->sock, buf, len);
-}
-
-gint fd_read(gint fd, gchar *buf, gint len)
-{
- if (fd_check_io(fd, G_IO_IN) < 0)
- return -1;
-
-#ifdef G_OS_WIN32
- return recv(fd, buf, len, 0);
-#else
- return read(fd, buf, len);
-#endif
-}
-
-#if USE_SSL
-gint ssl_read(SSL *ssl, gchar *buf, gint len)
-{
- gint err, ret;
-
- if (SSL_pending(ssl) == 0) {
- if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0)
- return -1;
- }
-
- ret = SSL_read(ssl, buf, len);
-
- switch ((err = SSL_get_error(ssl, ret))) {
- case SSL_ERROR_NONE:
- return ret;
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- errno = EAGAIN;
- return -1;
- case SSL_ERROR_ZERO_RETURN:
- return 0;
- default:
- g_warning("SSL_read() returned error %d, ret = %d\n", err, ret);
- if (ret == 0)
- return 0;
- return -1;
- }
-}
-#endif
-
-gint sock_write(SockInfo *sock, const gchar *buf, gint len)
-{
- g_return_val_if_fail(sock != NULL, -1);
-
-#if USE_SSL
- if (sock->ssl)
- return ssl_write(sock->ssl, buf, len);
-#endif
- return fd_write(sock->sock, buf, len);
-}
-
-gint fd_write(gint fd, const gchar *buf, gint len)
-{
- if (fd_check_io(fd, G_IO_OUT) < 0)
- return -1;
-
-#ifdef G_OS_WIN32
- return send(fd, buf, len, 0);
-#else
- return write(fd, buf, len);
-#endif
-}
-
-#if USE_SSL
-gint ssl_write(SSL *ssl, const gchar *buf, gint len)
-{
- gint ret;
-
- ret = SSL_write(ssl, buf, len);
-
- switch (SSL_get_error(ssl, ret)) {
- case SSL_ERROR_NONE:
- return ret;
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- errno = EAGAIN;
- return -1;
- default:
- return -1;
- }
-}
-#endif
-
-gint sock_write_all(SockInfo *sock, const gchar *buf, gint len)
-{
- g_return_val_if_fail(sock != NULL, -1);
-
-#if USE_SSL
- if (sock->ssl)
- return ssl_write_all(sock->ssl, buf, len);
-#endif
- return fd_write_all(sock->sock, buf, len);
-}
-
-gint fd_write_all(gint fd, const gchar *buf, gint len)
-{
- gint n, wrlen = 0;
-
- while (len) {
- n = fd_write(fd, buf, len);
- if (n <= 0)
- return -1;
- len -= n;
- wrlen += n;
- buf += n;
- }
-
- return wrlen;
-}
-
-#if USE_SSL
-gint ssl_write_all(SSL *ssl, const gchar *buf, gint len)
-{
- gint n, wrlen = 0;
-
- while (len) {
- n = ssl_write(ssl, buf, len);
- if (n <= 0)
- return -1;
- len -= n;
- wrlen += n;
- buf += n;
- }
-
- return wrlen;
-}
-#endif
-
-gint fd_recv(gint fd, gchar *buf, gint len, gint flags)
-{
- if (fd_check_io(fd, G_IO_IN) < 0)
- return -1;
-
- return recv(fd, buf, len, flags);
-}
-
-gint fd_gets(gint fd, gchar *buf, gint len)
-{
- gchar *newline, *bp = buf;
- gint n;
-
- if (--len < 1)
- return -1;
- do {
- if ((n = fd_recv(fd, bp, len, MSG_PEEK)) <= 0)
- return -1;
- if ((newline = memchr(bp, '\n', n)) != NULL)
- n = newline - bp + 1;
- if ((n = fd_read(fd, bp, n)) < 0)
- return -1;
- bp += n;
- len -= n;
- } while (!newline && len);
-
- *bp = '\0';
- return bp - buf;
-}
-
-#if USE_SSL
-gint ssl_gets(SSL *ssl, gchar *buf, gint len)
-{
- gchar *newline, *bp = buf;
- gint n;
-
- if (--len < 1)
- return -1;
- do {
- if ((n = ssl_peek(ssl, bp, len)) <= 0)
- return -1;
- if ((newline = memchr(bp, '\n', n)) != NULL)
- n = newline - bp + 1;
- if ((n = ssl_read(ssl, bp, n)) < 0)
- return -1;
- bp += n;
- len -= n;
- } while (!newline && len);
-
- *bp = '\0';
- return bp - buf;
-}
-#endif
-
-gint sock_gets(SockInfo *sock, gchar *buf, gint len)
-{
- g_return_val_if_fail(sock != NULL, -1);
-
-#if USE_SSL
- if (sock->ssl)
- return ssl_gets(sock->ssl, buf, len);
-#endif
- return fd_gets(sock->sock, buf, len);
-}
-
-gint fd_getline(gint fd, gchar **line)
-{
- gchar buf[BUFFSIZE];
- gchar *str = NULL;
- gint len;
- gulong size = 0;
- gulong cur_offset = 0;
-
- while ((len = fd_gets(fd, buf, sizeof(buf))) > 0) {
- size += len;
- str = g_realloc(str, size + 1);
- memcpy(str + cur_offset, buf, len + 1);
- cur_offset += len;
- if (buf[len - 1] == '\n')
- break;
- }
-
- *line = str;
-
- if (!str)
- return -1;
- else
- return (gint)size;
-}
-
-#if USE_SSL
-gint ssl_getline(SSL *ssl, gchar **line)
-{
- gchar buf[BUFFSIZE];
- gchar *str = NULL;
- gint len;
- gulong size = 0;
- gulong cur_offset = 0;
-
- while ((len = ssl_gets(ssl, buf, sizeof(buf))) > 0) {
- size += len;
- str = g_realloc(str, size + 1);
- memcpy(str + cur_offset, buf, len + 1);
- cur_offset += len;
- if (buf[len - 1] == '\n')
- break;
- }
-
- *line = str;
-
- if (!str)
- return -1;
- else
- return (gint)size;
-}
-#endif
-
-gint sock_getline(SockInfo *sock, gchar **line)
-{
- g_return_val_if_fail(sock != NULL, -1);
- g_return_val_if_fail(line != NULL, -1);
-
-#if USE_SSL
- if (sock->ssl)
- return ssl_getline(sock->ssl, line);
-#endif
- return fd_getline(sock->sock, line);
-}
-
-gint sock_puts(SockInfo *sock, const gchar *buf)
-{
- gint ret;
-
- if ((ret = sock_write_all(sock, buf, strlen(buf))) < 0)
- return ret;
- return sock_write_all(sock, "\r\n", 2);
-}
-
-/* peek at the socket data without actually reading it */
-#if USE_SSL
-gint ssl_peek(SSL *ssl, gchar *buf, gint len)
-{
- gint err, ret;
-
- if (SSL_pending(ssl) == 0) {
- if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0)
- return -1;
- }
-
- ret = SSL_peek(ssl, buf, len);
-
- switch ((err = SSL_get_error(ssl, ret))) {
- case SSL_ERROR_NONE:
- return ret;
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- errno = EAGAIN;
- return -1;
- case SSL_ERROR_ZERO_RETURN:
- return 0;
- default:
- g_warning("SSL_peek() returned error %d, ret = %d\n", err, ret);
- if (ret == 0)
- return 0;
- return -1;
- }
-}
-#endif
-
-gint sock_peek(SockInfo *sock, gchar *buf, gint len)
-{
- g_return_val_if_fail(sock != NULL, -1);
-
-#if USE_SSL
- if (sock->ssl)
- return ssl_peek(sock->ssl, buf, len);
-#endif
- return fd_recv(sock->sock, buf, len, MSG_PEEK);
-}
-
-gint sock_close(SockInfo *sock)
-{
- if (!sock)
- return 0;
-
-#if USE_SSL
- if (sock->ssl)
- ssl_done_socket(sock);
-#endif
-
- if (sock->sock_ch) {
- g_io_channel_shutdown(sock->sock_ch, FALSE, NULL);
- g_io_channel_unref(sock->sock_ch);
- }
-
- g_free(sock->hostname);
- g_free(sock);
-
- return 0;
-}
-
-gint fd_close(gint fd)
-{
-#ifdef G_OS_WIN32
- return closesocket(fd);
-#else
- return close(fd);
-#endif
-}
diff --git a/src/socket.h b/src/socket.h
deleted file mode 100644
index 5721a304..00000000
--- a/src/socket.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __SOCKET_H__
-#define __SOCKET_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#if HAVE_NETDB_H
-# include <netdb.h>
-#endif
-
-typedef struct _SockInfo SockInfo;
-
-#if USE_SSL
-# include "ssl.h"
-#endif
-
-typedef enum
-{
- CONN_READY,
- CONN_LOOKUPSUCCESS,
- CONN_ESTABLISHED,
- CONN_LOOKUPFAILED,
- CONN_FAILED
-} ConnectionState;
-
-typedef gint (*SockConnectFunc) (SockInfo *sock,
- gpointer data);
-typedef gboolean (*SockFunc) (SockInfo *sock,
- GIOCondition condition,
- gpointer data);
-
-struct _SockInfo
-{
- gint sock;
-#if USE_SSL
- SSL *ssl;
-#endif
- GIOChannel *sock_ch;
-
- gchar *hostname;
- gushort port;
- ConnectionState state;
- gpointer data;
-
- SockFunc callback;
- GIOCondition condition;
-};
-
-gint sock_init (void);
-gint sock_cleanup (void);
-
-gint sock_set_io_timeout (guint sec);
-
-gint sock_set_nonblocking_mode (SockInfo *sock, gboolean nonblock);
-gboolean sock_is_nonblocking_mode (SockInfo *sock);
-
-guint sock_add_watch (SockInfo *sock, GIOCondition condition,
- SockFunc func, gpointer data);
-
-struct hostent *my_gethostbyname (const gchar *hostname);
-
-SockInfo *sock_connect (const gchar *hostname, gushort port);
-#ifdef G_OS_UNIX
-gint sock_connect_async (const gchar *hostname, gushort port,
- SockConnectFunc func, gpointer data);
-gint sock_connect_async_cancel (gint id);
-#endif
-
-/* Basic I/O functions */
-gint sock_printf (SockInfo *sock, const gchar *format, ...)
- G_GNUC_PRINTF(2, 3);
-gint sock_read (SockInfo *sock, gchar *buf, gint len);
-gint sock_write (SockInfo *sock, const gchar *buf, gint len);
-gint sock_write_all (SockInfo *sock, const gchar *buf, gint len);
-gint sock_gets (SockInfo *sock, gchar *buf, gint len);
-gint sock_getline (SockInfo *sock, gchar **line);
-gint sock_puts (SockInfo *sock, const gchar *buf);
-gint sock_peek (SockInfo *sock, gchar *buf, gint len);
-gint sock_close (SockInfo *sock);
-
-/* Functions to directly work on FD. They are needed for pipes */
-gint fd_connect_unix (const gchar *path);
-gint fd_open_unix (const gchar *path);
-gint fd_accept (gint sock);
-
-gint fd_read (gint sock, gchar *buf, gint len);
-gint fd_write (gint sock, const gchar *buf, gint len);
-gint fd_write_all (gint sock, const gchar *buf, gint len);
-gint fd_gets (gint sock, gchar *buf, gint len);
-gint fd_getline (gint sock, gchar **line);
-gint fd_close (gint sock);
-
-/* Functions for SSL */
-#if USE_SSL
-gint ssl_read (SSL *ssl, gchar *buf, gint len);
-gint ssl_write (SSL *ssl, const gchar *buf, gint len);
-gint ssl_write_all (SSL *ssl, const gchar *buf, gint len);
-gint ssl_gets (SSL *ssl, gchar *buf, gint len);
-gint ssl_getline (SSL *ssl, gchar **line);
-gint ssl_peek (SSL *ssl, gchar *buf, gint len);
-#endif
-
-#endif /* __SOCKET_H__ */
diff --git a/src/ssl.c b/src/ssl.c
deleted file mode 100644
index b57c60a9..00000000
--- a/src/ssl.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#if USE_SSL
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-
-#include "utils.h"
-#include "ssl.h"
-
-static SSL_CTX *ssl_ctx_SSLv23;
-static SSL_CTX *ssl_ctx_TLSv1;
-
-void ssl_init(void)
-{
- gchar *certs_dir;
-
- SSL_library_init();
- SSL_load_error_strings();
-
- certs_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "certs", NULL);
- if (!is_dir_exist(certs_dir)) {
- debug_print("%s doesn't exist, or not a directory.\n",
- certs_dir);
- g_free(certs_dir);
- certs_dir = NULL;
- }
-
- ssl_ctx_SSLv23 = SSL_CTX_new(SSLv23_client_method());
- if (ssl_ctx_SSLv23 == NULL) {
- debug_print(_("SSLv23 not available\n"));
- } else {
- debug_print(_("SSLv23 available\n"));
- if (certs_dir &&
- !SSL_CTX_load_verify_locations(ssl_ctx_SSLv23, NULL,
- certs_dir))
- g_warning("SSLv23 SSL_CTX_load_verify_locations failed.\n");
- }
-
- ssl_ctx_TLSv1 = SSL_CTX_new(TLSv1_client_method());
- if (ssl_ctx_TLSv1 == NULL) {
- debug_print(_("TLSv1 not available\n"));
- } else {
- debug_print(_("TLSv1 available\n"));
- if (certs_dir &&
- !SSL_CTX_load_verify_locations(ssl_ctx_TLSv1, NULL,
- certs_dir))
- g_warning("TLSv1 SSL_CTX_load_verify_locations failed.\n");
- }
-
- g_free(certs_dir);
-}
-
-void ssl_done(void)
-{
- if (ssl_ctx_SSLv23) {
- SSL_CTX_free(ssl_ctx_SSLv23);
- }
-
- if (ssl_ctx_TLSv1) {
- SSL_CTX_free(ssl_ctx_TLSv1);
- }
-}
-
-gboolean ssl_init_socket(SockInfo *sockinfo)
-{
- return ssl_init_socket_with_method(sockinfo, SSL_METHOD_SSLv23);
-}
-
-gboolean ssl_init_socket_with_method(SockInfo *sockinfo, SSLMethod method)
-{
- X509 *server_cert;
- gint ret;
-
- switch (method) {
- case SSL_METHOD_SSLv23:
- if (!ssl_ctx_SSLv23) {
- g_warning(_("SSL method not available\n"));
- return FALSE;
- }
- sockinfo->ssl = SSL_new(ssl_ctx_SSLv23);
- break;
- case SSL_METHOD_TLSv1:
- if (!ssl_ctx_TLSv1) {
- g_warning(_("SSL method not available\n"));
- return FALSE;
- }
- sockinfo->ssl = SSL_new(ssl_ctx_TLSv1);
- break;
- default:
- g_warning(_("Unknown SSL method *PROGRAM BUG*\n"));
- return FALSE;
- break;
- }
-
- if (sockinfo->ssl == NULL) {
- g_warning(_("Error creating ssl context\n"));
- return FALSE;
- }
-
- SSL_set_fd(sockinfo->ssl, sockinfo->sock);
- if ((ret = SSL_connect(sockinfo->ssl)) == -1) {
- g_warning(_("SSL connect failed (%s)\n"),
- ERR_error_string(ERR_get_error(), NULL));
- return FALSE;
- }
-
- /* Get the cipher */
-
- debug_print(_("SSL connection using %s\n"),
- SSL_get_cipher(sockinfo->ssl));
-
- /* Get server's certificate (note: beware of dynamic allocation) */
-
- if ((server_cert = SSL_get_peer_certificate(sockinfo->ssl)) != NULL) {
- gchar *str;
- glong verify_result;
-
- debug_print(_("Server certificate:\n"));
-
- if ((str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0)) != NULL) {
- debug_print(_(" Subject: %s\n"), str);
- g_free(str);
- }
-
- if ((str = X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0)) != NULL) {
- debug_print(_(" Issuer: %s\n"), str);
- g_free(str);
- }
-
- verify_result = SSL_get_verify_result(sockinfo->ssl);
- if (verify_result == X509_V_OK)
- debug_print("SSL verify OK\n");
- else
- g_warning("%s: SSL certificate verify failed (%ld: %s)\n",
- sockinfo->hostname, verify_result,
- X509_verify_cert_error_string(verify_result));
-
- X509_free(server_cert);
- }
-
- return TRUE;
-}
-
-void ssl_done_socket(SockInfo *sockinfo)
-{
- if (sockinfo->ssl) {
- SSL_free(sockinfo->ssl);
- }
-}
-
-#endif /* USE_SSL */
diff --git a/src/ssl.h b/src/ssl.h
deleted file mode 100644
index 6c13ddac..00000000
--- a/src/ssl.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __SSL_H__
-#define __SSL_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#if USE_SSL
-
-#include <glib.h>
-#include <openssl/crypto.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
-#include "socket.h"
-
-typedef enum {
- SSL_METHOD_SSLv23,
- SSL_METHOD_TLSv1
-} SSLMethod;
-
-typedef enum {
- SSL_NONE,
- SSL_TUNNEL,
- SSL_STARTTLS
-} SSLType;
-
-void ssl_init (void);
-void ssl_done (void);
-gboolean ssl_init_socket (SockInfo *sockinfo);
-gboolean ssl_init_socket_with_method (SockInfo *sockinfo,
- SSLMethod method);
-void ssl_done_socket (SockInfo *sockinfo);
-
-#endif /* USE_SSL */
-
-#endif /* __SSL_H__ */
diff --git a/src/stringtable.c b/src/stringtable.c
deleted file mode 100644
index da5e0ea4..00000000
--- a/src/stringtable.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2001 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <glib.h>
-#include <string.h>
-
-#include "stringtable.h"
-#include "utils.h"
-
-/* alfons - hashed string table (I wasn't content with GStringChunk;
- * can't recall why :-) */
-
-#if 0
-#define XXX_DEBUG \
- debug_print
-#else
-#define XXX_DEBUG \
- if (0) debug_print
-#endif
-
-typedef struct StringEntry_ {
- gint ref_count;
- gchar *string;
-} StringEntry;
-
-static StringEntry *string_entry_new(const gchar *str)
-{
- StringEntry *entry;
-
- entry = g_new0(StringEntry, 1);
- entry->ref_count = 1;
- entry->string = g_strdup(str);
- return entry;
-}
-
-static void string_entry_free(StringEntry *entry)
-{
- g_return_if_fail(entry != NULL);
-
- g_free(entry->string);
- g_free(entry);
-}
-
-StringTable *string_table_new(void)
-{
- StringTable *strtable;
-
- strtable = g_new0(StringTable, 1);
- g_return_val_if_fail(strtable != NULL, NULL);
- strtable->hash_table = g_hash_table_new(g_str_hash, g_str_equal);
- g_return_val_if_fail(strtable->hash_table, NULL);
- return strtable;
-}
-
-gchar *string_table_lookup_string(StringTable *table, const gchar *str)
-{
- StringEntry *entry;
-
- entry = g_hash_table_lookup(table->hash_table, str);
-
- if (entry) {
- return entry->string;
- } else {
- return NULL;
- }
-}
-
-gchar *string_table_insert_string(StringTable *table, const gchar *str)
-{
- StringEntry *entry;
-
- entry = g_hash_table_lookup(table->hash_table, str);
-
- if (entry) {
- entry->ref_count++;
- XXX_DEBUG ("ref++ for %s (%d)\n", entry->string,
- entry->ref_count);
- } else {
- entry = string_entry_new(str);
- XXX_DEBUG ("inserting %s\n", str);
- /* insert entry->string instead of str, since it can be
- * invalid pointer after this. */
- g_hash_table_insert(table->hash_table, entry->string, entry);
- }
-
- return entry->string;
-}
-
-void string_table_free_string(StringTable *table, const gchar *str)
-{
- StringEntry *entry;
-
- entry = g_hash_table_lookup(table->hash_table, str);
-
- if (entry) {
- entry->ref_count--;
- if (entry->ref_count <= 0) {
- XXX_DEBUG ("refcount of string %s dropped to zero\n",
- entry->string);
- g_hash_table_remove(table->hash_table, str);
- string_entry_free(entry);
- } else {
- XXX_DEBUG ("ref-- for %s (%d)\n", entry->string,
- entry->ref_count);
- }
- }
-}
-
-static gboolean string_table_remove_for_each_fn(gchar *key, StringEntry *entry,
- gpointer user_data)
-{
- g_return_val_if_fail(key != NULL, TRUE);
- g_return_val_if_fail(entry != NULL, TRUE);
-
- string_entry_free(entry);
-
- return TRUE;
-}
-
-void string_table_free(StringTable *table)
-{
- g_return_if_fail(table != NULL);
- g_return_if_fail(table->hash_table != NULL);
-
- g_hash_table_foreach_remove(table->hash_table,
- (GHRFunc)string_table_remove_for_each_fn,
- NULL);
- g_hash_table_destroy(table->hash_table);
- g_free(table);
-}
-
-static void string_table_stats_for_each_fn(gchar *key, StringEntry *entry,
- guint *totals)
-{
- if (entry->ref_count > 1) {
- *totals += strlen(key) * (entry->ref_count - 1);
- }
-}
-
-void string_table_get_stats(StringTable *table)
-{
- guint totals = 0;
-
- g_hash_table_foreach(table->hash_table,
- (GHFunc)string_table_stats_for_each_fn, &totals);
- XXX_DEBUG ("TOTAL UNSPILLED %d (%dK)\n", totals, totals / 1024);
-}
diff --git a/src/stringtable.h b/src/stringtable.h
deleted file mode 100644
index 337ef2c7..00000000
--- a/src/stringtable.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * sylpheed -- a gtk+ based, lightweight, and fast e-mail client
- * copyright (c) 1999-2001 hiroyuki yamamoto
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2 of the license, or
- * (at your option) any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; if not, write to the free software
- * foundation, inc., 59 temple place - suite 330, boston, ma 02111-1307, usa.
- */
-
-#ifndef STRINGTABLE_H__
-#define STRINGTABLE_H__
-
-#include <glib.h>
-
-typedef struct {
- GHashTable *hash_table;
-} StringTable;
-
-StringTable *string_table_new (void);
-void string_table_free (StringTable *table);
-
-gchar *string_table_lookup_string (StringTable *table, const gchar *str);
-gchar *string_table_insert_string (StringTable *table, const gchar *str);
-void string_table_free_string (StringTable *table, const gchar *str);
-
-void string_table_get_stats (StringTable *table);
-
-#endif /* STRINGTABLE_H__ */
diff --git a/src/unmime.c b/src/unmime.c
deleted file mode 100644
index 23d787a3..00000000
--- a/src/unmime.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "codeconv.h"
-#include "base64.h"
-#include "quoted-printable.h"
-
-#define ENCODED_WORD_BEGIN "=?"
-#define ENCODED_WORD_END "?="
-
-/* Decodes headers based on RFC2045 and RFC2047. */
-
-gchar *unmime_header(const gchar *encoded_str)
-{
- const gchar *p = encoded_str;
- const gchar *eword_begin_p, *encoding_begin_p, *text_begin_p,
- *eword_end_p;
- gchar charset[32];
- gchar encoding;
- gchar *conv_str;
- GString *outbuf;
- gchar *out_str;
- gsize out_len;
-
- outbuf = g_string_sized_new(strlen(encoded_str) * 2);
-
- while (*p != '\0') {
- gchar *decoded_text = NULL;
- gint len;
-
- eword_begin_p = strstr(p, ENCODED_WORD_BEGIN);
- if (!eword_begin_p) {
- g_string_append(outbuf, p);
- break;
- }
- encoding_begin_p = strchr(eword_begin_p + 2, '?');
- if (!encoding_begin_p) {
- g_string_append(outbuf, p);
- break;
- }
- text_begin_p = strchr(encoding_begin_p + 1, '?');
- if (!text_begin_p) {
- g_string_append(outbuf, p);
- break;
- }
- eword_end_p = strstr(text_begin_p + 1, ENCODED_WORD_END);
- if (!eword_end_p) {
- g_string_append(outbuf, p);
- break;
- }
-
- if (p == encoded_str) {
- g_string_append_len(outbuf, p, eword_begin_p - p);
- p = eword_begin_p;
- } else {
- /* ignore spaces between encoded words */
- const gchar *sp;
-
- for (sp = p; sp < eword_begin_p; sp++) {
- if (!g_ascii_isspace(*sp)) {
- g_string_append_len
- (outbuf, p, eword_begin_p - p);
- p = eword_begin_p;
- break;
- }
- }
- }
-
- len = MIN(sizeof(charset) - 1,
- encoding_begin_p - (eword_begin_p + 2));
- memcpy(charset, eword_begin_p + 2, len);
- charset[len] = '\0';
- encoding = g_ascii_toupper(*(encoding_begin_p + 1));
-
- if (encoding == 'B') {
- decoded_text = g_malloc
- (eword_end_p - (text_begin_p + 1) + 1);
- len = base64_decode(decoded_text, text_begin_p + 1,
- eword_end_p - (text_begin_p + 1));
- decoded_text[len] = '\0';
- } else if (encoding == 'Q') {
- decoded_text = g_malloc
- (eword_end_p - (text_begin_p + 1) + 1);
- len = qp_decode_q_encoding
- (decoded_text, text_begin_p + 1,
- eword_end_p - (text_begin_p + 1));
- } else {
- g_string_append_len(outbuf, p, eword_end_p + 2 - p);
- p = eword_end_p + 2;
- continue;
- }
-
- /* convert to UTF-8 */
- conv_str = conv_codeset_strdup(decoded_text, charset, NULL);
- if (!conv_str)
- conv_str = conv_utf8todisp(decoded_text, NULL);
- g_string_append(outbuf, conv_str);
- g_free(conv_str);
-
- g_free(decoded_text);
-
- p = eword_end_p + 2;
- }
-
- out_str = outbuf->str;
- out_len = outbuf->len;
- g_string_free(outbuf, FALSE);
-
- return g_realloc(out_str, out_len + 1);
-}
diff --git a/src/unmime.h b/src/unmime.h
deleted file mode 100644
index be9f390e..00000000
--- a/src/unmime.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __UNMIME_H__
-#define __UNMIME_H__
-
-#include <glib.h>
-
-gchar *unmime_header (const gchar *encoded_str);
-
-#endif /* __UNMIME_H__ */
diff --git a/src/utils.c b/src/utils.c
deleted file mode 100644
index dc72b814..00000000
--- a/src/utils.c
+++ /dev/null
@@ -1,3436 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#if (HAVE_WCTYPE_H && HAVE_WCHAR_H)
-# include <wchar.h>
-# include <wctype.h>
-#endif
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#if HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-#include <dirent.h>
-#include <time.h>
-
-#ifdef G_OS_WIN32
-# include <direct.h>
-# include <io.h>
-#endif
-
-#include "utils.h"
-#include "socket.h"
-
-#define BUFFSIZE 8192
-
-static gboolean debug_mode = FALSE;
-
-
-#if !GLIB_CHECK_VERSION(2, 7, 0) && !defined(G_OS_UNIX)
-gint g_chdir(const gchar *path)
-{
-#ifdef G_OS_WIN32
- if (G_WIN32_HAVE_WIDECHAR_API()) {
- wchar_t *wpath;
- gint retval;
- gint save_errno;
-
- wpath = g_utf8_to_utf16(path, -1, NULL, NULL, NULL);
- if (wpath == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- retval = _wchdir(wpath);
- save_errno = errno;
-
- g_free(wpath);
-
- errno = save_errno;
- return retval;
- } else {
- gchar *cp_path;
- gint retval;
- gint save_errno;
-
- cp_path = g_locale_from_utf8(path, -1, NULL, NULL, NULL);
- if (cp_path == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- retval = chdir(cp_path);
- save_errno = errno;
-
- g_free(cp_path);
-
- errno = save_errno;
- return retval;
- }
-#else
- return chdir(path);
-#endif
-}
-
-gint g_chmod(const gchar *path, gint mode)
-{
-#ifdef G_OS_WIN32
- if (G_WIN32_HAVE_WIDECHAR_API()) {
- wchar_t *wpath;
- gint retval;
- gint save_errno;
-
- wpath = g_utf8_to_utf16(path, -1, NULL, NULL, NULL);
- if (wpath == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- retval = _wchmod(wpath, mode);
- save_errno = errno;
-
- g_free(wpath);
-
- errno = save_errno;
- return retval;
- } else {
- gchar *cp_path;
- gint retval;
- gint save_errno;
-
- cp_path = g_locale_from_utf8(path, -1, NULL, NULL, NULL);
- if (cp_path == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- retval = chmod(cp_path, mode);
- save_errno = errno;
-
- g_free(cp_path);
-
- errno = save_errno;
- return retval;
- }
-#else
- return chmod(path, mode);
-#endif
-}
-#endif /* GLIB_CHECK_VERSION && G_OS_UNIX */
-
-void list_free_strings(GList *list)
-{
- list = g_list_first(list);
-
- while (list != NULL) {
- g_free(list->data);
- list = list->next;
- }
-}
-
-void slist_free_strings(GSList *list)
-{
- while (list != NULL) {
- g_free(list->data);
- list = list->next;
- }
-}
-
-static void hash_free_strings_func(gpointer key, gpointer value, gpointer data)
-{
- g_free(key);
-}
-
-void hash_free_strings(GHashTable *table)
-{
- g_hash_table_foreach(table, hash_free_strings_func, NULL);
-}
-
-static void hash_free_value_mem_func(gpointer key, gpointer value,
- gpointer data)
-{
- g_free(value);
-}
-
-void hash_free_value_mem(GHashTable *table)
-{
- g_hash_table_foreach(table, hash_free_value_mem_func, NULL);
-}
-
-gint str_case_equal(gconstpointer v, gconstpointer v2)
-{
- return g_ascii_strcasecmp((const gchar *)v, (const gchar *)v2) == 0;
-}
-
-guint str_case_hash(gconstpointer key)
-{
- const gchar *p = key;
- guint h = *p;
-
- if (h) {
- h = g_ascii_tolower(h);
- for (p += 1; *p != '\0'; p++)
- h = (h << 5) - h + g_ascii_tolower(*p);
- }
-
- return h;
-}
-
-void ptr_array_free_strings(GPtrArray *array)
-{
- gint i;
- gchar *str;
-
- g_return_if_fail(array != NULL);
-
- for (i = 0; i < array->len; i++) {
- str = g_ptr_array_index(array, i);
- g_free(str);
- }
-}
-
-gboolean str_find(const gchar *haystack, const gchar *needle)
-{
- return strstr(haystack, needle) != NULL ? TRUE : FALSE;
-}
-
-gboolean str_case_find(const gchar *haystack, const gchar *needle)
-{
- return strcasestr(haystack, needle) != NULL ? TRUE : FALSE;
-}
-
-gboolean str_find_equal(const gchar *haystack, const gchar *needle)
-{
- return strcmp(haystack, needle) == 0;
-}
-
-gboolean str_case_find_equal(const gchar *haystack, const gchar *needle)
-{
- return g_ascii_strcasecmp(haystack, needle) == 0;
-}
-
-gint to_number(const gchar *nstr)
-{
- register const gchar *p;
-
- if (*nstr == '\0') return -1;
-
- for (p = nstr; *p != '\0'; p++)
- if (!g_ascii_isdigit(*p)) return -1;
-
- return atoi(nstr);
-}
-
-/* convert integer into string,
- nstr must be not lower than 11 characters length */
-gchar *itos_buf(gchar *nstr, gint n)
-{
- g_snprintf(nstr, 11, "%d", n);
- return nstr;
-}
-
-/* convert integer into string */
-gchar *itos(gint n)
-{
- static gchar nstr[11];
-
- return itos_buf(nstr, n);
-}
-
-gchar *to_human_readable(off_t size)
-{
- static gchar str[10];
-
- if (size < 1024)
- g_snprintf(str, sizeof(str), _("%dB"), (gint)size);
- else if (size >> 10 < 1024)
- g_snprintf(str, sizeof(str), _("%.1fKB"), (gfloat)size / (1 << 10));
- else if (size >> 20 < 1024)
- g_snprintf(str, sizeof(str), _("%.2fMB"), (gfloat)size / (1 << 20));
- else
- g_snprintf(str, sizeof(str), _("%.2fGB"), (gfloat)size / (1 << 30));
-
- return str;
-}
-
-/* strcmp with NULL-checking */
-gint strcmp2(const gchar *s1, const gchar *s2)
-{
- if (s1 == NULL || s2 == NULL)
- return -1;
- else
- return strcmp(s1, s2);
-}
-
-/* compare paths */
-gint path_cmp(const gchar *s1, const gchar *s2)
-{
- gint len1, len2;
-#ifdef G_OS_WIN32
- gchar *s1_, *s2_;
-#endif
-
- if (s1 == NULL || s2 == NULL) return -1;
- if (*s1 == '\0' || *s2 == '\0') return -1;
-
- len1 = strlen(s1);
- len2 = strlen(s2);
-
-#ifdef G_OS_WIN32
- Xstrdup_a(s1_, s1, return -1);
- Xstrdup_a(s2_, s2, return -1);
- subst_char(s1_, '/', G_DIR_SEPARATOR);
- subst_char(s2_, '/', G_DIR_SEPARATOR);
- if (s1_[len1 - 1] == G_DIR_SEPARATOR) len1--;
- if (s2_[len2 - 1] == G_DIR_SEPARATOR) len2--;
-
- return strncmp(s1_, s2_, MAX(len1, len2));
-#else
- if (s1[len1 - 1] == G_DIR_SEPARATOR) len1--;
- if (s2[len2 - 1] == G_DIR_SEPARATOR) len2--;
-
- return strncmp(s1, s2, MAX(len1, len2));
-#endif
-}
-
-/* remove trailing return code */
-gchar *strretchomp(gchar *str)
-{
- register gchar *s;
-
- if (!*str) return str;
-
- for (s = str + strlen(str) - 1;
- s >= str && (*s == '\n' || *s == '\r');
- s--)
- *s = '\0';
-
- return str;
-}
-
-/* remove trailing character */
-gchar *strtailchomp(gchar *str, gchar tail_char)
-{
- register gchar *s;
-
- if (!*str) return str;
- if (tail_char == '\0') return str;
-
- for (s = str + strlen(str) - 1; s >= str && *s == tail_char; s--)
- *s = '\0';
-
- return str;
-}
-
-/* remove CR (carriage return) */
-gchar *strcrchomp(gchar *str)
-{
- register gchar *s;
-
- if (!*str) return str;
-
- s = str + strlen(str) - 1;
- if (*s == '\n' && s > str && *(s - 1) == '\r') {
- *(s - 1) = '\n';
- *s = '\0';
- }
-
- return str;
-}
-
-/* Similar to `strstr' but this function ignores the case of both strings. */
-gchar *strcasestr(const gchar *haystack, const gchar *needle)
-{
- register size_t haystack_len, needle_len;
-
- haystack_len = strlen(haystack);
- needle_len = strlen(needle);
-
- if (haystack_len < needle_len || needle_len == 0)
- return NULL;
-
- while (haystack_len >= needle_len) {
- if (!g_ascii_strncasecmp(haystack, needle, needle_len))
- return (gchar *)haystack;
- else {
- haystack++;
- haystack_len--;
- }
- }
-
- return NULL;
-}
-
-gpointer my_memmem(gconstpointer haystack, size_t haystacklen,
- gconstpointer needle, size_t needlelen)
-{
- const gchar *haystack_ = (const gchar *)haystack;
- const gchar *needle_ = (const gchar *)needle;
- const gchar *haystack_cur = (const gchar *)haystack;
-
- if (needlelen == 1)
- return memchr(haystack_, *needle_, haystacklen);
-
- while ((haystack_cur = memchr(haystack_cur, *needle_, haystacklen))
- != NULL) {
- if (haystacklen - (haystack_cur - haystack_) < needlelen)
- break;
- if (memcmp(haystack_cur + 1, needle_ + 1, needlelen - 1) == 0)
- return (gpointer)haystack_cur;
- else
- haystack_cur++;
- }
-
- return NULL;
-}
-
-/* Copy no more than N characters of SRC to DEST, with NULL terminating. */
-gchar *strncpy2(gchar *dest, const gchar *src, size_t n)
-{
- register const gchar *s = src;
- register gchar *d = dest;
-
- while (--n && *s)
- *d++ = *s++;
- *d = '\0';
-
- return dest;
-}
-
-#if !HAVE_ISWALNUM
-int iswalnum(wint_t wc)
-{
- return g_ascii_isalnum((int)wc);
-}
-#endif
-
-#if !HAVE_ISWSPACE
-int iswspace(wint_t wc)
-{
- return g_ascii_isspace((int)wc);
-}
-#endif
-
-#if !HAVE_TOWLOWER
-wint_t towlower(wint_t wc)
-{
- if (wc >= L'A' && wc <= L'Z')
- return wc + L'a' - L'A';
-
- return wc;
-}
-#endif
-
-#if !HAVE_WCSLEN
-size_t wcslen(const wchar_t *s)
-{
- size_t len = 0;
-
- while (*s != L'\0')
- ++len, ++s;
-
- return len;
-}
-#endif
-
-#if !HAVE_WCSCPY
-/* Copy SRC to DEST. */
-wchar_t *wcscpy(wchar_t *dest, const wchar_t *src)
-{
- wint_t c;
- wchar_t *s = dest;
-
- do {
- c = *src++;
- *dest++ = c;
- } while (c != L'\0');
-
- return s;
-}
-#endif
-
-#if !HAVE_WCSNCPY
-/* Copy no more than N wide-characters of SRC to DEST. */
-wchar_t *wcsncpy (wchar_t *dest, const wchar_t *src, size_t n)
-{
- wint_t c;
- wchar_t *s = dest;
-
- do {
- c = *src++;
- *dest++ = c;
- if (--n == 0)
- return s;
- } while (c != L'\0');
-
- /* zero fill */
- do
- *dest++ = L'\0';
- while (--n > 0);
-
- return s;
-}
-#endif
-
-/* Duplicate S, returning an identical malloc'd string. */
-wchar_t *wcsdup(const wchar_t *s)
-{
- wchar_t *new_str;
-
- if (s) {
- new_str = g_new(wchar_t, wcslen(s) + 1);
- wcscpy(new_str, s);
- } else
- new_str = NULL;
-
- return new_str;
-}
-
-/* Duplicate no more than N wide-characters of S,
- returning an identical malloc'd string. */
-wchar_t *wcsndup(const wchar_t *s, size_t n)
-{
- wchar_t *new_str;
-
- if (s) {
- new_str = g_new(wchar_t, n + 1);
- wcsncpy(new_str, s, n);
- new_str[n] = (wchar_t)0;
- } else
- new_str = NULL;
-
- return new_str;
-}
-
-wchar_t *strdup_mbstowcs(const gchar *s)
-{
- wchar_t *new_str;
-
- if (s) {
- new_str = g_new(wchar_t, strlen(s) + 1);
- if (mbstowcs(new_str, s, strlen(s) + 1) < 0) {
- g_free(new_str);
- new_str = NULL;
- } else
- new_str = g_realloc(new_str,
- sizeof(wchar_t) * (wcslen(new_str) + 1));
- } else
- new_str = NULL;
-
- return new_str;
-}
-
-gchar *strdup_wcstombs(const wchar_t *s)
-{
- gchar *new_str;
- size_t len;
-
- if (s) {
- len = wcslen(s) * MB_CUR_MAX + 1;
- new_str = g_new(gchar, len);
- if (wcstombs(new_str, s, len) < 0) {
- g_free(new_str);
- new_str = NULL;
- } else
- new_str = g_realloc(new_str, strlen(new_str) + 1);
- } else
- new_str = NULL;
-
- return new_str;
-}
-
-/* Compare S1 and S2, ignoring case. */
-gint wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n)
-{
- wint_t c1;
- wint_t c2;
-
- while (n--) {
- c1 = towlower(*s1++);
- c2 = towlower(*s2++);
- if (c1 != c2)
- return c1 - c2;
- else if (c1 == 0 && c2 == 0)
- break;
- }
-
- return 0;
-}
-
-/* Find the first occurrence of NEEDLE in HAYSTACK, ignoring case. */
-wchar_t *wcscasestr(const wchar_t *haystack, const wchar_t *needle)
-{
- register size_t haystack_len, needle_len;
-
- haystack_len = wcslen(haystack);
- needle_len = wcslen(needle);
-
- if (haystack_len < needle_len || needle_len == 0)
- return NULL;
-
- while (haystack_len >= needle_len) {
- if (!wcsncasecmp(haystack, needle, needle_len))
- return (wchar_t *)haystack;
- else {
- haystack++;
- haystack_len--;
- }
- }
-
- return NULL;
-}
-
-gint get_mbs_len(const gchar *s)
-{
- const gchar *p = s;
- gint mb_len;
- gint len = 0;
-
- if (!p)
- return -1;
-
- while (*p != '\0') {
- mb_len = g_utf8_skip[*(guchar *)p];
- if (mb_len == 0)
- break;
- else
- len++;
-
- p += mb_len;
- }
-
- return len;
-}
-
-/* Examine if next block is non-ASCII string */
-gboolean is_next_nonascii(const gchar *s)
-{
- const gchar *p;
-
- /* skip head space */
- for (p = s; *p != '\0' && g_ascii_isspace(*p); p++)
- ;
- for (; *p != '\0' && !g_ascii_isspace(*p); p++) {
- if (*(guchar *)p > 127 || *(guchar *)p < 32)
- return TRUE;
- }
-
- return FALSE;
-}
-
-gint get_next_word_len(const gchar *s)
-{
- gint len = 0;
-
- for (; *s != '\0' && !g_ascii_isspace(*s); s++, len++)
- ;
-
- return len;
-}
-
-/* compare subjects */
-gint subject_compare(const gchar *s1, const gchar *s2)
-{
- gchar *str1, *str2;
-
- if (!s1 || !s2) return -1;
- if (!*s1 || !*s2) return -1;
-
- Xstrdup_a(str1, s1, return -1);
- Xstrdup_a(str2, s2, return -1);
-
- trim_subject_for_compare(str1);
- trim_subject_for_compare(str2);
-
- if (!*str1 || !*str2) return -1;
-
- return strcmp(str1, str2);
-}
-
-gint subject_compare_for_sort(const gchar *s1, const gchar *s2)
-{
- gchar *str1, *str2;
-
- if (!s1 || !s2) return -1;
-
- Xstrdup_a(str1, s1, return -1);
- Xstrdup_a(str2, s2, return -1);
-
- trim_subject_for_sort(str1);
- trim_subject_for_sort(str2);
-
- return g_ascii_strcasecmp(str1, str2);
-}
-
-void trim_subject_for_compare(gchar *str)
-{
- gchar *srcp;
-
- eliminate_parenthesis(str, '[', ']');
- eliminate_parenthesis(str, '(', ')');
- g_strstrip(str);
-
- while (!g_ascii_strncasecmp(str, "Re:", 3)) {
- srcp = str + 3;
- while (g_ascii_isspace(*srcp)) srcp++;
- memmove(str, srcp, strlen(srcp) + 1);
- }
-}
-
-void trim_subject_for_sort(gchar *str)
-{
- gchar *srcp;
-
- g_strstrip(str);
-
- while (!g_ascii_strncasecmp(str, "Re:", 3)) {
- srcp = str + 3;
- while (g_ascii_isspace(*srcp)) srcp++;
- memmove(str, srcp, strlen(srcp) + 1);
- }
-}
-
-void trim_subject(gchar *str)
-{
- register gchar *srcp, *destp;
- gchar op, cl;
- gint in_brace;
-
- destp = str;
- while (!g_ascii_strncasecmp(destp, "Re:", 3)) {
- destp += 3;
- while (g_ascii_isspace(*destp)) destp++;
- }
-
- if (*destp == '[') {
- op = '[';
- cl = ']';
- } else if (*destp == '(') {
- op = '(';
- cl = ')';
- } else
- return;
-
- srcp = destp + 1;
- in_brace = 1;
- while (*srcp) {
- if (*srcp == op)
- in_brace++;
- else if (*srcp == cl)
- in_brace--;
- srcp++;
- if (in_brace == 0)
- break;
- }
- while (g_ascii_isspace(*srcp)) srcp++;
- memmove(destp, srcp, strlen(srcp) + 1);
-}
-
-void eliminate_parenthesis(gchar *str, gchar op, gchar cl)
-{
- register gchar *srcp, *destp;
- gint in_brace;
-
- srcp = destp = str;
-
- while ((destp = strchr(destp, op))) {
- in_brace = 1;
- srcp = destp + 1;
- while (*srcp) {
- if (*srcp == op)
- in_brace++;
- else if (*srcp == cl)
- in_brace--;
- srcp++;
- if (in_brace == 0)
- break;
- }
- while (g_ascii_isspace(*srcp)) srcp++;
- memmove(destp, srcp, strlen(srcp) + 1);
- }
-}
-
-void extract_parenthesis(gchar *str, gchar op, gchar cl)
-{
- register gchar *srcp, *destp;
- gint in_brace;
-
- srcp = destp = str;
-
- while ((srcp = strchr(destp, op))) {
- if (destp > str)
- *destp++ = ' ';
- memmove(destp, srcp + 1, strlen(srcp));
- in_brace = 1;
- while(*destp) {
- if (*destp == op)
- in_brace++;
- else if (*destp == cl)
- in_brace--;
-
- if (in_brace == 0)
- break;
-
- destp++;
- }
- }
- *destp = '\0';
-}
-
-void extract_parenthesis_with_skip_quote(gchar *str, gchar quote_chr,
- gchar op, gchar cl)
-{
- register gchar *srcp, *destp;
- gint in_brace;
- gboolean in_quote = FALSE;
-
- srcp = destp = str;
-
- while ((srcp = strchr_with_skip_quote(destp, quote_chr, op))) {
- if (destp > str)
- *destp++ = ' ';
- memmove(destp, srcp + 1, strlen(srcp));
- in_brace = 1;
- while(*destp) {
- if (*destp == op && !in_quote)
- in_brace++;
- else if (*destp == cl && !in_quote)
- in_brace--;
- else if (*destp == quote_chr)
- in_quote ^= TRUE;
-
- if (in_brace == 0)
- break;
-
- destp++;
- }
- }
- *destp = '\0';
-}
-
-void eliminate_quote(gchar *str, gchar quote_chr)
-{
- register gchar *srcp, *destp;
-
- srcp = destp = str;
-
- while ((destp = strchr(destp, quote_chr))) {
- if ((srcp = strchr(destp + 1, quote_chr))) {
- srcp++;
- while (g_ascii_isspace(*srcp)) srcp++;
- memmove(destp, srcp, strlen(srcp) + 1);
- } else {
- *destp = '\0';
- break;
- }
- }
-}
-
-void extract_quote(gchar *str, gchar quote_chr)
-{
- register gchar *p;
-
- if ((str = strchr(str, quote_chr))) {
- if ((p = strchr(str + 1, quote_chr))) {
- *p = '\0';
- memmove(str, str + 1, p - str);
- }
- }
-}
-
-void eliminate_address_comment(gchar *str)
-{
- register gchar *srcp, *destp;
- gint in_brace;
-
- srcp = destp = str;
-
- while ((destp = strchr(destp, '"'))) {
- if ((srcp = strchr(destp + 1, '"'))) {
- srcp++;
- if (*srcp == '@') {
- destp = srcp + 1;
- } else {
- while (g_ascii_isspace(*srcp)) srcp++;
- memmove(destp, srcp, strlen(srcp) + 1);
- }
- } else {
- *destp = '\0';
- break;
- }
- }
-
- srcp = destp = str;
-
- while ((destp = strchr_with_skip_quote(destp, '"', '('))) {
- in_brace = 1;
- srcp = destp + 1;
- while (*srcp) {
- if (*srcp == '(')
- in_brace++;
- else if (*srcp == ')')
- in_brace--;
- srcp++;
- if (in_brace == 0)
- break;
- }
- while (g_ascii_isspace(*srcp)) srcp++;
- memmove(destp, srcp, strlen(srcp) + 1);
- }
-}
-
-gchar *strchr_with_skip_quote(const gchar *str, gint quote_chr, gint c)
-{
- gboolean in_quote = FALSE;
-
- while (*str) {
- if (*str == c && !in_quote)
- return (gchar *)str;
- if (*str == quote_chr)
- in_quote ^= TRUE;
- str++;
- }
-
- return NULL;
-}
-
-gchar *strrchr_with_skip_quote(const gchar *str, gint quote_chr, gint c)
-{
- gboolean in_quote = FALSE;
- const gchar *p;
-
- p = str + strlen(str) - 1;
- while (p >= str) {
- if (*p == c && !in_quote)
- return (gchar *)p;
- if (*p == quote_chr)
- in_quote ^= TRUE;
- p--;
- }
-
- return NULL;
-}
-
-void extract_address(gchar *str)
-{
- eliminate_address_comment(str);
- if (strchr_with_skip_quote(str, '"', '<'))
- extract_parenthesis_with_skip_quote(str, '"', '<', '>');
- g_strstrip(str);
-}
-
-void extract_list_id_str(gchar *str)
-{
- if (strchr_with_skip_quote(str, '"', '<'))
- extract_parenthesis_with_skip_quote(str, '"', '<', '>');
- g_strstrip(str);
-}
-
-GSList *address_list_append(GSList *addr_list, const gchar *str)
-{
- gchar *work;
- gchar *workp;
-
- if (!str) return addr_list;
-
- Xstrdup_a(work, str, return addr_list);
-
- eliminate_address_comment(work);
- workp = work;
-
- while (workp && *workp) {
- gchar *p, *next;
-
- if ((p = strchr_with_skip_quote(workp, '"', ','))) {
- *p = '\0';
- next = p + 1;
- } else
- next = NULL;
-
- if (strchr_with_skip_quote(workp, '"', '<'))
- extract_parenthesis_with_skip_quote
- (workp, '"', '<', '>');
-
- g_strstrip(workp);
- if (*workp)
- addr_list = g_slist_append(addr_list, g_strdup(workp));
-
- workp = next;
- }
-
- return addr_list;
-}
-
-GSList *references_list_prepend(GSList *msgid_list, const gchar *str)
-{
- const gchar *strp;
-
- if (!str) return msgid_list;
- strp = str;
-
- while (strp && *strp) {
- const gchar *start, *end;
- gchar *msgid;
-
- if ((start = strchr(strp, '<')) != NULL) {
- end = strchr(start + 1, '>');
- if (!end) break;
- } else
- break;
-
- msgid = g_strndup(start + 1, end - start - 1);
- g_strstrip(msgid);
- if (*msgid)
- msgid_list = g_slist_prepend(msgid_list, msgid);
- else
- g_free(msgid);
-
- strp = end + 1;
- }
-
- return msgid_list;
-}
-
-GSList *references_list_append(GSList *msgid_list, const gchar *str)
-{
- GSList *list;
-
- list = references_list_prepend(NULL, str);
- list = g_slist_reverse(list);
- msgid_list = g_slist_concat(msgid_list, list);
-
- return msgid_list;
-}
-
-GSList *newsgroup_list_append(GSList *group_list, const gchar *str)
-{
- gchar *work;
- gchar *workp;
-
- if (!str) return group_list;
-
- Xstrdup_a(work, str, return group_list);
-
- workp = work;
-
- while (workp && *workp) {
- gchar *p, *next;
-
- if ((p = strchr_with_skip_quote(workp, '"', ','))) {
- *p = '\0';
- next = p + 1;
- } else
- next = NULL;
-
- g_strstrip(workp);
- if (*workp)
- group_list = g_slist_append(group_list,
- g_strdup(workp));
-
- workp = next;
- }
-
- return group_list;
-}
-
-GList *add_history(GList *list, const gchar *str)
-{
- GList *old;
-
- g_return_val_if_fail(str != NULL, list);
-
- old = g_list_find_custom(list, (gpointer)str, (GCompareFunc)strcmp2);
- if (old) {
- g_free(old->data);
- list = g_list_remove(list, old->data);
- } else if (g_list_length(list) >= MAX_HISTORY_SIZE) {
- GList *last;
-
- last = g_list_last(list);
- if (last) {
- g_free(last->data);
- g_list_remove(list, last->data);
- }
- }
-
- list = g_list_prepend(list, g_strdup(str));
-
- return list;
-}
-
-void remove_return(gchar *str)
-{
- register gchar *p = str;
-
- while (*p) {
- if (*p == '\n' || *p == '\r')
- memmove(p, p + 1, strlen(p));
- else
- p++;
- }
-}
-
-void remove_space(gchar *str)
-{
- register gchar *p = str;
- register gint spc;
-
- while (*p) {
- spc = 0;
- while (g_ascii_isspace(*(p + spc)))
- spc++;
- if (spc)
- memmove(p, p + spc, strlen(p + spc) + 1);
- else
- p++;
- }
-}
-
-void unfold_line(gchar *str)
-{
- register gchar *p = str;
- register gint spc;
-
- while (*p) {
- if (*p == '\n' || *p == '\r') {
- *p++ = ' ';
- spc = 0;
- while (g_ascii_isspace(*(p + spc)))
- spc++;
- if (spc)
- memmove(p, p + spc, strlen(p + spc) + 1);
- } else
- p++;
- }
-}
-
-void subst_char(gchar *str, gchar orig, gchar subst)
-{
- register gchar *p = str;
-
- while (*p) {
- if (*p == orig)
- *p = subst;
- p++;
- }
-}
-
-void subst_chars(gchar *str, gchar *orig, gchar subst)
-{
- register gchar *p = str;
-
- while (*p) {
- if (strchr(orig, *p) != NULL)
- *p = subst;
- p++;
- }
-}
-
-void subst_null(gchar *str, gint len, gchar subst)
-{
- register gchar *p = str;
-
- while (len--) {
- if (*p == '\0')
- *p = subst;
- p++;
- }
-}
-
-void subst_for_filename(gchar *str)
-{
- subst_chars(str, " \t\r\n\"'/\\", '_');
-}
-
-gboolean is_header_line(const gchar *str)
-{
- if (str[0] == ':') return FALSE;
-
- while (*str != '\0' && *str != ' ') {
- if (*str == ':')
- return TRUE;
- str++;
- }
-
- return FALSE;
-}
-
-gboolean is_ascii_str(const gchar *str)
-{
- const guchar *p = (const guchar *)str;
-
- while (*p != '\0') {
- if (*p != '\t' && *p != ' ' &&
- *p != '\r' && *p != '\n' &&
- (*p < 32 || *p >= 127))
- return FALSE;
- p++;
- }
-
- return TRUE;
-}
-
-gint get_quote_level(const gchar *str)
-{
- const gchar *first_pos;
- const gchar *last_pos;
- const gchar *p = str;
- gint quote_level = -1;
-
- /* speed up line processing by only searching to the last '>' */
- if ((first_pos = strchr(str, '>')) != NULL) {
- /* skip a line if it contains a '<' before the initial '>' */
- if (memchr(str, '<', first_pos - str) != NULL)
- return -1;
- last_pos = strrchr(first_pos, '>');
- } else
- return -1;
-
- while (p <= last_pos) {
- while (p < last_pos) {
- if (g_ascii_isspace(*p))
- p++;
- else
- break;
- }
-
- if (*p == '>')
- quote_level++;
- else if (*p != '-' && !g_ascii_isspace(*p) && p <= last_pos) {
- /* any characters are allowed except '-' and space */
- while (*p != '-' && *p != '>' && !g_ascii_isspace(*p) &&
- p < last_pos)
- p++;
- if (*p == '>')
- quote_level++;
- else
- break;
- }
-
- p++;
- }
-
- return quote_level;
-}
-
-gint check_line_length(const gchar *str, gint max_chars, gint *line)
-{
- const gchar *p = str, *q;
- gint cur_line = 0, len;
-
- while ((q = strchr(p, '\n')) != NULL) {
- len = q - p + 1;
- if (len > max_chars) {
- if (line)
- *line = cur_line;
- return -1;
- }
- p = q + 1;
- ++cur_line;
- }
-
- len = strlen(p);
- if (len > max_chars) {
- if (line)
- *line = cur_line;
- return -1;
- }
-
- return 0;
-}
-
-gchar *strstr_with_skip_quote(const gchar *haystack, const gchar *needle)
-{
- register guint haystack_len, needle_len;
- gboolean in_squote = FALSE, in_dquote = FALSE;
-
- haystack_len = strlen(haystack);
- needle_len = strlen(needle);
-
- if (haystack_len < needle_len || needle_len == 0)
- return NULL;
-
- while (haystack_len >= needle_len) {
- if (!in_squote && !in_dquote &&
- !strncmp(haystack, needle, needle_len))
- return (gchar *)haystack;
-
- /* 'foo"bar"' -> foo"bar"
- "foo'bar'" -> foo'bar' */
- if (*haystack == '\'') {
- if (in_squote)
- in_squote = FALSE;
- else if (!in_dquote)
- in_squote = TRUE;
- } else if (*haystack == '\"') {
- if (in_dquote)
- in_dquote = FALSE;
- else if (!in_squote)
- in_dquote = TRUE;
- }
-
- haystack++;
- haystack_len--;
- }
-
- return NULL;
-}
-
-gchar *strchr_parenthesis_close(const gchar *str, gchar op, gchar cl)
-{
- const gchar *p;
- gchar quote_chr = '"';
- gint in_brace;
- gboolean in_quote = FALSE;
-
- p = str;
-
- if ((p = strchr_with_skip_quote(p, quote_chr, op))) {
- p++;
- in_brace = 1;
- while (*p) {
- if (*p == op && !in_quote)
- in_brace++;
- else if (*p == cl && !in_quote)
- in_brace--;
- else if (*p == quote_chr)
- in_quote ^= TRUE;
-
- if (in_brace == 0)
- return (gchar *)p;
-
- p++;
- }
- }
-
- return NULL;
-}
-
-gchar **strsplit_parenthesis(const gchar *str, gchar op, gchar cl,
- gint max_tokens)
-{
- GSList *string_list = NULL, *slist;
- gchar **str_array;
- const gchar *s_op, *s_cl;
- guint i, n = 1;
-
- g_return_val_if_fail(str != NULL, NULL);
-
- if (max_tokens < 1)
- max_tokens = G_MAXINT;
-
- s_op = strchr_with_skip_quote(str, '"', op);
- if (!s_op) return NULL;
- str = s_op;
- s_cl = strchr_parenthesis_close(str, op, cl);
- if (s_cl) {
- do {
- guint len;
- gchar *new_string;
-
- str++;
- len = s_cl - str;
- new_string = g_new(gchar, len + 1);
- strncpy(new_string, str, len);
- new_string[len] = 0;
- string_list = g_slist_prepend(string_list, new_string);
- n++;
- str = s_cl + 1;
-
- while (*str && g_ascii_isspace(*str)) str++;
- if (*str != op) {
- string_list = g_slist_prepend(string_list,
- g_strdup(""));
- n++;
- s_op = strchr_with_skip_quote(str, '"', op);
- if (!--max_tokens || !s_op) break;
- str = s_op;
- } else
- s_op = str;
- s_cl = strchr_parenthesis_close(str, op, cl);
- } while (--max_tokens && s_cl);
- }
-
- str_array = g_new(gchar*, n);
-
- i = n - 1;
-
- str_array[i--] = NULL;
- for (slist = string_list; slist; slist = slist->next)
- str_array[i--] = slist->data;
-
- g_slist_free(string_list);
-
- return str_array;
-}
-
-gchar **strsplit_with_quote(const gchar *str, const gchar *delim,
- gint max_tokens)
-{
- GSList *string_list = NULL, *slist;
- gchar **str_array, *s, *new_str;
- guint i, n = 1, len;
-
- g_return_val_if_fail(str != NULL, NULL);
- g_return_val_if_fail(delim != NULL, NULL);
-
- if (max_tokens < 1)
- max_tokens = G_MAXINT;
-
- s = strstr_with_skip_quote(str, delim);
- if (s) {
- guint delimiter_len = strlen(delim);
-
- do {
- len = s - str;
- new_str = g_strndup(str, len);
-
- if (new_str[0] == '\'' || new_str[0] == '\"') {
- if (new_str[len - 1] == new_str[0]) {
- new_str[len - 1] = '\0';
- memmove(new_str, new_str + 1, len - 1);
- }
- }
- string_list = g_slist_prepend(string_list, new_str);
- n++;
- str = s + delimiter_len;
- s = strstr_with_skip_quote(str, delim);
- } while (--max_tokens && s);
- }
-
- if (*str) {
- new_str = g_strdup(str);
- if (new_str[0] == '\'' || new_str[0] == '\"') {
- len = strlen(str);
- if (new_str[len - 1] == new_str[0]) {
- new_str[len - 1] = '\0';
- memmove(new_str, new_str + 1, len - 1);
- }
- }
- string_list = g_slist_prepend(string_list, new_str);
- n++;
- }
-
- str_array = g_new(gchar*, n);
-
- i = n - 1;
-
- str_array[i--] = NULL;
- for (slist = string_list; slist; slist = slist->next)
- str_array[i--] = slist->data;
-
- g_slist_free(string_list);
-
- return str_array;
-}
-
-gchar *get_abbrev_newsgroup_name(const gchar *group, gint len)
-{
- gchar *abbrev_group;
- gchar *ap;
- const gchar *p = group;
- const gchar *last;
-
- last = group + strlen(group);
- abbrev_group = ap = g_malloc(strlen(group) + 1);
-
- while (*p) {
- while (*p == '.')
- *ap++ = *p++;
- if ((ap - abbrev_group) + (last - p) > len && strchr(p, '.')) {
- *ap++ = *p++;
- while (*p != '.') p++;
- } else {
- strcpy(ap, p);
- return abbrev_group;
- }
- }
-
- *ap = '\0';
- return abbrev_group;
-}
-
-gchar *trim_string(const gchar *str, gint len)
-{
- const gchar *p = str;
- gint mb_len;
- gchar *new_str;
- gint new_len = 0;
-
- if (!str) return NULL;
- if (strlen(str) <= len)
- return g_strdup(str);
- if (g_utf8_validate(str, -1, NULL) == FALSE)
- return g_strdup(str);
-
- while (*p != '\0') {
- mb_len = g_utf8_skip[*(guchar *)p];
- if (mb_len == 0)
- break;
- else if (new_len + mb_len > len)
- break;
-
- new_len += mb_len;
- p += mb_len;
- }
-
- Xstrndup_a(new_str, str, new_len, return g_strdup(str));
- return g_strconcat(new_str, "...", NULL);
-}
-
-gchar *trim_string_before(const gchar *str, gint len)
-{
- const gchar *p = str;
- gint mb_len;
- gint new_len;
-
- if (!str) return NULL;
- if ((new_len = strlen(str)) <= len)
- return g_strdup(str);
- if (g_utf8_validate(str, -1, NULL) == FALSE)
- return g_strdup(str);
-
- while (*p != '\0') {
- mb_len = g_utf8_skip[*(guchar *)p];
- if (mb_len == 0)
- break;
-
- new_len -= mb_len;
- p += mb_len;
-
- if (new_len <= len)
- break;
- }
-
- return g_strconcat("...", p, NULL);
-}
-
-GList *uri_list_extract_filenames(const gchar *uri_list)
-{
- GList *result = NULL;
- const gchar *p, *q;
- gchar *file;
-
- p = uri_list;
-
- while (p) {
- if (*p != '#') {
- while (g_ascii_isspace(*p)) p++;
- if (!strncmp(p, "file:", 5)) {
- p += 5;
- while (*p == '/' && *(p + 1) == '/') p++;
- q = p;
- while (*q && *q != '\n' && *q != '\r') q++;
-
- if (q > p) {
- q--;
- while (q > p && g_ascii_isspace(*q))
- q--;
- file = g_malloc(q - p + 2);
- strncpy(file, p, q - p + 1);
- file[q - p + 1] = '\0';
- decode_uri(file, file);
- result = g_list_append(result,file);
- }
- }
- }
- p = strchr(p, '\n');
- if (p) p++;
- }
-
- return result;
-}
-
-#define HEX_TO_INT(val, hex) \
-{ \
- gchar c = hex; \
- \
- if ('0' <= c && c <= '9') { \
- val = c - '0'; \
- } else if ('a' <= c && c <= 'f') { \
- val = c - 'a' + 10; \
- } else if ('A' <= c && c <= 'F') { \
- val = c - 'A' + 10; \
- } else { \
- val = 0; \
- } \
-}
-
-/* Converts two-digit hexadecimal to decimal. Used for unescaping escaped
- * characters.
- */
-static gint axtoi(const gchar *hex_str)
-{
- gint hi, lo;
-
- HEX_TO_INT(hi, hex_str[0]);
- HEX_TO_INT(lo, hex_str[1]);
-
- return (hi << 4) + lo;
-}
-
-gboolean is_uri_string(const gchar *str)
-{
- return (g_ascii_strncasecmp(str, "http://", 7) == 0 ||
- g_ascii_strncasecmp(str, "https://", 8) == 0 ||
- g_ascii_strncasecmp(str, "ftp://", 6) == 0 ||
- g_ascii_strncasecmp(str, "www.", 4) == 0);
-}
-
-gchar *get_uri_path(const gchar *uri)
-{
- if (g_ascii_strncasecmp(uri, "http://", 7) == 0)
- return (gchar *)(uri + 7);
- else if (g_ascii_strncasecmp(uri, "https://", 8) == 0)
- return (gchar *)(uri + 8);
- else if (g_ascii_strncasecmp(uri, "ftp://", 6) == 0)
- return (gchar *)(uri + 6);
- else
- return (gchar *)uri;
-}
-
-gint get_uri_len(const gchar *str)
-{
- const gchar *p;
-
- if (is_uri_string(str)) {
- for (p = str; *p != '\0'; p++) {
- if (!g_ascii_isgraph(*p) || strchr("()<>\"", *p))
- break;
- }
- return p - str;
- }
-
- return 0;
-}
-
-/* Decodes URL-Encoded strings (i.e. strings in which spaces are replaced by
- * plusses, and escape characters are used)
- * Note: decoded_uri and encoded_uri can point the same location
- */
-void decode_uri(gchar *decoded_uri, const gchar *encoded_uri)
-{
- gchar *dec = decoded_uri;
- const gchar *enc = encoded_uri;
-
- while (*enc) {
- if (*enc == '%') {
- enc++;
- if (isxdigit((guchar)enc[0]) &&
- isxdigit((guchar)enc[1])) {
- *dec = axtoi(enc);
- dec++;
- enc += 2;
- }
- } else {
- if (*enc == '+')
- *dec = ' ';
- else
- *dec = *enc;
- dec++;
- enc++;
- }
- }
-
- *dec = '\0';
-}
-
-gchar *encode_uri(const gchar *filename)
-{
- gchar *uri;
-
- uri = g_filename_to_uri(filename, NULL, NULL);
- if (!uri)
- uri = g_strconcat("file://", filename, NULL);
-
- return uri;
-}
-
-gint scan_mailto_url(const gchar *mailto, gchar **to, gchar **cc, gchar **bcc,
- gchar **subject, gchar **body)
-{
- gchar *tmp_mailto;
- gchar *p;
-
- Xstrdup_a(tmp_mailto, mailto, return -1);
-
- if (!strncmp(tmp_mailto, "mailto:", 7))
- tmp_mailto += 7;
-
- p = strchr(tmp_mailto, '?');
- if (p) {
- *p = '\0';
- p++;
- }
-
- if (to && !*to)
- *to = g_strdup(tmp_mailto);
-
- while (p) {
- gchar *field, *value;
-
- field = p;
-
- p = strchr(p, '=');
- if (!p) break;
- *p = '\0';
- p++;
-
- value = p;
-
- p = strchr(p, '&');
- if (p) {
- *p = '\0';
- p++;
- }
-
- if (*value == '\0') continue;
-
- if (cc && !*cc && !g_ascii_strcasecmp(field, "cc")) {
- *cc = g_strdup(value);
- } else if (bcc && !*bcc && !g_ascii_strcasecmp(field, "bcc")) {
- *bcc = g_strdup(value);
- } else if (subject && !*subject &&
- !g_ascii_strcasecmp(field, "subject")) {
- *subject = g_malloc(strlen(value) + 1);
- decode_uri(*subject, value);
- } else if (body && !*body &&
- !g_ascii_strcasecmp(field, "body")) {
- *body = g_malloc(strlen(value) + 1);
- decode_uri(*body, value);
- }
- }
-
- return 0;
-}
-
-const gchar *get_home_dir(void)
-{
-#ifdef G_OS_WIN32
- static const gchar *home_dir = NULL;
-
- if (!home_dir) {
- home_dir = g_get_home_dir();
- if (!home_dir)
- home_dir = "C:\\Sylpheed";
- }
-
- return home_dir;
-#else
- return g_get_home_dir();
-#endif
-}
-
-const gchar *get_rc_dir(void)
-{
- static gchar *rc_dir = NULL;
-
- if (!rc_dir)
-#ifdef G_OS_WIN32
- rc_dir = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S,
- "Application Data", G_DIR_SEPARATOR_S,
- RC_DIR, NULL);
-#else
- rc_dir = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S,
- RC_DIR, NULL);
-#endif
-
- return rc_dir;
-}
-
-const gchar *get_old_rc_dir(void)
-{
- static gchar *old_rc_dir = NULL;
-
- if (!old_rc_dir)
- old_rc_dir = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S,
- OLD_RC_DIR, NULL);
-
- return old_rc_dir;
-}
-
-const gchar *get_mail_base_dir(void)
-{
-#ifdef G_OS_WIN32
- static gchar *mail_base_dir = NULL;
-
- if (!mail_base_dir)
- mail_base_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- "Mailboxes", NULL);
-
- return mail_base_dir;
-#else
- return get_home_dir();
-#endif
-}
-
-const gchar *get_news_cache_dir(void)
-{
- static gchar *news_cache_dir = NULL;
-
- if (!news_cache_dir)
- news_cache_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- NEWS_CACHE_DIR, NULL);
-
- return news_cache_dir;
-}
-
-const gchar *get_imap_cache_dir(void)
-{
- static gchar *imap_cache_dir = NULL;
-
- if (!imap_cache_dir)
- imap_cache_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- IMAP_CACHE_DIR, NULL);
-
- return imap_cache_dir;
-}
-
-const gchar *get_mime_tmp_dir(void)
-{
- static gchar *mime_tmp_dir = NULL;
-
- if (!mime_tmp_dir)
- mime_tmp_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- MIME_TMP_DIR, NULL);
-
- return mime_tmp_dir;
-}
-
-const gchar *get_template_dir(void)
-{
- static gchar *template_dir = NULL;
-
- if (!template_dir)
- template_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- TEMPLATE_DIR, NULL);
-
- return template_dir;
-}
-
-const gchar *get_tmp_dir(void)
-{
- static gchar *tmp_dir = NULL;
-
- if (!tmp_dir)
- tmp_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- TMP_DIR, NULL);
-
- return tmp_dir;
-}
-
-gchar *get_tmp_file(void)
-{
- gchar *tmp_file;
- static guint32 id = 0;
-
- tmp_file = g_strdup_printf("%s%ctmpfile.%08x",
- get_tmp_dir(), G_DIR_SEPARATOR, id++);
-
- return tmp_file;
-}
-
-const gchar *get_domain_name(void)
-{
-#ifdef G_OS_UNIX
- static gchar *domain_name = NULL;
-
- if (!domain_name) {
- gchar buf[128] = "";
- struct hostent *hp;
-
- if (gethostname(buf, sizeof(buf)) < 0) {
- perror("gethostname");
- domain_name = "unknown";
- } else {
- buf[sizeof(buf) - 1] = '\0';
- if ((hp = my_gethostbyname(buf)) == NULL) {
- perror("gethostbyname");
- domain_name = g_strdup(buf);
- } else {
- domain_name = g_strdup(hp->h_name);
- }
- }
-
- debug_print("domain name = %s\n", domain_name);
- }
-
- return domain_name;
-#else
- return "unknown";
-#endif
-}
-
-off_t get_file_size(const gchar *file)
-{
- struct stat s;
-
- if (g_stat(file, &s) < 0) {
- FILE_OP_ERROR(file, "stat");
- return -1;
- }
-
- return s.st_size;
-}
-
-off_t get_file_size_as_crlf(const gchar *file)
-{
- FILE *fp;
- off_t size = 0;
- gchar buf[BUFFSIZE];
-
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- strretchomp(buf);
- size += strlen(buf) + 2;
- }
-
- if (ferror(fp)) {
- FILE_OP_ERROR(file, "fgets");
- size = -1;
- }
-
- fclose(fp);
-
- return size;
-}
-
-off_t get_left_file_size(FILE *fp)
-{
- glong pos;
- glong end;
- off_t size;
-
- if ((pos = ftell(fp)) < 0) {
- perror("ftell");
- return -1;
- }
- if (fseek(fp, 0L, SEEK_END) < 0) {
- perror("fseek");
- return -1;
- }
- if ((end = ftell(fp)) < 0) {
- perror("fseek");
- return -1;
- }
- size = end - pos;
- if (fseek(fp, pos, SEEK_SET) < 0) {
- perror("fseek");
- return -1;
- }
-
- return size;
-}
-
-gboolean file_exist(const gchar *file, gboolean allow_fifo)
-{
- struct stat s;
-
- if (file == NULL)
- return FALSE;
-
- if (g_stat(file, &s) < 0) {
- if (ENOENT != errno) FILE_OP_ERROR(file, "stat");
- return FALSE;
- }
-
- if (S_ISREG(s.st_mode) || (allow_fifo && S_ISFIFO(s.st_mode)))
- return TRUE;
-
- return FALSE;
-}
-
-gboolean is_dir_exist(const gchar *dir)
-{
- if (dir == NULL)
- return FALSE;
-
- return g_file_test(dir, G_FILE_TEST_IS_DIR);
-}
-
-gboolean is_file_entry_exist(const gchar *file)
-{
- if (file == NULL)
- return FALSE;
-
- return g_file_test(file, G_FILE_TEST_EXISTS);
-}
-
-gboolean dirent_is_regular_file(struct dirent *d)
-{
-#ifdef HAVE_DIRENT_D_TYPE
- if (d->d_type == DT_REG)
- return TRUE;
- else if (d->d_type != DT_UNKNOWN)
- return FALSE;
-#endif
-
- return g_file_test(d->d_name, G_FILE_TEST_IS_REGULAR);
-}
-
-gboolean dirent_is_directory(struct dirent *d)
-{
-#ifdef HAVE_DIRENT_D_TYPE
- if (d->d_type == DT_DIR)
- return TRUE;
- else if (d->d_type != DT_UNKNOWN)
- return FALSE;
-#endif
-
- return g_file_test(d->d_name, G_FILE_TEST_IS_DIR);
-}
-
-gint change_dir(const gchar *dir)
-{
- gchar *prevdir = NULL;
-
- if (debug_mode)
- prevdir = g_get_current_dir();
-
- if (g_chdir(dir) < 0) {
- FILE_OP_ERROR(dir, "chdir");
- if (debug_mode) g_free(prevdir);
- return -1;
- } else if (debug_mode) {
- gchar *cwd;
-
- cwd = g_get_current_dir();
- if (strcmp(prevdir, cwd) != 0)
- g_print("current dir: %s\n", cwd);
- g_free(cwd);
- g_free(prevdir);
- }
-
- return 0;
-}
-
-gint make_dir(const gchar *dir)
-{
- if (g_mkdir(dir, S_IRWXU) < 0) {
- FILE_OP_ERROR(dir, "mkdir");
- return -1;
- }
- if (g_chmod(dir, S_IRWXU) < 0)
- FILE_OP_ERROR(dir, "chmod");
-
- return 0;
-}
-
-gint make_dir_hier(const gchar *dir)
-{
- gchar *parent_dir;
- const gchar *p;
-
- for (p = dir; (p = strchr(p, G_DIR_SEPARATOR)) != NULL; p++) {
- parent_dir = g_strndup(dir, p - dir);
- if (*parent_dir != '\0') {
- if (!is_dir_exist(parent_dir)) {
- if (make_dir(parent_dir) < 0) {
- g_free(parent_dir);
- return -1;
- }
- }
- }
- g_free(parent_dir);
- }
-
- if (!is_dir_exist(dir)) {
- if (make_dir(dir) < 0)
- return -1;
- }
-
- return 0;
-}
-
-gint remove_all_files(const gchar *dir)
-{
- GDir *dp;
- const gchar *dir_name;
- gchar *prev_dir;
-
- prev_dir = g_get_current_dir();
-
- if (g_chdir(dir) < 0) {
- FILE_OP_ERROR(dir, "chdir");
- g_free(prev_dir);
- return -1;
- }
-
- if ((dp = g_dir_open(".", 0, NULL)) == NULL) {
- g_warning("failed to open directory: %s\n", dir);
- g_free(prev_dir);
- return -1;
- }
-
- while ((dir_name = g_dir_read_name(dp)) != NULL) {
- if (g_unlink(dir_name) < 0)
- FILE_OP_ERROR(dir_name, "unlink");
- }
-
- g_dir_close(dp);
-
- if (g_chdir(prev_dir) < 0) {
- FILE_OP_ERROR(prev_dir, "chdir");
- g_free(prev_dir);
- return -1;
- }
-
- g_free(prev_dir);
-
- return 0;
-}
-
-gint remove_numbered_files(const gchar *dir, guint first, guint last)
-{
- GDir *dp;
- const gchar *dir_name;
- gchar *prev_dir;
- gint file_no;
-
- prev_dir = g_get_current_dir();
-
- if (g_chdir(dir) < 0) {
- FILE_OP_ERROR(dir, "chdir");
- g_free(prev_dir);
- return -1;
- }
-
- if ((dp = g_dir_open(".", 0, NULL)) == NULL) {
- g_warning("failed to open directory: %s\n", dir);
- g_free(prev_dir);
- return -1;
- }
-
- while ((dir_name = g_dir_read_name(dp)) != NULL) {
- file_no = to_number(dir_name);
- if (file_no > 0 && first <= file_no && file_no <= last) {
- if (is_dir_exist(dir_name))
- continue;
- if (g_unlink(dir_name) < 0)
- FILE_OP_ERROR(dir_name, "unlink");
- }
- }
-
- g_dir_close(dp);
-
- if (g_chdir(prev_dir) < 0) {
- FILE_OP_ERROR(prev_dir, "chdir");
- g_free(prev_dir);
- return -1;
- }
-
- g_free(prev_dir);
-
- return 0;
-}
-
-gint remove_all_numbered_files(const gchar *dir)
-{
- return remove_numbered_files(dir, 0, UINT_MAX);
-}
-
-gint remove_expired_files(const gchar *dir, guint hours)
-{
- GDir *dp;
- const gchar *dir_name;
- struct stat s;
- gchar *prev_dir;
- gint file_no;
- time_t mtime, now, expire_time;
-
- prev_dir = g_get_current_dir();
-
- if (g_chdir(dir) < 0) {
- FILE_OP_ERROR(dir, "chdir");
- g_free(prev_dir);
- return -1;
- }
-
- if ((dp = g_dir_open(".", 0, NULL)) == NULL) {
- g_warning("failed to open directory: %s\n", dir);
- g_free(prev_dir);
- return -1;
- }
-
- now = time(NULL);
- expire_time = hours * 60 * 60;
-
- while ((dir_name = g_dir_read_name(dp)) != NULL) {
- file_no = to_number(dir_name);
- if (file_no > 0) {
- if (g_stat(dir_name, &s) < 0) {
- FILE_OP_ERROR(dir_name, "stat");
- continue;
- }
- if (S_ISDIR(s.st_mode))
- continue;
- mtime = MAX(s.st_mtime, s.st_atime);
- if (now - mtime > expire_time) {
- if (g_unlink(dir_name) < 0)
- FILE_OP_ERROR(dir_name, "unlink");
- }
- }
- }
-
- g_dir_close(dp);
-
- if (g_chdir(prev_dir) < 0) {
- FILE_OP_ERROR(prev_dir, "chdir");
- g_free(prev_dir);
- return -1;
- }
-
- g_free(prev_dir);
-
- return 0;
-}
-
-static gint remove_dir_recursive_real(const gchar *dir)
-{
- struct stat s;
- GDir *dp;
- const gchar *dir_name;
- gchar *prev_dir;
-
- if (g_stat(dir, &s) < 0) {
- FILE_OP_ERROR(dir, "stat");
- if (ENOENT == errno) return 0;
- return -1;
- }
-
- if (!S_ISDIR(s.st_mode)) {
- if (g_unlink(dir) < 0) {
- FILE_OP_ERROR(dir, "unlink");
- return -1;
- }
-
- return 0;
- }
-
- prev_dir = g_get_current_dir();
- /* g_print("prev_dir = %s\n", prev_dir); */
-
- if (g_chdir(dir) < 0) {
- FILE_OP_ERROR(dir, "chdir");
- g_free(prev_dir);
- return -1;
- }
-
- if ((dp = g_dir_open(".", 0, NULL)) == NULL) {
- g_warning("failed to open directory: %s\n", dir);
- g_chdir(prev_dir);
- g_free(prev_dir);
- return -1;
- }
-
- /* remove all files in the directory */
- while ((dir_name = g_dir_read_name(dp)) != NULL) {
- /* g_print("removing %s\n", dir_name); */
-
- if (is_dir_exist(dir_name)) {
- if (remove_dir_recursive_real(dir_name) < 0) {
- g_warning("can't remove directory\n");
- return -1;
- }
- } else {
- if (g_unlink(dir_name) < 0)
- FILE_OP_ERROR(dir_name, "unlink");
- }
- }
-
- g_dir_close(dp);
-
- if (g_chdir(prev_dir) < 0) {
- FILE_OP_ERROR(prev_dir, "chdir");
- g_free(prev_dir);
- return -1;
- }
-
- g_free(prev_dir);
-
- if (g_rmdir(dir) < 0) {
- FILE_OP_ERROR(dir, "rmdir");
- return -1;
- }
-
- return 0;
-}
-
-gint remove_dir_recursive(const gchar *dir)
-{
- gchar *cur_dir;
- gint ret;
-
- cur_dir = g_get_current_dir();
-
- if (g_chdir(dir) < 0) {
- FILE_OP_ERROR(dir, "chdir");
- ret = -1;
- goto leave;
- }
- if (g_chdir("..") < 0) {
- FILE_OP_ERROR(dir, "chdir");
- ret = -1;
- goto leave;
- }
-
- ret = remove_dir_recursive_real(dir);
-
-leave:
- if (is_dir_exist(cur_dir)) {
- if (g_chdir(cur_dir) < 0) {
- FILE_OP_ERROR(cur_dir, "chdir");
- }
- }
-
- g_free(cur_dir);
-
- return ret;
-}
-
-gint rename_force(const gchar *oldpath, const gchar *newpath)
-{
-#ifndef G_OS_UNIX
- if (!is_file_entry_exist(oldpath)) {
- errno = ENOENT;
- return -1;
- }
- if (is_file_exist(newpath)) {
- if (g_unlink(newpath) < 0)
- FILE_OP_ERROR(newpath, "unlink");
- }
-#endif
- return g_rename(oldpath, newpath);
-}
-
-gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup)
-{
- FILE *src_fp, *dest_fp;
- gint n_read;
- gchar buf[BUFSIZ];
- gchar *dest_bak = NULL;
- gboolean err = FALSE;
-
- if ((src_fp = g_fopen(src, "rb")) == NULL) {
- FILE_OP_ERROR(src, "fopen");
- return -1;
- }
- if (is_file_exist(dest)) {
- dest_bak = g_strconcat(dest, ".bak", NULL);
- if (rename_force(dest, dest_bak) < 0) {
- FILE_OP_ERROR(dest, "rename");
- fclose(src_fp);
- g_free(dest_bak);
- return -1;
- }
- }
-
- if ((dest_fp = g_fopen(dest, "wb")) == NULL) {
- FILE_OP_ERROR(dest, "fopen");
- fclose(src_fp);
- if (dest_bak) {
- if (rename_force(dest_bak, dest) < 0)
- FILE_OP_ERROR(dest_bak, "rename");
- g_free(dest_bak);
- }
- return -1;
- }
-
- if (change_file_mode_rw(dest_fp, dest) < 0) {
- FILE_OP_ERROR(dest, "chmod");
- g_warning(_("can't change file mode\n"));
- }
-
- while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), src_fp)) > 0) {
- if (n_read < sizeof(buf) && ferror(src_fp))
- break;
- if (fwrite(buf, n_read, 1, dest_fp) < 1) {
- g_warning(_("writing to %s failed.\n"), dest);
- fclose(dest_fp);
- fclose(src_fp);
- g_unlink(dest);
- if (dest_bak) {
- if (rename_force(dest_bak, dest) < 0)
- FILE_OP_ERROR(dest_bak, "rename");
- g_free(dest_bak);
- }
- return -1;
- }
- }
-
- if (ferror(src_fp)) {
- FILE_OP_ERROR(src, "fread");
- err = TRUE;
- }
- fclose(src_fp);
- if (fclose(dest_fp) == EOF) {
- FILE_OP_ERROR(dest, "fclose");
- err = TRUE;
- }
-
- if (err) {
- g_unlink(dest);
- if (dest_bak) {
- if (rename_force(dest_bak, dest) < 0)
- FILE_OP_ERROR(dest_bak, "rename");
- g_free(dest_bak);
- }
- return -1;
- }
-
- if (keep_backup == FALSE && dest_bak)
- g_unlink(dest_bak);
-
- g_free(dest_bak);
-
- return 0;
-}
-
-gint copy_dir(const gchar *src, const gchar *dest)
-{
- GDir *dir;
- const gchar *dir_name;
- gchar *src_file;
- gchar *dest_file;
-
- if ((dir = g_dir_open(src, 0, NULL)) == NULL) {
- g_warning("failed to open directory: %s\n", src);
- return -1;
- }
-
- if (make_dir_hier(dest) < 0) {
- g_dir_close(dir);
- return -1;
- }
-
- while ((dir_name = g_dir_read_name(dir)) != NULL) {
- src_file = g_strconcat(src, G_DIR_SEPARATOR_S, dir_name, NULL);
- dest_file = g_strconcat(dest, G_DIR_SEPARATOR_S, dir_name,
- NULL);
- if (is_file_exist(src_file))
- copy_file(src_file, dest_file, FALSE);
- g_free(dest_file);
- g_free(src_file);
- }
-
- g_dir_close(dir);
-
- return 0;
-}
-
-gint move_file(const gchar *src, const gchar *dest, gboolean overwrite)
-{
- if (overwrite == FALSE && is_file_exist(dest)) {
- g_warning("move_file(): file %s already exists.", dest);
- return -1;
- }
-
- if (rename_force(src, dest) == 0) return 0;
-
- if (EXDEV != errno) {
- FILE_OP_ERROR(src, "rename");
- return -1;
- }
-
- if (copy_file(src, dest, FALSE) < 0) return -1;
-
- g_unlink(src);
-
- return 0;
-}
-
-gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest)
-{
- FILE *dest_fp;
- gint n_read;
- gint bytes_left, to_read;
- gchar buf[BUFSIZ];
- gboolean err = FALSE;
-
- if (fseek(fp, offset, SEEK_SET) < 0) {
- perror("fseek");
- return -1;
- }
-
- if ((dest_fp = g_fopen(dest, "wb")) == NULL) {
- FILE_OP_ERROR(dest, "fopen");
- return -1;
- }
-
- if (change_file_mode_rw(dest_fp, dest) < 0) {
- FILE_OP_ERROR(dest, "chmod");
- g_warning("can't change file mode\n");
- }
-
- bytes_left = length;
- to_read = MIN(bytes_left, sizeof(buf));
-
- while ((n_read = fread(buf, sizeof(gchar), to_read, fp)) > 0) {
- if (n_read < to_read && ferror(fp))
- break;
- if (fwrite(buf, n_read, 1, dest_fp) < 1) {
- g_warning(_("writing to %s failed.\n"), dest);
- fclose(dest_fp);
- g_unlink(dest);
- return -1;
- }
- bytes_left -= n_read;
- if (bytes_left == 0)
- break;
- to_read = MIN(bytes_left, sizeof(buf));
- }
-
- if (ferror(fp)) {
- perror("fread");
- err = TRUE;
- }
- if (fclose(dest_fp) == EOF) {
- FILE_OP_ERROR(dest, "fclose");
- err = TRUE;
- }
-
- if (err) {
- g_unlink(dest);
- return -1;
- }
-
- return 0;
-}
-
-/* convert line endings into CRLF. If the last line doesn't end with
- * linebreak, add it.
- */
-gchar *canonicalize_str(const gchar *str)
-{
- const gchar *p;
- guint new_len = 0;
- gchar *out, *outp;
-
- for (p = str; *p != '\0'; ++p) {
- if (*p != '\r') {
- ++new_len;
- if (*p == '\n')
- ++new_len;
- }
- }
- if (p == str || *(p - 1) != '\n')
- new_len += 2;
-
- out = outp = g_malloc(new_len + 1);
- for (p = str; *p != '\0'; ++p) {
- if (*p != '\r') {
- if (*p == '\n')
- *outp++ = '\r';
- *outp++ = *p;
- }
- }
- if (p == str || *(p - 1) != '\n') {
- *outp++ = '\r';
- *outp++ = '\n';
- }
- *outp = '\0';
-
- return out;
-}
-
-gint canonicalize_file(const gchar *src, const gchar *dest)
-{
- FILE *src_fp, *dest_fp;
- gchar buf[BUFFSIZE];
- gint len;
- gboolean err = FALSE;
- gboolean last_linebreak = FALSE;
-
- if ((src_fp = g_fopen(src, "rb")) == NULL) {
- FILE_OP_ERROR(src, "fopen");
- return -1;
- }
-
- if ((dest_fp = g_fopen(dest, "wb")) == NULL) {
- FILE_OP_ERROR(dest, "fopen");
- fclose(src_fp);
- return -1;
- }
-
- if (change_file_mode_rw(dest_fp, dest) < 0) {
- FILE_OP_ERROR(dest, "chmod");
- g_warning("can't change file mode\n");
- }
-
- while (fgets(buf, sizeof(buf), src_fp) != NULL) {
- gint r = 0;
-
- len = strlen(buf);
- if (len == 0) break;
- last_linebreak = FALSE;
-
- if (buf[len - 1] != '\n') {
- last_linebreak = TRUE;
- r = fputs(buf, dest_fp);
- } else if (len > 1 && buf[len - 1] == '\n' && buf[len - 2] == '\r') {
- r = fputs(buf, dest_fp);
- } else {
- if (len > 1) {
- r = fwrite(buf, len - 1, 1, dest_fp);
- if (r != 1)
- r = EOF;
- }
- if (r != EOF)
- r = fputs("\r\n", dest_fp);
- }
-
- if (r == EOF) {
- g_warning("writing to %s failed.\n", dest);
- fclose(dest_fp);
- fclose(src_fp);
- g_unlink(dest);
- return -1;
- }
- }
-
- if (last_linebreak == TRUE) {
- if (fputs("\r\n", dest_fp) == EOF)
- err = TRUE;
- }
-
- if (ferror(src_fp)) {
- FILE_OP_ERROR(src, "fgets");
- err = TRUE;
- }
- fclose(src_fp);
- if (fclose(dest_fp) == EOF) {
- FILE_OP_ERROR(dest, "fclose");
- err = TRUE;
- }
-
- if (err) {
- g_unlink(dest);
- return -1;
- }
-
- return 0;
-}
-
-gint canonicalize_file_replace(const gchar *file)
-{
- gchar *tmp_file;
-
- tmp_file = get_tmp_file();
-
- if (canonicalize_file(file, tmp_file) < 0) {
- g_free(tmp_file);
- return -1;
- }
-
- if (move_file(tmp_file, file, TRUE) < 0) {
- g_warning("can't replace %s .\n", file);
- g_unlink(tmp_file);
- g_free(tmp_file);
- return -1;
- }
-
- g_free(tmp_file);
- return 0;
-}
-
-gint uncanonicalize_file(const gchar *src, const gchar *dest)
-{
- FILE *src_fp, *dest_fp;
- gchar buf[BUFFSIZE];
- gboolean err = FALSE;
-
- if ((src_fp = g_fopen(src, "rb")) == NULL) {
- FILE_OP_ERROR(src, "fopen");
- return -1;
- }
-
- if ((dest_fp = g_fopen(dest, "wb")) == NULL) {
- FILE_OP_ERROR(dest, "fopen");
- fclose(src_fp);
- return -1;
- }
-
- if (change_file_mode_rw(dest_fp, dest) < 0) {
- FILE_OP_ERROR(dest, "chmod");
- g_warning("can't change file mode\n");
- }
-
- while (fgets(buf, sizeof(buf), src_fp) != NULL) {
- strcrchomp(buf);
- if (fputs(buf, dest_fp) == EOF) {
- g_warning("writing to %s failed.\n", dest);
- fclose(dest_fp);
- fclose(src_fp);
- g_unlink(dest);
- return -1;
- }
- }
-
- if (ferror(src_fp)) {
- FILE_OP_ERROR(src, "fgets");
- err = TRUE;
- }
- fclose(src_fp);
- if (fclose(dest_fp) == EOF) {
- FILE_OP_ERROR(dest, "fclose");
- err = TRUE;
- }
-
- if (err) {
- g_unlink(dest);
- return -1;
- }
-
- return 0;
-}
-
-gint uncanonicalize_file_replace(const gchar *file)
-{
- gchar *tmp_file;
-
- tmp_file = get_tmp_file();
-
- if (uncanonicalize_file(file, tmp_file) < 0) {
- g_free(tmp_file);
- return -1;
- }
-
- if (move_file(tmp_file, file, TRUE) < 0) {
- g_warning("can't replace %s .\n", file);
- g_unlink(tmp_file);
- g_free(tmp_file);
- return -1;
- }
-
- g_free(tmp_file);
- return 0;
-}
-
-gchar *normalize_newlines(const gchar *str)
-{
- const gchar *p = str;
- gchar *out, *outp;
-
- out = outp = g_malloc(strlen(str) + 1);
- for (p = str; *p != '\0'; ++p) {
- if (*p == '\r') {
- if (*(p + 1) != '\n')
- *outp++ = '\n';
- } else
- *outp++ = *p;
- }
-
- *outp = '\0';
-
- return out;
-}
-
-gchar *get_outgoing_rfc2822_str(FILE *fp)
-{
- gchar buf[BUFFSIZE];
- GString *str;
- gchar *ret;
-
- str = g_string_new(NULL);
-
- /* output header part */
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- strretchomp(buf);
- if (!g_ascii_strncasecmp(buf, "Bcc:", 4)) {
- gint next;
-
- for (;;) {
- next = fgetc(fp);
- if (next == EOF)
- break;
- else if (next != ' ' && next != '\t') {
- ungetc(next, fp);
- break;
- }
- if (fgets(buf, sizeof(buf), fp) == NULL)
- break;
- }
-#if 0
- } else if (!g_ascii_strncasecmp(buf, "Date:", 5)) {
- get_rfc822_date(buf, sizeof(buf));
- g_string_append_printf(str, "Date: %s\r\n", buf);
-#endif
- } else {
- g_string_append(str, buf);
- g_string_append(str, "\r\n");
- if (buf[0] == '\0')
- break;
- }
- }
-
- /* output body part */
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- strretchomp(buf);
- if (buf[0] == '.')
- g_string_append_c(str, '.');
- g_string_append(str, buf);
- g_string_append(str, "\r\n");
- }
-
- ret = str->str;
- g_string_free(str, FALSE);
-
- return ret;
-}
-
-/*
- * Create a new boundary in a way that it is very unlikely that this
- * will occur in the following text. It would be easy to ensure
- * uniqueness if everything is either quoted-printable or base64
- * encoded (note that conversion is allowed), but because MIME bodies
- * may be nested, it may happen that the same boundary has already
- * been used. We avoid scanning the message for conflicts and hope the
- * best.
- *
- * boundary := 0*69<bchars> bcharsnospace
- * bchars := bcharsnospace / " "
- * bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
- * "+" / "_" / "," / "-" / "." /
- * "/" / ":" / "=" / "?"
- *
- * some special characters removed because of buggy MTAs
- */
-
-gchar *generate_mime_boundary(const gchar *prefix)
-{
- static gchar tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "1234567890+_./=";
- gchar buf_uniq[17];
- gchar buf_date[64];
- gint i;
-
- for (i = 0; i < sizeof(buf_uniq) - 1; i++)
- buf_uniq[i] = tbl[g_random_int_range(0, sizeof(tbl) - 1)];
- buf_uniq[i] = '\0';
-
- get_rfc822_date(buf_date, sizeof(buf_date));
- subst_char(buf_date, ' ', '_');
- subst_char(buf_date, ',', '_');
- subst_char(buf_date, ':', '_');
-
- return g_strdup_printf("%s=_%s_%s", prefix ? prefix : "Multipart",
- buf_date, buf_uniq);
-}
-
-gint change_file_mode_rw(FILE *fp, const gchar *file)
-{
-#if HAVE_FCHMOD
- return fchmod(fileno(fp), S_IRUSR|S_IWUSR);
-#else
- return g_chmod(file, S_IRUSR|S_IWUSR);
-#endif
-}
-
-FILE *my_tmpfile(void)
-{
-#if HAVE_MKSTEMP
- const gchar suffix[] = ".XXXXXX";
- const gchar *tmpdir;
- guint tmplen;
- const gchar *progname;
- guint proglen;
- gchar *fname;
- gint fd;
- FILE *fp;
-
- tmpdir = get_tmp_dir();
- tmplen = strlen(tmpdir);
- progname = g_get_prgname();
- proglen = strlen(progname);
- Xalloca(fname, tmplen + 1 + proglen + sizeof(suffix),
- return tmpfile());
-
- memcpy(fname, tmpdir, tmplen);
- fname[tmplen] = G_DIR_SEPARATOR;
- memcpy(fname + tmplen + 1, progname, proglen);
- memcpy(fname + tmplen + 1 + proglen, suffix, sizeof(suffix));
-
- fd = mkstemp(fname);
- if (fd < 0)
- return tmpfile();
-
- g_unlink(fname);
-
- fp = fdopen(fd, "w+b");
- if (!fp)
- close(fd);
- else
- return fp;
-#endif /* HAVE_MKSTEMP */
-
- return tmpfile();
-}
-
-FILE *str_open_as_stream(const gchar *str)
-{
- FILE *fp;
- size_t len;
-
- g_return_val_if_fail(str != NULL, NULL);
-
- fp = my_tmpfile();
- if (!fp) {
- FILE_OP_ERROR("str_open_as_stream", "my_tmpfile");
- return NULL;
- }
-
- len = strlen(str);
- if (len == 0) return fp;
-
- if (fwrite(str, len, 1, fp) != 1) {
- FILE_OP_ERROR("str_open_as_stream", "fwrite");
- fclose(fp);
- return NULL;
- }
-
- rewind(fp);
- return fp;
-}
-
-gint str_write_to_file(const gchar *str, const gchar *file)
-{
- FILE *fp;
- size_t len;
-
- g_return_val_if_fail(str != NULL, -1);
- g_return_val_if_fail(file != NULL, -1);
-
- if ((fp = g_fopen(file, "wb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return -1;
- }
-
- len = strlen(str);
- if (len == 0) {
- fclose(fp);
- return 0;
- }
-
- if (fwrite(str, len, 1, fp) != 1) {
- FILE_OP_ERROR(file, "fwrite");
- fclose(fp);
- g_unlink(file);
- return -1;
- }
-
- if (fclose(fp) == EOF) {
- FILE_OP_ERROR(file, "fclose");
- g_unlink(file);
- return -1;
- }
-
- return 0;
-}
-
-gchar *file_read_to_str(const gchar *file)
-{
- FILE *fp;
- gchar *str;
-
- g_return_val_if_fail(file != NULL, NULL);
-
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return NULL;
- }
-
- str = file_read_stream_to_str(fp);
-
- fclose(fp);
-
- return str;
-}
-
-gchar *file_read_stream_to_str(FILE *fp)
-{
- GByteArray *array;
- guchar buf[BUFSIZ];
- gint n_read;
- gchar *str;
-
- g_return_val_if_fail(fp != NULL, NULL);
-
- array = g_byte_array_new();
-
- while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), fp)) > 0) {
- if (n_read < sizeof(buf) && ferror(fp))
- break;
- g_byte_array_append(array, buf, n_read);
- }
-
- if (ferror(fp)) {
- FILE_OP_ERROR("file stream", "fread");
- g_byte_array_free(array, TRUE);
- return NULL;
- }
-
- buf[0] = '\0';
- g_byte_array_append(array, buf, 1);
- str = (gchar *)array->data;
- g_byte_array_free(array, FALSE);
-
- return str;
-}
-
-gint execute_async(gchar *const argv[])
-{
- g_return_val_if_fail(argv != NULL && argv[0] != NULL, -1);
-
- if (g_spawn_async(NULL, (gchar **)argv, NULL, G_SPAWN_SEARCH_PATH,
- NULL, NULL, NULL, FALSE) == FALSE) {
- g_warning("Can't execute command: %s\n", argv[0]);
- return -1;
- }
-
- return 0;
-}
-
-gint execute_sync(gchar *const argv[])
-{
- gint status;
-
- g_return_val_if_fail(argv != NULL && argv[0] != NULL, -1);
-
- if (g_spawn_sync(NULL, (gchar **)argv, NULL, G_SPAWN_SEARCH_PATH,
- NULL, NULL, NULL, NULL, &status, NULL) == FALSE) {
- g_warning("Can't execute command: %s\n", argv[0]);
- return -1;
- }
-
-#ifdef G_OS_UNIX
- if (WIFEXITED(status))
- return WEXITSTATUS(status);
- else
- return -1;
-#else
- return status;
-#endif
-}
-
-gint execute_command_line(const gchar *cmdline, gboolean async)
-{
- gchar **argv;
- gint ret;
-
- debug_print("execute_command_line(): executing: %s\n", cmdline);
-
- argv = strsplit_with_quote(cmdline, " ", 0);
-
- if (async)
- ret = execute_async(argv);
- else
- ret = execute_sync(argv);
-
- g_strfreev(argv);
-
- return ret;
-}
-
-gchar *get_command_output(const gchar *cmdline)
-{
- gchar *child_stdout;
- gint status;
-
- g_return_val_if_fail(cmdline != NULL, NULL);
-
- debug_print("get_command_output(): executing: %s\n", cmdline);
-
- if (g_spawn_command_line_sync(cmdline, &child_stdout, NULL, &status,
- NULL) == FALSE) {
- g_warning("Can't execute command: %s\n", cmdline);
- return NULL;
- }
-
- return child_stdout;
-}
-
-gint open_uri(const gchar *uri, const gchar *cmdline)
-{
- gchar buf[BUFFSIZE];
- gchar *p;
-
- g_return_val_if_fail(uri != NULL, -1);
-
- if (cmdline &&
- (p = strchr(cmdline, '%')) && *(p + 1) == 's' &&
- !strchr(p + 2, '%'))
- g_snprintf(buf, sizeof(buf), cmdline, uri);
- else {
- if (cmdline)
- g_warning("Open URI command line is invalid "
- "(there must be only one '%%s'): %s",
- cmdline);
- g_snprintf(buf, sizeof(buf), DEFAULT_BROWSER_CMD, uri);
- }
-
- execute_command_line(buf, TRUE);
-
- return 0;
-}
-
-time_t remote_tzoffset_sec(const gchar *zone)
-{
- static gchar ustzstr[] = "PSTPDTMSTMDTCSTCDTESTEDT";
- gchar zone3[4];
- gchar *p;
- gchar c;
- gint iustz;
- gint offset;
- time_t remoteoffset;
-
- strncpy(zone3, zone, 3);
- zone3[3] = '\0';
- remoteoffset = 0;
-
- if (sscanf(zone, "%c%d", &c, &offset) == 2 &&
- (c == '+' || c == '-')) {
- remoteoffset = ((offset / 100) * 60 + (offset % 100)) * 60;
- if (c == '-')
- remoteoffset = -remoteoffset;
- } else if (!strncmp(zone, "UT" , 2) ||
- !strncmp(zone, "GMT", 2)) {
- remoteoffset = 0;
- } else if (strlen(zone3) == 3) {
- for (p = ustzstr; *p != '\0'; p += 3) {
- if (!g_ascii_strncasecmp(p, zone3, 3)) {
- iustz = ((gint)(p - ustzstr) / 3 + 1) / 2 - 8;
- remoteoffset = iustz * 3600;
- break;
- }
- }
- if (*p == '\0')
- return -1;
- } else if (strlen(zone3) == 1) {
- switch (zone[0]) {
- case 'Z': remoteoffset = 0; break;
- case 'A': remoteoffset = -1; break;
- case 'B': remoteoffset = -2; break;
- case 'C': remoteoffset = -3; break;
- case 'D': remoteoffset = -4; break;
- case 'E': remoteoffset = -5; break;
- case 'F': remoteoffset = -6; break;
- case 'G': remoteoffset = -7; break;
- case 'H': remoteoffset = -8; break;
- case 'I': remoteoffset = -9; break;
- case 'K': remoteoffset = -10; break; /* J is not used */
- case 'L': remoteoffset = -11; break;
- case 'M': remoteoffset = -12; break;
- case 'N': remoteoffset = 1; break;
- case 'O': remoteoffset = 2; break;
- case 'P': remoteoffset = 3; break;
- case 'Q': remoteoffset = 4; break;
- case 'R': remoteoffset = 5; break;
- case 'S': remoteoffset = 6; break;
- case 'T': remoteoffset = 7; break;
- case 'U': remoteoffset = 8; break;
- case 'V': remoteoffset = 9; break;
- case 'W': remoteoffset = 10; break;
- case 'X': remoteoffset = 11; break;
- case 'Y': remoteoffset = 12; break;
- default: remoteoffset = 0; break;
- }
- remoteoffset = remoteoffset * 3600;
- } else
- return -1;
-
- return remoteoffset;
-}
-
-time_t tzoffset_sec(time_t *now)
-{
- struct tm gmt, *lt;
- gint off;
-
- gmt = *gmtime(now);
- lt = localtime(now);
-
- off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min;
-
- if (lt->tm_year < gmt.tm_year)
- off -= 24 * 60;
- else if (lt->tm_year > gmt.tm_year)
- off += 24 * 60;
- else if (lt->tm_yday < gmt.tm_yday)
- off -= 24 * 60;
- else if (lt->tm_yday > gmt.tm_yday)
- off += 24 * 60;
-
- if (off >= 24 * 60) /* should be impossible */
- off = 23 * 60 + 59; /* if not, insert silly value */
- if (off <= -24 * 60)
- off = -(23 * 60 + 59);
-
- return off * 60;
-}
-
-/* calculate timezone offset */
-gchar *tzoffset(time_t *now)
-{
- static gchar offset_string[6];
- struct tm gmt, *lt;
- gint off;
- gchar sign = '+';
-
- gmt = *gmtime(now);
- lt = localtime(now);
-
- off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min;
-
- if (lt->tm_year < gmt.tm_year)
- off -= 24 * 60;
- else if (lt->tm_year > gmt.tm_year)
- off += 24 * 60;
- else if (lt->tm_yday < gmt.tm_yday)
- off -= 24 * 60;
- else if (lt->tm_yday > gmt.tm_yday)
- off += 24 * 60;
-
- if (off < 0) {
- sign = '-';
- off = -off;
- }
-
- if (off >= 24 * 60) /* should be impossible */
- off = 23 * 60 + 59; /* if not, insert silly value */
-
- sprintf(offset_string, "%c%02d%02d", sign, off / 60, off % 60);
-
- return offset_string;
-}
-
-void get_rfc822_date(gchar *buf, gint len)
-{
- struct tm *lt;
- time_t t;
- gchar day[4], mon[4];
- gint dd, hh, mm, ss, yyyy;
-
- t = time(NULL);
- lt = localtime(&t);
-
- sscanf(asctime(lt), "%3s %3s %d %d:%d:%d %d\n",
- day, mon, &dd, &hh, &mm, &ss, &yyyy);
- g_snprintf(buf, len, "%s, %d %s %d %02d:%02d:%02d %s",
- day, dd, mon, yyyy, hh, mm, ss, tzoffset(&t));
-}
-
-/* just a wrapper to suppress the warning of gcc about %c */
-size_t my_strftime(gchar *s, size_t max, const gchar *format,
- const struct tm *tm)
-{
- return strftime(s, max, format, tm);
-}
-
-static FILE *log_fp = NULL;
-
-void set_log_file(const gchar *filename)
-{
- if (log_fp) return;
- log_fp = g_fopen(filename, "wb");
- if (!log_fp)
- FILE_OP_ERROR(filename, "fopen");
-}
-
-void close_log_file(void)
-{
- if (log_fp) {
- fclose(log_fp);
- log_fp = NULL;
- }
-}
-
-static guint log_verbosity_count = 0;
-
-void set_log_verbosity(gboolean verbose)
-{
- if (verbose)
- log_verbosity_count++;
- else if (log_verbosity_count > 0)
- log_verbosity_count--;
-}
-
-gboolean get_debug_mode(void)
-{
- return debug_mode;
-}
-
-void set_debug_mode(gboolean enable)
-{
- debug_mode = enable;
-}
-
-static void log_dummy_func(const gchar *str)
-{
-}
-
-static LogFunc log_print_ui_func = log_dummy_func;
-static LogFunc log_message_ui_func = log_dummy_func;
-static LogFunc log_warning_ui_func = log_dummy_func;
-static LogFunc log_error_ui_func = log_dummy_func;
-
-static LogFunc log_show_status_func = log_dummy_func;
-
-void set_log_ui_func(LogFunc print_func, LogFunc message_func,
- LogFunc warning_func, LogFunc error_func)
-{
- log_print_ui_func = print_func;
- log_message_ui_func = message_func;
- log_warning_ui_func = warning_func;
- log_error_ui_func = error_func;
-}
-
-void set_log_show_status_func(LogFunc status_func)
-{
- log_show_status_func = status_func;
-}
-
-void debug_print(const gchar *format, ...)
-{
- va_list args;
- gchar buf[BUFFSIZE];
-
- if (!debug_mode) return;
-
- va_start(args, format);
- g_vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
-
- g_print("%s", buf);
-}
-
-#define TIME_LEN 11
-
-void log_print(const gchar *format, ...)
-{
- va_list args;
- gchar buf[BUFFSIZE + TIME_LEN];
- time_t t;
-
- time(&t);
- strftime(buf, TIME_LEN + 1, "[%H:%M:%S] ", localtime(&t));
-
- va_start(args, format);
- g_vsnprintf(buf + TIME_LEN, BUFFSIZE, format, args);
- va_end(args);
-
- if (debug_mode) fputs(buf, stdout);
- log_print_ui_func(buf);
- if (log_fp) {
- fputs(buf, log_fp);
- fflush(log_fp);
- }
- if (log_verbosity_count)
- log_show_status_func(buf + TIME_LEN);
-}
-
-void log_message(const gchar *format, ...)
-{
- va_list args;
- gchar buf[BUFFSIZE + TIME_LEN];
- time_t t;
-
- time(&t);
- strftime(buf, TIME_LEN + 1, "[%H:%M:%S] ", localtime(&t));
-
- va_start(args, format);
- g_vsnprintf(buf + TIME_LEN, BUFFSIZE, format, args);
- va_end(args);
-
- if (debug_mode) g_message("%s", buf + TIME_LEN);
- log_message_ui_func(buf + TIME_LEN);
- if (log_fp) {
- fwrite(buf, TIME_LEN, 1, log_fp);
- fputs("* message: ", log_fp);
- fputs(buf + TIME_LEN, log_fp);
- fflush(log_fp);
- }
- log_show_status_func(buf + TIME_LEN);
-}
-
-void log_warning(const gchar *format, ...)
-{
- va_list args;
- gchar buf[BUFFSIZE + TIME_LEN];
- time_t t;
-
- time(&t);
- strftime(buf, TIME_LEN + 1, "[%H:%M:%S] ", localtime(&t));
-
- va_start(args, format);
- g_vsnprintf(buf + TIME_LEN, BUFFSIZE, format, args);
- va_end(args);
-
- g_warning("%s", buf);
- log_warning_ui_func(buf + TIME_LEN);
- if (log_fp) {
- fwrite(buf, TIME_LEN, 1, log_fp);
- fputs("** warning: ", log_fp);
- fputs(buf + TIME_LEN, log_fp);
- fflush(log_fp);
- }
-}
-
-void log_error(const gchar *format, ...)
-{
- va_list args;
- gchar buf[BUFFSIZE + TIME_LEN];
- time_t t;
-
- time(&t);
- strftime(buf, TIME_LEN + 1, "[%H:%M:%S] ", localtime(&t));
-
- va_start(args, format);
- g_vsnprintf(buf + TIME_LEN, BUFFSIZE, format, args);
- va_end(args);
-
- g_warning("%s", buf);
- log_error_ui_func(buf + TIME_LEN);
- if (log_fp) {
- fwrite(buf, TIME_LEN, 1, log_fp);
- fputs("*** error: ", log_fp);
- fputs(buf + TIME_LEN, log_fp);
- fflush(log_fp);
- }
-}
diff --git a/src/utils.h b/src/utils.h
deleted file mode 100644
index fbda26a3..00000000
--- a/src/utils.h
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __UTILS_H__
-#define __UTILS_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <time.h>
-#if HAVE_ALLOCA_H
-# include <alloca.h>
-#endif
-#if HAVE_WCHAR_H
-# include <wchar.h>
-#endif
-
-/* Wrappers for C library function that take pathname arguments. */
-#if GLIB_CHECK_VERSION(2, 6, 0)
-# include <glib/gstdio.h>
-#else
-
-#define g_open open
-#define g_rename rename
-#define g_mkdir mkdir
-#define g_stat stat
-#define g_lstat lstat
-#define g_unlink unlink
-#define g_remove remove
-#define g_rmdir rmdir
-#define g_fopen fopen
-#define g_freopen freopen
-
-#endif /* GLIB_CHECK_VERSION */
-
-#if !GLIB_CHECK_VERSION(2, 7, 0)
-
-#ifdef G_OS_UNIX
-#define g_chdir chdir
-#define g_chmod chmod
-#else
-gint g_chdir (const gchar *path);
-gint g_chmod (const gchar *path,
- gint mode);
-#endif /* G_OS_UNIX */
-
-#endif /* !GLIB_CHECK_VERSION */
-
-/* The AC_CHECK_SIZEOF() in configure fails for some machines.
- * we provide some fallback values here */
-#if !SIZEOF_UNSIGNED_SHORT
- #undef SIZEOF_UNSIGNED_SHORT
- #define SIZEOF_UNSIGNED_SHORT 2
-#endif
-#if !SIZEOF_UNSIGNED_INT
- #undef SIZEOF_UNSIGNED_INT
- #define SIZEOF_UNSIGNED_INT 4
-#endif
-#if !SIZEOF_UNSIGNED_LONG
- #undef SIZEOF_UNSIGNED_LONG
- #define SIZEOF_UNSIGNED_LONG 4
-#endif
-
-#ifndef HAVE_U32_TYPEDEF
- #undef u32 /* maybe there is a macro with this name */
- typedef guint32 u32;
- #define HAVE_U32_TYPEDEF
-#endif
-
-#ifndef BIG_ENDIAN_HOST
- #if (G_BYTE_ORDER == G_BIG_ENDIAN)
- #define BIG_ENDIAN_HOST 1
- #endif
-#endif
-
-#define CHDIR_RETURN_IF_FAIL(dir) \
-{ \
- if (change_dir(dir) < 0) return; \
-}
-
-#define CHDIR_RETURN_VAL_IF_FAIL(dir, val) \
-{ \
- if (change_dir(dir) < 0) return val; \
-}
-
-#define Xalloca(ptr, size, iffail) \
-{ \
- if ((ptr = alloca(size)) == NULL) { \
- g_warning("can't allocate memory\n"); \
- iffail; \
- } \
-}
-
-#define Xstrdup_a(ptr, str, iffail) \
-{ \
- gchar *__tmp; \
- \
- if ((__tmp = alloca(strlen(str) + 1)) == NULL) { \
- g_warning("can't allocate memory\n"); \
- iffail; \
- } else \
- strcpy(__tmp, str); \
- \
- ptr = __tmp; \
-}
-
-#define Xstrndup_a(ptr, str, len, iffail) \
-{ \
- gchar *__tmp; \
- \
- if ((__tmp = alloca(len + 1)) == NULL) { \
- g_warning("can't allocate memory\n"); \
- iffail; \
- } else { \
- strncpy(__tmp, str, len); \
- __tmp[len] = '\0'; \
- } \
- \
- ptr = __tmp; \
-}
-
-#define Xstrcat_a(ptr, str1, str2, iffail) \
-{ \
- gchar *__tmp; \
- gint len1, len2; \
- \
- len1 = strlen(str1); \
- len2 = strlen(str2); \
- if ((__tmp = alloca(len1 + len2 + 1)) == NULL) { \
- g_warning("can't allocate memory\n"); \
- iffail; \
- } else { \
- memcpy(__tmp, str1, len1); \
- memcpy(__tmp + len1, str2, len2 + 1); \
- } \
- \
- ptr = __tmp; \
-}
-
-#define AUTORELEASE_STR(str, iffail) \
-{ \
- gchar *__str; \
- Xstrdup_a(__str, str, iffail); \
- g_free(str); \
- str = __str; \
-}
-
-#define FILE_OP_ERROR(file, func) \
-{ \
- fprintf(stderr, "%s: ", file); \
- fflush(stderr); \
- perror(func); \
-}
-
-typedef void (*LogFunc) (const gchar *str);
-
-/* for macro expansion */
-#define Str(x) #x
-#define Xstr(x) Str(x)
-
-void list_free_strings (GList *list);
-void slist_free_strings (GSList *list);
-
-void hash_free_strings (GHashTable *table);
-void hash_free_value_mem (GHashTable *table);
-
-gint str_case_equal (gconstpointer v,
- gconstpointer v2);
-guint str_case_hash (gconstpointer key);
-
-void ptr_array_free_strings (GPtrArray *array);
-
-typedef gboolean (*StrFindFunc) (const gchar *haystack,
- const gchar *needle);
-
-gboolean str_find (const gchar *haystack,
- const gchar *needle);
-gboolean str_case_find (const gchar *haystack,
- const gchar *needle);
-gboolean str_find_equal (const gchar *haystack,
- const gchar *needle);
-gboolean str_case_find_equal (const gchar *haystack,
- const gchar *needle);
-
-/* number-string conversion */
-gint to_number (const gchar *nstr);
-gchar *itos_buf (gchar *nstr,
- gint n);
-gchar *itos (gint n);
-gchar *to_human_readable (off_t size);
-
-/* alternative string functions */
-gint strcmp2 (const gchar *s1,
- const gchar *s2);
-gint path_cmp (const gchar *s1,
- const gchar *s2);
-gchar *strretchomp (gchar *str);
-gchar *strtailchomp (gchar *str,
- gchar tail_char);
-gchar *strcrchomp (gchar *str);
-gchar *strcasestr (const gchar *haystack,
- const gchar *needle);
-gpointer my_memmem (gconstpointer haystack,
- size_t haystacklen,
- gconstpointer needle,
- size_t needlelen);
-gchar *strncpy2 (gchar *dest,
- const gchar *src,
- size_t n);
-
-/* wide-character functions */
-#if !HAVE_ISWALNUM
-int iswalnum (wint_t wc);
-#endif
-#if !HAVE_ISWSPACE
-int iswspace (wint_t wc);
-#endif
-#if !HAVE_TOWLOWER
-wint_t towlower (wint_t wc);
-#endif
-
-#if !HAVE_WCSLEN
-size_t wcslen (const wchar_t *s);
-#endif
-#if !HAVE_WCSCPY
-wchar_t *wcscpy (wchar_t *dest,
- const wchar_t *src);
-#endif
-#if !HAVE_WCSNCPY
-wchar_t *wcsncpy (wchar_t *dest,
- const wchar_t *src,
- size_t n);
-#endif
-
-wchar_t *wcsdup (const wchar_t *s);
-wchar_t *wcsndup (const wchar_t *s,
- size_t n);
-wchar_t *strdup_mbstowcs (const gchar *s);
-gchar *strdup_wcstombs (const wchar_t *s);
-gint wcsncasecmp (const wchar_t *s1,
- const wchar_t *s2,
- size_t n);
-wchar_t *wcscasestr (const wchar_t *haystack,
- const wchar_t *needle);
-gint get_mbs_len (const gchar *s);
-
-gboolean is_next_nonascii (const gchar *s);
-gint get_next_word_len (const gchar *s);
-
-/* functions for string parsing */
-gint subject_compare (const gchar *s1,
- const gchar *s2);
-gint subject_compare_for_sort (const gchar *s1,
- const gchar *s2);
-void trim_subject_for_compare (gchar *str);
-void trim_subject_for_sort (gchar *str);
-void trim_subject (gchar *str);
-void eliminate_parenthesis (gchar *str,
- gchar op,
- gchar cl);
-void extract_parenthesis (gchar *str,
- gchar op,
- gchar cl);
-
-void extract_parenthesis_with_skip_quote (gchar *str,
- gchar quote_chr,
- gchar op,
- gchar cl);
-
-void eliminate_quote (gchar *str,
- gchar quote_chr);
-void extract_quote (gchar *str,
- gchar quote_chr);
-void eliminate_address_comment (gchar *str);
-gchar *strchr_with_skip_quote (const gchar *str,
- gint quote_chr,
- gint c);
-gchar *strrchr_with_skip_quote (const gchar *str,
- gint quote_chr,
- gint c);
-void extract_address (gchar *str);
-void extract_list_id_str (gchar *str);
-
-GSList *address_list_append (GSList *addr_list,
- const gchar *str);
-GSList *references_list_prepend (GSList *msgid_list,
- const gchar *str);
-GSList *references_list_append (GSList *msgid_list,
- const gchar *str);
-GSList *newsgroup_list_append (GSList *group_list,
- const gchar *str);
-
-GList *add_history (GList *list,
- const gchar *str);
-
-void remove_return (gchar *str);
-void remove_space (gchar *str);
-void unfold_line (gchar *str);
-void subst_char (gchar *str,
- gchar orig,
- gchar subst);
-void subst_chars (gchar *str,
- gchar *orig,
- gchar subst);
-void subst_null (gchar *str,
- gint len,
- gchar subst);
-void subst_for_filename (gchar *str);
-gboolean is_header_line (const gchar *str);
-gboolean is_ascii_str (const gchar *str);
-gint get_quote_level (const gchar *str);
-gint check_line_length (const gchar *str,
- gint max_chars,
- gint *line);
-
-gchar *strstr_with_skip_quote (const gchar *haystack,
- const gchar *needle);
-gchar *strchr_parenthesis_close (const gchar *str,
- gchar op,
- gchar cl);
-
-gchar **strsplit_parenthesis (const gchar *str,
- gchar op,
- gchar cl,
- gint max_tokens);
-gchar **strsplit_with_quote (const gchar *str,
- const gchar *delim,
- gint max_tokens);
-
-gchar *get_abbrev_newsgroup_name (const gchar *group,
- gint len);
-gchar *trim_string (const gchar *str,
- gint len);
-gchar *trim_string_before (const gchar *str,
- gint len);
-
-GList *uri_list_extract_filenames (const gchar *uri_list);
-gboolean is_uri_string (const gchar *str);
-gchar *get_uri_path (const gchar *uri);
-gint get_uri_len (const gchar *str);
-void decode_uri (gchar *decoded_uri,
- const gchar *encoded_uri);
-gchar *encode_uri (const gchar *filename);
-gint scan_mailto_url (const gchar *mailto,
- gchar **to,
- gchar **cc,
- gchar **bcc,
- gchar **subject,
- gchar **body);
-
-/* return static strings */
-const gchar *get_home_dir (void);
-const gchar *get_rc_dir (void);
-const gchar *get_old_rc_dir (void);
-const gchar *get_mail_base_dir (void);
-const gchar *get_news_cache_dir (void);
-const gchar *get_imap_cache_dir (void);
-const gchar *get_mime_tmp_dir (void);
-const gchar *get_template_dir (void);
-const gchar *get_tmp_dir (void);
-gchar *get_tmp_file (void);
-const gchar *get_domain_name (void);
-
-/* file / directory handling */
-off_t get_file_size (const gchar *file);
-off_t get_file_size_as_crlf (const gchar *file);
-off_t get_left_file_size (FILE *fp);
-
-gboolean file_exist (const gchar *file,
- gboolean allow_fifo);
-gboolean is_dir_exist (const gchar *dir);
-gboolean is_file_entry_exist (const gchar *file);
-gboolean dirent_is_regular_file (struct dirent *d);
-gboolean dirent_is_directory (struct dirent *d);
-
-#define is_file_exist(file) file_exist(file, FALSE)
-#define is_file_or_fifo_exist(file) file_exist(file, TRUE)
-
-gint change_dir (const gchar *dir);
-gint make_dir (const gchar *dir);
-gint make_dir_hier (const gchar *dir);
-gint remove_all_files (const gchar *dir);
-gint remove_numbered_files (const gchar *dir,
- guint first,
- guint last);
-gint remove_all_numbered_files (const gchar *dir);
-gint remove_expired_files (const gchar *dir,
- guint hours);
-gint remove_dir_recursive (const gchar *dir);
-gint rename_force (const gchar *oldpath,
- const gchar *newpath);
-gint copy_file (const gchar *src,
- const gchar *dest,
- gboolean keep_backup);
-gint copy_dir (const gchar *src,
- const gchar *dest);
-gint move_file (const gchar *src,
- const gchar *dest,
- gboolean overwrite);
-gint copy_file_part (FILE *fp,
- off_t offset,
- size_t length,
- const gchar *dest);
-
-gchar *canonicalize_str (const gchar *str);
-gint canonicalize_file (const gchar *src,
- const gchar *dest);
-gint canonicalize_file_replace (const gchar *file);
-gint uncanonicalize_file (const gchar *src,
- const gchar *dest);
-gint uncanonicalize_file_replace(const gchar *file);
-
-gchar *normalize_newlines (const gchar *str);
-
-gchar *get_outgoing_rfc2822_str (FILE *fp);
-gchar *generate_mime_boundary (const gchar *prefix);
-
-gint change_file_mode_rw (FILE *fp,
- const gchar *file);
-FILE *my_tmpfile (void);
-FILE *str_open_as_stream (const gchar *str);
-gint str_write_to_file (const gchar *str,
- const gchar *file);
-gchar *file_read_to_str (const gchar *file);
-gchar *file_read_stream_to_str (FILE *fp);
-
-/* process execution */
-gint execute_async (gchar *const argv[]);
-gint execute_sync (gchar *const argv[]);
-gint execute_command_line (const gchar *cmdline,
- gboolean async);
-gchar *get_command_output (const gchar *cmdline);
-
-/* open URI with external browser */
-gint open_uri(const gchar *uri, const gchar *cmdline);
-
-/* time functions */
-time_t remote_tzoffset_sec (const gchar *zone);
-time_t tzoffset_sec (time_t *now);
-gchar *tzoffset (time_t *now);
-void get_rfc822_date (gchar *buf,
- gint len);
-
-size_t my_strftime (gchar *s,
- size_t max,
- const gchar *format,
- const struct tm *tm);
-
-/* logging */
-void set_log_file (const gchar *filename);
-void close_log_file (void);
-void set_log_verbosity (gboolean verbose);
-gboolean get_debug_mode (void);
-void set_debug_mode (gboolean enable);
-
-void set_log_ui_func (LogFunc print_func,
- LogFunc message_func,
- LogFunc warning_func,
- LogFunc error_func);
-
-void set_log_show_status_func (LogFunc status_func);
-
-void debug_print (const gchar *format, ...) G_GNUC_PRINTF(1, 2);
-void log_print (const gchar *format, ...) G_GNUC_PRINTF(1, 2);
-void log_message (const gchar *format, ...) G_GNUC_PRINTF(1, 2);
-void log_warning (const gchar *format, ...) G_GNUC_PRINTF(1, 2);
-void log_error (const gchar *format, ...) G_GNUC_PRINTF(1, 2);
-
-#endif /* __UTILS_H__ */
diff --git a/src/uuencode.c b/src/uuencode.c
deleted file mode 100644
index e0b2e79a..00000000
--- a/src/uuencode.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <ctype.h>
-
-#define UUDECODE(c) (c=='`' ? 0 : c - ' ')
-#define N64(i) (i & ~63)
-
-const char uudigit[64] =
-{
- '`', '!', '"', '#', '$', '%', '&', '\'',
- '(', ')', '*', '+', ',', '-', '.', '/',
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', ':', ';', '<', '=', '>', '?',
- '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
- 'X', 'Y', 'Z', '[', '\\', ']', '^', '_'
-};
-
-int touufrombits(unsigned char *out, const unsigned char *in, int inlen)
-{
- int len;
-
- if (inlen > 45) return -1;
- len = (inlen * 4 + 2) / 3 + 1;
- *out++ = uudigit[inlen];
-
- for (; inlen >= 3; inlen -= 3) {
- *out++ = uudigit[in[0] >> 2];
- *out++ = uudigit[((in[0] << 4) & 0x30) | (in[1] >> 4)];
- *out++ = uudigit[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
- *out++ = uudigit[in[2] & 0x3f];
- in += 3;
- }
-
- if (inlen > 0) {
- *out++ = uudigit[(in[0] >> 2)];
- if (inlen == 1) {
- *out++ = uudigit[((in[0] << 4) & 0x30)];
- } else {
- *out++ = uudigit[(((in[0] << 4) & 0x30) | (in[1] >> 4))] ;
- *out++ = uudigit[((in[1] << 2) & 0x3c)];
- }
- }
- *out = '\0';
-
- return len;
-}
-
-int fromuutobits(char *out, const char *in)
-{
- int len, outlen, inlen;
- register unsigned char digit1, digit2;
-
- outlen = UUDECODE(in[0]);
- in += 1;
- if(outlen < 0 || outlen > 45)
- return -2;
- if(outlen == 0)
- return 0;
- inlen = (outlen * 4 + 2) / 3;
- len = 0;
-
- for( ; inlen>0; inlen-=4) {
- digit1 = UUDECODE(in[0]);
- if (N64(digit1)) return -1;
- digit2 = UUDECODE(in[1]);
- if (N64(digit2)) return -1;
- out[len++] = (digit1 << 2) | (digit2 >> 4);
- if (inlen > 2) {
- digit1 = UUDECODE(in[2]);
- if (N64(digit1)) return -1;
- out[len++] = (digit2 << 4) | (digit1 >> 2);
- if (inlen > 3) {
- digit2 = UUDECODE(in[3]);
- if (N64(digit2)) return -1;
- out[len++] = (digit1 << 6) | digit2;
- }
- }
- in += 4;
- }
-
- return len == outlen ? len : -3;
-}
diff --git a/src/uuencode.h b/src/uuencode.h
deleted file mode 100644
index 3658ebc6..00000000
--- a/src/uuencode.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-void touufrombits(unsigned char *, const unsigned char *, int);
-int fromuutobits(char *, const char *);
-
-#define X_UUENCODE_END_LINE '`'
-#define UUENCODE_END_LINE ' '
diff --git a/src/xml.c b/src/xml.c
deleted file mode 100644
index e9c4adf8..00000000
--- a/src/xml.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <glib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "xml.h"
-#include "main.h"
-#include "utils.h"
-#include "codeconv.h"
-
-#define SPARSE_MEMORY
-/* if this is defined all attr.names and tag.names are stored
- * in a hash table */
-#if defined(SPARSE_MEMORY)
-#include "stringtable.h"
-
-static StringTable *xml_string_table;
-
-static void xml_string_table_create(void)
-{
- if (xml_string_table == NULL)
- xml_string_table = string_table_new();
-}
-#define XML_STRING_ADD(str) \
- string_table_insert_string(xml_string_table, (str))
-#define XML_STRING_FREE(str) \
- string_table_free_string(xml_string_table, (str))
-
-#define XML_STRING_TABLE_CREATE() \
- xml_string_table_create()
-
-#else /* !SPARSE_MEMORY */
-
-#define XML_STRING_ADD(str) \
- g_strdup(str)
-#define XML_STRING_FREE(str) \
- g_free(str)
-
-#define XML_STRING_TABLE_CREATE()
-
-#endif /* SPARSE_MEMORY */
-
-static void xml_free_tag (XMLTag *tag);
-static gint xml_get_parenthesis (XMLFile *file,
- gchar *buf,
- gint len);
-
-XMLFile *xml_open_file(const gchar *path)
-{
- XMLFile *newfile;
-
- g_return_val_if_fail(path != NULL, NULL);
-
- XML_STRING_TABLE_CREATE();
-
- newfile = g_new(XMLFile, 1);
-
- newfile->fp = g_fopen(path, "rb");
- if (!newfile->fp) {
- g_free(newfile);
- return NULL;
- }
-
- newfile->buf = g_string_new(NULL);
- newfile->bufp = newfile->buf->str;
-
- newfile->dtd = NULL;
- newfile->encoding = NULL;
- newfile->tag_stack = NULL;
- newfile->level = 0;
- newfile->is_empty_element = FALSE;
-
- return newfile;
-}
-
-void xml_close_file(XMLFile *file)
-{
- g_return_if_fail(file != NULL);
-
- if (file->fp) fclose(file->fp);
-
- g_string_free(file->buf, TRUE);
-
- g_free(file->dtd);
- g_free(file->encoding);
-
- while (file->tag_stack != NULL)
- xml_pop_tag(file);
-
- g_free(file);
-}
-
-static GNode *xml_build_tree(XMLFile *file, GNode *parent, guint level)
-{
- GNode *node = NULL;
- XMLNode *xmlnode;
- XMLTag *tag;
-
- while (xml_parse_next_tag(file) == 0) {
- if (file->level < level) break;
- if (file->level == level) {
- g_warning("xml_build_tree(): Parse error\n");
- break;
- }
-
- tag = xml_get_current_tag(file);
- if (!tag) break;
- xmlnode = xml_node_new(xml_copy_tag(tag), NULL);
- xmlnode->element = xml_get_element(file);
- if (!parent)
- node = g_node_new(xmlnode);
- else
- node = g_node_append_data(parent, xmlnode);
-
- xml_build_tree(file, node, file->level);
- if (file->level == 0) break;
- }
-
- return node;
-}
-
-GNode *xml_parse_file(const gchar *path)
-{
- XMLFile *file;
- GNode *node;
-
- file = xml_open_file(path);
- g_return_val_if_fail(file != NULL, NULL);
-
- xml_get_dtd(file);
-
- node = xml_build_tree(file, NULL, file->level);
-
- xml_close_file(file);
-
-#if defined(SPARSE_MEMORY)
- if (get_debug_mode())
- string_table_get_stats(xml_string_table);
-#endif
-
- return node;
-}
-
-gint xml_get_dtd(XMLFile *file)
-{
- gchar buf[XMLBUFSIZE];
- gchar *bufp = buf;
-
- if (xml_get_parenthesis(file, buf, sizeof(buf)) < 0) return -1;
-
- if ((*bufp++ == '?') &&
- (bufp = strcasestr(bufp, "xml")) &&
- (bufp = strcasestr(bufp + 3, "version")) &&
- (bufp = strchr(bufp + 7, '?'))) {
- file->dtd = g_strdup(buf);
- if ((bufp = strcasestr(buf, "encoding=\""))) {
- bufp += 9;
- extract_quote(bufp, '"');
- file->encoding = g_strdup(bufp);
- } else
- file->encoding = g_strdup(CS_INTERNAL);
- } else {
- g_warning("Can't get xml dtd\n");
- return -1;
- }
-
- return 0;
-}
-
-gint xml_parse_next_tag(XMLFile *file)
-{
- gchar buf[XMLBUFSIZE];
- gchar *bufp = buf;
- gchar *tag_str;
- XMLTag *tag;
- gint len;
-
- if (file->is_empty_element == TRUE) {
- file->is_empty_element = FALSE;
- xml_pop_tag(file);
- return 0;
- }
-
- if (xml_get_parenthesis(file, buf, sizeof(buf)) < 0) {
- g_warning("xml_parse_next_tag(): Can't parse next tag\n");
- return -1;
- }
-
- /* end-tag */
- if (buf[0] == '/') {
- if (strcmp(xml_get_current_tag(file)->tag, buf + 1) != 0) {
- g_warning("xml_parse_next_tag(): Tag name mismatch: %s\n", buf);
- return -1;
- }
- xml_pop_tag(file);
- return 0;
- }
-
- tag = xml_tag_new(NULL);
- xml_push_tag(file, tag);
-
- len = strlen(buf);
- if (len > 0 && buf[len - 1] == '/') {
- file->is_empty_element = TRUE;
- buf[len - 1] = '\0';
- g_strchomp(buf);
- }
- if (strlen(buf) == 0) {
- g_warning("xml_parse_next_tag(): Tag name is empty\n");
- return -1;
- }
-
- while (*bufp != '\0' && !g_ascii_isspace(*bufp)) bufp++;
- if (*bufp == '\0') {
- tag_str = conv_codeset_strdup(buf, file->encoding, CS_INTERNAL);
- if (tag_str) {
- tag->tag = XML_STRING_ADD(tag_str);
- g_free(tag_str);
- } else
- tag->tag = XML_STRING_ADD(buf);
- return 0;
- } else {
- *bufp++ = '\0';
- tag_str = conv_codeset_strdup(buf, file->encoding, CS_INTERNAL);
- if (tag_str) {
- tag->tag = XML_STRING_ADD(tag_str);
- g_free(tag_str);
- } else
- tag->tag = XML_STRING_ADD(buf);
- }
-
- /* parse attributes ( name=value ) */
- while (*bufp) {
- XMLAttr *attr;
- gchar *attr_name;
- gchar *attr_value;
- gchar *utf8_attr_name;
- gchar *utf8_attr_value;
- gchar *p;
- gchar quote;
-
- while (g_ascii_isspace(*bufp)) bufp++;
- attr_name = bufp;
- if ((p = strchr(attr_name, '=')) == NULL) {
- g_warning("xml_parse_next_tag(): Syntax error in tag\n");
- return -1;
- }
- bufp = p;
- *bufp++ = '\0';
- while (g_ascii_isspace(*bufp)) bufp++;
-
- if (*bufp != '"' && *bufp != '\'') {
- g_warning("xml_parse_next_tag(): Syntax error in tag\n");
- return -1;
- }
- quote = *bufp;
- bufp++;
- attr_value = bufp;
- if ((p = strchr(attr_value, quote)) == NULL) {
- g_warning("xml_parse_next_tag(): Syntax error in tag\n");
- return -1;
- }
- bufp = p;
- *bufp++ = '\0';
-
- g_strchomp(attr_name);
- xml_unescape_str(attr_value);
- utf8_attr_name = conv_codeset_strdup
- (attr_name, file->encoding, CS_INTERNAL);
- utf8_attr_value = conv_codeset_strdup
- (attr_value, file->encoding, CS_INTERNAL);
- if (!utf8_attr_name)
- utf8_attr_name = g_strdup(attr_name);
- if (!utf8_attr_value)
- utf8_attr_value = g_strdup(attr_value);
-
- attr = xml_attr_new(utf8_attr_name, utf8_attr_value);
- xml_tag_add_attr(tag, attr);
-
- g_free(utf8_attr_value);
- g_free(utf8_attr_name);
- }
-
- return 0;
-}
-
-void xml_push_tag(XMLFile *file, XMLTag *tag)
-{
- g_return_if_fail(tag != NULL);
-
- file->tag_stack = g_list_prepend(file->tag_stack, tag);
- file->level++;
-}
-
-void xml_pop_tag(XMLFile *file)
-{
- XMLTag *tag;
-
- if (!file->tag_stack) return;
-
- tag = (XMLTag *)file->tag_stack->data;
-
- xml_free_tag(tag);
- file->tag_stack = g_list_remove(file->tag_stack, tag);
- file->level--;
-}
-
-XMLTag *xml_get_current_tag(XMLFile *file)
-{
- if (file->tag_stack)
- return (XMLTag *)file->tag_stack->data;
- else
- return NULL;
-}
-
-GList *xml_get_current_tag_attr(XMLFile *file)
-{
- XMLTag *tag;
-
- tag = xml_get_current_tag(file);
- if (!tag) return NULL;
-
- return tag->attr;
-}
-
-gchar *xml_get_element(XMLFile *file)
-{
- gchar *str;
- gchar *new_str;
- gchar *end;
-
- while ((end = strchr(file->bufp, '<')) == NULL)
- if (xml_read_line(file) < 0) return NULL;
-
- if (end == file->bufp)
- return NULL;
-
- str = g_strndup(file->bufp, end - file->bufp);
- /* this is not XML1.0 strict */
- g_strstrip(str);
- xml_unescape_str(str);
-
- file->bufp = end;
- xml_truncate_buf(file);
-
- if (str[0] == '\0') {
- g_free(str);
- return NULL;
- }
-
- new_str = conv_codeset_strdup(str, file->encoding, CS_INTERNAL);
- if (!new_str)
- new_str = g_strdup(str);
- g_free(str);
-
- return new_str;
-}
-
-gint xml_read_line(XMLFile *file)
-{
- gchar buf[XMLBUFSIZE];
- gint index;
-
- if (fgets(buf, sizeof(buf), file->fp) == NULL)
- return -1;
-
- index = file->bufp - file->buf->str;
-
- g_string_append(file->buf, buf);
-
- file->bufp = file->buf->str + index;
-
- return 0;
-}
-
-void xml_truncate_buf(XMLFile *file)
-{
- gint len;
-
- len = file->bufp - file->buf->str;
- if (len > 0) {
- g_string_erase(file->buf, 0, len);
- file->bufp = file->buf->str;
- }
-}
-
-gboolean xml_compare_tag(XMLFile *file, const gchar *name)
-{
- XMLTag *tag;
-
- tag = xml_get_current_tag(file);
-
- if (tag && strcmp(tag->tag, name) == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-XMLNode *xml_node_new(XMLTag *tag, const gchar *text)
-{
- XMLNode *node;
-
- node = g_new(XMLNode, 1);
- node->tag = tag;
- node->element = g_strdup(text);
-
- return node;
-}
-
-XMLTag *xml_tag_new(const gchar *tag)
-{
- XMLTag *new_tag;
-
- new_tag = g_new(XMLTag, 1);
- if (tag)
- new_tag->tag = XML_STRING_ADD(tag);
- else
- new_tag->tag = NULL;
- new_tag->attr = NULL;
-
- return new_tag;
-}
-
-XMLAttr *xml_attr_new(const gchar *name, const gchar *value)
-{
- XMLAttr *new_attr;
-
- new_attr = g_new(XMLAttr, 1);
- new_attr->name = XML_STRING_ADD(name);
- new_attr->value = g_strdup(value);
-
- return new_attr;
-}
-
-void xml_tag_add_attr(XMLTag *tag, XMLAttr *attr)
-{
- tag->attr = g_list_append(tag->attr, attr);
-}
-
-XMLTag *xml_copy_tag(XMLTag *tag)
-{
- XMLTag *new_tag;
- XMLAttr *attr;
- GList *list;
-
- new_tag = xml_tag_new(tag->tag);
- for (list = tag->attr; list != NULL; list = list->next) {
- attr = xml_copy_attr((XMLAttr *)list->data);
- xml_tag_add_attr(new_tag, attr);
- }
-
- return new_tag;
-}
-
-XMLAttr *xml_copy_attr(XMLAttr *attr)
-{
- return xml_attr_new(attr->name, attr->value);
-}
-
-gint xml_unescape_str(gchar *str)
-{
- gchar *start;
- gchar *end;
- gchar *p = str;
- gchar *esc_str;
- gchar ch;
- gint len;
-
- while ((start = strchr(p, '&')) != NULL) {
- if ((end = strchr(start + 1, ';')) == NULL) {
- g_warning("Unescaped `&' appeared\n");
- p = start + 1;
- continue;
- }
- len = end - start + 1;
- if (len < 3) {
- p = end + 1;
- continue;
- }
-
- Xstrndup_a(esc_str, start, len, return -1);
- if (!strcmp(esc_str, "&lt;"))
- ch = '<';
- else if (!strcmp(esc_str, "&gt;"))
- ch = '>';
- else if (!strcmp(esc_str, "&amp;"))
- ch = '&';
- else if (!strcmp(esc_str, "&apos;"))
- ch = '\'';
- else if (!strcmp(esc_str, "&quot;"))
- ch = '\"';
- else {
- p = end + 1;
- continue;
- }
-
- *start = ch;
- memmove(start + 1, end + 1, strlen(end + 1) + 1);
- p = start + 1;
- }
-
- return 0;
-}
-
-gint xml_file_put_escape_str(FILE *fp, const gchar *str)
-{
- const gchar *p;
-
- g_return_val_if_fail(fp != NULL, -1);
-
- if (!str) return 0;
-
- for (p = str; *p != '\0'; p++) {
- switch (*p) {
- case '<':
- fputs("&lt;", fp);
- break;
- case '>':
- fputs("&gt;", fp);
- break;
- case '&':
- fputs("&amp;", fp);
- break;
- case '\'':
- fputs("&apos;", fp);
- break;
- case '\"':
- fputs("&quot;", fp);
- break;
- default:
- fputc(*p, fp);
- }
- }
-
- return 0;
-}
-
-gint xml_file_put_xml_decl(FILE *fp)
-{
- g_return_val_if_fail(fp != NULL, -1);
-
- fprintf(fp, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", CS_INTERNAL);
- return 0;
-}
-
-gint xml_file_put_node(FILE *fp, XMLNode *node)
-{
- GList *cur;
-
- g_return_val_if_fail(fp != NULL, -1);
- g_return_val_if_fail(node != NULL, -1);
-
- fprintf(fp, "<%s", node->tag->tag);
-
- for (cur = node->tag->attr; cur != NULL; cur = cur->next) {
- XMLAttr *attr = (XMLAttr *)cur->data;
- fprintf(fp, " %s=\"", attr->name);
- xml_file_put_escape_str(fp, attr->value);
- fputs("\"", fp);
- }
-
- if (node->element) {
- fputs(">", fp);
- xml_file_put_escape_str(fp, node->element);
- fprintf(fp, "</%s>\n", node->tag->tag);
- } else {
- fputs(" />\n", fp);
- }
-
- return 0;
-}
-
-void xml_free_node(XMLNode *node)
-{
- if (!node) return;
-
- xml_free_tag(node->tag);
- g_free(node->element);
- g_free(node);
-}
-
-static gboolean xml_free_func(GNode *node, gpointer data)
-{
- XMLNode *xmlnode = node->data;
-
- xml_free_node(xmlnode);
- return FALSE;
-}
-
-void xml_free_tree(GNode *node)
-{
- g_return_if_fail(node != NULL);
-
- g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, xml_free_func,
- NULL);
-
- g_node_destroy(node);
-}
-
-static void xml_free_tag(XMLTag *tag)
-{
- if (!tag) return;
-
- XML_STRING_FREE(tag->tag);
- while (tag->attr != NULL) {
- XMLAttr *attr = (XMLAttr *)tag->attr->data;
- XML_STRING_FREE(attr->name);
- g_free(attr->value);
- g_free(attr);
- tag->attr = g_list_remove(tag->attr, tag->attr->data);
- }
- g_free(tag);
-}
-
-static gint xml_get_parenthesis(XMLFile *file, gchar *buf, gint len)
-{
- gchar *start;
- gchar *end;
-
- buf[0] = '\0';
-
- while ((start = strchr(file->bufp, '<')) == NULL)
- if (xml_read_line(file) < 0) return -1;
-
- start++;
- file->bufp = start;
-
- while ((end = strchr(file->bufp, '>')) == NULL)
- if (xml_read_line(file) < 0) return -1;
-
- strncpy2(buf, file->bufp, MIN(end - file->bufp + 1, len));
- g_strstrip(buf);
- file->bufp = end + 1;
- xml_truncate_buf(file);
-
- return 0;
-}
diff --git a/src/xml.h b/src/xml.h
deleted file mode 100644
index b41449a4..00000000
--- a/src/xml.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2004 Hiroyuki Yamamoto
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __XML_H__
-#define __XML_H__
-
-#include <glib.h>
-#include <stdio.h>
-
-#define XMLBUFSIZE 8192
-
-typedef struct _XMLAttr XMLAttr;
-typedef struct _XMLTag XMLTag;
-typedef struct _XMLNode XMLNode;
-typedef struct _XMLFile XMLFile;
-
-struct _XMLAttr
-{
- gchar *name;
- gchar *value;
-};
-
-struct _XMLTag
-{
- gchar *tag;
- GList *attr;
-};
-
-struct _XMLNode
-{
- XMLTag *tag;
- gchar *element;
-};
-
-struct _XMLFile
-{
- FILE *fp;
-
- GString *buf;
- gchar *bufp;
-
- gchar *dtd;
- gchar *encoding;
-
- GList *tag_stack;
- guint level;
-
- gboolean is_empty_element;
-};
-
-XMLFile *xml_open_file (const gchar *path);
-void xml_close_file (XMLFile *file);
-GNode *xml_parse_file (const gchar *path);
-
-gint xml_get_dtd (XMLFile *file);
-gint xml_parse_next_tag (XMLFile *file);
-void xml_push_tag (XMLFile *file,
- XMLTag *tag);
-void xml_pop_tag (XMLFile *file);
-
-XMLTag *xml_get_current_tag (XMLFile *file);
-GList *xml_get_current_tag_attr(XMLFile *file);
-gchar *xml_get_element (XMLFile *file);
-
-gint xml_read_line (XMLFile *file);
-void xml_truncate_buf (XMLFile *file);
-gboolean xml_compare_tag (XMLFile *file,
- const gchar *name);
-
-XMLNode *xml_node_new (XMLTag *tag,
- const gchar *text);
-XMLTag *xml_tag_new (const gchar *tag);
-XMLAttr *xml_attr_new (const gchar *name,
- const gchar *value);
-void xml_tag_add_attr (XMLTag *tag,
- XMLAttr *attr);
-
-XMLTag *xml_copy_tag (XMLTag *tag);
-XMLAttr *xml_copy_attr (XMLAttr *attr);
-
-gint xml_unescape_str (gchar *str);
-gint xml_file_put_escape_str (FILE *fp,
- const gchar *str);
-
-gint xml_file_put_xml_decl (FILE *fp);
-gint xml_file_put_node (FILE *fp,
- XMLNode *node);
-
-void xml_free_node (XMLNode *node);
-void xml_free_tree (GNode *node);
-
-#endif /* __XML_H__ */