sync 098claws
This commit is contained in:
parent
d28c8f98ae
commit
61ee51da1d
179 changed files with 36579 additions and 49049 deletions
12
AUTHORS
12
AUTHORS
|
@ -16,7 +16,7 @@ claws-branch (http://sylpheed-claws.sourceforge.net)
|
|||
Colin Leroy <colin@colino.net>
|
||||
Paul Mangan <claws@thewildbeast.co.uk>
|
||||
Leandro A. F. Pereira <leandro@linuxmag.com.br>
|
||||
Luke Plant <lukeplant@softhome.net>
|
||||
Luke Plant <L.Plant.98@cantab.net>
|
||||
Martin Schaaf <mascha@ma-scha.de>
|
||||
Carsten Schurig <Carsten.Schurig@web.de>
|
||||
Sergey Vlasov <vsu@users.sourceforge.net>
|
||||
|
@ -39,11 +39,12 @@ sylpheed-claws translation team
|
|||
[fr] Melvin Hadasht <melvin.hadasht@free.fr>
|
||||
[hr] Dragan <drleskov@inet.hr>
|
||||
[it] Alessandro Maestri <maestri@cs.tin.it>
|
||||
[pl] Witold Wladyslaw Wojciech Wilk
|
||||
<maniack@zawilcow.tyc.katowice.supermedia.pl>
|
||||
[ja] Rui Hirokawa <rui_hirokawa@ybb.ne.jp>
|
||||
[pl] Emil <eminowbl@posejdon.wpk.p.lodz.pl>
|
||||
[ru] Ruslan N. Balkin <baron@voices.ru>
|
||||
[sk] Andrej Kacian <andrej@kacian.sk>
|
||||
[sr] Urke MMI <urke@gmx.net>
|
||||
[zh_CN] Hansom Young <hansom_young@yahoo.com>
|
||||
|
||||
sylpheed documentation (http://sylpheeddoc.sourceforge.net)
|
||||
|
||||
|
@ -194,3 +195,8 @@ contributors (beside the above; based on Changelog)
|
|||
Martin Zwickel
|
||||
Martin Wicke
|
||||
Pawel Pêkala
|
||||
Bogdan Sumanariu
|
||||
David Relson
|
||||
Matthias Förste
|
||||
David Chalmers
|
||||
Chad Robinson
|
||||
|
|
284
ChangeLog
284
ChangeLog
|
@ -1,3 +1,287 @@
|
|||
2003-12-15
|
||||
|
||||
* version 0.9.8a
|
||||
|
||||
2003-12-15
|
||||
|
||||
* src/procmsg.c: procmsg_open_data_file(): set buffer if DATA_READ
|
||||
is specified and a buffer is given.
|
||||
procmsg_open_cache_file_with_buffer(): new.
|
||||
procmsg_read_cache(): fixed a bug that called setvbuf() after an
|
||||
file I/O which caused buffer read error.
|
||||
|
||||
2003-12-12
|
||||
|
||||
* version 0.9.8
|
||||
|
||||
2003-12-12
|
||||
|
||||
* configure.in: enable IPv6 support by default.
|
||||
|
||||
2003-12-11
|
||||
|
||||
* src/inc.c: inc_mail(), inc_all_account_mail(): ask user to switch
|
||||
to online when in offline mode.
|
||||
* src/mainwindow.h: added main_window_toggle_online().
|
||||
|
||||
2003-12-11
|
||||
|
||||
* src/foldersel.c
|
||||
src/folderview.[ch]
|
||||
src/mainwindow.c
|
||||
src/stock_pixmap.[ch]
|
||||
src/pixmap/dir-noselect.xpm: made no-select folders display with
|
||||
dim icon and string.
|
||||
* src/Makefile.am: added offline.xpm, online.xpm, and
|
||||
dir-noselect.xpm to EXTRA_DIST.
|
||||
|
||||
2003-12-11
|
||||
|
||||
* src/folder.h: added macro FOLDER_ITEM_CAN_ADD().
|
||||
* src/folderview.c: folderview_drag_motion_cb(): code cleanup.
|
||||
folderview_drag_received_cb(): don't accept at no_select folder or
|
||||
from itself.
|
||||
* src/foldersel.c: made folders on which no_select flag is set not
|
||||
selectable.
|
||||
|
||||
2003-12-10
|
||||
|
||||
* src/imap.c: imap_do_copy_msgs(), imap_remove_msgs(): code cleanup.
|
||||
set MSG_INVALID flag when messages are deleted.
|
||||
* src/mh.c: mh_do_move_msgs(), mh_remove_msg(): set MSG_INVALID flag
|
||||
when messages are deleted.
|
||||
* src/procmsg.[ch]:
|
||||
procmsg_move_messages()
|
||||
procmsg_copy_messages(): return error status.
|
||||
Added MSG_INVALID to MsgTmpFlags.
|
||||
* src/summaryview.c: summary_execute(): detect errors and only remove
|
||||
nodes that are invalidated.
|
||||
summary_unthread_for_exec(): fixed a bug that didn't remove nodes
|
||||
in collapsed trees.
|
||||
|
||||
2003-12-06
|
||||
|
||||
* src/mainwindow.[ch]: added online switch button to the statusbar,
|
||||
and "/File/Work offline" in the menu.
|
||||
* src/pixmaps/offline.xpm
|
||||
src/pixmaps/online.xpm: new (borrowed from
|
||||
themes/classic/communicator/icons/ in Mozilla).
|
||||
* src/stock_pixmap.[ch]: added online.xpm and offline.xpm.
|
||||
* src/textview.[ch]: textview_show_error(): new.
|
||||
* src/summaryview.c: summary_display_msg_full(): update marks only
|
||||
if messages are displayed.
|
||||
* src/prefs_common.[ch]: added PrefsCommon::online_mode.
|
||||
* src/news.c: news_session_get()
|
||||
src/imap.c: imap_session_get(): return NULL when in offline mode.
|
||||
* src/messageview.[ch]: messageview_show(): return status whether
|
||||
messages are successfully displayed. Display error messages in
|
||||
the view when failed.
|
||||
* src/procmsg.c:
|
||||
procmsg_get_message_file()
|
||||
procmsg_open_message(): don't output warnings when fetch failed.
|
||||
|
||||
2003-12-04
|
||||
|
||||
* src/html.c: html_get_tag(): support attributes which don't have
|
||||
values.
|
||||
|
||||
2003-12-04
|
||||
|
||||
* src/codeconv.c: conv_get_code_conv_func(): return conv_latintodisp
|
||||
only if src_charset and current charset is identical or current
|
||||
one is multibyte (fixes display of ISO-8859-5 on KOI8-R locale etc.).
|
||||
|
||||
2003-11-25
|
||||
|
||||
* autogen.sh: don't include m4 directory in aclocal.
|
||||
* intl/libgnuintl.h: removed from cvs.
|
||||
* po/.cvsignore: added stamp-po and remove-potcdate.sed.
|
||||
|
||||
2003-11-24
|
||||
|
||||
* upgraded to gettext-0.12.1.
|
||||
|
||||
2003-11-24 gettextize <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* Makefile.am (SUBDIRS): Add m4.
|
||||
(ACLOCAL_AMFLAGS): New variable.
|
||||
(EXTRA_DIST): Add config.rpath.
|
||||
* configure.in (AC_OUTPUT): Add m4/Makefile.
|
||||
|
||||
2003-11-21
|
||||
|
||||
* configure.in: added check for d_type member in struct dirent.
|
||||
* src/mh.c: mh_scan_folder(): use d->d_type if available.
|
||||
mh_get_uncached_msgs(): removed redundant stat().
|
||||
mh_parse_msg(): return NULL if not a regular file.
|
||||
mh_scan_tree_recursive(): use d->d_type if available.
|
||||
* src/utils.[ch]:
|
||||
dirent_is_regular_file()
|
||||
dirent_is_directory(): new. Use d->d_type to determine the type
|
||||
of entry if available.
|
||||
remove_dir_recursive(): use dirent_is_directory().
|
||||
|
||||
2003-11-14
|
||||
|
||||
* src/folder.h: added 'updated' flag to FolderItem.
|
||||
* src/folderview.[ch]: folderview_update_all_updated(): new. It
|
||||
updates all updated folders.
|
||||
* src/imap.c: set FolderView::update flag on changes of contents.
|
||||
* src/main.c: send_queue()
|
||||
src/mainwindow.c: send_queue_cb(): code cleanup.
|
||||
* src/mh.c: code cleanup.
|
||||
mh_scan_folder(): correctly count new messages.
|
||||
* src/procmsg.[ch]: code cleanup.
|
||||
procmsg_open_cache_file(): new.
|
||||
procmsg_open_mark_file(): enable read/write/append.
|
||||
procmsg_send_queue(): correctly choose outbox for accounts.
|
||||
* src/send_message.[ch]: send_get_queue_info(): get a queue
|
||||
information from queued messages.
|
||||
send_queue_info_free(): free QueueInfo.
|
||||
send_message_queue(): take QueueInfo as an argument instead of file.
|
||||
* src/summaryview.c: summary_write_cache(): code cleanup.
|
||||
|
||||
2003-11-10
|
||||
|
||||
* src/compose.c: compose_redirect_write_headers(): correctly add
|
||||
Resent-Cc: header.
|
||||
|
||||
2003-11-05
|
||||
|
||||
* src/imap.c: imap_get_msg_list(): fallback to FETCH command if SEARCH
|
||||
command to get flags failed.
|
||||
imap_search_flags(): returns UID array and flags hash table using
|
||||
SEARCH command.
|
||||
imap_fetch_flags(): returns UID array and flags hash table using
|
||||
FETCH command.
|
||||
|
||||
2003-10-28
|
||||
|
||||
* src/summary_search.c: summary_search_execute(): fixed 'Select all
|
||||
matched' when backward search is enabled.
|
||||
Made the backward search button insensitive when 'select all
|
||||
matched' is enabled.
|
||||
|
||||
2003-10-15
|
||||
|
||||
* version 0.9.7
|
||||
|
||||
2003-10-15
|
||||
|
||||
* src/imap.c: imap_scan_tree(): check the existence of root directory
|
||||
with LIST instead of STATUS.
|
||||
|
||||
2003-10-07
|
||||
|
||||
* src/send_message.c: fixed format string bug (exploitable by
|
||||
malicious SMTP server) when calling alertpanel_error()
|
||||
(thanks to Georgi Guninski).
|
||||
|
||||
2003-10-03
|
||||
|
||||
* src/folder.[ch]
|
||||
src/imap.[ch]
|
||||
src/mh.[ch]
|
||||
src/news.[ch]: refactoring of the folder system (based on the claws'
|
||||
implementation).
|
||||
* src/account.c
|
||||
src/foldersel.c
|
||||
src/folderview.c
|
||||
src/mainwindow.c
|
||||
src/messageview.c
|
||||
src/procmsg.c
|
||||
src/setup.c
|
||||
src/summaryview.c: use FOLDER_TYPE() macro at every place.
|
||||
|
||||
2003-09-17
|
||||
|
||||
* version 0.9.6
|
||||
|
||||
2003-09-17
|
||||
|
||||
* src/addressbook.c:
|
||||
addressbook_folder_load_person()
|
||||
addressbook_folder_load_group(): sort the ctree after the end of
|
||||
the loop (fixes performance issue when many addresses are in one
|
||||
folder) (thanks to christian mock).
|
||||
|
||||
2003-09-16
|
||||
|
||||
* src/folderview.c: folder_init(): code cleanup.
|
||||
* src/summaryview.c: summary_init(): check if boldfont is
|
||||
successfully loaded.
|
||||
* src/grouplistdialog.c: use proper callback for delete_event (thanks
|
||||
to Takuro Ashie).
|
||||
* src/imap.c: allow zero-length messages.
|
||||
* src/recv.c: recv_bytes_write(): return immediately if size == 0.
|
||||
|
||||
2003-09-16
|
||||
|
||||
* src/folderview.c: folderview_init(): if font can't be loaded, fall
|
||||
back to gtk default (fixes crashes on startup). Also removed the
|
||||
redundant code.
|
||||
|
||||
2003-09-15
|
||||
|
||||
* src/compose.c: compose_insert_sig(): insert signature at the
|
||||
current cursor position on manual operation.
|
||||
|
||||
2003-09-11
|
||||
|
||||
* src/summaryview.c: summary_key_pressed(): don't ignore delete key
|
||||
even if the main window is locked.
|
||||
|
||||
2003-09-10
|
||||
|
||||
* src/action.c: improved synchronous action exit code (fixes long
|
||||
delay after action exit on RH9) (thanks to Melvin).
|
||||
* src/stringtable.[ch]: string_table_insert_string(): modified the
|
||||
code to remove the warning "dereferencing type-punned pointer will
|
||||
break strict-aliasing rules".
|
||||
Use const gchar * instead of gchar * for arguments.
|
||||
|
||||
2003-09-05
|
||||
|
||||
* src/utils.[ch]: generate_mime_boundary(): a new function to create
|
||||
MIME boundary (moved from rfc2015.c).
|
||||
Removed more special characters.
|
||||
Use random() instead of lrand48() which is obsolete.
|
||||
Added an argument for prefix to prevent duplication.
|
||||
Always add "=_" as a counter-QP sequence to simplify the code.
|
||||
* src/rfc2015.c:
|
||||
rfc2015_decrypt_message()
|
||||
rfc2015_encrypt()
|
||||
rfc2015_sign(): fixed a bug that didn't handle continuous content
|
||||
lines correctly.
|
||||
* src/compose.c
|
||||
src/rfc2015.c: use generate_mime_boundary().
|
||||
|
||||
2003-09-05
|
||||
|
||||
* src/folderview.c:
|
||||
folderview_delete_folder_cb()
|
||||
folderview_remove_mailbox_cb(): close currently displayed folder
|
||||
before removing FolderItem (fixes crash on deleting folder).
|
||||
* src/folder.h
|
||||
src/imap.[ch]: imap_scan_tree()
|
||||
src/mh.[ch]: mh_scan_tree(): return -1 when scanning failed.
|
||||
* src/summaryview.c: summary_clear_all(): also clear the message view.
|
||||
* src/imap.c: imap_close(): fail if the specified folder is not
|
||||
selected.
|
||||
imap_scan_tree(): check if the specified root directory exist, and
|
||||
try creating it if not.
|
||||
imap_parse_list(): output warning if a server returns error.
|
||||
imap_find_namespace_from_list(): support not slash-delimited path.
|
||||
imap_status(): don't return values if they're not specified.
|
||||
|
||||
2003-09-02
|
||||
|
||||
* sylpheed.spec.in: fixed a typo.
|
||||
|
||||
2003-09-02
|
||||
|
||||
* version 0.9.5
|
||||
|
||||
2003-09-01
|
||||
|
||||
* src/inc.[ch]
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2004-01-12 Thorsten Maerz <torte@netztorte.de>
|
||||
|
||||
* sync 098claws
|
||||
|
||||
2004-01-08 Thorsten Maerz <torte@netztorte.de>
|
||||
* configure.ac
|
||||
Makefile.am
|
||||
|
|
9839
ChangeLog.claws
9839
ChangeLog.claws
File diff suppressed because it is too large
Load diff
284
ChangeLog.jp
284
ChangeLog.jp
|
@ -1,3 +1,287 @@
|
|||
2003-12-15
|
||||
|
||||
* version 0.9.8a
|
||||
|
||||
2003-12-15
|
||||
|
||||
* src/procmsg.c: procmsg_open_data_file(): DATA_READ が指定されて
|
||||
バッファが与えられたらバッファをセットするようにした。
|
||||
procmsg_open_cache_file_with_buffer(): 新規。
|
||||
procmsg_read_cache(): ファイル I/O の後に setvbuf() を呼んでいた
|
||||
(バッファ読み込みエラーを起こしていた)バグを修正。
|
||||
|
||||
2003-12-12
|
||||
|
||||
* version 0.9.8
|
||||
|
||||
2003-12-12
|
||||
|
||||
* configure.in: IPv6 にデフォルトで対応するようにした。
|
||||
|
||||
2003-12-11
|
||||
|
||||
* src/inc.c: inc_mail(), inc_all_account_mail(): オフラインモードの
|
||||
ときはユーザにオンラインに切り替えるように促すようにした。
|
||||
* src/mainwindow.h: main_window_toggle_online() を追加。
|
||||
|
||||
2003-12-11
|
||||
|
||||
* src/foldersel.c
|
||||
src/folderview.[ch]
|
||||
src/mainwindow.c
|
||||
src/stock_pixmap.[ch]
|
||||
src/pixmap/dir-noselect.xpm: no-select フォルダを薄いアイコンと
|
||||
文字列で表示。
|
||||
* src/Makefile.am: offline.xpm, online.xpm, dir-noselect.xpm を
|
||||
EXTRA_DIST に追加。
|
||||
|
||||
2003-12-11
|
||||
|
||||
* src/folder.h: マクロ FOLDER_ITEM_CAN_ADD() を追加。
|
||||
* src/folderview.c: folderview_drag_motion_cb(): コードの整理。
|
||||
folderview_drag_received_cb(): no_select フォルダで、あるいは
|
||||
それ自身から受け付けないようにした。
|
||||
* src/foldersel.c: no_select フラグがセットされているフォルダを選択
|
||||
不可にした。
|
||||
|
||||
2003-12-10
|
||||
|
||||
* src/imap.c: imap_do_copy_msgs(), imap_remove_msgs(): コードの整理。
|
||||
メッセージを削除したときに MSG_INVALID フラグをセット。
|
||||
* src/mh.c: mh_do_move_msgs(), mh_remove_msg(): メッセージを削除した
|
||||
ときに MSG_INVALID フラグをセット。
|
||||
* src/procmsg.[ch]:
|
||||
procmsg_move_messages()
|
||||
procmsg_copy_messages(): エラーステータスを返すようにした。
|
||||
MsgTmpFlags に MSG_INVALID を追加。
|
||||
* src/summaryview.c: summary_execute(): エラーを検出し、無効になった
|
||||
ノードのみを削除するようにした。
|
||||
summary_unthread_for_exec(): 閉じたツリー中のノードを削除しない
|
||||
バグを修正。
|
||||
|
||||
2003-12-06
|
||||
|
||||
* src/mainwindow.[ch]: ステータスバーにオンラインスイッチボタンを
|
||||
追加し、メニューに「/ファイル/オフラインにする」を追加。
|
||||
* src/pixmaps/offline.xpm
|
||||
src/pixmaps/online.xpm: 新規(Mozilla の
|
||||
themes/classic/communicator/icons/ から拝借)。
|
||||
* src/stock_pixmap.[ch]: online.xpm と offline.xpm を追加。
|
||||
* src/textview.[ch]: textview_show_error(): 新規。
|
||||
* src/summaryview.c: summary_display_msg_full(): メッセージが表示
|
||||
された場合のみマークを更新。
|
||||
* src/prefs_common.[ch]: PrefsCommon::online_mode を追加。
|
||||
* src/news.c: news_session_get()
|
||||
src/imap.c: imap_session_get(): オフラインモードのときは NULL を
|
||||
返すようにした。
|
||||
* src/messageview.[ch]: messageview_show(): メッセージが表示できた
|
||||
かどうかのステータスを返すようにした。失敗したときはエラー
|
||||
メッセージをビューに表示するようにした。
|
||||
* src/procmsg.c:
|
||||
procmsg_get_message_file()
|
||||
procmsg_open_message(): 取得に失敗したときに警告を表示しないように
|
||||
した。
|
||||
|
||||
2003-12-04
|
||||
|
||||
* src/html.c: html_get_tag(): 値を持たない属性に対応。
|
||||
|
||||
2003-12-04
|
||||
|
||||
* src/codeconv.c: conv_get_code_conv_func(): src_charset と現在の
|
||||
文字コードが同一の場合、または現在の文字コードがマルチバイトで
|
||||
ある場合のみ conv_latintodisp を返す(KOI8-R locale 上での
|
||||
ISO-8859-5 の表示を修正)。
|
||||
|
||||
2003-11-25
|
||||
|
||||
* autogen.sh: aclocal で m4 ディレクトリを含まないようにした。
|
||||
* intl/libgnuintl.h: cvs から削除。
|
||||
* po/.cvsignore: stamp-po と remove-potcdate.sed を追加。
|
||||
|
||||
2003-11-24
|
||||
|
||||
* gettext-0.12.1 に移行。
|
||||
|
||||
2003-11-21
|
||||
|
||||
* configure.in: struct dirent 中の d_type メンバのチェックを追加。
|
||||
* src/mh.c: mh_scan_folder(): 利用可能な場合は d->d_type を使用。
|
||||
mh_get_uncached_msgs(): 余分な stat() を削除。
|
||||
mh_parse_msg(): 通常のファイルでない場合は NULL を返す。
|
||||
mh_scan_tree_recursive(): 利用可能な場合は d->d_type を使用。
|
||||
* src/utils.[ch]:
|
||||
dirent_is_regular_file()
|
||||
dirent_is_directory(): 新規。利用可能な場合はエントリのタイプを
|
||||
判別するのに d->d_type を使用。
|
||||
remove_dir_recursive(): dirent_is_directory() を使用。
|
||||
|
||||
2003-11-14
|
||||
|
||||
* src/folder.h: FolderItem に 'updated' フラグを追加。
|
||||
* src/folderview.[ch]: folderview_update_all_updated(): 新規。全ての
|
||||
更新されたフォルダを更新する。
|
||||
* src/imap.c: 内容の変更時に FolderView::update フラグをセット。
|
||||
* src/main.c: send_queue()
|
||||
src/mainwindow.c: send_queue_cb(): コードの整理。
|
||||
* src/mh.c: コードの整理。
|
||||
mh_scan_folder(): 新着メッセージを正しくカウントするようにした。
|
||||
* src/procmsg.[ch]: コードの整理。
|
||||
procmsg_open_cache_file(): 新規。
|
||||
procmsg_open_mark_file(): 読み込み/書き込み/追加書き込みができる
|
||||
ようにした。
|
||||
procmsg_send_queue(): アカウントに対応する送信控を正しく選択する
|
||||
ようにした。
|
||||
* src/send_message.[ch]: send_get_queue_info(): 送信待ちメッセージ
|
||||
からキュー情報を取得。
|
||||
send_queue_info_free(): QueueInfo を開放。
|
||||
send_message_queue(): ファイルの代わりに QueueInfo を引数にとる
|
||||
ようにした。
|
||||
* src/summaryview.c: summary_write_cache(): コードの整理。
|
||||
|
||||
2003-11-10
|
||||
|
||||
* src/compose.c: compose_redirect_write_headers(): Resent-Cc: ヘッダ
|
||||
を正しく付加するようにした。
|
||||
|
||||
2003-11-05
|
||||
|
||||
* src/imap.c: imap_get_msg_list(): フラグを得るための SEARCH コマンド
|
||||
に失敗した場合 FETCH コマンドに fallback するようにした。
|
||||
imap_search_flags(): SEARCH コマンドを使用して UID の配列とフラグの
|
||||
ハッシュテーブルを返す。
|
||||
imap_fetch_flags(): FETCH コマンドを使用して UID の配列とフラグの
|
||||
ハッシュテーブルを返す。
|
||||
|
||||
2003-10-28
|
||||
|
||||
* src/summary_search.c: summary_search_execute(): 後方検索が有効な
|
||||
ときの「一括検索」を修正。
|
||||
「一括検索」が有効なときは後方検索ボタンを無効にするようにした。
|
||||
|
||||
2003-10-15
|
||||
|
||||
* version 0.9.7
|
||||
|
||||
2003-10-15
|
||||
|
||||
* src/imap.c: imap_scan_tree(): ルートディレクトリの存在を STATUS
|
||||
ではなく LIST でチェックするようにした。
|
||||
|
||||
2003-10-07
|
||||
|
||||
* src/send_message.c: alertpanel_error() を呼ぶときのフォーマット
|
||||
文字列のバグ(悪意のある SMTP サーバによって攻撃可能)を修正
|
||||
(Georgi Guninski さん thanks)。
|
||||
|
||||
2003-10-03
|
||||
|
||||
* src/folder.[ch]
|
||||
src/imap.[ch
|
||||
src/mh.[ch]
|
||||
src/news.[ch]: フォルダシステムのリファクタリング(claws の実装に
|
||||
基づく)。
|
||||
* src/account.c
|
||||
src/foldersel.c
|
||||
src/folderview.c
|
||||
src/mainwindow.c
|
||||
src/messageview.c
|
||||
src/procmsg.c
|
||||
src/setup.c
|
||||
src/summaryview.c: 全ての場所で FOLDER_TYPE() マクロを使用。
|
||||
|
||||
2003-09-17
|
||||
|
||||
* version 0.9.6
|
||||
|
||||
2003-09-17
|
||||
|
||||
* src/addressbook.c:
|
||||
addressbook_folder_load_person()
|
||||
addressbook_folder_load_group(): ループの後で ctree をソートする
|
||||
ようにした(一つのフォルダに多くのアドレスがある場合のパフォーマンス
|
||||
の問題を解決)(christian mock さん thanks)。
|
||||
|
||||
2003-09-16
|
||||
|
||||
* src/folderview.c: folder_init(): コードを整理。
|
||||
* src/summaryview.c: summary_init(): boldfont が正しくロードされたか
|
||||
どうかをチェック。
|
||||
* src/grouplistdialog.c: delete_event に適切なコールバックを使用する
|
||||
ようにした(足永さん thanks)。
|
||||
* src/imap.c: ゼロ長メッセージを許すようにした。
|
||||
* src/recv.c: recv_bytes_write(): size == 0 の場合はすぐに戻るように
|
||||
した。
|
||||
|
||||
2003-09-16
|
||||
|
||||
* src/folderview.c: folderview_init(): フォントが読み込めない場合は
|
||||
gtk のデフォルトに fallback するようにした(起動時のクラッシュを
|
||||
修正)。さらに不要なコードを除去。
|
||||
|
||||
2003-09-15
|
||||
|
||||
* src/compose.c: compose_insert_sig(): マニュアル操作のときは現在の
|
||||
カーソルの位置に署名を挿入するようにした。
|
||||
|
||||
2003-09-11
|
||||
|
||||
* src/summaryview.c: summary_key_pressed(): メインウィンドウがロック
|
||||
されていても delete キーを無視しないようにした。
|
||||
|
||||
2003-09-10
|
||||
|
||||
* src/action.c: action 終了のコードを改良(RH9 で action 終了時に
|
||||
長時間待たされるのを修正) (Melvin さん thanks)。
|
||||
* src/stringtable.[ch]: string_table_insert_string(): 警告
|
||||
"dereferencing type-punned pointer will break strict-aliasing
|
||||
rules" を除去するためにコードを修正。
|
||||
引数に gchar * の代わりに const gchar * を使用。
|
||||
|
||||
2003-09-05
|
||||
|
||||
* src/utils.[ch]: generate_mime_boundary(): MIME boundary を作成する
|
||||
新規関数(rfc2015.c から移動)。
|
||||
さらに特別文字を除去。
|
||||
obsolete な lrand48() のかわりに random() を使用。
|
||||
重複を避けるために prefix の引数を追加。
|
||||
対 QP シーケンスとして常に "=_" を追加し、コードを単純化。
|
||||
* src/rfc2015.c:
|
||||
rfc2015_decrypt_message()
|
||||
rfc2015_encrypt()
|
||||
rfc2015_sign(): 継続する content 行を正しく扱っていなかったバグを
|
||||
修正。
|
||||
* src/compose.c
|
||||
src/rfc2015.c: generate_mime_boundary() を使用。
|
||||
|
||||
2003-09-05
|
||||
|
||||
* src/folderview.c:
|
||||
folderview_delete_folder_cb()
|
||||
folderview_remove_mailbox_cb(): FolderItem を削除する前に現在表示
|
||||
されているフォルダを閉じるようにした(フォルダ削除時のクラッシュを
|
||||
修正)。
|
||||
* src/folder.h
|
||||
src/imap.[ch]: imap_scan_tree()
|
||||
src/mh.[ch]: mh_scan_tree(): スキャンに失敗したときは -1 を返す。
|
||||
* src/summaryview.c: summary_clear_all(): メッセージビューもクリア。
|
||||
* src/imap.c: imap_close(): 指定したフォルダが選択されていなければ
|
||||
失敗。
|
||||
imap_scan_tree(): 指定したルートディレクトリが存在するかどうかを
|
||||
調べ、なければ作成するようにした。
|
||||
imap_parse_list(): サーバがエラーを返したら警告を出力。
|
||||
imap_find_namespace_from_list(): スラッシュで区切られていないパス
|
||||
に対応。
|
||||
imap_status(): 指定しなければ値を返さないようにした。
|
||||
|
||||
2003-09-02
|
||||
|
||||
* sylpheed.spec.in: typo を修正。
|
||||
|
||||
2003-09-02
|
||||
|
||||
* version 0.9.5
|
||||
|
||||
2003-09-01
|
||||
|
||||
* src/inc.[ch]
|
||||
|
|
10
INSTALL
10
INSTALL
|
@ -31,7 +31,7 @@ o RedHat Linux 5.2 (glibc 2.0.7)
|
|||
o RedHat Linux 6.0
|
||||
o RedHat Linux 6.1 + Helix GNOME (glibc 2.1.x)
|
||||
o RedHat Linux 6.2 / 6.2J (glibc 2.1.x)
|
||||
o RedHat Linux 7.0 / 7.0J / 7.1 / 7.2 / 7.3 / 8.0
|
||||
o RedHat Linux 7.0 / 7.0J / 7.1 / 7.2 / 7.3 / 8.0 / 9.0
|
||||
o LinuxPPC2000 + Yukikaze(Japanization kit)
|
||||
o Linux2000G (Intel / PPC)
|
||||
o HOLON Linux 2.0 (Intel / PPC)
|
||||
|
@ -44,7 +44,7 @@ o Plamo Linux 2.0 / 2.1 / 2.2.x / 3.0
|
|||
o Slackware 7.0 / 7.1 / 8.0 / 8.1 / 9.0
|
||||
o Linux Mandrake 7.0 / 7.1 / 7.2 / 8.0 / 8.1 / 9.0 / 9.1
|
||||
o SuSE Linux 6.3 (glibc 2.1.2) / 6.4
|
||||
o SuSE Linux 7.0 / 7.1 / 7.2 / 7.3 / 8.0 / 8.1
|
||||
o SuSE Linux 7.0 / 7.1 / 7.2 / 7.3 / 8.0 / 8.1 / 8.2
|
||||
o OpenLinux 2.3 (glibc 2.1.1 -> 2.1.3)
|
||||
o Caldera OpenDesktop 2.4
|
||||
o Caldera Workstation 3.1
|
||||
|
@ -74,10 +74,10 @@ Other commercial Unix
|
|||
|
||||
o Solaris 2.5 / 2.5.1 / 2.6
|
||||
o Solaris 7 / 8 / 9
|
||||
o AIX 4.3.3
|
||||
o IRIX 6.3 / 6.4 / 6.5 6.5.8m
|
||||
o HP-UX 10.20 / 11.0 / 11i
|
||||
o Tru64 Unix 5.0 (OSF1 V5.0)
|
||||
o SCO UnixWare 7
|
||||
o Mac OS X 10.1.4 (Darwin 5.4) + XDarwin (without XLocale support) + libxpg4
|
||||
|
||||
Others
|
||||
|
@ -126,11 +126,11 @@ Options for configure script
|
|||
============================
|
||||
|
||||
--disable-compface disable compface (X-Face) support
|
||||
--enable-openssl SSL support (requires OpenSSL)
|
||||
--enable-ipv6 IPv6 support
|
||||
--disable-ipv6 disable IPv6 support
|
||||
--enable-gpgme GnuPG support (requires GPGME and GnuPG)
|
||||
--enable-ldap LDAP support
|
||||
--enable-jpilot JPilot support
|
||||
--enable-openssl SSL support (requires OpenSSL)
|
||||
|
||||
For other options, refer to ./configure --help .
|
||||
|
||||
|
|
33
NEWS
33
NEWS
|
@ -1,5 +1,38 @@
|
|||
Changes of Sylpheed
|
||||
|
||||
* 0.9.8a
|
||||
|
||||
* The bug that caused the failure of cache data read has been fixed.
|
||||
|
||||
* 0.9.8
|
||||
|
||||
* The offline mode has been implemented.
|
||||
* The performance of the scanning of MH folders has been improved on
|
||||
the platforms which support d_type in 'struct dirent'.
|
||||
* The error checking on moving/deleting messages has become strict.
|
||||
* When getting IMAP4 message list, it now fallbacks to FETCH command
|
||||
if server doesn't fully support SEARCH command.
|
||||
* Outbox for accounts are now correctly chosen when sending from queue.
|
||||
* Gettext has been upgraded to 0.12.1.
|
||||
* IPv6 support is now enabled by default.
|
||||
* Other bugfixes have been made.
|
||||
|
||||
* 0.9.7
|
||||
|
||||
* The vulnerability in SMTP response handling, which is exploitable by
|
||||
a malicious SMTP server, has been fixed.
|
||||
* The structure of folder system has been sorted out.
|
||||
* The checking of the existence of IMAP root directory has been modified.
|
||||
|
||||
* 0.9.6
|
||||
|
||||
* A crash bug when deleting currently opened folder has been fixed.
|
||||
* The performance issue of the address book has been fixed.
|
||||
* The behavior of manual signature insertion has been reverted.
|
||||
* A crash bug on startup when a font can't be loaded has been fixed.
|
||||
* The format of MIME boundary has been modified again.
|
||||
* Other minor bugfixes have been made.
|
||||
|
||||
* 0.9.5
|
||||
|
||||
* The size, the position, and the visibility of separated views are now
|
||||
|
|
13
TODO.claws
13
TODO.claws
|
@ -17,20 +17,15 @@ win32 0.8.0claws+
|
|||
[hoa]
|
||||
|
||||
o work on sylpheed :)
|
||||
o several actions on filtering condition
|
||||
o separate code of compose dialog and building of message
|
||||
compose should return some kind of MIME structure so that
|
||||
a message can be built.
|
||||
o use libEtPan! in sylpheed
|
||||
|
||||
[christoph]
|
||||
|
||||
o Maildir support
|
||||
o complete UIDPLUS IMAP support
|
||||
o make summaryview display any list of messages,
|
||||
fix processing rules by score
|
||||
o privacy api that is independent from the crypto system
|
||||
o rewrite mime message parsing (maybe required for privacy stuff)
|
||||
o PEM support (S/MIME)
|
||||
o add new messages to the summaryview without reloading the
|
||||
whole list
|
||||
|
@ -56,3 +51,11 @@ win32 0.8.0claws+
|
|||
o Selective Download:
|
||||
- pluginify selective download (separate filtering rules)
|
||||
- create pop3 preview Folder as a part of the plugin
|
||||
|
||||
[luke]
|
||||
o Content-Disposition header
|
||||
- re-add parsing of Content-Disposition, to get names
|
||||
for attachments (some MUAs do not set the Content-Type
|
||||
'name' parameter)
|
||||
o option to use KDE/GNOME for opening attachments
|
||||
|
||||
|
|
|
@ -38,8 +38,6 @@ AC_DEFUN([AM_PATH_OPENSSL],
|
|||
AC_ARG_WITH(openssl-libs, [ --with-openssl-libs=PREFIX Location of OpenSSL libs.],
|
||||
with_openssl_libs="$withval")
|
||||
if test "x${with_openssl_libs}" != "xno" -a "x${have_openssl_includes}" != "xno"; then
|
||||
LIBS_save="$LIBS"
|
||||
|
||||
case $with_openssl_libs in
|
||||
""|-L*) ;;
|
||||
*) with_openssl_libs="-L$with_openssl_libs" ;;
|
||||
|
@ -48,6 +46,7 @@ AC_DEFUN([AM_PATH_OPENSSL],
|
|||
AC_CHECK_LIB(dl, dlopen, DL_LIBS="-ldl", DL_LIBS="")
|
||||
AC_CACHE_CHECK([for OpenSSL libraries], openssl_libs,
|
||||
[
|
||||
LIBS_save="$LIBS"
|
||||
LIBS="$LIBS $with_openssl_libs -lssl -lcrypto $DL_LIBS"
|
||||
AC_TRY_LINK_FUNC(SSL_read, openssl_libs="yes", openssl_libs="no")
|
||||
LIBS="$LIBS_save"
|
||||
|
|
|
@ -21,13 +21,6 @@ fi
|
|||
|
||||
dnl ----------------------------------------------------------------------
|
||||
|
||||
AC_CHECK_LIB(socket, socket)
|
||||
AC_CHECK_LIB(crypto, CRYPTO_lock)
|
||||
AC_CHECK_LIB(ssl, SSL_CTX_free,,,-lcrypto)
|
||||
AC_CHECK_LIB(inet, connect)
|
||||
AC_CHECK_LIB(nsl, t_accept)
|
||||
AC_CHECK_LIB(dl, dlopen)
|
||||
|
||||
AC_CHECK_FUNCS(socket strdup strtod strtol snprintf shutdown)
|
||||
|
||||
dnl ----------------------------------------------------------------------
|
||||
|
|
72
configure.ac
72
configure.ac
|
@ -8,7 +8,7 @@ PACKAGE=sylpheed
|
|||
dnl version number
|
||||
MAJOR_VERSION=0
|
||||
MINOR_VERSION=9
|
||||
MICRO_VERSION=5
|
||||
MICRO_VERSION=8
|
||||
INTERFACE_AGE=0
|
||||
BINARY_AGE=0
|
||||
EXTRA_VERSION=0
|
||||
|
@ -60,7 +60,7 @@ AC_SUBST(LT_REVISION)
|
|||
AC_SUBST(LT_AGE)
|
||||
|
||||
dnl Specify a header configuration file
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
|
@ -68,7 +68,6 @@ dnl Checks for programs.
|
|||
dnl AC_ARG_PROGRAM
|
||||
AC_PROG_CC
|
||||
AC_ISC_POSIX
|
||||
AM_PROG_CC_STDC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
|
@ -76,7 +75,7 @@ AC_PROG_CPP
|
|||
dnl AC_PROG_RANLIB
|
||||
AM_PROG_LEX
|
||||
AC_PROG_YACC
|
||||
AM_PROG_LIBTOOL
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
SYLPHEED_ACLOCAL_INCLUDE(ac)
|
||||
|
||||
|
@ -126,7 +125,7 @@ dnl Checks for iconv
|
|||
AM_ICONV
|
||||
|
||||
dnl for gettext
|
||||
ALL_LINGUAS="bg cs de el en_GB es fr hr hu it ja ko nl pl pt_BR ru sk sr sv zh_TW.Big5"
|
||||
ALL_LINGUAS="bg cs de el en_GB es fr hr hu it ja ko nl pl pt_BR ru sk sr sv zh_CN zh_TW.Big5"
|
||||
GETTEXT_PACKAGE=sylpheed
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define text domain.])
|
||||
|
@ -172,6 +171,19 @@ else
|
|||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
dnl Check for d_type member in struct dirent
|
||||
AC_MSG_CHECKING([whether struct dirent has d_type member])
|
||||
AC_CACHE_VAL(ac_cv_dirent_d_type,[
|
||||
AC_TRY_COMPILE([#include <dirent.h>],
|
||||
[struct dirent d; d.d_type = DT_REG;],
|
||||
ac_cv_dirent_d_type=yes, ac_cv_dirent_d_type=no)
|
||||
])
|
||||
AC_MSG_RESULT($ac_cv_dirent_d_type)
|
||||
if test $ac_cv_dirent_d_type = yes; then
|
||||
AC_DEFINE(HAVE_DIRENT_D_TYPE, 1,
|
||||
Define if `struct dirent' has `d_type' member.)
|
||||
fi
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
|
@ -239,8 +251,8 @@ LIBS=$syl_save_LIBS
|
|||
|
||||
dnl check for IPv6 option
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
[ --enable-ipv6 Enable IPv6 support [default=no]],
|
||||
[ac_cv_enable_ipv6=$enableval], [ac_cv_enable_ipv6=no])
|
||||
[ --disable-ipv6 Disable IPv6 support],
|
||||
[ac_cv_enable_ipv6=$enableval], [ac_cv_enable_ipv6=yes])
|
||||
|
||||
dnl automated checks for IPv6 support.
|
||||
AC_MSG_CHECKING([whether to use IPv6])
|
||||
|
@ -337,8 +349,20 @@ dnl Check for X-Face support
|
|||
AC_ARG_ENABLE(compface,
|
||||
[ --disable-compface Do not use compface (X-Face)],
|
||||
[ac_cv_enable_compface=$enableval], [ac_cv_enable_compface=yes])
|
||||
if test "$ac_cv_enable_compface" = yes; then
|
||||
AC_CHECK_LIB(compface, uncompface,,[ac_cv_enable_compface=no])
|
||||
AC_MSG_CHECKING([whether to use compface])
|
||||
if test x"$ac_cv_enable_compface" = xyes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_CHECK_LIB(compface, uncompface,
|
||||
[AC_DEFINE(HAVE_LIBCOMPFACE, 1, Define if you want compface support.)],
|
||||
[ac_cv_enable_compface=no])
|
||||
if test x"$ac_cv_enable_compface" = xyes; then
|
||||
COMPFACE_LIBS="-lcompface"
|
||||
else
|
||||
COMPFACE_LIBS=""
|
||||
fi
|
||||
AC_SUBST(COMPFACE_LIBS)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
dnl for LDAP support in addressbook
|
||||
|
@ -401,12 +425,14 @@ if test "$ac_cv_enable_jpilot" = yes; then
|
|||
[ ac_cv_enable_jpilot=yes
|
||||
AC_DEFINE(USE_JPILOT, 1, Define if you want JPilot support in addressbook.) ])
|
||||
fi
|
||||
AC_MSG_CHECKING([whether jpilot is available])
|
||||
AC_MSG_RESULT($ac_cv_enable_jpilot)
|
||||
|
||||
if test "$ac_cv_enable_jpilot" = yes; then
|
||||
LIBS="$LIBS -lpisock"
|
||||
AC_CHECK_LIB(pisock, unpack_Address, [JPILOT_LIBS="-lpisock"], [JPILOT_LIBS="" ac_cv_enable_jpilot="no"])
|
||||
if test x"$ac_cv_enable_jpilot" = xyes; then
|
||||
AC_DEFINE(USE_JPILOT, 1, Define if you want JPilot support in addressbook.)
|
||||
else
|
||||
AC_MSG_NOTICE([JPilot support not available])
|
||||
fi
|
||||
AC_SUBST(JPILOT_LIBS)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
@ -433,7 +459,7 @@ PLUGINS=""
|
|||
|
||||
dnl --- Trayicon ---
|
||||
AC_ARG_ENABLE(trayicon-plugin,
|
||||
[ --enable-trayicon-plugin System Tray Icon [default=no]],
|
||||
[ --disable-trayicon-plugin Do not build System Tray Icon plugin],
|
||||
[ac_cv_enable_trayicon_plugin=$enableval], [ac_cv_enable_trayicon_plugin=yes])
|
||||
if test x"$ac_cv_enable_trayicon_plugin" = xyes; then
|
||||
PLUGINS="trayicon $PLUGINS"
|
||||
|
@ -442,7 +468,7 @@ AM_CONDITIONAL(BUILD_TRAYICON_PLUGIN, test x"$ac_cv_enable_trayicon_plugin" = xy
|
|||
|
||||
dnl --- SpamAssassin ---
|
||||
AC_ARG_ENABLE(spamassassin-plugin,
|
||||
[ --enable-spamassassin-plugin Build SpamAssassin plugin [default=no]],
|
||||
[ --enable-spamassassin-plugin Build SpamAssassin plugin [default=no]],
|
||||
[ac_cv_enable_spamassassin_plugin=$enableval], [ac_cv_enable_spamassassin_plugin=no])
|
||||
if test x"$ac_cv_enable_spamassassin_plugin" = xyes; then
|
||||
AC_SPAMASSASSIN
|
||||
|
@ -452,10 +478,10 @@ AM_CONDITIONAL(BUILD_SPAMASSASSIN_PLUGIN, test x"$ac_cv_enable_spamassassin_plug
|
|||
|
||||
dnl --- MathML Viewer ---
|
||||
AC_ARG_ENABLE(mathml-viewer-plugin,
|
||||
[ --enable-mathml-viewer-plugin Build MathML-Viewer plugin [default=no]],
|
||||
[ --disable-mathml-viewer-plugin Do not build MathML-Viewer plugin],
|
||||
[ac_cv_enable_mathml_viewer_plugin=$enableval], [ac_cv_enable_mathml_viewer_plugin=yes])
|
||||
if test x"$ac_cv_enable_mathml_viewer_plugin" = xyes; then
|
||||
PKG_CHECK_MODULES(GTK_MATH_VIEW, gtkmathview >= 0.4.2, :, ac_cv_enable_mathml_viewer_plugin=no)
|
||||
PKG_CHECK_MODULES(GTK_MATH_VIEW, gtkmathview >= 0.4.2 gtkmathview < 0.5, :, ac_cv_enable_mathml_viewer_plugin=no)
|
||||
|
||||
if test x"$ac_cv_enable_mathml_viewer_plugin" = xyes; then
|
||||
AC_SUBST(GTK_MATH_VIEW_CFLAGS)
|
||||
|
@ -468,14 +494,14 @@ AM_CONDITIONAL(BUILD_MATHML_VIEWER_PLUGIN, test x"$ac_cv_enable_mathml_viewer_pl
|
|||
|
||||
dnl --- Image Viewer ---
|
||||
AC_ARG_ENABLE(image-viewer-plugin,
|
||||
[ --disable-image-viewer-plugin Do not build image viewer plugin],
|
||||
[ --disable-image-viewer-plugin Do not build image viewer plugin],
|
||||
[ac_cv_enable_image_viewer_plugin=$enableval], [ac_cv_enable_image_viewer_plugin=yes])
|
||||
if test x"$ac_cv_enable_image_viewer_plugin" = xyes; then
|
||||
AC_ARG_ENABLE(gdk-pixbuf,
|
||||
[ --disable-gdk-pixbuf Do not use gdk-pixbuf],
|
||||
[ --disable-gdk-pixbuf Do not use gdk-pixbuf],
|
||||
[ac_cv_enable_gdk_pixbuf=$enableval], [ac_cv_enable_gdk_pixbuf=yes])
|
||||
AC_ARG_ENABLE(imlib,
|
||||
[ --disable-imlib Do not use imlib],
|
||||
[ --disable-imlib Do not use imlib],
|
||||
[ac_cv_enable_imlib=$enableval], [ac_cv_enable_imlib=yes])
|
||||
|
||||
if test "$ac_cv_enable_gdk_pixbuf" = yes; then
|
||||
|
@ -495,7 +521,7 @@ AM_CONDITIONAL(BUILD_IMAGE_VIEWER_PLUGIN, test x"$ac_cv_enable_image_viewer_plug
|
|||
|
||||
dnl --- Dillo Viewer ---
|
||||
AC_ARG_ENABLE(dillo-viewer-plugin,
|
||||
[ --enable-dillo-viewer-plugin Build Dillo plugin for html mail rendering [default=no]],
|
||||
[ --disable-dillo-viewer-plugin Do not build Dillo plugin for html mail rendering],
|
||||
[ac_cv_enable_dillo_viewer_plugin=$enableval], [ac_cv_enable_dillo_viewer_plugin=yes])
|
||||
if test x"$ac_cv_enable_dillo_viewer_plugin" = xyes; then
|
||||
PLUGINS="dillo-viewer $PLUGINS"
|
||||
|
@ -504,7 +530,7 @@ AM_CONDITIONAL(BUILD_DILLO_VIEWER_PLUGIN, test x"$ac_cv_enable_dillo_viewer_plug
|
|||
|
||||
dnl --- Demo ---
|
||||
AC_ARG_ENABLE(demo-plugin,
|
||||
[ --enable-demo-plugin Build demo plugin [default=no]],
|
||||
[ --enable-demo-plugin Build demo plugin [default=no]],
|
||||
[ac_cv_enable_demo_plugin=$enableval], [ac_cv_enable_demo_plugin=no])
|
||||
if test x"$ac_cv_enable_demo_plugin" = xyes; then
|
||||
PLUGINS="demo $PLUGINS"
|
||||
|
@ -513,7 +539,7 @@ AM_CONDITIONAL(BUILD_DEMO_PLUGIN, test x"$ac_cv_enable_demo_plugin" = xyes)
|
|||
|
||||
dnl --- ClamAV ---
|
||||
AC_ARG_ENABLE(clamav-plugin,
|
||||
[ --enable-clamav-plugin Build Clam AntiVirus plugin [default=no]],
|
||||
[ --disable-clamav-plugin Do not build Clam AntiVirus plugin],
|
||||
[ac_cv_enable_clamav_plugin=$enableval], [ac_cv_enable_clamav_plugin=yes])
|
||||
if test x"$ac_cv_enable_clamav_plugin" = xyes; then
|
||||
AC_CHECK_LIB(clamav, cl_scanfile, clamav_lib=-lclamav, ac_cv_enable_clamav_plugin=no)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
.TH "Sylpheed" "1" "" "Hiroyuki Yamamoto" ""
|
||||
.TH "Sylpheed-Claws" "1" "" "Hiroyuki Yamamoto & the Sylpheed-Claws team" ""
|
||||
.SH "NAME"
|
||||
.LP
|
||||
Sylpheed \- a GTK+ based fast e\-mail and news client
|
||||
Sylpheed\-Claws \- a GTK+ based fast e\-mail and news client
|
||||
.SH "DESCRIPTION"
|
||||
.TP
|
||||
Sylpheed is an e\-mail client (and news reader) based on GTK+, running on X Window System, and aiming for
|
||||
Sylpheed\-Claws is an e\-mail client (and news reader) based on GTK+, running on X Window System, and aiming for
|
||||
.br
|
||||
* Quick response
|
||||
.br
|
||||
|
@ -79,6 +79,8 @@ o automake + autoconf support
|
|||
o internationalization of messages by gettext
|
||||
.br
|
||||
o support of many code sets, including UTF\-8 (Unicode) (when using libjconv)
|
||||
.br
|
||||
o support for plugins
|
||||
\fR
|
||||
.LP
|
||||
This list is not complete.
|
||||
|
@ -109,6 +111,8 @@ This list is not complete.
|
|||
\fB \-\-help\fR
|
||||
.br
|
||||
\fB \-\-version\fR
|
||||
.br
|
||||
\fB \-\-config\-dir\fR
|
||||
.SH "FILES"
|
||||
.LP
|
||||
.TP
|
||||
|
@ -124,8 +128,20 @@ Manual files in HTML format
|
|||
$PREFIX/share/sylpheed/faq
|
||||
FAQ files in HTML format
|
||||
.TP
|
||||
$PREFIX/share/sylpheed/themes
|
||||
Global themes directory
|
||||
.TP
|
||||
$PREFIX/lib/sylpheed/plugins
|
||||
Directory for plugins
|
||||
.TP
|
||||
$PREFIX/include/sylpheed
|
||||
Directory for header files
|
||||
.TP
|
||||
$HOME/.sylpheed
|
||||
User's configuration files directory
|
||||
Default directory for user's configuration files directory
|
||||
.TP
|
||||
$HOME/.sylpheed/themes
|
||||
User's themes directory
|
||||
.TP
|
||||
$HOME/.sylpheed/accountrc
|
||||
Configuration for account(s)
|
||||
|
@ -142,8 +158,8 @@ Configuration for custom headers for sending mail
|
|||
$HOME/.sylpheed/dispheaderrc
|
||||
Configuration for custom display of headers in message view
|
||||
.TP
|
||||
$HOME/.sylpheed/filterrc
|
||||
Filter function configuration
|
||||
$HOME/.sylpheed/matcherrc
|
||||
Filtering and Processing function configuration
|
||||
.TP
|
||||
$HOME/.sylpheed/folderlist.xml
|
||||
Folder hierachy listing
|
||||
|
@ -210,11 +226,13 @@ Start sylpheed in (or switch to, if already running) online mode
|
|||
Start sylpheed in (or switch to, if already running) offline mode
|
||||
.TP
|
||||
\fB\-\-help\fR
|
||||
.br
|
||||
display the help message and exit
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
display version number and exit
|
||||
.TP
|
||||
\fB\-\-config\-dir\fR
|
||||
display the CONFIG\-DIR and exit
|
||||
.SH "INSTALLATION"
|
||||
.LP
|
||||
This program requires GTK+ 1.2.6 or higher to be compiled.
|
||||
|
@ -235,7 +253,7 @@ Password: [Enter password]
|
|||
.br
|
||||
# make install
|
||||
.LP
|
||||
See INSTALL from the source distribution package for full installation instructions.
|
||||
Refer to ./configure \-\-help for further information.
|
||||
.SH "AUTHORS"
|
||||
.LP
|
||||
.TP
|
||||
|
@ -262,6 +280,8 @@ Thorsten Maerz <torte@netztorte.de>
|
|||
.br
|
||||
Paul Mangan <claws@thewildbeast.co.uk>
|
||||
.br
|
||||
Luke Plant <L.Plant.98@cantab.net>
|
||||
.br
|
||||
Martin Schaaf <mascha@ma\-scha.de>
|
||||
.br
|
||||
Carsten Schurig <Carsten.Schurig@web.de>
|
||||
|
@ -270,10 +290,7 @@ Sergey Vlasov <vsu@users.sourceforge.net>
|
|||
.br
|
||||
Hiroyuki Yamamoto <hiro\-y@kcn.ne.jp>
|
||||
.TP
|
||||
sylpheed\-w32 (http://www.gnupg.org/cvs\-access.html)
|
||||
Werner Koch <wk@gnupg.org>
|
||||
.TP
|
||||
sylpheed\-claws\-w32 (http://claws\-w32.sourceforge.net)
|
||||
sylpheed\-claws\-w32
|
||||
Thorsten Maerz <torte@netztorte.de>\fR
|
||||
|
||||
|
||||
|
@ -284,10 +301,7 @@ Sylpheed Homepage
|
|||
<http://sylpheed.good\-day.net>
|
||||
.TP
|
||||
Sylpheed\-Claws Homepage
|
||||
<http://www.sf.net/sylpheed\-claws>
|
||||
.TP
|
||||
Sylpheed Win32
|
||||
<http://www.gnupg.org/cvs\-access.html>
|
||||
<http://sylpheed\-claws.sf.net>
|
||||
.TP
|
||||
Sylpheed\-Claws Win32 Homepage
|
||||
<http://www.sf.net/claws\-w32>
|
||||
<http://sylpheed\-claws.sf.net/win32>
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
src/account.c
|
||||
src/action.c
|
||||
src/addressadd.c
|
||||
src/addressbook.c
|
||||
src/addrgather.c
|
||||
src/addrindex.c
|
||||
src/alertpanel.c
|
||||
src/browseldap.c
|
||||
src/common/intl.h
|
||||
src/common/md5.c
|
||||
src/common/nntp.c
|
||||
src/common/plugin.c
|
||||
src/common/smtp.c
|
||||
src/common/ssl.c
|
||||
src/common/ssl_certificate.c
|
||||
src/common/utils.c
|
||||
src/compose.c
|
||||
src/crash.c
|
||||
src/editaddress.c
|
||||
src/editbook.c
|
||||
src/editgroup.c
|
||||
src/editjpilot.c
|
||||
src/editldap.c
|
||||
src/editldap_basedn.c
|
||||
src/editldap.c
|
||||
src/editvcard.c
|
||||
src/exphtmldlg.c
|
||||
src/expldifdlg.c
|
||||
|
@ -30,11 +34,14 @@ src/folderview.c
|
|||
src/grouplistdialog.c
|
||||
src/gtk/about.c
|
||||
src/gtk/colorlabel.c
|
||||
src/gtk/description_window.c
|
||||
src/gtk/gtkaspell.c
|
||||
src/gtk/gtkutils.c
|
||||
src/gtk/logwindow.c
|
||||
src/gtk/pluginwindow.c
|
||||
src/gtk/prefswindow.c
|
||||
src/gtk/progressdialog.c
|
||||
src/gtk/sslcertwindow.c
|
||||
src/gtk/gtkaspell.c
|
||||
src/headerview.c
|
||||
src/imap.c
|
||||
src/import.c
|
||||
|
@ -43,56 +50,58 @@ src/importmutt.c
|
|||
src/importpine.c
|
||||
src/inc.c
|
||||
src/inputdialog.c
|
||||
src/logwindow.c
|
||||
src/ldif.c
|
||||
src/main.c
|
||||
src/mainwindow.c
|
||||
src/matcher.c
|
||||
src/message_search.c
|
||||
src/messageview.c
|
||||
src/mh.c
|
||||
src/mimeview.c
|
||||
src/news.c
|
||||
src/passphrase.c
|
||||
src/plugins/clamav/clamav_plugin.c
|
||||
src/plugins/clamav/clamav_plugin_gtk.c
|
||||
src/plugins/demo/demo.c
|
||||
src/plugins/dillo_viewer/dillo_prefs.c
|
||||
src/plugins/dillo_viewer/dillo_viewer.c
|
||||
src/plugins/image_viewer/plugin.c
|
||||
src/plugins/image_viewer/viewer.c
|
||||
src/plugins/image_viewer/viewerprefs.c
|
||||
src/plugins/mathml_viewer/mathml_viewer.c
|
||||
src/plugins/spamassassin/libspamc.c
|
||||
src/plugins/spamassassin/spamassassin.c
|
||||
src/plugins/spamassassin/spamassassin_gtk.c
|
||||
src/plugins/spamassassin/utils.c
|
||||
src/plugins/trayicon/trayicon.c
|
||||
src/pop.c
|
||||
src/prefs_gtk.c
|
||||
src/prefs_account.c
|
||||
src/prefs_actions.c
|
||||
src/prefs_common.c
|
||||
src/prefs_customheader.c
|
||||
src/prefs_display_header.c
|
||||
src/prefs_filtering_action.c
|
||||
src/prefs_filtering.c
|
||||
src/prefs_folder_item.c
|
||||
src/prefs_fonts.c
|
||||
src/prefs_gtk.c
|
||||
src/prefs_matcher.c
|
||||
src/prefs_scoring.c
|
||||
src/prefs_spelling.c
|
||||
src/prefs_summary_column.c
|
||||
src/prefs_template.c
|
||||
src/prefs_toolbar.c
|
||||
src/privacy.c
|
||||
src/procmsg.c
|
||||
src/progressdialog.c
|
||||
src/quote_fmt.c
|
||||
src/rfc2015.c
|
||||
src/select-keys.c
|
||||
src/send_message.c
|
||||
src/setup.c
|
||||
src/sigstatus.c
|
||||
src/sgpgme.c
|
||||
src/sourcewindow.c
|
||||
src/ssl_manager.c
|
||||
src/string_match.c
|
||||
src/summary_search.c
|
||||
src/summaryview.c
|
||||
src/textview.c
|
||||
src/toolbar.c
|
||||
src/plugins/demo/demo.c
|
||||
src/plugins/trayicon/trayicon.c
|
||||
src/plugins/mathml_viewer/mathml_viewer.c
|
||||
src/plugins/image_viewer/viewerprefs.c
|
||||
src/plugins/image_viewer/viewer.c
|
||||
src/plugins/image_viewer/plugin.c
|
||||
src/plugins/dillo_viewer/dillo_viewer.c
|
||||
src/plugins/dillo_viewer/dillo_prefs.c
|
||||
src/plugins/clamav/clamav_plugin_gtk.c
|
||||
src/plugins/clamav/clamav_plugin.c
|
||||
src/plugins/spamassassin/spamassassin.c
|
||||
src/plugins/spamassassin/libspamc.c
|
||||
src/plugins/spamassassin/spamassassin_gtk.c
|
||||
src/plugins/spamassassin/utils.c
|
||||
|
|
7259
po/en_GB.po
7259
po/en_GB.po
File diff suppressed because it is too large
Load diff
|
@ -19,10 +19,10 @@ bin_PROGRAMS = sylpheed
|
|||
sylpheed_SOURCES = \
|
||||
account.c \
|
||||
action.c \
|
||||
addr_compl.c \
|
||||
addrbook.c \
|
||||
addrcache.c \
|
||||
addrclip.c \
|
||||
addr_compl.c \
|
||||
addressadd.c \
|
||||
addressbook.c \
|
||||
addrgather.c \
|
||||
|
@ -32,6 +32,7 @@ sylpheed_SOURCES = \
|
|||
addrquery.c \
|
||||
addrselect.c \
|
||||
alertpanel.c \
|
||||
browseldap.c \
|
||||
codeconv.c \
|
||||
compose.c \
|
||||
crash.c \
|
||||
|
@ -41,8 +42,8 @@ sylpheed_SOURCES = \
|
|||
editbook.c \
|
||||
editgroup.c \
|
||||
editjpilot.c \
|
||||
editldap.c \
|
||||
editldap_basedn.c \
|
||||
editldap.c \
|
||||
editvcard.c \
|
||||
enriched.c \
|
||||
exphtmldlg.c \
|
||||
|
@ -67,11 +68,11 @@ sylpheed_SOURCES = \
|
|||
inputdialog.c \
|
||||
jpilot.c \
|
||||
ldapctrl.c \
|
||||
ldaplocate.c \
|
||||
ldapquery.c \
|
||||
ldapserver.c \
|
||||
ldaputil.c \
|
||||
ldif.c \
|
||||
logwindow.c \
|
||||
main.c \
|
||||
mainwindow.c \
|
||||
manual.c \
|
||||
|
@ -79,7 +80,6 @@ sylpheed_SOURCES = \
|
|||
matcher_parser_lex.l \
|
||||
matcher_parser_parse.y \
|
||||
mbox.c \
|
||||
mbox_folder.c \
|
||||
message_search.c \
|
||||
messageview.c \
|
||||
mh.c \
|
||||
|
@ -89,6 +89,7 @@ sylpheed_SOURCES = \
|
|||
news.c \
|
||||
noticeview.c \
|
||||
passphrase.c \
|
||||
pgpmime.c \
|
||||
pine.c \
|
||||
pop.c \
|
||||
prefs_account.c \
|
||||
|
@ -96,30 +97,29 @@ sylpheed_SOURCES = \
|
|||
prefs_common.c \
|
||||
prefs_customheader.c \
|
||||
prefs_display_header.c \
|
||||
prefs_filtering.c \
|
||||
prefs_filtering_action.c \
|
||||
prefs_filtering.c \
|
||||
prefs_folder_item.c \
|
||||
prefs_fonts.c \
|
||||
prefs_gtk.c \
|
||||
prefs_matcher.c \
|
||||
prefs_scoring.c \
|
||||
prefs_spelling.c \
|
||||
prefs_summary_column.c \
|
||||
prefs_template.c \
|
||||
prefs_toolbar.c \
|
||||
privacy.c \
|
||||
procheader.c \
|
||||
procmime.c \
|
||||
procmsg.c \
|
||||
progressdialog.c \
|
||||
quote_fmt.c \
|
||||
quote_fmt_lex.l \
|
||||
quote_fmt_parse.y \
|
||||
recv.c \
|
||||
rfc2015.c \
|
||||
scoring.c \
|
||||
select-keys.c \
|
||||
send_message.c \
|
||||
setup.c \
|
||||
sigstatus.c \
|
||||
sgpgme.c \
|
||||
simple-gettext.c \
|
||||
sourcewindow.c \
|
||||
ssl_manager.c \
|
||||
|
@ -132,6 +132,8 @@ sylpheed_SOURCES = \
|
|||
toolbar.c \
|
||||
undo.c \
|
||||
unmime.c \
|
||||
localfolder.c \
|
||||
remotefolder.c \
|
||||
vcard.c
|
||||
|
||||
sylpheedincludedir = $(pkgincludedir)
|
||||
|
@ -139,10 +141,11 @@ sylpheedinclude_HEADERS = \
|
|||
account.h \
|
||||
action.h \
|
||||
adbookbase.h \
|
||||
addr_compl.h \
|
||||
addrbook.h \
|
||||
addrcache.h \
|
||||
addrclip.h \
|
||||
addr_compl.h \
|
||||
addrdefs.h \
|
||||
addressadd.h \
|
||||
addressbook.h \
|
||||
addressitem.h \
|
||||
|
@ -153,6 +156,7 @@ sylpheedinclude_HEADERS = \
|
|||
addrquery.h \
|
||||
addrselect.h \
|
||||
alertpanel.h \
|
||||
browseldap.h \
|
||||
codeconv.h \
|
||||
compose.h \
|
||||
crash.h \
|
||||
|
@ -162,8 +166,8 @@ sylpheedinclude_HEADERS = \
|
|||
editbook.h \
|
||||
editgroup.h \
|
||||
editjpilot.h \
|
||||
editldap.h \
|
||||
editldap_basedn.h \
|
||||
editldap.h \
|
||||
editvcard.h \
|
||||
enriched.h \
|
||||
exphtmldlg.h \
|
||||
|
@ -188,11 +192,11 @@ sylpheedinclude_HEADERS = \
|
|||
inputdialog.h \
|
||||
jpilot.h \
|
||||
ldapctrl.h \
|
||||
ldaplocate.h \
|
||||
ldapquery.h \
|
||||
ldapserver.h \
|
||||
ldaputil.h \
|
||||
ldif.h \
|
||||
logwindow.h \
|
||||
main.h \
|
||||
mainwindow.h \
|
||||
manual.h \
|
||||
|
@ -201,7 +205,6 @@ sylpheedinclude_HEADERS = \
|
|||
matcher_parser_lex.h \
|
||||
matcher_parser_parse.h \
|
||||
mbox.h \
|
||||
mbox_folder.h \
|
||||
message_search.h \
|
||||
messageview.h \
|
||||
mh.h \
|
||||
|
@ -211,6 +214,7 @@ sylpheedinclude_HEADERS = \
|
|||
news.h \
|
||||
noticeview.h \
|
||||
passphrase.h \
|
||||
pgpmime.h \
|
||||
pine.h \
|
||||
pop.h \
|
||||
prefs_account.h \
|
||||
|
@ -218,30 +222,29 @@ sylpheedinclude_HEADERS = \
|
|||
prefs_common.h \
|
||||
prefs_customheader.h \
|
||||
prefs_display_header.h \
|
||||
prefs_filtering.h \
|
||||
prefs_filtering_action.h \
|
||||
prefs_filtering.h \
|
||||
prefs_folder_item.h \
|
||||
prefs_fonts.h \
|
||||
prefs_gtk.h \
|
||||
prefs_matcher.h \
|
||||
prefs_scoring.h \
|
||||
prefs_spelling.h \
|
||||
prefs_summary_column.h \
|
||||
prefs_template.h \
|
||||
prefs_toolbar.h \
|
||||
privacy.h \
|
||||
procheader.h \
|
||||
procmime.h \
|
||||
procmsg.h \
|
||||
progressdialog.h \
|
||||
quote_fmt.h \
|
||||
quote_fmt_lex.h \
|
||||
quote_fmt_parse.h \
|
||||
recv.h \
|
||||
rfc2015.h \
|
||||
scoring.h \
|
||||
select-keys.h \
|
||||
send_message.h \
|
||||
setup.h \
|
||||
sigstatus.h \
|
||||
sgpgme.h \
|
||||
sourcewindow.h \
|
||||
ssl_manager.h \
|
||||
statusbar.h \
|
||||
|
@ -253,6 +256,8 @@ sylpheedinclude_HEADERS = \
|
|||
toolbar.h \
|
||||
undo.h \
|
||||
unmime.h \
|
||||
localfolder.h \
|
||||
remotefolder.h \
|
||||
vcard.h
|
||||
|
||||
BUILT_SOURCES = \
|
||||
|
@ -268,6 +273,7 @@ EXTRA_DIST = \
|
|||
pixmaps/category.xpm \
|
||||
pixmaps/checkbox_off.xpm \
|
||||
pixmaps/checkbox_on.xpm \
|
||||
pixmaps/check_spelling.xpm \
|
||||
pixmaps/clipkey.xpm \
|
||||
pixmaps/clip.xpm \
|
||||
pixmaps/close.xpm \
|
||||
|
@ -307,16 +313,10 @@ EXTRA_DIST = \
|
|||
pixmaps/mail_send.xpm \
|
||||
pixmaps/mail.xpm \
|
||||
pixmaps/mark.xpm \
|
||||
pixmaps/messageview_text.xpm \
|
||||
pixmaps/mime_application_octet_stream.xpm \
|
||||
pixmaps/mime_application.xpm \
|
||||
pixmaps/mime_audio.xpm \
|
||||
pixmaps/mime_gpg_expired.xpm \
|
||||
pixmaps/mime_gpg_failed.xpm \
|
||||
pixmaps/mime_gpg_passed.xpm \
|
||||
pixmaps/mime_gpg_signed.xpm \
|
||||
pixmaps/mime_gpg_unknown.xpm \
|
||||
pixmaps/mime_image.xpm \
|
||||
pixmaps/mime_message.xpm \
|
||||
pixmaps/mime_text_enriched.xpm \
|
||||
pixmaps/mime_text_html.xpm \
|
||||
pixmaps/mime_text_plain.xpm \
|
||||
|
@ -326,10 +326,18 @@ EXTRA_DIST = \
|
|||
pixmaps/notice_error.xpm \
|
||||
pixmaps/notice_note.xpm \
|
||||
pixmaps/notice_warn.xpm \
|
||||
pixmaps/offline.xpm \
|
||||
pixmaps/online.xpm \
|
||||
pixmaps/outbox_hrm.xpm \
|
||||
pixmaps/outbox.xpm \
|
||||
pixmaps/paste.xpm \
|
||||
pixmaps/preferences.xpm \
|
||||
pixmaps/privacy_expired.xpm \
|
||||
pixmaps/privacy_failed.xpm \
|
||||
pixmaps/privacy_passed.xpm \
|
||||
pixmaps/privacy_signed.xpm \
|
||||
pixmaps/privacy_unknown.xpm \
|
||||
pixmaps/privacy_warn.xpm \
|
||||
pixmaps/properties.xpm \
|
||||
pixmaps/quicksearch.xpm \
|
||||
pixmaps/regular.xpm \
|
||||
|
@ -341,9 +349,7 @@ EXTRA_DIST = \
|
|||
pixmaps/trash.xpm \
|
||||
pixmaps/unread.xpm \
|
||||
pixmaps/up_arrow.xpm \
|
||||
pixmaps/vcard.xpm \
|
||||
pixmaps/work_offline.xpm \
|
||||
pixmaps/work_online.xpm
|
||||
pixmaps/vcard.xpm
|
||||
|
||||
INCLUDES = \
|
||||
-Icommon \
|
||||
|
@ -361,6 +367,8 @@ sylpheed_LDADD = \
|
|||
$(GPGME_LIBS) \
|
||||
$(LDAP_LIBS) \
|
||||
$(OPENSSL_LIBS) \
|
||||
$(COMPFACE_LIBS) \
|
||||
$(JPILOT_LIBS) \
|
||||
$(LIBICONV) \
|
||||
$(SYLPHEED_RES)
|
||||
|
||||
|
|
185
src/account.c
185
src/account.c
|
@ -46,6 +46,8 @@
|
|||
#include "utils.h"
|
||||
#include "alertpanel.h"
|
||||
#include "procheader.h"
|
||||
#include "customheader.h"
|
||||
#include "remotefolder.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -81,6 +83,7 @@ static void account_edit_create (void);
|
|||
|
||||
static void account_edit_prefs (void);
|
||||
static void account_delete (void);
|
||||
static void account_clone (void);
|
||||
|
||||
static void account_up (void);
|
||||
static void account_down (void);
|
||||
|
@ -88,6 +91,10 @@ static void account_down (void);
|
|||
static void account_set_default (void);
|
||||
|
||||
static void account_edit_close (void);
|
||||
|
||||
static gint account_clone_event (GtkWidget *widget,
|
||||
GdkEventAny *event,
|
||||
gpointer data);
|
||||
static gint account_delete_event (GtkWidget *widget,
|
||||
GdkEventAny *event,
|
||||
gpointer data);
|
||||
|
@ -349,7 +356,7 @@ void account_add(void)
|
|||
}
|
||||
|
||||
folder->account = ac_prefs;
|
||||
ac_prefs->folder = REMOTE_FOLDER(folder);
|
||||
ac_prefs->folder = folder;
|
||||
folder_add(folder);
|
||||
if (ac_prefs->protocol == A_IMAP4)
|
||||
folder->klass->create_tree(folder);
|
||||
|
@ -432,7 +439,7 @@ void account_set_missing_folder(void)
|
|||
}
|
||||
|
||||
folder->account = ap;
|
||||
ap->folder = REMOTE_FOLDER(folder);
|
||||
ap->folder = folder;
|
||||
folder_add(folder);
|
||||
if (ap->protocol == A_IMAP4)
|
||||
folder->klass->create_tree(folder);
|
||||
|
@ -539,6 +546,7 @@ static void account_edit_create(void)
|
|||
GtkWidget *add_btn;
|
||||
GtkWidget *edit_btn;
|
||||
GtkWidget *del_btn;
|
||||
GtkWidget *clone_btn;
|
||||
GtkWidget *up_btn;
|
||||
GtkWidget *down_btn;
|
||||
|
||||
|
@ -550,7 +558,7 @@ static void account_edit_create(void)
|
|||
debug_print("Creating account edit window...\n");
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_widget_set_size_request (window, 500, 320);
|
||||
gtk_widget_set_usize (window, 500, 350);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
|
||||
gtk_window_set_title (GTK_WINDOW (window), _("Edit accounts"));
|
||||
gtk_window_set_modal (GTK_WINDOW (window), TRUE);
|
||||
|
@ -639,6 +647,12 @@ static void account_edit_create(void)
|
|||
g_signal_connect (G_OBJECT(del_btn), "clicked",
|
||||
G_CALLBACK (account_delete), NULL);
|
||||
|
||||
clone_btn = gtk_button_new_with_label (_(" Clone "));
|
||||
gtk_widget_show (clone_btn);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), clone_btn, FALSE, FALSE, 4);
|
||||
gtk_signal_connect (GTK_OBJECT(clone_btn), "clicked",
|
||||
GTK_SIGNAL_FUNC (account_clone), NULL);
|
||||
|
||||
down_btn = gtk_button_new_with_label (_("Down"));
|
||||
gtk_widget_show (down_btn);
|
||||
gtk_box_pack_end (GTK_BOX (vbox2), down_btn, FALSE, FALSE, 4);
|
||||
|
@ -723,6 +737,162 @@ static gboolean account_delete_references_func(GNode *node, gpointer data)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#define ACP_FDUP(fld) ac_clon->fld = ((ac_prefs->fld) != NULL)?\
|
||||
g_strdup(ac_prefs->fld): NULL
|
||||
#define ACP_FASSIGN(fld) ac_clon->fld = ac_prefs->fld
|
||||
static void account_clone(void)
|
||||
{
|
||||
GtkCList *clist = GTK_CLIST(edit_account.clist);
|
||||
gint row;
|
||||
PrefsAccount *ac_prefs, *ac_clon;
|
||||
GSList *hdrs = NULL;
|
||||
CustomHeader *cch = NULL, *ch = NULL;
|
||||
|
||||
if (!clist->selection) return;
|
||||
|
||||
row = GPOINTER_TO_INT(clist->selection->data);
|
||||
ac_prefs = gtk_clist_get_row_data(clist, row);
|
||||
|
||||
if (ac_prefs->protocol == A_IMAP4 || ac_prefs->protocol == A_NNTP) {
|
||||
alertpanel_error(_("Accounts with remote folders cannot be cloned"));
|
||||
return;
|
||||
}
|
||||
|
||||
ac_clon = prefs_account_new();
|
||||
/* copy fields */
|
||||
ac_clon->account_name = g_strdup_printf(_("Cloned %s"),
|
||||
ac_prefs->account_name);
|
||||
/* personal */
|
||||
ACP_FDUP(name);
|
||||
ACP_FDUP(address);
|
||||
ACP_FDUP(organization);
|
||||
|
||||
/* server */
|
||||
ACP_FASSIGN(protocol);
|
||||
ACP_FDUP(recv_server);
|
||||
ACP_FDUP(smtp_server);
|
||||
ACP_FDUP(nntp_server);
|
||||
ACP_FASSIGN(use_nntp_auth);
|
||||
ACP_FASSIGN(use_nntp_auth_onconnect);
|
||||
ACP_FDUP(userid);
|
||||
ACP_FDUP(passwd);
|
||||
|
||||
ACP_FDUP(local_mbox);
|
||||
ACP_FASSIGN(use_mail_command);
|
||||
ACP_FDUP(mail_command);
|
||||
|
||||
#if USE_OPENSSL
|
||||
ACP_FASSIGN(ssl_pop);
|
||||
ACP_FASSIGN(ssl_imap);
|
||||
ACP_FASSIGN(ssl_nntp);
|
||||
ACP_FASSIGN(ssl_smtp);
|
||||
ACP_FASSIGN(use_nonblocking_ssl);
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
ac_clon->tmp_pass = NULL;
|
||||
|
||||
/* receive */
|
||||
ACP_FASSIGN(rmmail);
|
||||
ACP_FASSIGN(msg_leave_time);
|
||||
ACP_FASSIGN(getall);
|
||||
ACP_FASSIGN(recv_at_getall);
|
||||
ACP_FASSIGN(sd_rmmail_on_download);
|
||||
ACP_FASSIGN(sd_filter_on_recv);
|
||||
ACP_FASSIGN(enable_size_limit);
|
||||
ACP_FASSIGN(size_limit);
|
||||
ACP_FASSIGN(filter_on_recv);
|
||||
ACP_FDUP(inbox);
|
||||
ACP_FASSIGN(max_articles);
|
||||
|
||||
ACP_FASSIGN(imap_auth_type);
|
||||
|
||||
/* send */
|
||||
ACP_FASSIGN(add_date);
|
||||
ACP_FASSIGN(gen_msgid);
|
||||
ACP_FASSIGN(add_customhdr);
|
||||
ACP_FASSIGN(use_smtp_auth);
|
||||
ACP_FASSIGN(smtp_auth_type);
|
||||
ACP_FDUP(smtp_userid);
|
||||
ACP_FDUP(smtp_passwd);
|
||||
|
||||
ac_clon->tmp_smtp_pass = NULL;
|
||||
|
||||
ACP_FASSIGN(pop_before_smtp);
|
||||
ACP_FASSIGN(pop_before_smtp_timeout);
|
||||
ACP_FASSIGN(last_pop_login_time);
|
||||
|
||||
ac_clon->customhdr_list = NULL;
|
||||
hdrs = ac_prefs->customhdr_list;
|
||||
while (hdrs != NULL) {
|
||||
ch = (CustomHeader *)hdrs->data;
|
||||
|
||||
cch = g_new0(CustomHeader, 1);
|
||||
cch->account_id = ac_clon->account_id;
|
||||
cch->name = (ch->name != NULL) ? g_strdup(ch->name) : NULL;
|
||||
cch->value = (ch->value != NULL) ? g_strdup(ch->value) : NULL;
|
||||
|
||||
ac_clon->customhdr_list = g_slist_append(ac_clon->customhdr_list, cch);
|
||||
|
||||
hdrs = g_slist_next(hdrs);
|
||||
}
|
||||
|
||||
/* compose */
|
||||
ACP_FASSIGN(sig_type);
|
||||
ACP_FDUP(sig_path);
|
||||
ACP_FASSIGN(auto_sig);
|
||||
ACP_FDUP(sig_sep);
|
||||
ACP_FASSIGN(set_autocc);
|
||||
ACP_FDUP(auto_cc);
|
||||
ACP_FASSIGN(set_autobcc);
|
||||
ACP_FDUP(auto_bcc);
|
||||
ACP_FASSIGN(set_autoreplyto);
|
||||
ACP_FDUP(auto_replyto);
|
||||
|
||||
#if USE_GPGME
|
||||
/* privacy */
|
||||
ACP_FASSIGN(default_encrypt);
|
||||
ACP_FASSIGN(default_sign);
|
||||
ACP_FASSIGN(default_gnupg_mode);
|
||||
ACP_FASSIGN(sign_key);
|
||||
ACP_FDUP(sign_key_id);
|
||||
#endif /* USE_GPGME */
|
||||
|
||||
/* advanced */
|
||||
ACP_FASSIGN(set_smtpport);
|
||||
ACP_FASSIGN(smtpport);
|
||||
ACP_FASSIGN(set_popport);
|
||||
ACP_FASSIGN(popport);
|
||||
ACP_FASSIGN(set_imapport);
|
||||
ACP_FASSIGN(imapport);
|
||||
ACP_FASSIGN(set_nntpport);
|
||||
ACP_FASSIGN(nntpport);
|
||||
ACP_FASSIGN(set_domain);
|
||||
ACP_FDUP(domain);
|
||||
ACP_FASSIGN(mark_crosspost_read);
|
||||
ACP_FASSIGN(crosspost_col);
|
||||
|
||||
ACP_FASSIGN(set_tunnelcmd);
|
||||
ACP_FDUP(tunnelcmd);
|
||||
|
||||
ACP_FDUP(imap_dir);
|
||||
|
||||
ACP_FASSIGN(set_sent_folder);
|
||||
ACP_FDUP(sent_folder);
|
||||
ACP_FASSIGN(set_draft_folder);
|
||||
ACP_FDUP(draft_folder);
|
||||
ACP_FASSIGN(set_trash_folder);
|
||||
ACP_FDUP(trash_folder);
|
||||
/* don't want two default accounts */
|
||||
ac_clon->is_default = FALSE;
|
||||
ACP_FASSIGN(folder);
|
||||
|
||||
account_list = g_list_append(account_list, ac_clon);
|
||||
account_clist_set();
|
||||
}
|
||||
#undef ACP_FDUP
|
||||
#undef ACP_FASSIGN
|
||||
|
||||
static void account_delete(void)
|
||||
{
|
||||
GtkCList *clist = GTK_CLIST(edit_account.clist);
|
||||
|
@ -820,6 +990,13 @@ static void account_edit_close(void)
|
|||
inc_unlock();
|
||||
}
|
||||
|
||||
static gint account_clone_event(GtkWidget *widget, GdkEventAny *event,
|
||||
gpointer data)
|
||||
{
|
||||
account_clone();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint account_delete_event(GtkWidget *widget, GdkEventAny *event,
|
||||
gpointer data)
|
||||
{
|
||||
|
@ -1015,7 +1192,7 @@ PrefsAccount *account_get_reply_account(MsgInfo *msginfo, gboolean reply_autosel
|
|||
}
|
||||
if (!account) {
|
||||
gchar cc[BUFFSIZE];
|
||||
if (!get_header_from_msginfo(msginfo, cc, sizeof(cc), "CC:")) { /* Found a CC header */
|
||||
if (!procheader_get_header_from_msginfo(msginfo, cc, sizeof(cc), "CC:")) { /* Found a CC header */
|
||||
extract_address(cc);
|
||||
account = account_find_from_address(cc);
|
||||
}
|
||||
|
|
68
src/action.c
68
src/action.c
|
@ -50,6 +50,8 @@
|
|||
#include "compose.h"
|
||||
#include "procmsg.h"
|
||||
#include "textview.h"
|
||||
#include "matcher_parser.h" /* CLAWS */
|
||||
#include "filtering.h"
|
||||
|
||||
typedef struct _Children Children;
|
||||
typedef struct _ChildInfo ChildInfo;
|
||||
|
@ -114,6 +116,9 @@ static void message_actions_execute (MessageView *msgview,
|
|||
guint action_nb,
|
||||
GSList *msg_list);
|
||||
|
||||
static gboolean execute_filtering_actions(gchar *action,
|
||||
GSList *msglist);
|
||||
|
||||
static gboolean execute_actions (gchar *action,
|
||||
GSList *msg_list,
|
||||
GtkWidget *text,
|
||||
|
@ -192,8 +197,18 @@ ActionType action_get_type(const gchar *action_str)
|
|||
return ACTION_ERROR;
|
||||
|
||||
while (*p && action_type != ACTION_ERROR) {
|
||||
if (p[0] == '%') {
|
||||
if (p[0] == '%' && p[1]) {
|
||||
switch (p[1]) {
|
||||
case 'a':
|
||||
/* CLAWS: filtering action is a mutually exclusive
|
||||
* action. we can enable others if needed later. we
|
||||
* add ACTION_SINGLE | ACTION_MULTIPLE so it will
|
||||
* only be executed from the main window toolbar */
|
||||
if (p[2] == 's') /* source messages */
|
||||
action_type = ACTION_FILTERING_ACTION
|
||||
| ACTION_SINGLE
|
||||
| ACTION_MULTIPLE;
|
||||
break;
|
||||
case 'f':
|
||||
action_type |= ACTION_SINGLE;
|
||||
break;
|
||||
|
@ -358,7 +373,7 @@ static gboolean parse_append_msgpart(GString *cmd, MsgInfo *msginfo,
|
|||
filename = procmsg_get_message_file_path(msginfo);
|
||||
part_filename = procmime_get_tmp_file_name(partinfo);
|
||||
|
||||
ret = procmime_get_part(part_filename, filename, partinfo);
|
||||
ret = procmime_get_part(part_filename, partinfo);
|
||||
|
||||
if (single_part)
|
||||
procmime_mimeinfo_free_all(partinfo);
|
||||
|
@ -472,7 +487,7 @@ static void compose_actions_execute_cb(Compose *compose, guint action_nb,
|
|||
if (action_type & (ACTION_SINGLE | ACTION_MULTIPLE)) {
|
||||
alertpanel_warning
|
||||
(_("The selected action cannot be used in the compose window\n"
|
||||
"because it contains %%f, %%F or %%p."));
|
||||
"because it contains %%f, %%F, %%as or %%p."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -533,7 +548,39 @@ static void message_actions_execute(MessageView *msgview, guint action_nb,
|
|||
if (action_type & (ACTION_PIPE_OUT | ACTION_INSERT))
|
||||
msgview->filtered = TRUE;
|
||||
|
||||
execute_actions(action, msg_list, text, body_pos, partinfo);
|
||||
if (action_type & ACTION_FILTERING_ACTION)
|
||||
/* CLAWS: most of the above code is not necessary for applying
|
||||
* filtering */
|
||||
execute_filtering_actions(action, msg_list);
|
||||
else
|
||||
execute_actions(action, msg_list, text, body_pos, partinfo);
|
||||
}
|
||||
|
||||
static gboolean execute_filtering_actions(gchar *action, GSList *msglist)
|
||||
{
|
||||
GSList *action_list, *p;
|
||||
const gchar *sbegin, *send;
|
||||
gchar *action_string;
|
||||
|
||||
if (NULL == (sbegin = strstr2(action, "%as{")))
|
||||
return FALSE;
|
||||
sbegin += sizeof "%as{" - 1;
|
||||
if (NULL == (send = strrchr(sbegin, '}')))
|
||||
return FALSE;
|
||||
action_string = g_strndup(sbegin, send - sbegin);
|
||||
|
||||
action_list = matcher_parser_get_action_list(action_string);
|
||||
g_free(action_string);
|
||||
if (action_list == NULL) return FALSE;
|
||||
|
||||
/* apply actions on each message info */
|
||||
for (p = msglist; p && p->data; p = g_slist_next(p))
|
||||
filteringaction_apply_action_list(action_list, (MsgInfo *) p->data);
|
||||
|
||||
for (p = action_list; p; p = g_slist_next(p))
|
||||
if (p->data) filteringaction_free(p->data);
|
||||
g_slist_free(action_list);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean execute_actions(gchar *action, GSList *msg_list,
|
||||
|
@ -1017,7 +1064,10 @@ static void update_io_dialog(Children *children)
|
|||
ChildInfo *child_info;
|
||||
GtkTextBuffer *textbuf;
|
||||
GtkTextIter iter, start_iter, end_iter;
|
||||
GdkFont *font;
|
||||
|
||||
font = gtk_object_get_data(GTK_OBJECT(children->dialog),
|
||||
"s_txtfont");
|
||||
gtk_widget_show(children->scrolledwin);
|
||||
textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(text));
|
||||
gtk_text_buffer_get_start_iter (textbuf, &start_iter);
|
||||
|
@ -1058,6 +1108,7 @@ static void create_io_dialog(Children *children)
|
|||
GtkWidget *progress_bar = NULL;
|
||||
GtkWidget *abort_button;
|
||||
GtkWidget *close_button;
|
||||
GdkFont *output_font;
|
||||
|
||||
debug_print("Creating action IO dialog\n");
|
||||
|
||||
|
@ -1134,7 +1185,7 @@ static void create_io_dialog(Children *children)
|
|||
children->initial_nb -children->nb,
|
||||
0.0, children->initial_nb);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(vbox), progress_bar, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), progress_bar, FALSE, FALSE, 0);
|
||||
gtk_widget_show(progress_bar);
|
||||
}
|
||||
|
||||
|
@ -1160,6 +1211,13 @@ static void create_io_dialog(Children *children)
|
|||
children->abort_btn = abort_button;
|
||||
children->close_btn = close_button;
|
||||
|
||||
#warning FIXME_GTK2 convert to Pango / FontDesc?
|
||||
#if 0
|
||||
output_font = gtkut_font_load_from_fontset(prefs_common.textfont);
|
||||
gtk_object_set_data_full(GTK_OBJECT(dialog), "s_txtfont",
|
||||
output_font,
|
||||
(GtkDestroyNotify)gdk_font_unref);
|
||||
#endif
|
||||
gtk_widget_show(dialog);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ typedef enum
|
|||
ACTION_USER_STR = 1 << 9,
|
||||
ACTION_USER_HIDDEN_STR = 1 << 10,
|
||||
ACTION_SELECTION_STR = 1 << 11,
|
||||
ACTION_FILTERING_ACTION = 1 << 12,
|
||||
ACTION_ERROR = 1 << 30
|
||||
} ActionType;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
# include <wctype.h>
|
||||
#endif
|
||||
|
||||
#include "addressbook.h"
|
||||
#include "addrindex.h"
|
||||
#include "addr_compl.h"
|
||||
#include "utils.h"
|
||||
#include <pthread.h>
|
||||
|
@ -63,11 +63,6 @@
|
|||
* any of those words).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reference to address index.
|
||||
*/
|
||||
static AddressIndex *_addressIndex_ = NULL;
|
||||
|
||||
/**
|
||||
* address_entry - structure which refers to the original address entry in the
|
||||
* address book .
|
||||
|
@ -210,7 +205,7 @@ static gint add_address(const gchar *name, const gchar *address, const gchar *al
|
|||
* Read address book, creating all entries in the completion index.
|
||||
*/
|
||||
static void read_address_book(void) {
|
||||
addrindex_load_completion( _addressIndex_, add_address );
|
||||
addrindex_load_completion( add_address );
|
||||
g_address_list = g_list_reverse(g_address_list);
|
||||
g_completion_list = g_list_reverse(g_completion_list);
|
||||
}
|
||||
|
@ -594,6 +589,9 @@ static CompletionWindow *addrcompl_create_window( void ) {
|
|||
* \param cw Window to destroy.
|
||||
*/
|
||||
static void addrcompl_destroy_window( CompletionWindow *cw ) {
|
||||
/* Stop all searches currently in progress */
|
||||
addrindex_stop_search( _queryID_ );
|
||||
|
||||
/* Remove idler function... or application may not terminate */
|
||||
if( _completionIdleID_ != 0 ) {
|
||||
gtk_idle_remove( _completionIdleID_ );
|
||||
|
@ -747,17 +745,15 @@ static void addrcompl_add_entry( CompletionWindow *cw, gchar *address ) {
|
|||
static gboolean addrcompl_idle( gpointer data ) {
|
||||
GList *node;
|
||||
gchar *address;
|
||||
CompletionWindow *cw;
|
||||
|
||||
/* Process all entries in display queue */
|
||||
pthread_mutex_lock( & _completionMutex_ );
|
||||
if( _displayQueue_ ) {
|
||||
cw = data;
|
||||
node = _displayQueue_;
|
||||
while( node ) {
|
||||
address = node->data;
|
||||
/* printf( "address ::: %s :::\n", address ); */
|
||||
addrcompl_add_entry( cw, address );
|
||||
addrcompl_add_entry( _compWindow_, address );
|
||||
g_free( address );
|
||||
node = g_list_next( node );
|
||||
}
|
||||
|
@ -772,35 +768,34 @@ static gboolean addrcompl_idle( gpointer data ) {
|
|||
/**
|
||||
* Callback entry point. The background thread (if any) appends the address
|
||||
* list to the display queue.
|
||||
* \param sender Sender of query.
|
||||
* \param queryID Query ID of search request.
|
||||
* \param listEMail List of zero of more email objects that met search
|
||||
* criteria.
|
||||
* \param target Target object to received data.
|
||||
* \param data Query data.
|
||||
*/
|
||||
static gint addrcompl_callback(
|
||||
gint queryID, GList *listEMail, gpointer target )
|
||||
static gint addrcompl_callback_entry(
|
||||
gpointer sender, gint queryID, GList *listEMail, gpointer data )
|
||||
{
|
||||
GList *node;
|
||||
gchar *address;
|
||||
|
||||
/* printf( "addrcompl_callback::queryID=%d\n", queryID ); */
|
||||
/* printf( "addrcompl_callback_entry::queryID=%d\n", queryID ); */
|
||||
pthread_mutex_lock( & _completionMutex_ );
|
||||
if( target ) {
|
||||
if( queryID == _queryID_ ) {
|
||||
/* Append contents to end of display queue */
|
||||
node = listEMail;
|
||||
while( node ) {
|
||||
ItemEMail *email = node->data;
|
||||
if( queryID == _queryID_ ) {
|
||||
/* Append contents to end of display queue */
|
||||
node = listEMail;
|
||||
while( node ) {
|
||||
ItemEMail *email = node->data;
|
||||
|
||||
address = addritem_format_email( email );
|
||||
/* printf( "\temail/address ::%s::\n", address ); */
|
||||
_displayQueue_ = g_list_append( _displayQueue_, address );
|
||||
node = g_list_next( node );
|
||||
}
|
||||
address = addritem_format_email( email );
|
||||
/* printf( "\temail/address ::%s::\n", address ); */
|
||||
_displayQueue_ = g_list_append( _displayQueue_, address );
|
||||
node = g_list_next( node );
|
||||
}
|
||||
}
|
||||
g_list_free( listEMail );
|
||||
pthread_mutex_unlock( & _completionMutex_ );
|
||||
/* printf( "addrcompl_callback...done\n" ); */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -830,9 +825,8 @@ static void addrcompl_add_queue( gchar *address ) {
|
|||
|
||||
/**
|
||||
* Load list with entries from local completion index.
|
||||
* \param cw Completion window.
|
||||
*/
|
||||
static void addrcompl_load_local( CompletionWindow *cw ) {
|
||||
static void addrcompl_load_local( void ) {
|
||||
guint count = 0;
|
||||
|
||||
for (count = 0; count < get_completion_count(); count++) {
|
||||
|
@ -856,19 +850,19 @@ static void addrcompl_start_search( void ) {
|
|||
|
||||
/* Setup the search */
|
||||
_queryID_ = addrindex_setup_search(
|
||||
_addressIndex_, searchTerm, _compWindow_, addrcompl_callback );
|
||||
searchTerm, NULL, addrcompl_callback_entry );
|
||||
g_free( searchTerm );
|
||||
/* printf( "addrcompl_start_search::queryID=%d\n", _queryID_ ); */
|
||||
|
||||
/* Load local stuff */
|
||||
addrcompl_load_local( _compWindow_ );
|
||||
addrcompl_load_local();
|
||||
|
||||
/* Sit back and wait until something happens */
|
||||
_completionIdleID_ =
|
||||
gtk_idle_add( ( GtkFunction ) addrcompl_idle, _compWindow_ );
|
||||
gtk_idle_add( ( GtkFunction ) addrcompl_idle, NULL );
|
||||
/* printf( "addrindex_start_search::queryID=%d\n", _queryID_ ); */
|
||||
|
||||
addrindex_start_search( _addressIndex_, _queryID_ );
|
||||
addrindex_start_search( _queryID_ );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1374,12 +1368,8 @@ static gboolean completion_window_key_press(GtkWidget *widget,
|
|||
|
||||
/**
|
||||
* Setup completion object.
|
||||
* \param addrIndex Address index object.
|
||||
*/
|
||||
void addrcompl_initialize( AddressIndex *addrIndex ) {
|
||||
g_return_if_fail( addrIndex != NULL );
|
||||
_addressIndex_ = addrIndex;
|
||||
|
||||
void addrcompl_initialize( void ) {
|
||||
/* printf( "addrcompl_initialize...\n" ); */
|
||||
if( ! _compWindow_ ) {
|
||||
_compWindow_ = addrcompl_create_window();
|
||||
|
@ -1401,7 +1391,6 @@ void addrcompl_teardown( void ) {
|
|||
}
|
||||
_displayQueue_ = NULL;
|
||||
_completionIdleID_ = 0;
|
||||
_addressIndex_ = NULL;
|
||||
/* printf( "addrcompl_teardown...done\n" ); */
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,9 @@
|
|||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "addrindex.h"
|
||||
|
||||
gint start_address_completion (void);
|
||||
guint complete_address (const gchar *str);
|
||||
gchar *get_complete_address (gint index);
|
||||
gchar *get_complete_address (gint index);
|
||||
gint invalidate_address_completion (void);
|
||||
gint end_address_completion (void);
|
||||
|
||||
|
@ -37,7 +35,7 @@ void address_completion_register_entry (GtkEntry *entry);
|
|||
void address_completion_unregister_entry(GtkEntry *entry);
|
||||
void address_completion_end (GtkWidget *mainwindow);
|
||||
|
||||
void addrcompl_initialize ( AddressIndex *addrIndex );
|
||||
void addrcompl_initialize ( void );
|
||||
void addrcompl_teardown ( void );
|
||||
|
||||
#endif /* __ADDR_COMPL_H__ */
|
||||
|
|
|
@ -1720,6 +1720,11 @@ ItemGroup *addrbook_add_group_list(AddressBookFile *book, ItemFolder *folder,
|
|||
* <code>g_free()</code> when done.
|
||||
*/
|
||||
ItemFolder *addrbook_add_new_folder(AddressBookFile *book, ItemFolder *parent)
|
||||
{
|
||||
g_return_val_if_fail(book != NULL, NULL);
|
||||
return addrcache_add_new_folder( book->addressCache, parent );
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
ItemFolder *folder = NULL;
|
||||
ItemFolder *p = parent;
|
||||
|
@ -1741,6 +1746,7 @@ ItemFolder *addrbook_add_new_folder(AddressBookFile *book, ItemFolder *parent)
|
|||
}
|
||||
return folder;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Update address book attribute list for specified person. Note: The existing
|
||||
|
|
|
@ -1326,17 +1326,19 @@ ItemFolder *addrcache_remove_folder_delete( AddressCache *cache, ItemFolder *fol
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add person and address data to cache.
|
||||
* Enter: cache Cache.
|
||||
* folder Folder where to add person, or NULL for root folder.
|
||||
* name Common name.
|
||||
* address EMail address.
|
||||
* remarks Remarks.
|
||||
* Return: Person added. Do not *NOT* to use the addrbook_free_xxx() functions...
|
||||
* this will destroy the address book data.
|
||||
*/
|
||||
ItemPerson *addrcache_add_contact( AddressCache *cache, ItemFolder *folder, const gchar *name,
|
||||
/**
|
||||
* Add person and address data to cache.
|
||||
* \param cache Cache.
|
||||
* \param folder Folder where to add person, or NULL for root folder.
|
||||
* \param name Common name.
|
||||
* \param address EMail address.
|
||||
* \param remarks Remarks.
|
||||
* \return Person added. Do not *NOT* to use the
|
||||
* <code>addrbook_free_xxx()</code> functions...; this will destroy
|
||||
* the address book data.
|
||||
*/
|
||||
ItemPerson *addrcache_add_contact(
|
||||
AddressCache *cache, ItemFolder *folder, const gchar *name,
|
||||
const gchar *address, const gchar *remarks )
|
||||
{
|
||||
ItemPerson *person = NULL;
|
||||
|
@ -1364,6 +1366,36 @@ ItemPerson *addrcache_add_contact( AddressCache *cache, ItemFolder *folder, cons
|
|||
return person;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new folder and add to address cache.
|
||||
* \param cache Address cache.
|
||||
* \param folder Parent folder where to add folder, or <i>NULL</i> for
|
||||
* root folder.
|
||||
* \return Folder that was created. This should <b>*NOT*</b> be
|
||||
* <code>g_free()</code> when done.
|
||||
*/
|
||||
ItemFolder *addrcache_add_new_folder( AddressCache *cache, ItemFolder *parent )
|
||||
{
|
||||
ItemFolder *folder;
|
||||
ItemFolder *p = parent;
|
||||
|
||||
g_return_val_if_fail( cache != NULL, NULL );
|
||||
|
||||
if( !p ) p = cache->rootFolder;
|
||||
folder = addritem_create_item_folder();
|
||||
addrcache_id_folder( cache, folder );
|
||||
if( addrcache_hash_add_folder( cache, folder ) ) {
|
||||
p->listFolder = g_list_append( p->listFolder, folder );
|
||||
ADDRITEM_PARENT(folder) = ADDRITEM_OBJECT(p);
|
||||
addrcache_set_dirty( cache, TRUE );
|
||||
}
|
||||
else {
|
||||
addritem_free_item_folder( folder );
|
||||
folder = NULL;
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
|
||||
/*
|
||||
* End of Source.
|
||||
*/
|
||||
|
|
|
@ -170,4 +170,7 @@ ItemPerson *addrcache_add_contact ( AddressCache *cache,
|
|||
const gchar *address,
|
||||
const gchar *remarks );
|
||||
|
||||
ItemFolder *addrcache_add_new_folder ( AddressCache *cache,
|
||||
ItemFolder *parent );
|
||||
|
||||
#endif /* __ADDRCACHE_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load diff
572
src/addrindex.c
572
src/addrindex.c
|
@ -94,10 +94,17 @@
|
|||
#define ATTAG_LDAP_TIMEOUT "timeout"
|
||||
#define ATTAG_LDAP_MAX_AGE "max-age"
|
||||
#define ATTAG_LDAP_DYN_SEARCH "dyn-search"
|
||||
#define ATTAG_LDAP_MATCH_OPT "match-opt"
|
||||
|
||||
#define ELTAG_LDAP_ATTR_SRCH "attribute"
|
||||
#define ATTAG_LDAP_ATTR_NAME "name"
|
||||
|
||||
/* Attribute values */
|
||||
#define ATVAL_BOOLEAN_YES "yes"
|
||||
#define ATVAL_BOOLEAN_NO "no"
|
||||
#define ATVAL_LDAP_MATCH_BEGIN "begin-with"
|
||||
#define ATVAL_LDAP_MATCH_CONTAINS "contains"
|
||||
|
||||
/* New attributes */
|
||||
#define ATTAG_LDAP_DEFAULT "default"
|
||||
|
||||
|
@ -116,6 +123,11 @@ N_("Personal address")
|
|||
#define DISP_OLD_COMMON _("Common address")
|
||||
#define DISP_OLD_PERSONAL _("Personal address")
|
||||
|
||||
/**
|
||||
* Singleton object.
|
||||
*/
|
||||
static AddressIndex *_addressIndex_ = NULL;
|
||||
|
||||
/*
|
||||
* Define attribute name-value pair.
|
||||
*/
|
||||
|
@ -572,7 +584,7 @@ static void addrindex_free_cache_hash( GHashTable *table ) {
|
|||
g_hash_table_destroy( table );
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Remove data source from internal hashtable.
|
||||
* \param addrIndex Address index.
|
||||
* \param ds Data source to remove.
|
||||
|
@ -590,32 +602,44 @@ static void addrindex_hash_remove_cache(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new address index.
|
||||
/**
|
||||
* Create a new address index. This is created as a singleton object.
|
||||
* \return Initialized address index object.
|
||||
*/
|
||||
AddressIndex *addrindex_create_index( void ) {
|
||||
AddressIndex *addrIndex = g_new0( AddressIndex, 1 );
|
||||
AddressIndex *index;
|
||||
|
||||
ADDRITEM_TYPE(addrIndex) = ITEMTYPE_INDEX;
|
||||
ADDRITEM_ID(addrIndex) = NULL;
|
||||
ADDRITEM_NAME(addrIndex) = g_strdup( "Address Index" );
|
||||
ADDRITEM_PARENT(addrIndex) = NULL;
|
||||
ADDRITEM_SUBTYPE(addrIndex) = 0;
|
||||
addrIndex->filePath = NULL;
|
||||
addrIndex->fileName = NULL;
|
||||
addrIndex->retVal = MGU_SUCCESS;
|
||||
addrIndex->needsConversion = FALSE;
|
||||
addrIndex->wasConverted = FALSE;
|
||||
addrIndex->conversionError = FALSE;
|
||||
addrIndex->interfaceList = NULL;
|
||||
addrIndex->lastType = ADDR_IF_NONE;
|
||||
addrIndex->dirtyFlag = FALSE;
|
||||
addrIndex->hashCache = g_hash_table_new( g_str_hash, g_str_equal );
|
||||
addrIndex->loadedFlag = FALSE;
|
||||
addrIndex->searchOrder = NULL;
|
||||
addrindex_build_if_list( addrIndex );
|
||||
return addrIndex;
|
||||
if( _addressIndex_ == NULL ) {
|
||||
index = g_new0( AddressIndex, 1 );
|
||||
ADDRITEM_TYPE(index) = ITEMTYPE_INDEX;
|
||||
ADDRITEM_ID(index) = NULL;
|
||||
ADDRITEM_NAME(index) = g_strdup( "Address Index" );
|
||||
ADDRITEM_PARENT(index) = NULL;
|
||||
ADDRITEM_SUBTYPE(index) = 0;
|
||||
index->filePath = NULL;
|
||||
index->fileName = NULL;
|
||||
index->retVal = MGU_SUCCESS;
|
||||
index->needsConversion = FALSE;
|
||||
index->wasConverted = FALSE;
|
||||
index->conversionError = FALSE;
|
||||
index->interfaceList = NULL;
|
||||
index->lastType = ADDR_IF_NONE;
|
||||
index->dirtyFlag = FALSE;
|
||||
index->hashCache = g_hash_table_new( g_str_hash, g_str_equal );
|
||||
index->loadedFlag = FALSE;
|
||||
index->searchOrder = NULL;
|
||||
addrindex_build_if_list( index );
|
||||
_addressIndex_ = index;
|
||||
}
|
||||
return _addressIndex_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to address index.
|
||||
* \return Address index object.
|
||||
*/
|
||||
AddressIndex *addrindex_get_object( void ) {
|
||||
return _addressIndex_;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -671,18 +695,16 @@ GList *addrindex_get_interface_list( AddressIndex *addrIndex ) {
|
|||
|
||||
/**
|
||||
* Perform any other initialization of address index.
|
||||
* \param addrIndex Address index.
|
||||
*/
|
||||
void addrindex_initialize( AddressIndex *addrIndex ) {
|
||||
void addrindex_initialize( void ) {
|
||||
qrymgr_initialize();
|
||||
addrcompl_initialize( addrIndex );
|
||||
addrcompl_initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform any other teardown of address index.
|
||||
* \param addrIndex Address index.
|
||||
*/
|
||||
void addrindex_teardown( AddressIndex *addrIndex ) {
|
||||
void addrindex_teardown( void ) {
|
||||
addrcompl_teardown();
|
||||
qrymgr_teardown();
|
||||
}
|
||||
|
@ -738,6 +760,8 @@ void addrindex_free_index( AddressIndex *addrIndex ) {
|
|||
addrIndex->loadedFlag = FALSE;
|
||||
|
||||
g_free( addrIndex );
|
||||
addrIndex = NULL;
|
||||
_addressIndex_ = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1055,7 +1079,7 @@ static void addrindex_write_fragment(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#if 0
|
||||
static void addrindex_print_fragment_r(
|
||||
const AddressIfFragment *fragment, FILE *stream, gint lvl )
|
||||
{
|
||||
|
@ -1084,7 +1108,7 @@ static void addrindex_print_fragment_r(
|
|||
static void addrindex_print_fragment( const AddressIfFragment *fragment, FILE *stream ) {
|
||||
addrindex_print_fragment_r( fragment, stream, 0 );
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Read/parse address index file, creating a data source for a regular
|
||||
|
@ -1312,6 +1336,11 @@ static void addrindex_parse_ldap_attrlist( XMLFile *file, LdapControl *ctl ) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse LDAP control data from XML file.
|
||||
* \param file Index file.
|
||||
* \return Initialized data soruce object.
|
||||
*/
|
||||
static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
|
||||
AddressDataSource *ds;
|
||||
LdapServer *server;
|
||||
|
@ -1319,10 +1348,13 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
|
|||
GList *attr;
|
||||
gchar *serverName = NULL;
|
||||
gchar *criteria = NULL;
|
||||
gboolean bSearch = FALSE;
|
||||
gboolean cvtFlag = TRUE;
|
||||
gboolean bDynSearch;
|
||||
gint iMatch;
|
||||
|
||||
/* printf( "addrindex_parse_ldap\n" ); */
|
||||
/* Set up some defaults */
|
||||
bDynSearch = FALSE;
|
||||
iMatch = LDAPCTL_MATCH_BEGINWITH;
|
||||
|
||||
ds = addrindex_create_datasource( ADDR_IF_LDAP );
|
||||
ctl = ldapctl_create();
|
||||
|
@ -1365,10 +1397,15 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
|
|||
ldapctl_set_max_query_age( ctl, ivalue );
|
||||
}
|
||||
else if( strcmp( name, ATTAG_LDAP_DYN_SEARCH ) == 0 ) {
|
||||
bSearch = FALSE;
|
||||
cvtFlag = FALSE;
|
||||
if( strcmp( value, "yes" ) == 0 ) {
|
||||
bSearch = TRUE;
|
||||
bDynSearch = FALSE;
|
||||
if( strcmp( value, ATVAL_BOOLEAN_YES ) == 0 ) {
|
||||
bDynSearch = TRUE;
|
||||
}
|
||||
}
|
||||
else if( strcmp( name, ATTAG_LDAP_MATCH_OPT ) == 0 ) {
|
||||
iMatch = LDAPCTL_MATCH_BEGINWITH;
|
||||
if( strcmp( value, ATVAL_LDAP_MATCH_CONTAINS ) == 0 ) {
|
||||
iMatch = LDAPCTL_MATCH_CONTAINS;
|
||||
}
|
||||
}
|
||||
attr = g_list_next( attr );
|
||||
|
@ -1376,7 +1413,8 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
|
|||
|
||||
server = ldapsvr_create_noctl();
|
||||
ldapsvr_set_name( server, serverName );
|
||||
ldapsvr_set_search_flag( server, bSearch );
|
||||
ldapsvr_set_search_flag( server, bDynSearch );
|
||||
ldapctl_set_matching_option( ctl, iMatch );
|
||||
g_free( serverName );
|
||||
ldapsvr_set_control( server, ctl );
|
||||
ds->rawDataSource = server;
|
||||
|
@ -1393,13 +1431,6 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
|
|||
}
|
||||
g_free( criteria );
|
||||
}
|
||||
/*
|
||||
* If no search flag was found, then we are converting from old format
|
||||
* server data to new format.
|
||||
*/
|
||||
if( cvtFlag ) {
|
||||
ldapsvr_set_search_flag( server, TRUE );
|
||||
}
|
||||
/* ldapsvr_print_data( server, stdout ); */
|
||||
|
||||
return ds;
|
||||
|
@ -1436,7 +1467,12 @@ static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
|
|||
addrindex_write_attr( fp, ATTAG_LDAP_MAX_AGE, value );
|
||||
|
||||
addrindex_write_attr( fp, ATTAG_LDAP_DYN_SEARCH,
|
||||
server->searchFlag ? "yes" : "no" );
|
||||
server->searchFlag ?
|
||||
ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO );
|
||||
|
||||
addrindex_write_attr( fp, ATTAG_LDAP_MATCH_OPT,
|
||||
( ctl->matchingOption == LDAPCTL_MATCH_CONTAINS ) ?
|
||||
ATVAL_LDAP_MATCH_CONTAINS : ATVAL_LDAP_MATCH_BEGIN );
|
||||
|
||||
fputs(" >\n", fp);
|
||||
|
||||
|
@ -2456,174 +2492,60 @@ GList *addrindex_ds_get_all_groups( AddressDataSource *ds ) {
|
|||
*/
|
||||
|
||||
/**
|
||||
* Current query ID. This is incremented for each query created.
|
||||
*/
|
||||
static gint _currentQueryID_ = 0;
|
||||
|
||||
/*
|
||||
* Variables for the search that is being performed.
|
||||
*/
|
||||
static gchar *_searchTerm_ = NULL;
|
||||
static gpointer _searchTarget_ = NULL;
|
||||
static AddrSearchCallbackFunc *_searchCallback_ = NULL;
|
||||
|
||||
/**
|
||||
* Setup or register the search that will be performed.
|
||||
* \param addrIndex Address index object.
|
||||
* \param searchTerm Search term. A private copy will be made.
|
||||
* \param target Target object that will receive data.
|
||||
* \param callBack Callback function.
|
||||
* Setup or register the dynamic search that will be performed. The search
|
||||
* is registered with the query manager.
|
||||
*
|
||||
* \param searchTerm Search term. A private copy will be made.
|
||||
* \param callBackEntry Callback function that should be called when
|
||||
* each entry is received.
|
||||
* \param callBackEnd Callback function that should be called when
|
||||
* search has finished running.
|
||||
* \return ID allocated to query that will be executed.
|
||||
*/
|
||||
gint addrindex_setup_search(
|
||||
AddressIndex *addrIndex, const gchar *searchTerm,
|
||||
const gpointer target, AddrSearchCallbackFunc callBack )
|
||||
const gchar *searchTerm, void *callBackEnd, void *callBackEntry )
|
||||
{
|
||||
QueryRequest *req;
|
||||
gint queryID;
|
||||
|
||||
/* printf( "search term ::%s::\n", searchTerm ); */
|
||||
g_free( _searchTerm_ );
|
||||
_searchTerm_ = g_strdup( searchTerm );
|
||||
/* Set up a dynamic address query */
|
||||
req = qrymgr_add_request( searchTerm, callBackEnd, callBackEntry );
|
||||
queryID = req->queryID;
|
||||
qryreq_set_search_type( req, ADDRSEARCH_DYNAMIC );
|
||||
|
||||
queryID = ++_currentQueryID_;
|
||||
_searchTarget_ = target;
|
||||
_searchCallback_ = callBack;
|
||||
/* printf( "query ID ::%d::\n", queryID ); */
|
||||
/* printf( "***> query ID ::%d::\n", queryID ); */
|
||||
return queryID;
|
||||
}
|
||||
|
||||
#ifdef USE_LDAP
|
||||
/**
|
||||
* LDAP callback entry point for each address entry found.
|
||||
* \param qry LDAP query.
|
||||
* \param listEMail List of Item EMail objects found.
|
||||
*/
|
||||
static void addrindex_ldap_entry_cb( LdapQuery *qry, GList *listEMail ) {
|
||||
/*
|
||||
GList *node;
|
||||
|
||||
printf( "\naddrindex::addrindex_ldap_entry_cb ::%s::\n", qry->queryName );
|
||||
node = listEMail;
|
||||
while( node ) {
|
||||
ItemEMail *email = node->data;
|
||||
printf( "\temail ::%s::\n", email->address );
|
||||
node = g_list_next( node );
|
||||
}
|
||||
*/
|
||||
if( _searchCallback_ ) {
|
||||
( _searchCallback_ ) ( qry->queryID, listEMail, _searchTarget_ );
|
||||
}
|
||||
g_list_free( listEMail );
|
||||
}
|
||||
|
||||
/**
|
||||
* LDAP callback entry point for completion of search.
|
||||
* \param qry LDAP query.
|
||||
*/
|
||||
static void addrindex_ldap_end_cb( LdapQuery *qry ) {
|
||||
/* printf( "\naddrindex::addrindex_ldap_end_cb ::%s::\n", qry->queryName ); */
|
||||
}
|
||||
|
||||
/**
|
||||
* Return results of previous query.
|
||||
* \param folder.
|
||||
* \return List of ItemEMail objects.
|
||||
*/
|
||||
static void addrindex_ldap_use_previous(
|
||||
const ItemFolder *folder, const gint queryID )
|
||||
{
|
||||
GList *listEMail;
|
||||
GList *node;
|
||||
GList *nodeEM;
|
||||
|
||||
listEMail = NULL;
|
||||
if( _searchCallback_ ) {
|
||||
node = folder->listPerson;
|
||||
while( node ) {
|
||||
AddrItemObject *aio = node->data;
|
||||
if( aio && aio->type == ITEMTYPE_PERSON ) {
|
||||
ItemPerson *person = node->data;
|
||||
nodeEM = person->listEMail;
|
||||
while( nodeEM ) {
|
||||
ItemEMail *email = nodeEM->data;
|
||||
nodeEM = g_list_next( nodeEM );
|
||||
listEMail = g_list_append( listEMail, email );
|
||||
}
|
||||
}
|
||||
node = g_list_next( node );
|
||||
}
|
||||
( _searchCallback_ ) ( queryID, listEMail, _searchTarget_ );
|
||||
g_list_free( listEMail );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function prototype (not in header file or circular reference encountered!)
|
||||
* Function prototypes (not in header file or circular reference errors are
|
||||
* encountered!)
|
||||
*/
|
||||
LdapQuery *ldapsvr_locate_query( LdapServer *server, const gchar *searchTerm );
|
||||
|
||||
/**
|
||||
* Construct an LDAP query and initiate an LDAP dynamic search.
|
||||
* \param server LDAP server object.
|
||||
* \param queryID ID of search query to be executed.
|
||||
*/
|
||||
static void addrindex_search_ldap( LdapServer *server, const gint queryID ) {
|
||||
LdapQuery *qry;
|
||||
gchar *name;
|
||||
|
||||
if( ! server->searchFlag ) return;
|
||||
|
||||
/* Retire any aged queries */
|
||||
ldapsvr_retire_query( server );
|
||||
|
||||
/* Test whether any queries for the same term exist */
|
||||
qry = ldapsvr_locate_query( server, _searchTerm_ );
|
||||
if( qry ) {
|
||||
ItemFolder *folder = qry->folder;
|
||||
|
||||
/* Touch query to ensure it hangs around for a bit longer */
|
||||
ldapqry_touch( qry );
|
||||
if( folder ) {
|
||||
addrindex_ldap_use_previous( folder, queryID );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct a query */
|
||||
qry = ldapqry_create();
|
||||
ldapqry_set_query_id( qry, queryID );
|
||||
ldapqry_set_search_value( qry, _searchTerm_ );
|
||||
ldapqry_set_query_type( qry, LDAPQUERY_DYNAMIC );
|
||||
ldapqry_set_callback_entry( qry, addrindex_ldap_entry_cb );
|
||||
ldapqry_set_callback_end( qry, addrindex_ldap_end_cb );
|
||||
|
||||
/* Name the query */
|
||||
name = g_strdup_printf( "Search for '%s'", _searchTerm_ );
|
||||
ldapqry_set_name( qry, name );
|
||||
g_free( name );
|
||||
|
||||
ldapsvr_add_query( server, qry );
|
||||
ldapsvr_execute_query( server, qry );
|
||||
}
|
||||
LdapQuery *ldapsvr_new_dynamic_search(
|
||||
LdapServer *server, QueryRequest *req );
|
||||
LdapQuery *ldapsvr_new_explicit_search(
|
||||
LdapServer *server, QueryRequest *req, ItemFolder *folder );
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Perform the previously registered search.
|
||||
* \param addrIndex Address index object.
|
||||
* \param queryID ID of search query to be executed.
|
||||
* Execute the previously registered dynamic search.
|
||||
*
|
||||
* \param req Address query object to execute.
|
||||
* \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
|
||||
* failed.
|
||||
*/
|
||||
gboolean addrindex_start_search( AddressIndex *addrIndex, const gint queryID ) {
|
||||
static gboolean addrindex_start_dynamic( QueryRequest *req ) {
|
||||
AddressInterface *iface;
|
||||
AddressDataSource *ds;
|
||||
GList *nodeIf;
|
||||
GList *nodeDS;
|
||||
gint type;
|
||||
|
||||
/* printf( "addrindex_start_search::%d::\n", queryID ); */
|
||||
nodeIf = addrIndex->searchOrder;
|
||||
/* printf( "addrindex_start_dynamic::%d::\n", req->queryID ); */
|
||||
nodeIf = _addressIndex_->searchOrder;
|
||||
while( nodeIf ) {
|
||||
iface = nodeIf->data;
|
||||
nodeIf = g_list_next( nodeIf );
|
||||
|
@ -2631,7 +2553,6 @@ gboolean addrindex_start_search( AddressIndex *addrIndex, const gint queryID ) {
|
|||
if( ! iface->useInterface ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ! iface->externalQuery ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -2643,8 +2564,22 @@ gboolean addrindex_start_search( AddressIndex *addrIndex, const gint queryID ) {
|
|||
nodeDS = g_list_next( nodeDS );
|
||||
#ifdef USE_LDAP
|
||||
if( type == ADDR_IF_LDAP ) {
|
||||
LdapServer *server = ds->rawDataSource;
|
||||
addrindex_search_ldap( server, queryID );
|
||||
LdapServer *server;
|
||||
LdapQuery *qry;
|
||||
|
||||
server = ds->rawDataSource;
|
||||
if( ! server->searchFlag ) {
|
||||
continue;
|
||||
}
|
||||
if( ldapsvr_reuse_previous( server, req ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Start a new dynamic search */
|
||||
qry = ldapsvr_new_dynamic_search( server, req );
|
||||
if( qry ) {
|
||||
ldapsvr_execute_query( server, qry );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2654,230 +2589,193 @@ gboolean addrindex_start_search( AddressIndex *addrIndex, const gint queryID ) {
|
|||
|
||||
/**
|
||||
* Stop the previously registered search.
|
||||
* \param addrIndex Address index object.
|
||||
*
|
||||
* \param queryID ID of search query to stop.
|
||||
*/
|
||||
void addrindex_stop_search( AddressIndex *addrIndex, const gint queryID ){
|
||||
#ifdef USE_LDAP
|
||||
AddressInterface *iface;
|
||||
AddressDataSource *ds;
|
||||
GList *nodeIf;
|
||||
GList *nodeDS;
|
||||
gint type;
|
||||
void addrindex_stop_search( const gint queryID ){
|
||||
QueryRequest *req;
|
||||
AddrQueryObject *aqo;
|
||||
GList *node;
|
||||
|
||||
/* printf( "addrindex_stop_search/queryID=%d\n", queryID ); */
|
||||
/* If query ID does not match, search has not been setup */
|
||||
/* if( queryID != _queryID_ ) return; */
|
||||
|
||||
/* printf( "addrindex_stop_search::%d::\n", queryID ); */
|
||||
nodeIf = addrIndex->searchOrder;
|
||||
while( nodeIf ) {
|
||||
iface = nodeIf->data;
|
||||
nodeIf = g_list_next( nodeIf );
|
||||
|
||||
if( ! iface->useInterface ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
type = iface->type;
|
||||
nodeDS = iface->listSource;
|
||||
while( nodeDS ) {
|
||||
ds = nodeDS->data;
|
||||
nodeDS = g_list_next( nodeDS );
|
||||
if( type == ADDR_IF_LDAP ) {
|
||||
LdapServer *server = ds->rawDataSource;
|
||||
ldapsvr_stop_all_query( server );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_LDAP
|
||||
/**
|
||||
* LDAP callback entry point for completion of search.
|
||||
* \param qry LDAP query.
|
||||
*/
|
||||
static void addrindex_ldap_end_static_cb( LdapQuery *qry ) {
|
||||
AddrQuery *addrQry;
|
||||
gint queryID;
|
||||
AddrQueryType queryType;
|
||||
AddrSearchStaticFunc *callBack;
|
||||
|
||||
queryID = qry->queryID;
|
||||
queryType = qry->queryType;
|
||||
addrQry = qrymgr_find_query( queryID );
|
||||
if( addrQry == NULL ) {
|
||||
req = qrymgr_find_request( queryID );
|
||||
if( req == NULL ) {
|
||||
return;
|
||||
}
|
||||
callBack = addrQry->callBack;
|
||||
|
||||
/* Delete query */
|
||||
qrymgr_delete_query( queryID );
|
||||
|
||||
/* Execute callback function */
|
||||
callBack( queryID, queryType, qry->retVal );
|
||||
}
|
||||
/* Stop all queries that were associated with request */
|
||||
node = req->queryList;
|
||||
while( node ) {
|
||||
aqo = node->data;
|
||||
#ifdef USE_LDAP
|
||||
if( aqo->queryType == ADDRQUERY_LDAP ) {
|
||||
LdapQuery *qry = ( LdapQuery * ) aqo;
|
||||
ldapqry_set_stop_flag( qry, TRUE );
|
||||
}
|
||||
#endif
|
||||
node->data = NULL;
|
||||
node = g_list_next( node );
|
||||
}
|
||||
|
||||
/* Delete query request */
|
||||
qrymgr_delete_request( queryID );
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the explicit search that will be performed. The search is registered with
|
||||
* the query manager.
|
||||
* Setup or register the explicit search that will be performed. The search is
|
||||
* registered with the query manager.
|
||||
*
|
||||
* \param ds Data source to search.
|
||||
* \param searchTerm Search term to locate.
|
||||
* \param folder Folder to receive search results; may be NULL.
|
||||
* \param callbackEnd Function to call when search has terminated.
|
||||
* \param ds Data source to search.
|
||||
* \param searchTerm Search term to locate.
|
||||
* \param folder Folder to receive search results; may be NULL.
|
||||
* \param callbackEnd Function to call when search has terminated.
|
||||
* \param callbackEntry Function to called for each entry processed.
|
||||
* \return ID allocated to query that will be executed.
|
||||
*/
|
||||
gint addrindex_setup_static_search(
|
||||
gint addrindex_setup_explicit_search(
|
||||
AddressDataSource *ds, const gchar *searchTerm, ItemFolder *folder,
|
||||
void *callbackEnd )
|
||||
void *callBackEnd, void *callBackEntry )
|
||||
{
|
||||
AddrQuery *addrQry;
|
||||
QueryRequest *req;
|
||||
gint queryID;
|
||||
gchar *name;
|
||||
|
||||
queryID = ++_currentQueryID_;
|
||||
|
||||
/* Name the query */
|
||||
name = g_strdup_printf( "Search '%s'", searchTerm );
|
||||
|
||||
/* Set up a generic address query */
|
||||
addrQry = qrymgr_add_query( queryID, searchTerm, callbackEnd, NULL );
|
||||
/* Set up query request */
|
||||
req = qrymgr_add_request( searchTerm, callBackEnd, callBackEntry );
|
||||
qryreq_set_search_type( req, ADDRSEARCH_EXPLICIT );
|
||||
queryID = req->queryID;
|
||||
|
||||
if( ds->type == ADDR_IF_LDAP ) {
|
||||
#ifdef USE_LDAP
|
||||
LdapServer *server;
|
||||
LdapQuery *qry;
|
||||
|
||||
server = ds->rawDataSource;
|
||||
|
||||
/* Construct a query */
|
||||
qry = ldapqry_create();
|
||||
ldapqry_set_query_id( qry, queryID );
|
||||
ldapqry_set_name( qry, name );
|
||||
ldapqry_set_search_value( qry, searchTerm );
|
||||
ldapqry_set_query_type( qry, LDAPQUERY_STATIC );
|
||||
ldapqry_set_callback_end( qry, addrindex_ldap_end_static_cb );
|
||||
|
||||
/* Specify folder type and back reference */
|
||||
qry->folder = folder;
|
||||
folder->folderType = ADDRFOLDER_LDAP_QUERY;
|
||||
folder->folderData = ( gpointer ) qry;
|
||||
|
||||
/* Setup server */
|
||||
ldapsvr_add_query( server, qry );
|
||||
|
||||
/* Set up generic query */
|
||||
addrqry_set_query_type( addrQry, ADDRQUERY_LDAP );
|
||||
addrqry_set_server( addrQry, server );
|
||||
addrqry_set_query( addrQry, qry );
|
||||
ldapsvr_new_explicit_search( server, req, folder );
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
qrymgr_delete_query( queryID );
|
||||
qrymgr_delete_request( queryID );
|
||||
queryID = 0;
|
||||
}
|
||||
|
||||
g_free( name );
|
||||
|
||||
return queryID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the previously registered explicit search.
|
||||
* \param queryID ID of search query to be executed.
|
||||
* \param idleID Idler ID.
|
||||
* Execute the previously registered explicit search.
|
||||
*
|
||||
* \param req Address query request object to execute.
|
||||
* \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
|
||||
* failed.
|
||||
*/
|
||||
gboolean addrindex_start_static_search( const gint queryID, const guint idleID )
|
||||
{
|
||||
static gboolean addrindex_start_explicit( QueryRequest *req ) {
|
||||
gboolean retVal;
|
||||
AddrQuery *addrQry;
|
||||
AddrQueryObject *aqo;
|
||||
|
||||
retVal = FALSE;
|
||||
addrQry = qrymgr_find_query( queryID );
|
||||
if( addrQry == NULL ) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
if( addrQry->queryType == ADDRQUERY_LDAP ) {
|
||||
/* Note: there should only be one query in the list. */
|
||||
aqo = req->queryList->data;
|
||||
#ifdef USE_LDAP
|
||||
if( aqo->queryType == ADDRQUERY_LDAP ) {
|
||||
LdapServer *server;
|
||||
LdapQuery *qry;
|
||||
|
||||
server = ( LdapServer * ) addrQry->serverObject;
|
||||
qry = ( LdapQuery * ) addrQry->queryObject;
|
||||
|
||||
/* Retire any aged queries */
|
||||
ldapsvr_retire_query( server );
|
||||
qry = ( LdapQuery * ) aqo;
|
||||
server = qry->server;
|
||||
|
||||
/* Start the search */
|
||||
ldapsvr_execute_query( server, qry );
|
||||
retVal = TRUE;
|
||||
ldapsvr_execute_query( server, qry );
|
||||
}
|
||||
#endif
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the previously registered search.
|
||||
*
|
||||
* \param queryID ID of search query to be executed.
|
||||
* \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
|
||||
* failed.
|
||||
*/
|
||||
gboolean addrindex_start_search( const gint queryID ) {
|
||||
gboolean retVal;
|
||||
QueryRequest *req;
|
||||
AddrSearchType searchType;
|
||||
|
||||
retVal = FALSE;
|
||||
/* printf( "addrindex_start_search/queryID=%d\n", queryID ); */
|
||||
req = qrymgr_find_request( queryID );
|
||||
if( req == NULL ) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
if( retVal ) {
|
||||
addrqry_set_idle_id( addrQry, idleID );
|
||||
searchType = req->searchType;
|
||||
if( searchType == ADDRSEARCH_DYNAMIC ) {
|
||||
retVal = addrindex_start_dynamic( req );
|
||||
}
|
||||
else if( searchType == ADDRSEARCH_EXPLICIT ) {
|
||||
retVal = addrindex_start_explicit( req );
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all address books that do not support dynamic queries.
|
||||
* \param addrIndex Address index object.
|
||||
* Remove results (folder and data) for specified data source and folder.
|
||||
* \param ds Data source to process.
|
||||
* \param folder Results folder to remove.
|
||||
*/
|
||||
void addrindex_read_all( AddressIndex *addrIndex ) {
|
||||
AddressInterface *iface;
|
||||
AddressDataSource *ds;
|
||||
GList *nodeIf;
|
||||
GList *nodeDS;
|
||||
void addrindex_remove_results( AddressDataSource *ds, ItemFolder *folder ) {
|
||||
AddrBookBase *adbase;
|
||||
AddressCache *cache;
|
||||
gint queryID = 0;
|
||||
|
||||
nodeIf = addrIndex->searchOrder;
|
||||
while( nodeIf ) {
|
||||
iface = nodeIf->data;
|
||||
nodeIf = g_list_next( nodeIf );
|
||||
/* Test for folder */
|
||||
if( folder->folderType != ADDRFOLDER_QUERY_RESULTS ) return;
|
||||
adbase = ( AddrBookBase * ) ds->rawDataSource;
|
||||
if( adbase == NULL ) return;
|
||||
cache = adbase->addressCache;
|
||||
|
||||
if( ! iface->useInterface ) {
|
||||
continue;
|
||||
}
|
||||
if( iface->externalQuery ) {
|
||||
continue;
|
||||
}
|
||||
nodeDS = iface->listSource;
|
||||
while( nodeDS ) {
|
||||
ds = nodeDS->data;
|
||||
nodeDS = g_list_next( nodeDS );
|
||||
/* Hide folder to prevent re-display */
|
||||
addritem_folder_set_hidden( folder, TRUE );
|
||||
|
||||
/* Read address book */
|
||||
if( addrindex_ds_get_modify_flag( ds ) ) {
|
||||
addrindex_ds_read_data( ds );
|
||||
continue;
|
||||
}
|
||||
if( ds->type == ADDR_IF_LDAP ) {
|
||||
#ifdef USE_LDAP
|
||||
LdapQuery *qry;
|
||||
|
||||
if( ! addrindex_ds_get_read_flag( ds ) ) {
|
||||
addrindex_ds_read_data( ds );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
qry = ( LdapQuery * ) folder->folderData;
|
||||
queryID = ADDRQUERY_ID(qry);
|
||||
ldapquery_remove_results( qry );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Delete query request */
|
||||
if( queryID > 0 ) {
|
||||
qrymgr_delete_request( queryID );
|
||||
}
|
||||
addrIndex->loadedFlag = TRUE;
|
||||
}
|
||||
|
||||
/* **********************************************************************
|
||||
* Address completion stuff.
|
||||
* ***********************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* This function is used by the address completion function to load
|
||||
* addresses for all non-external address book interfaces.
|
||||
*
|
||||
* \param addrIndex Address index object.
|
||||
* \param callBackFunc Function to be called when an address is
|
||||
* to be loaded.
|
||||
* \return <i>TRUE</i> if data loaded, <i>FALSE</i> if address index not loaded.
|
||||
*/
|
||||
gboolean addrindex_load_completion(
|
||||
AddressIndex *addrIndex,
|
||||
gint (*callBackFunc) ( const gchar *, const gchar *, const gchar * ) )
|
||||
{
|
||||
AddressDataSource *ds;
|
||||
|
@ -2886,9 +2784,7 @@ gboolean addrindex_load_completion(
|
|||
GList *nodeM;
|
||||
gchar *sName, *sAddress, *sAlias, *sFriendly;
|
||||
|
||||
if( addrIndex == NULL ) return FALSE;
|
||||
|
||||
nodeIf = addrindex_get_interface_list( addrIndex );
|
||||
nodeIf = addrindex_get_interface_list( _addressIndex_ );
|
||||
while( nodeIf ) {
|
||||
AddressInterface *iface = nodeIf->data;
|
||||
|
||||
|
|
|
@ -99,10 +99,11 @@ struct _AddressDataSource {
|
|||
gpointer rawDataSource;
|
||||
};
|
||||
|
||||
void addrindex_initialize ( AddressIndex *addrIndex );
|
||||
void addrindex_teardown ( AddressIndex *addrIndex );
|
||||
void addrindex_initialize ( void );
|
||||
void addrindex_teardown ( void );
|
||||
|
||||
AddressIndex *addrindex_create_index ( void );
|
||||
AddressIndex *addrindex_get_object ( void );
|
||||
void addrindex_set_file_path ( AddressIndex *addrIndex,
|
||||
const gchar *value );
|
||||
void addrindex_set_file_name ( AddressIndex *addrIndex,
|
||||
|
@ -157,20 +158,27 @@ GList *addrindex_ds_get_all_persons ( AddressDataSource *ds );
|
|||
GList *addrindex_ds_get_all_groups ( AddressDataSource *ds );
|
||||
|
||||
/* Search support */
|
||||
gint addrindex_setup_search ( AddressIndex *addrIndex,
|
||||
const gchar *searchTerm,
|
||||
const gpointer target,
|
||||
AddrSearchCallbackFunc callBack );
|
||||
gboolean addrindex_start_search ( AddressIndex *addrIndex,
|
||||
const gint queryID );
|
||||
void addrindex_stop_search ( AddressIndex *addrIndex,
|
||||
const gint queryID );
|
||||
gint addrindex_setup_search ( const gchar *searchTerm,
|
||||
void *callBackEnd,
|
||||
void *callBackEntry );
|
||||
|
||||
gint addrindex_setup_static_search ( AddressDataSource *ds,
|
||||
const gchar *searchTerm,
|
||||
ItemFolder *folder,
|
||||
void *callBackEnd,
|
||||
void *callBackEntry );
|
||||
|
||||
gboolean addrindex_start_search ( const gint queryID );
|
||||
void addrindex_stop_search ( const gint queryID );
|
||||
void addrindex_remove_results ( AddressDataSource *ds,
|
||||
ItemFolder *folder );
|
||||
|
||||
void addrindex_read_all ( AddressIndex *addrIndex );
|
||||
gboolean addrindex_load_completion(
|
||||
AddressIndex *addrIndex,
|
||||
gint (*callBackFunc)
|
||||
( const gchar *, const gchar *, const gchar * ) );
|
||||
gint addrindex_setup_explicit_search(
|
||||
AddressDataSource *ds, const gchar *searchTerm, ItemFolder *folder,
|
||||
void *callBackEnd, void *callBackEntry );
|
||||
|
||||
#endif /* __ADDRINDEX_H__ */
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "addritem.h"
|
||||
#include "mgutils.h"
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ typedef enum {
|
|||
ADDRFOLDER_ROOT,
|
||||
ADDRFOLDER_REGULAR,
|
||||
ADDRFOLDER_CATEGORY,
|
||||
ADDRFOLDER_LDAP_QUERY
|
||||
ADDRFOLDER_QUERY_RESULTS
|
||||
} AddressFolderType;
|
||||
|
||||
typedef struct _AddrItemObject AddrItemObject;
|
||||
|
|
260
src/addrquery.c
260
src/addrquery.c
|
@ -32,154 +32,152 @@
|
|||
/**
|
||||
* Query list for tracking current queries.
|
||||
*/
|
||||
static GList *_queryList_ = NULL;
|
||||
static GList *_requestList_ = NULL;
|
||||
|
||||
/**
|
||||
* Mutex to protect list from multiple threads.
|
||||
*/
|
||||
static pthread_mutex_t _queryListMutex_ = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t _requestListMutex_ = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Current query ID. This is incremented for each query request created.
|
||||
*/
|
||||
static gint _currentQueryID_ = 0;
|
||||
|
||||
/**
|
||||
* Create new address query.
|
||||
* \return Initialized address query object.
|
||||
*/
|
||||
AddrQuery *addrqry_create( void ) {
|
||||
AddrQuery *qry;
|
||||
QueryRequest *reqreq_create( void ) {
|
||||
QueryRequest *req;
|
||||
|
||||
qry = g_new0( AddrQuery, 1 );
|
||||
qry->queryType = ADDRQUERY_NONE;
|
||||
qry->queryID = 0;
|
||||
qry->idleID = 0;
|
||||
qry->searchTerm = NULL;
|
||||
qry->callBack = NULL;
|
||||
qry->target = NULL;
|
||||
qry->serverObject = NULL;
|
||||
qry->queryObject = NULL;
|
||||
return qry;
|
||||
req = g_new0( QueryRequest, 1 );
|
||||
req->queryID = 0;
|
||||
req->searchType = ADDRSEARCH_NONE;
|
||||
req->searchTerm = NULL;
|
||||
req->callBackEnd = NULL;
|
||||
req->callBackEntry = NULL;
|
||||
req->queryList = NULL;
|
||||
return req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the query.
|
||||
* \param qry Address query object.
|
||||
* \param req Request query object.
|
||||
*/
|
||||
void addrqry_clear( AddrQuery *qry ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
g_free( qry->searchTerm );
|
||||
qry->queryType = ADDRQUERY_NONE;
|
||||
qry->queryID = 0;
|
||||
qry->idleID = 0;
|
||||
qry->searchTerm = NULL;
|
||||
qry->callBack = NULL;
|
||||
qry->target = NULL;
|
||||
qry->serverObject = NULL;
|
||||
qry->queryObject = NULL;
|
||||
void qryreq_clear( QueryRequest *req ) {
|
||||
GList *node;
|
||||
|
||||
g_return_if_fail( req != NULL );
|
||||
g_free( req->searchTerm );
|
||||
req->queryID = 0;
|
||||
req->searchType = ADDRSEARCH_NONE;
|
||||
req->searchTerm = NULL;
|
||||
req->callBackEnd = NULL;
|
||||
req->callBackEntry = NULL;
|
||||
|
||||
/* Empty the list */
|
||||
node = req->queryList;
|
||||
while( node ) {
|
||||
node->data = NULL;
|
||||
node = g_list_next( node );
|
||||
}
|
||||
g_list_free( req->queryList );
|
||||
req->queryList = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free query.
|
||||
* \param qry Address query object.
|
||||
* \param req Request query object.
|
||||
*/
|
||||
void addrqry_free( AddrQuery *qry ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
addrqry_clear( qry );
|
||||
g_free( qry );
|
||||
void qryreq_free( QueryRequest *req ) {
|
||||
g_return_if_fail( req != NULL );
|
||||
qryreq_clear( req );
|
||||
g_free( req );
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify query type.
|
||||
* \param qry Address query object.
|
||||
* Specify search type.
|
||||
* \param req Request query object.
|
||||
* \param value Type.
|
||||
*/
|
||||
void addrqry_set_query_type( AddrQuery *qry, const AddrQueryType value ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
qry->queryType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify idle ID.
|
||||
* \param qry Address query object.
|
||||
* \param value Idle ID.
|
||||
*/
|
||||
void addrqry_set_idle_id( AddrQuery *qry, const guint value ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
qry->idleID = value;
|
||||
void qryreq_set_search_type( QueryRequest *req, const AddrSearchType value ) {
|
||||
g_return_if_fail( req != NULL );
|
||||
req->searchType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify search term to be used.
|
||||
* \param qry Address query object.
|
||||
* \param req Request query object.
|
||||
* \param value Search term.
|
||||
*/
|
||||
void addrqry_set_search_term( AddrQuery* qry, const gchar *value ) {
|
||||
qry->searchTerm = mgu_replace_string( qry->searchTerm, value );
|
||||
g_return_if_fail( qry != NULL );
|
||||
g_strstrip( qry->searchTerm );
|
||||
void qryreq_set_search_term( QueryRequest *req, const gchar *value ) {
|
||||
req->searchTerm = mgu_replace_string( req->searchTerm, value );
|
||||
g_return_if_fail( req != NULL );
|
||||
g_strstrip( req->searchTerm );
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify server object to be used.
|
||||
* \param qry Address query object.
|
||||
* \param value Server object that performs the search.
|
||||
* Add address query object to request.
|
||||
* \param req Request query object.
|
||||
* \param aqo Address query object that performs the search.
|
||||
*/
|
||||
void addrqry_set_server( AddrQuery* qry, const gpointer value ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
qry->serverObject = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify query object to be used.
|
||||
* \param qry Address query object.
|
||||
* \param value Query object that performs the search.
|
||||
*/
|
||||
void addrqry_set_query( AddrQuery* qry, const gpointer value ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
qry->queryObject = value;
|
||||
void qryreq_add_query( QueryRequest *req, AddrQueryObject *aqo ) {
|
||||
g_return_if_fail( req != NULL );
|
||||
g_return_if_fail( aqo != NULL );
|
||||
req->queryList = g_list_append( req->queryList, aqo );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display object to specified stream.
|
||||
* \param qry Address query object.
|
||||
* \param req Request query object.
|
||||
* \param stream Output stream.
|
||||
*/
|
||||
void addrqry_print( const AddrQuery *qry, FILE *stream ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
void qryreq_print( const QueryRequest *req, FILE *stream ) {
|
||||
GList *node;
|
||||
g_return_if_fail( req != NULL );
|
||||
|
||||
fprintf( stream, "AddressQuery:\n" );
|
||||
fprintf( stream, " queryID: %d\n", qry->queryID );
|
||||
fprintf( stream, " idleID: %d\n", qry->idleID );
|
||||
fprintf( stream, " searchTerm: '%s'\n", qry->searchTerm );
|
||||
fprintf( stream, "QueryRequest:\n" );
|
||||
fprintf( stream, " queryID: %d\n", req->queryID );
|
||||
fprintf( stream, " searchType: %d\n", req->searchType );
|
||||
fprintf( stream, " searchTerm: '%s'\n", req->searchTerm );
|
||||
node = req->queryList;
|
||||
while( node ) {
|
||||
AddrQueryObject *aqo = node->data;
|
||||
fprintf( stream, " --- type: %d\n", aqo->queryType );
|
||||
node = g_list_next( node );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add query to list.
|
||||
* \param queryID ID of query being executed.
|
||||
* \param searchTerm Search term. A private copy will be made.
|
||||
* \param callBack Callback function.
|
||||
* \param target Target object to receive data.
|
||||
*
|
||||
* \param searchTerm Search term. A private copy will be made.
|
||||
* \param callBackEnd Callback function that will be called when query
|
||||
* terminates.
|
||||
* \param callBackEntry Callback function that will be called after each
|
||||
* address entry has been read.
|
||||
* \return Initialize query request object.
|
||||
*/
|
||||
AddrQuery *qrymgr_add_query(
|
||||
const gint queryID, const gchar *searchTerm, void *callBack,
|
||||
gpointer target )
|
||||
QueryRequest *qrymgr_add_request(
|
||||
const gchar *searchTerm, void *callBackEnd, void *callBackEntry )
|
||||
{
|
||||
AddrQuery *qry;
|
||||
QueryRequest *req;
|
||||
|
||||
qry = g_new0( AddrQuery, 1 );
|
||||
qry->queryType = ADDRQUERY_NONE;
|
||||
qry->queryID = queryID;
|
||||
qry->idleID = 0;
|
||||
qry->searchTerm = g_strdup( searchTerm );
|
||||
qry->callBack = callBack;
|
||||
qry->target = NULL;
|
||||
qry->timeStart = time( NULL );
|
||||
qry->serverObject = NULL;
|
||||
qry->queryObject = NULL;
|
||||
req = g_new0( QueryRequest, 1 );
|
||||
req->searchTerm = g_strdup( searchTerm );
|
||||
req->callBackEnd = callBackEnd;
|
||||
req->callBackEntry = callBackEntry;
|
||||
req->timeStart = time( NULL );
|
||||
req->queryList = NULL;
|
||||
|
||||
/* Insert in head of list */
|
||||
pthread_mutex_lock( & _queryListMutex_ );
|
||||
_queryList_ = g_list_prepend( _queryList_, qry );
|
||||
pthread_mutex_unlock( & _queryListMutex_ );
|
||||
pthread_mutex_lock( & _requestListMutex_ );
|
||||
req->queryID = ++_currentQueryID_;
|
||||
_requestList_ = g_list_prepend( _requestList_, req );
|
||||
pthread_mutex_unlock( & _requestListMutex_ );
|
||||
|
||||
return qry;
|
||||
return req;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,45 +185,45 @@ AddrQuery *qrymgr_add_query(
|
|||
* \param queryID ID of query to find.
|
||||
* \return Query object, or <i>NULL</i> if not found.
|
||||
*/
|
||||
AddrQuery *qrymgr_find_query( const gint queryID ) {
|
||||
AddrQuery *qry;
|
||||
AddrQuery *q;
|
||||
QueryRequest *qrymgr_find_request( const gint queryID ) {
|
||||
QueryRequest *req;
|
||||
QueryRequest *q;
|
||||
GList *node;
|
||||
|
||||
pthread_mutex_lock( & _queryListMutex_ );
|
||||
qry = NULL;
|
||||
node = _queryList_;
|
||||
pthread_mutex_lock( & _requestListMutex_ );
|
||||
req = NULL;
|
||||
node = _requestList_;
|
||||
while( node ) {
|
||||
q = node->data;
|
||||
if( q->queryID == queryID ) {
|
||||
qry = q;
|
||||
req = q;
|
||||
break;
|
||||
}
|
||||
node = g_list_next( node );
|
||||
}
|
||||
pthread_mutex_unlock( & _queryListMutex_ );
|
||||
pthread_mutex_unlock( & _requestListMutex_ );
|
||||
|
||||
return qry;
|
||||
return req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete specified query.
|
||||
* \param queryID ID of query to retire.
|
||||
*/
|
||||
void qrymgr_delete_query( const gint queryID ) {
|
||||
AddrQuery *qry;
|
||||
void qrymgr_delete_request( const gint queryID ) {
|
||||
QueryRequest *req;
|
||||
GList *node, *nf;
|
||||
|
||||
pthread_mutex_lock( & _queryListMutex_ );
|
||||
pthread_mutex_lock( & _requestListMutex_ );
|
||||
|
||||
/* Find node */
|
||||
nf = NULL;
|
||||
node = _queryList_;
|
||||
node = _requestList_;
|
||||
while( node ) {
|
||||
qry = node->data;
|
||||
if( qry->queryID == queryID ) {
|
||||
req = node->data;
|
||||
if( req->queryID == queryID ) {
|
||||
nf = node;
|
||||
addrqry_free( qry );
|
||||
qryreq_free( req );
|
||||
break;
|
||||
}
|
||||
node = g_list_next( node );
|
||||
|
@ -233,45 +231,45 @@ void qrymgr_delete_query( const gint queryID ) {
|
|||
|
||||
/* Free link element and associated query */
|
||||
if( nf ) {
|
||||
_queryList_ = g_list_remove_link( _queryList_, nf );
|
||||
_requestList_ = g_list_remove_link( _requestList_, nf );
|
||||
g_list_free_1( nf );
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( & _queryListMutex_ );
|
||||
pthread_mutex_unlock( & _requestListMutex_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize query manager.
|
||||
*/
|
||||
void qrymgr_initialize( void ) {
|
||||
_queryList_ = NULL;
|
||||
_requestList_ = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all queries.
|
||||
*/
|
||||
static void qrymgr_free_all_query( void ) {
|
||||
AddrQuery *qry;
|
||||
static void qrymgr_free_all_request( void ) {
|
||||
QueryRequest *req;
|
||||
GList *node;
|
||||
|
||||
pthread_mutex_lock( & _queryListMutex_ );
|
||||
node = _queryList_;
|
||||
pthread_mutex_lock( & _requestListMutex_ );
|
||||
node = _requestList_;
|
||||
while( node ) {
|
||||
qry = node->data;
|
||||
addrqry_free( qry );
|
||||
req = node->data;
|
||||
qryreq_free( req );
|
||||
node->data = NULL;
|
||||
node = g_list_next( node );
|
||||
}
|
||||
g_list_free( _queryList_ );
|
||||
_queryList_ = NULL;
|
||||
pthread_mutex_unlock( & _queryListMutex_ );
|
||||
g_list_free( _requestList_ );
|
||||
_requestList_ = NULL;
|
||||
pthread_mutex_unlock( & _requestListMutex_ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Teardown query manager.
|
||||
*/
|
||||
void qrymgr_teardown( void ) {
|
||||
qrymgr_free_all_query();
|
||||
qrymgr_free_all_request();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,19 +277,19 @@ void qrymgr_teardown( void ) {
|
|||
* \param stream Output stream.
|
||||
*/
|
||||
void qrymgr_print( FILE *stream ) {
|
||||
AddrQuery *qry;
|
||||
QueryRequest *req;
|
||||
GList *node;
|
||||
|
||||
pthread_mutex_lock( & _queryListMutex_ );
|
||||
pthread_mutex_lock( & _requestListMutex_ );
|
||||
fprintf( stream, "=== Query Manager ===\n" );
|
||||
node = _queryList_;
|
||||
node = _requestList_;
|
||||
while( node ) {
|
||||
qry = node->data;
|
||||
addrqry_print( qry, stream );
|
||||
req = node->data;
|
||||
qryreq_print( req, stream );
|
||||
fprintf( stream, "---\n" );
|
||||
node = g_list_next( node );
|
||||
}
|
||||
pthread_mutex_unlock( & _queryListMutex_ );
|
||||
pthread_mutex_unlock( & _requestListMutex_ );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -27,53 +27,82 @@
|
|||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include "addritem.h"
|
||||
|
||||
/* Query types */
|
||||
#define ADDRQUERY_NONE 0
|
||||
#define ADDRQUERY_LDAP 1
|
||||
|
||||
/* Search type */
|
||||
typedef enum {
|
||||
ADDRQUERY_NONE,
|
||||
ADDRQUERY_LDAP
|
||||
} AddrQueryType;
|
||||
|
||||
/* Address search call back function */
|
||||
typedef gint ( AddrSearchCallbackFunc ) ( gint cacheID,
|
||||
GList *listEMail,
|
||||
gpointer target );
|
||||
|
||||
typedef void ( AddrSearchStaticFunc ) ( gint qid, AddrQueryType qty, gint status );
|
||||
ADDRSEARCH_NONE,
|
||||
ADDRSEARCH_DYNAMIC,
|
||||
ADDRSEARCH_EXPLICIT,
|
||||
ADDRSEARCH_LOCATE
|
||||
} AddrSearchType;
|
||||
|
||||
/* Data structures */
|
||||
typedef struct {
|
||||
AddrQueryType queryType;
|
||||
gint queryID;
|
||||
gint idleID;
|
||||
gchar *searchTerm;
|
||||
time_t timeStart;
|
||||
AddrSearchStaticFunc *callBack;
|
||||
gpointer target;
|
||||
gpointer serverObject;
|
||||
gpointer queryObject;
|
||||
gint queryID;
|
||||
AddrSearchType searchType;
|
||||
gchar *searchTerm;
|
||||
time_t timeStart;
|
||||
void ( *callBackEnd ) ( void * );
|
||||
void ( *callBackEntry ) ( void * );
|
||||
GList *queryList;
|
||||
}
|
||||
AddrQuery;
|
||||
QueryRequest;
|
||||
|
||||
/* Some macros */
|
||||
#define ADDRQUERY_OBJECT(obj) ((AddrQueryObject *)obj)
|
||||
#define ADDRQUERY_TYPE(obj) (ADDRQUERY_OBJECT(obj)->queryType)
|
||||
#define ADDRQUERY_ID(obj) (ADDRQUERY_OBJECT(obj)->queryID)
|
||||
#define ADDRQUERY_SEARCHTYPE(obj) (ADDRQUERY_OBJECT(obj)->searchType)
|
||||
#define ADDRQUERY_NAME(obj) (ADDRQUERY_OBJECT(obj)->queryName)
|
||||
#define ADDRQUERY_RETVAL(obj) (ADDRQUERY_OBJECT(obj)->retVal)
|
||||
#define ADDRQUERY_FOLDER(obj) (ADDRQUERY_OBJECT(obj)->folder)
|
||||
#define ADDRQUERY_SEARCHVALUE(obj) (ADDRQUERY_OBJECT(obj)->searchValue)
|
||||
|
||||
/* Generic address query (base class) */
|
||||
typedef struct _AddrQueryObject AddrQueryObject;
|
||||
struct _AddrQueryObject {
|
||||
gint queryType;
|
||||
gint queryID;
|
||||
AddrSearchType searchType;
|
||||
gchar *queryName;
|
||||
gint retVal;
|
||||
ItemFolder *folder; /* Reference to folder in cache */
|
||||
gchar *searchValue;
|
||||
};
|
||||
|
||||
/* Address search call back functions */
|
||||
typedef gint ( AddrSearchCallbackEntry ) ( gpointer sender,
|
||||
gint queryID,
|
||||
GList *listEMail,
|
||||
gpointer data );
|
||||
|
||||
typedef void ( AddrSearchCallbackEnd ) ( gpointer sender,
|
||||
gint queryID,
|
||||
gint status,
|
||||
gpointer data );
|
||||
|
||||
/* Function prototypes */
|
||||
AddrQuery *addrqry_create ( void );
|
||||
void addrqry_clear ( AddrQuery *qry );
|
||||
void addrqry_free ( AddrQuery *qry );
|
||||
void addrqry_set_query_type ( AddrQuery *qry, const AddrQueryType value );
|
||||
void addrqry_set_idle_id ( AddrQuery *qry, const guint value );
|
||||
void addrqry_set_search_term ( AddrQuery* qry, const gchar *value );
|
||||
void addrqry_set_server ( AddrQuery* qry, const gpointer server );
|
||||
void addrqry_set_query ( AddrQuery* qry, const gpointer query );
|
||||
void addrqry_print ( const AddrQuery *qry, FILE *stream );
|
||||
QueryRequest *qryreq_create ( void );
|
||||
void qryreq_clear ( QueryRequest *req );
|
||||
void qryreq_free ( QueryRequest *req );
|
||||
void qryreq_set_search_type ( QueryRequest *req, const AddrSearchType value );
|
||||
void qryreq_set_search_term ( QueryRequest *req, const gchar *value );
|
||||
void qryreq_add_query ( QueryRequest *req, AddrQueryObject *aqo );
|
||||
void qryreq_print ( const QueryRequest *req, FILE *stream );
|
||||
|
||||
void qrymgr_initialize ( void );
|
||||
void qrymgr_teardown ( void );
|
||||
AddrQuery *qrymgr_add_query(
|
||||
const gint queryID, const gchar *searchTerm,
|
||||
void *callBack, gpointer target );
|
||||
QueryRequest *qrymgr_add_request( const gchar *searchTerm,
|
||||
void *callBackEnd,
|
||||
void *callBackEntry );
|
||||
|
||||
AddrQuery *qrymgr_find_query ( const gint queryID );
|
||||
void qrymgr_delete_query ( const gint queryID );
|
||||
QueryRequest *qrymgr_find_request( const gint queryID );
|
||||
void qrymgr_delete_request ( const gint queryID );
|
||||
void qrymgr_print ( FILE *stream );
|
||||
|
||||
#endif /* __ADDRQUERY_H__ */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
|
@ -31,7 +32,6 @@
|
|||
#include "utils.h"
|
||||
#include "gtkutils.h"
|
||||
#include "inc.h"
|
||||
#include "log.h"
|
||||
#include "logwindow.h"
|
||||
#include "prefs_common.h"
|
||||
|
||||
|
|
|
@ -803,7 +803,9 @@ CodeConvFunc conv_get_code_conv_func(const gchar *src_charset_str,
|
|||
case C_ISO_8859_13:
|
||||
case C_ISO_8859_14:
|
||||
case C_ISO_8859_15:
|
||||
if (dest_charset == C_AUTO)
|
||||
if (dest_charset == C_AUTO &&
|
||||
(conv_get_current_charset() == src_charset ||
|
||||
MB_CUR_MAX > 1))
|
||||
code_conv = conv_latintodisp;
|
||||
break;
|
||||
case C_SHIFT_JIS:
|
||||
|
|
|
@ -201,7 +201,7 @@ void plugin_unload_all(const gchar *type)
|
|||
}
|
||||
g_slist_free(list);
|
||||
|
||||
cur = g_slist_find_custom(plugin_types, type, list_find_by_string);
|
||||
cur = g_slist_find_custom(plugin_types, (gpointer) type, list_find_by_string);
|
||||
if (cur) {
|
||||
g_free(cur->data);
|
||||
g_slist_remove(plugin_types, cur);
|
||||
|
|
|
@ -37,7 +37,6 @@ static SSL_CTX *ssl_ctx;
|
|||
void ssl_init(void)
|
||||
{
|
||||
SSL_METHOD *meth;
|
||||
FILE *cert_test;
|
||||
|
||||
/* Global system initialization*/
|
||||
SSL_library_init();
|
||||
|
|
|
@ -68,26 +68,29 @@ StringTable *string_table_new(void)
|
|||
return strtable;
|
||||
}
|
||||
|
||||
gchar *string_table_lookup_string(StringTable *table, gchar *str)
|
||||
gchar *string_table_lookup_string(StringTable *table, const gchar *str)
|
||||
{
|
||||
StringEntry *entry = g_hash_table_lookup(table->hash_table,
|
||||
(gconstpointer)str);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
} else {
|
||||
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, gchar *str)
|
||||
gchar *string_table_insert_string(StringTable *table, const gchar *str)
|
||||
{
|
||||
gchar *key = NULL;
|
||||
StringEntry *entry = NULL;
|
||||
StringEntry *entry;
|
||||
|
||||
if (g_hash_table_lookup_extended
|
||||
(table->hash_table, str, (gpointer *)&key, (gpointer *)&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);
|
||||
XXX_DEBUG ("ref++ for %s (%d)\n", entry->string,
|
||||
entry->ref_count);
|
||||
} else {
|
||||
entry = string_entry_new(str);
|
||||
XXX_DEBUG ("inserting %s\n", str);
|
||||
|
@ -99,7 +102,7 @@ gchar *string_table_insert_string(StringTable *table, gchar *str)
|
|||
return entry->string;
|
||||
}
|
||||
|
||||
void string_table_free_string(StringTable *table, gchar *str)
|
||||
void string_table_free_string(StringTable *table, const gchar *str)
|
||||
{
|
||||
StringEntry *entry;
|
||||
|
||||
|
@ -108,11 +111,13 @@ void string_table_free_string(StringTable *table, gchar *str)
|
|||
if (entry) {
|
||||
entry->ref_count--;
|
||||
if (entry->ref_count <= 0) {
|
||||
XXX_DEBUG ("refcount of string %s dropped to zero\n", entry->string);
|
||||
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);
|
||||
XXX_DEBUG ("ref-- for %s (%d)\n", entry->string,
|
||||
entry->ref_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ typedef struct {
|
|||
StringTable *string_table_new (void);
|
||||
void string_table_free (StringTable *table);
|
||||
|
||||
gchar *string_table_lookup_string (StringTable *table, gchar *str);
|
||||
gchar *string_table_insert_string (StringTable *table, gchar *str);
|
||||
void string_table_free_string (StringTable *table, gchar *str);
|
||||
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);
|
||||
|
||||
|
|
|
@ -1040,6 +1040,12 @@ void subst_for_filename(gchar *str)
|
|||
subst_chars(str, " \t\r\n\"/\\", '_');
|
||||
}
|
||||
|
||||
void subst_for_shellsafe_filename(gchar *str)
|
||||
{
|
||||
subst_for_filename(str);
|
||||
subst_chars(str, "|&;()<>'!{}[]",'_');
|
||||
}
|
||||
|
||||
gboolean is_header_line(const gchar *str)
|
||||
{
|
||||
if (str[0] == ':') return FALSE;
|
||||
|
@ -1787,6 +1793,34 @@ gboolean is_file_entry_exist(const gchar *file)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean dirent_is_regular_file(struct dirent *d)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
#ifdef HAVE_DIRENT_D_TYPE
|
||||
if (d->d_type == DT_REG)
|
||||
return TRUE;
|
||||
else if (d->d_type != DT_UNKNOWN)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
return (stat(d->d_name, &s) == 0 && S_ISREG(s.st_mode));
|
||||
}
|
||||
|
||||
gboolean dirent_is_directory(struct dirent *d)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
#ifdef HAVE_DIRENT_D_TYPE
|
||||
if (d->d_type == DT_DIR)
|
||||
return TRUE;
|
||||
else if (d->d_type != DT_UNKNOWN)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
return (stat(d->d_name, &s) == 0 && S_ISDIR(s.st_mode));
|
||||
}
|
||||
|
||||
gint change_dir(const gchar *dir)
|
||||
{
|
||||
gchar *prevdir = NULL;
|
||||
|
@ -2096,14 +2130,9 @@ gint remove_dir_recursive(const gchar *dir)
|
|||
!strcmp(d->d_name, ".."))
|
||||
continue;
|
||||
|
||||
if (stat(d->d_name, &s) < 0) {
|
||||
FILE_OP_ERROR(d->d_name, "stat");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* g_print("removing %s\n", d->d_name); */
|
||||
|
||||
if (S_ISDIR(s.st_mode)) {
|
||||
if (dirent_is_directory(d)) {
|
||||
if (remove_dir_recursive(d->d_name) < 0) {
|
||||
g_warning("can't remove directory\n");
|
||||
return -1;
|
||||
|
@ -2707,6 +2736,55 @@ gchar *get_outgoing_rfc2822_str(FILE *fp)
|
|||
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;
|
||||
gint pid;
|
||||
|
||||
pid = getpid();
|
||||
|
||||
/* We make the boundary depend on the pid, so that all running
|
||||
* processes generate different values even when they have been
|
||||
* started within the same second and srandom(time(NULL)) has been
|
||||
* used. I can't see whether this is really an advantage but it
|
||||
* doesn't do any harm.
|
||||
*/
|
||||
for (i = 0; i < sizeof(buf_uniq) - 1; i++)
|
||||
buf_uniq[i] = tbl[(random() ^ pid) % (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
|
||||
|
@ -2756,6 +2834,16 @@ FILE *my_tmpfile(void)
|
|||
return tmpfile();
|
||||
}
|
||||
|
||||
FILE *get_tmpfile_in_dir(const gchar *dir, gchar **filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
*filename = g_strdup_printf("%s%csylpheed.XXXXXX", dir, G_DIR_SEPARATOR);
|
||||
fd = mkstemp(*filename);
|
||||
|
||||
return fdopen(fd, "w+");
|
||||
}
|
||||
|
||||
FILE *str_open_as_stream(const gchar *str)
|
||||
{
|
||||
FILE *fp;
|
||||
|
@ -3364,16 +3452,6 @@ int subject_get_prefix_length(const gchar *subject)
|
|||
return 0;
|
||||
}
|
||||
|
||||
FILE *get_tmpfile_in_dir(const gchar *dir, gchar **filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
*filename = g_strdup_printf("%s%csylpheed.XXXXXX", dir, G_DIR_SEPARATOR);
|
||||
fd = mkstemp(*filename);
|
||||
|
||||
return fdopen(fd, "w+");
|
||||
}
|
||||
|
||||
/* allow Mutt-like patterns in quick search */
|
||||
gchar *expand_search_string(const gchar *search_string)
|
||||
{
|
||||
|
@ -3425,6 +3503,7 @@ gchar *expand_search_string(const gchar *search_string)
|
|||
{ "T", "marked", 0, FALSE, FALSE },
|
||||
{ "U", "unread", 0, FALSE, FALSE },
|
||||
{ "x", "header \"References\"", 1, TRUE, TRUE },
|
||||
{ "X", "test", 1, FALSE, FALSE },
|
||||
{ "y", "header \"X-Label\"", 1, TRUE, TRUE },
|
||||
{ "&", "&", 0, FALSE, FALSE },
|
||||
{ "|", "|", 0, FALSE, FALSE },
|
||||
|
@ -3615,64 +3694,60 @@ gchar *generate_msgid(const gchar *address, gchar *buf, gint len)
|
|||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 / "'" / "(" / ")" /
|
||||
* "+" / "_" / "," / "-" / "." /
|
||||
* "/" / ":" / "=" / "?"
|
||||
*
|
||||
* ":" and "," removed because of buggy MTAs
|
||||
*/
|
||||
|
||||
gchar *generate_mime_boundary(void)
|
||||
/*
|
||||
quote_cmd_argument()
|
||||
|
||||
return a quoted string safely usable in argument of a command.
|
||||
|
||||
code is extracted and adapted from etPan! project -- DINH V. Hoà.
|
||||
*/
|
||||
|
||||
gint quote_cmd_argument(gchar * result, guint size,
|
||||
const gchar * path)
|
||||
{
|
||||
static gchar tbl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"1234567890'()+_./=?";
|
||||
gchar bufuniq[17];
|
||||
gchar bufdate[BUFFSIZE];
|
||||
int i, equal;
|
||||
int pid;
|
||||
const gchar * p;
|
||||
gchar * result_p;
|
||||
guint remaining;
|
||||
|
||||
pid = getpid();
|
||||
result_p = result;
|
||||
remaining = size;
|
||||
|
||||
/* We make the boundary depend on the pid, so that all running
|
||||
* processed generate different values even when they have been
|
||||
* started within the same second and srand48(time(NULL)) has been
|
||||
* used. I can't see whether this is really an advantage but it
|
||||
* doesn't do any harm.
|
||||
*/
|
||||
equal = -1;
|
||||
for (i = 0; i < sizeof(bufuniq) - 1; i++) {
|
||||
bufuniq[i] = tbl[(lrand48() ^ pid) % (sizeof(tbl) - 1)]; /* fill with random */
|
||||
if (bufuniq[i] == '=' && equal == -1)
|
||||
equal = i;
|
||||
for(p = path ; * p != '\0' ; p ++) {
|
||||
|
||||
if (isalnum(* p) || (* p == '/')) {
|
||||
if (remaining > 0) {
|
||||
* result_p = * p;
|
||||
result_p ++;
|
||||
remaining --;
|
||||
}
|
||||
else {
|
||||
result[size - 1] = '\0';
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (remaining >= 2) {
|
||||
* result_p = '\\';
|
||||
result_p ++;
|
||||
* result_p = * p;
|
||||
result_p ++;
|
||||
remaining -= 2;
|
||||
}
|
||||
else {
|
||||
result[size - 1] = '\0';
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (remaining > 0) {
|
||||
* result_p = '\0';
|
||||
}
|
||||
bufuniq[i] = 0;
|
||||
|
||||
/* now make sure that we do have the sequence "=." in it which cannot
|
||||
* be matched by quoted-printable or base64 encoding */
|
||||
if (equal != -1 && (equal + 1) < i)
|
||||
bufuniq[equal + 1] = '.';
|
||||
else {
|
||||
bufuniq[0] = '=';
|
||||
bufuniq[1] = '.';
|
||||
result[size - 1] = '\0';
|
||||
return -1;
|
||||
}
|
||||
|
||||
get_rfc822_date(bufdate, sizeof(bufdate));
|
||||
subst_char(bufdate, ' ', '_');
|
||||
subst_char(bufdate, ',', '_');
|
||||
subst_char(bufdate, ':', '_');
|
||||
|
||||
return g_strdup_printf("Multipart_%s_%s",
|
||||
bufdate, bufuniq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <time.h>
|
||||
#if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
|
@ -279,6 +280,7 @@ void subst_chars (gchar *str,
|
|||
gchar *orig,
|
||||
gchar subst);
|
||||
void subst_for_filename (gchar *str);
|
||||
void subst_for_shellsafe_filename (gchar *str);
|
||||
gboolean is_header_line (const gchar *str);
|
||||
gboolean is_ascii_str (const guchar *str);
|
||||
gint get_quote_level (const gchar *str,
|
||||
|
@ -334,6 +336,8 @@ 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)
|
||||
|
@ -380,6 +384,8 @@ gchar *get_outgoing_rfc2822_str (FILE *fp);
|
|||
gint change_file_mode_rw (FILE *fp,
|
||||
const gchar *file);
|
||||
FILE *my_tmpfile (void);
|
||||
FILE *get_tmpfile_in_dir (const gchar *dir,
|
||||
gchar **filename);
|
||||
FILE *str_open_as_stream (const gchar *str);
|
||||
gint str_write_to_file (const gchar *str,
|
||||
const gchar *file);
|
||||
|
@ -427,6 +433,9 @@ gint g_stricase_equal (gconstpointer gptr1, gconstpointer gptr2);
|
|||
gint g_int_compare (gconstpointer a, gconstpointer b);
|
||||
|
||||
gchar *generate_msgid (const gchar *address, gchar *buf, gint len);
|
||||
gchar *generate_mime_boundary (void);
|
||||
gchar *generate_mime_boundary (const gchar *prefix);
|
||||
|
||||
gint quote_cmd_argument(gchar * result, guint size,
|
||||
const gchar * path);
|
||||
|
||||
#endif /* __UTILS_H__ */
|
||||
|
|
|
@ -58,7 +58,6 @@ static void xml_string_table_create(void)
|
|||
|
||||
#endif /* SPARSE_MEMORY */
|
||||
|
||||
static void xml_free_tag (XMLTag *tag);
|
||||
static gint xml_get_parenthesis (XMLFile *file,
|
||||
gchar *buf,
|
||||
gint len);
|
||||
|
@ -558,7 +557,7 @@ void xml_free_tree(GNode *node)
|
|||
g_node_destroy(node);
|
||||
}
|
||||
|
||||
static void xml_free_tag(XMLTag *tag)
|
||||
void xml_free_tag(XMLTag *tag)
|
||||
{
|
||||
if (!tag) return;
|
||||
|
||||
|
@ -596,3 +595,14 @@ static gint xml_get_parenthesis(XMLFile *file, gchar *buf, gint len)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xml_tag_add_attr(XMLTag *tag, const gchar *name, gchar *value)
|
||||
{
|
||||
XMLAttr *attr;
|
||||
|
||||
attr = g_new0(XMLAttr, 1);
|
||||
attr->name = XML_STRING_ADD(name);
|
||||
attr->value = value;
|
||||
|
||||
tag->attr = g_list_append(tag->attr, attr);
|
||||
}
|
||||
|
|
|
@ -91,4 +91,9 @@ gint xml_file_put_escape_str (FILE *fp,
|
|||
void xml_free_node (XMLNode *node);
|
||||
void xml_free_tree (GNode *node);
|
||||
|
||||
void xml_free_tag (XMLTag *tag);
|
||||
void xml_tag_add_attr (XMLTag *tag,
|
||||
const gchar *name,
|
||||
gchar *value);
|
||||
|
||||
#endif /* __XML_H__ */
|
||||
|
|
301
src/compose.c
301
src/compose.c
|
@ -64,6 +64,7 @@
|
|||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#if (HAVE_WCTYPE_H && HAVE_WCHAR_H)
|
||||
# include <wchar.h>
|
||||
|
@ -150,6 +151,14 @@ typedef enum
|
|||
PRIORITY_LOWEST
|
||||
} PriorityLevel;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMPOSE_INSERT_SUCCESS,
|
||||
COMPOSE_INSERT_READ_ERROR,
|
||||
COMPOSE_INSERT_INVALID_CHARACTER,
|
||||
COMPOSE_INSERT_NO_FILE
|
||||
} ComposeInsertResult;
|
||||
|
||||
#define B64_LINE_SIZE 57
|
||||
#define B64_BUFFSIZE 77
|
||||
|
||||
|
@ -200,7 +209,7 @@ static void compose_reedit_set_entry (Compose *compose,
|
|||
static void compose_insert_sig (Compose *compose,
|
||||
gboolean replace);
|
||||
static gchar *compose_get_signature_str (Compose *compose);
|
||||
static void compose_insert_file (Compose *compose,
|
||||
static ComposeInsertResult compose_insert_file (Compose *compose,
|
||||
const gchar *file);
|
||||
static void compose_attach_append (Compose *compose,
|
||||
const gchar *file,
|
||||
|
@ -250,8 +259,7 @@ static void compose_convert_header (gchar *dest,
|
|||
gchar *src,
|
||||
gint header_len,
|
||||
gboolean addr_field);
|
||||
static void compose_generate_msgid (Compose *compose,
|
||||
gchar *buf,
|
||||
static void compose_generate_msgid (gchar *buf,
|
||||
gint len);
|
||||
|
||||
static void compose_attach_info_free (AttachInfo *ainfo);
|
||||
|
@ -868,7 +876,7 @@ void compose_reply_mode(ComposeMode mode, GSList *msginfo_list, gchar *body)
|
|||
case COMPOSE_FORWARD_INLINE:
|
||||
/* check if we reply to more than one Message */
|
||||
if (list_len == 1) {
|
||||
compose_forward(NULL, msginfo, FALSE, body);
|
||||
compose_forward(NULL, msginfo, FALSE, body, FALSE);
|
||||
break;
|
||||
}
|
||||
/* more messages FALL THROUGH */
|
||||
|
@ -1007,7 +1015,8 @@ if (msginfo->var && *msginfo->var) { \
|
|||
}
|
||||
|
||||
Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
|
||||
gboolean as_attach, const gchar *body)
|
||||
gboolean as_attach, const gchar *body,
|
||||
gboolean no_extedit)
|
||||
{
|
||||
Compose *compose;
|
||||
GtkTextView *textview;
|
||||
|
@ -1030,7 +1039,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
|
|||
|
||||
if (!account && prefs_common.forward_account_autosel) {
|
||||
gchar cc[BUFFSIZE];
|
||||
if (!get_header_from_msginfo(msginfo,cc,sizeof(cc),"CC:")){ /* Found a CC header */
|
||||
if (!procheader_get_header_from_msginfo(msginfo,cc,sizeof(cc),"CC:")){ /* Found a CC header */
|
||||
extract_address(cc);
|
||||
account = account_find_from_address(cc);
|
||||
}
|
||||
|
@ -1118,7 +1127,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
|
|||
#endif
|
||||
gtk_widget_grab_focus(compose->header_last->entry);
|
||||
|
||||
if (prefs_common.auto_exteditor)
|
||||
if (!no_extedit && prefs_common.auto_exteditor)
|
||||
compose_exec_ext_editor(compose);
|
||||
|
||||
/*save folder*/
|
||||
|
@ -1221,22 +1230,22 @@ void compose_reedit(MsgInfo *msginfo)
|
|||
gint id;
|
||||
|
||||
/* Select Account from queue headers */
|
||||
if (!get_header_from_msginfo(msginfo, queueheader_buf,
|
||||
if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf,
|
||||
sizeof(queueheader_buf), "X-Sylpheed-Account-Id:")) {
|
||||
id = atoi(&queueheader_buf[22]);
|
||||
account = account_find_from_id(id);
|
||||
}
|
||||
if (!account && !get_header_from_msginfo(msginfo, queueheader_buf,
|
||||
if (!account && !procheader_get_header_from_msginfo(msginfo, queueheader_buf,
|
||||
sizeof(queueheader_buf), "NAID:")) {
|
||||
id = atoi(&queueheader_buf[5]);
|
||||
account = account_find_from_id(id);
|
||||
}
|
||||
if (!account && !get_header_from_msginfo(msginfo, queueheader_buf,
|
||||
if (!account && !procheader_get_header_from_msginfo(msginfo, queueheader_buf,
|
||||
sizeof(queueheader_buf), "MAID:")) {
|
||||
id = atoi(&queueheader_buf[5]);
|
||||
account = account_find_from_id(id);
|
||||
}
|
||||
if (!account && !get_header_from_msginfo(msginfo, queueheader_buf,
|
||||
if (!account && !procheader_get_header_from_msginfo(msginfo, queueheader_buf,
|
||||
sizeof(queueheader_buf), "S:")) {
|
||||
account = account_find_from_address(queueheader_buf);
|
||||
}
|
||||
|
@ -1245,7 +1254,7 @@ void compose_reedit(MsgInfo *msginfo)
|
|||
|
||||
if (!account && prefs_common.reedit_account_autosel) {
|
||||
gchar from[BUFFSIZE];
|
||||
if (!get_header_from_msginfo(msginfo, from, sizeof(from), "FROM:")){
|
||||
if (!procheader_get_header_from_msginfo(msginfo, from, sizeof(from), "FROM:")){
|
||||
extract_address(from);
|
||||
account = account_find_from_address(from);
|
||||
}
|
||||
|
@ -1261,7 +1270,7 @@ void compose_reedit(MsgInfo *msginfo)
|
|||
gchar queueheader_buf[BUFFSIZE];
|
||||
|
||||
/* Set message save folder */
|
||||
if (!get_header_from_msginfo(msginfo, queueheader_buf, sizeof(queueheader_buf), "SCF:")) {
|
||||
if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, sizeof(queueheader_buf), "SCF:")) {
|
||||
gint startpos = 0;
|
||||
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), TRUE);
|
||||
|
@ -1300,6 +1309,7 @@ Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo)
|
|||
Compose *compose;
|
||||
gchar *filename;
|
||||
GtkItemFactory *ifactory;
|
||||
FolderItem *item;
|
||||
|
||||
g_return_val_if_fail(msginfo != NULL, NULL);
|
||||
|
||||
|
@ -1324,6 +1334,17 @@ Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo)
|
|||
|
||||
compose->redirect_filename = filename;
|
||||
|
||||
/* Set save folder */
|
||||
item = msginfo->folder;
|
||||
if (item && item->prefs && item->prefs->save_copy_to_folder) {
|
||||
gchar *folderidentifier;
|
||||
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), prefs_common.savemsg);
|
||||
folderidentifier = folder_item_get_identifier(item);
|
||||
gtk_entry_set_text(GTK_ENTRY(compose->savemsg_entry), folderidentifier);
|
||||
g_free(folderidentifier);
|
||||
}
|
||||
|
||||
compose_attach_parts(compose, msginfo);
|
||||
|
||||
if (msginfo->subject)
|
||||
|
@ -1477,6 +1498,11 @@ void compose_toolbar_cb(gint action, gpointer data)
|
|||
case A_ADDRBOOK:
|
||||
compose_address_cb(compose, 0, NULL);
|
||||
break;
|
||||
#ifdef USE_ASPELL
|
||||
case A_CHECK_SPELLING:
|
||||
compose_check_all(compose);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1850,6 +1876,10 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
|
|||
|
||||
if (replyto && from)
|
||||
cc_list = address_list_append_with_comments(cc_list, from);
|
||||
if (to_all && msginfo->folder &&
|
||||
msginfo->folder->prefs->enable_default_reply_to)
|
||||
cc_list = address_list_append_with_comments(cc_list,
|
||||
msginfo->folder->prefs->default_reply_to);
|
||||
cc_list = address_list_append_with_comments(cc_list, msginfo->to);
|
||||
cc_list = address_list_append_with_comments(cc_list, compose->cc);
|
||||
|
||||
|
@ -2015,7 +2045,7 @@ static gchar *compose_get_signature_str(Compose *compose)
|
|||
return sig_str;
|
||||
}
|
||||
|
||||
static void compose_insert_file(Compose *compose, const gchar *file)
|
||||
static ComposeInsertResult compose_insert_file(Compose *compose, const gchar *file)
|
||||
{
|
||||
GtkTextView *text;
|
||||
GtkTextBuffer *buffer;
|
||||
|
@ -2024,12 +2054,13 @@ static void compose_insert_file(Compose *compose, const gchar *file)
|
|||
gchar buf[BUFFSIZE];
|
||||
gint len;
|
||||
FILE *fp;
|
||||
gboolean badtxt = FALSE;
|
||||
|
||||
g_return_if_fail(file != NULL);
|
||||
g_return_val_if_fail(file != NULL, COMPOSE_INSERT_NO_FILE);
|
||||
|
||||
if ((fp = fopen(file, "rb")) == NULL) {
|
||||
FILE_OP_ERROR(file, "fopen");
|
||||
return;
|
||||
return COMPOSE_INSERT_READ_ERROR;
|
||||
}
|
||||
|
||||
text = GTK_TEXT_VIEW(compose->text);
|
||||
|
@ -2060,6 +2091,11 @@ static void compose_insert_file(Compose *compose, const gchar *file)
|
|||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (badtxt)
|
||||
return COMPOSE_INSERT_INVALID_CHARACTER;
|
||||
else
|
||||
return COMPOSE_INSERT_SUCCESS;
|
||||
}
|
||||
|
||||
static void compose_attach_append(Compose *compose, const gchar *file,
|
||||
|
@ -2157,69 +2193,124 @@ static void compose_attach_append(Compose *compose, const gchar *file,
|
|||
gtk_clist_set_row_data(GTK_CLIST(compose->attach_clist), row, ainfo);
|
||||
}
|
||||
|
||||
#define IS_FIRST_PART_TEXT(info) \
|
||||
((info->mime_type == MIME_TEXT || info->mime_type == MIME_TEXT_HTML || \
|
||||
info->mime_type == MIME_TEXT_ENRICHED) || \
|
||||
(info->mime_type == MIME_MULTIPART && info->content_type && \
|
||||
!strcasecmp(info->content_type, "multipart/alternative") && \
|
||||
(info->children && \
|
||||
(info->children->mime_type == MIME_TEXT || \
|
||||
info->children->mime_type == MIME_TEXT_HTML || \
|
||||
info->children->mime_type == MIME_TEXT_ENRICHED))))
|
||||
#ifdef USE_GPGME
|
||||
static void compose_use_signing(Compose *compose, gboolean use_signing)
|
||||
{
|
||||
GtkItemFactory *ifactory;
|
||||
GtkWidget *menuitem = NULL;
|
||||
|
||||
compose->use_signing = use_signing;
|
||||
ifactory = gtk_item_factory_from_widget(compose->menubar);
|
||||
menuitem = gtk_item_factory_get_item
|
||||
(ifactory, "/Message/Sign");
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
|
||||
use_signing);
|
||||
compose_update_gnupg_mode_menu_item(compose);
|
||||
}
|
||||
#endif /* USE_GPGME */
|
||||
|
||||
#define NEXT_PART_NOT_CHILD(info) \
|
||||
{ \
|
||||
node = info->node; \
|
||||
while (node->children) \
|
||||
node = g_node_last_child(node); \
|
||||
info = procmime_mimeinfo_next((MimeInfo *)node->data); \
|
||||
}
|
||||
|
||||
static void compose_attach_parts(Compose *compose, MsgInfo *msginfo)
|
||||
{
|
||||
MimeInfo *mimeinfo;
|
||||
MimeInfo *child;
|
||||
gchar *infile;
|
||||
MimeInfo *firsttext = NULL;
|
||||
MimeInfo *encrypted = NULL;
|
||||
GNode *node;
|
||||
gchar *outfile;
|
||||
const gchar *partname = NULL;
|
||||
|
||||
mimeinfo = procmime_scan_message(msginfo);
|
||||
if (!mimeinfo) return;
|
||||
|
||||
/* skip first text (presumably message body) */
|
||||
child = mimeinfo->children;
|
||||
if (!child || IS_FIRST_PART_TEXT(mimeinfo)) {
|
||||
if (mimeinfo->node->children == NULL) {
|
||||
procmime_mimeinfo_free_all(mimeinfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_FIRST_PART_TEXT(child))
|
||||
child = child->next;
|
||||
|
||||
infile = procmsg_get_message_file_path(msginfo);
|
||||
/* find first content part */
|
||||
child = (MimeInfo *) mimeinfo->node->children->data;
|
||||
while (child && child->node->children && (child->type == MIMETYPE_MULTIPART))
|
||||
child = (MimeInfo *)child->node->children->data;
|
||||
|
||||
if (child->type == MIMETYPE_TEXT) {
|
||||
firsttext = child;
|
||||
debug_print("First text part found\n");
|
||||
} else if (compose->mode == COMPOSE_REEDIT &&
|
||||
child->type == MIMETYPE_APPLICATION &&
|
||||
!strcasecmp(child->subtype, "pgp-encrypted")) {
|
||||
AlertValue val;
|
||||
val = alertpanel(_("Encrypted message"),
|
||||
_("Cannot re-edit an encrypted message. \n"
|
||||
"Discard encrypted part?"),
|
||||
_("Yes"), _("No"), NULL);
|
||||
if (val == G_ALERTDEFAULT)
|
||||
encrypted = (MimeInfo *)child->node->parent->data;
|
||||
}
|
||||
|
||||
child = (MimeInfo *) mimeinfo->node->children->data;
|
||||
while (child != NULL) {
|
||||
if (child->children || child->mime_type == MIME_MULTIPART) {
|
||||
if (child == encrypted) {
|
||||
/* skip this part of tree */
|
||||
NEXT_PART_NOT_CHILD(child);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child->type == MIMETYPE_MULTIPART) {
|
||||
/* get the actual content */
|
||||
child = procmime_mimeinfo_next(child);
|
||||
continue;
|
||||
}
|
||||
if (child->parent && child->parent->parent
|
||||
&& !strcasecmp(child->parent->parent->content_type, "multipart/signed")
|
||||
&& child->mime_type == MIME_TEXT) {
|
||||
/* this is the main text part of a signed message */
|
||||
|
||||
if (child == firsttext) {
|
||||
child = procmime_mimeinfo_next(child);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((compose->mode == COMPOSE_REEDIT ||
|
||||
compose->mode == COMPOSE_FORWARD_INLINE ||
|
||||
compose->mode == COMPOSE_FORWARD ) &&
|
||||
(child->type == MIMETYPE_APPLICATION) &&
|
||||
!strcmp(child->subtype, "pgp-signature")) {
|
||||
#ifdef USE_GPGME
|
||||
if (compose->mode == COMPOSE_REEDIT) {
|
||||
compose->gnupg_mode = GNUPG_MODE_DETACH;
|
||||
compose_use_signing(compose, TRUE);
|
||||
}
|
||||
#endif
|
||||
child = procmime_mimeinfo_next(child);
|
||||
continue;
|
||||
}
|
||||
outfile = procmime_get_tmp_file_name(child);
|
||||
if (procmime_get_part(outfile, infile, child) < 0)
|
||||
if (procmime_get_part(outfile, child) < 0)
|
||||
g_warning("Can't get the part of multipart message.");
|
||||
else if (compose->mode != COMPOSE_REEDIT || strcmp(child->content_type, "application/pgp-signature"))
|
||||
compose_attach_append
|
||||
(compose, outfile,
|
||||
child->filename ? child->filename : child->name,
|
||||
child->content_type);
|
||||
else {
|
||||
gchar *content_type;
|
||||
|
||||
child = child->next;
|
||||
content_type = g_strdup_printf("%s/%s", procmime_get_type_str(child->type), child->subtype);
|
||||
partname = procmime_mimeinfo_get_parameter(child, "name");
|
||||
if (partname == NULL)
|
||||
partname = "";
|
||||
compose_attach_append(compose, outfile,
|
||||
partname, content_type);
|
||||
g_free(content_type);
|
||||
}
|
||||
g_free(outfile);
|
||||
NEXT_PART_NOT_CHILD(child);
|
||||
}
|
||||
|
||||
g_free(infile);
|
||||
procmime_mimeinfo_free_all(mimeinfo);
|
||||
}
|
||||
|
||||
#undef IS_FIRST_PART_TEXT
|
||||
|
||||
#define CHAR_BUF_SIZE 8
|
||||
#undef NEXT_PART_NOT_CHILD
|
||||
|
||||
#define GET_CHAR(iter_p, buf, len) \
|
||||
{ \
|
||||
|
@ -3209,7 +3300,8 @@ static gint compose_redirect_write_headers_from_headerlist(Compose *compose,
|
|||
{
|
||||
gchar buf[BUFFSIZE];
|
||||
gchar *str;
|
||||
gboolean first_address;
|
||||
gboolean first_to_address;
|
||||
gboolean first_cc_address;
|
||||
GSList *list;
|
||||
ComposeHeaderEntry *headerentry;
|
||||
const gchar *headerentryname;
|
||||
|
@ -3221,7 +3313,8 @@ static gint compose_redirect_write_headers_from_headerlist(Compose *compose,
|
|||
cc_hdr = prefs_common.trans_hdr ? _("Cc:") : "Cc:";
|
||||
to_hdr = prefs_common.trans_hdr ? _("To:") : "To:";
|
||||
|
||||
first_address = TRUE;
|
||||
first_to_address = TRUE;
|
||||
first_cc_address = TRUE;
|
||||
for (list = compose->header_list; list; list = list->next) {
|
||||
headerentry = ((ComposeHeaderEntry *)list->data);
|
||||
headerentryname = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(headerentry->combo)->entry));
|
||||
|
@ -3235,12 +3328,24 @@ static gint compose_redirect_write_headers_from_headerlist(Compose *compose,
|
|||
compose_convert_header
|
||||
(buf, sizeof(buf), str,
|
||||
strlen("Resent-To") + 2, TRUE);
|
||||
if (first_address) {
|
||||
fprintf(fp, "Resent-To: ");
|
||||
first_address = FALSE;
|
||||
} else {
|
||||
fprintf(fp, ",");
|
||||
if (g_strcasecmp(headerentryname, to_hdr) == 0) {
|
||||
if (first_to_address) {
|
||||
fprintf(fp, "Resent-To: ");
|
||||
first_to_address = FALSE;
|
||||
} else {
|
||||
fprintf(fp, ",");
|
||||
}
|
||||
}
|
||||
if (g_strcasecmp(headerentryname, cc_hdr) == 0) {
|
||||
if (first_cc_address) {
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "Resent-Cc: ");
|
||||
first_cc_address = FALSE;
|
||||
} else {
|
||||
fprintf(fp, ",");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "%s", buf);
|
||||
}
|
||||
}
|
||||
|
@ -3291,7 +3396,7 @@ static gint compose_redirect_write_headers(Compose *compose, FILE *fp)
|
|||
|
||||
/* Resent-Message-ID */
|
||||
if (compose->account->gen_msgid) {
|
||||
compose_generate_msgid(compose, buf, sizeof(buf));
|
||||
compose_generate_msgid(buf, sizeof(buf));
|
||||
fprintf(fp, "Resent-Message-Id: <%s>\n", buf);
|
||||
compose->msgid = g_strdup(buf);
|
||||
}
|
||||
|
@ -3328,7 +3433,7 @@ static gint compose_redirect_write_to_file(Compose *compose, const gchar *file)
|
|||
g_warning("can't change file mode\n");
|
||||
}
|
||||
|
||||
while (procheader_get_unfolded_line(buf, sizeof(buf), fp)) {
|
||||
while (procheader_get_one_field(buf, sizeof(buf), fp, NULL) != -1) {
|
||||
/* should filter returnpath, delivered-to */
|
||||
if (g_strncasecmp(buf, "Return-Path:",
|
||||
strlen("Return-Path:")) == 0 ||
|
||||
|
@ -3789,7 +3894,6 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
|
|||
GSList *cur;
|
||||
gchar buf[BUFFSIZE];
|
||||
gint num;
|
||||
MsgFlags flag = {0, 0};
|
||||
static gboolean lock = FALSE;
|
||||
PrefsAccount *mailac = NULL, *newsac = NULL;
|
||||
|
||||
|
@ -4110,14 +4214,15 @@ static void compose_write_attach(Compose *compose, FILE *fp)
|
|||
|
||||
static gint compose_write_headers_from_headerlist(Compose *compose,
|
||||
FILE *fp,
|
||||
gchar *header)
|
||||
const gchar *header,
|
||||
const gchar *seperator)
|
||||
{
|
||||
gchar buf[BUFFSIZE];
|
||||
gchar *str, *header_w_colon, *trans_hdr;
|
||||
gboolean first_address;
|
||||
gboolean write_header = FALSE;
|
||||
GSList *list;
|
||||
ComposeHeaderEntry *headerentry;
|
||||
const gchar * headerentryname;
|
||||
GString *headerstr;
|
||||
|
||||
if (IS_IN_CUSTOM_HEADER(header)) {
|
||||
return 0;
|
||||
|
@ -4125,10 +4230,11 @@ static gint compose_write_headers_from_headerlist(Compose *compose,
|
|||
|
||||
debug_print("Writing %s-header\n", header);
|
||||
|
||||
headerstr = g_string_sized_new(64);
|
||||
|
||||
header_w_colon = g_strconcat(header, ":", NULL);
|
||||
trans_hdr = (prefs_common.trans_hdr ? gettext(header_w_colon) : header_w_colon);
|
||||
|
||||
first_address = TRUE;
|
||||
for (list = compose->header_list; list; list = list->next) {
|
||||
headerentry = ((ComposeHeaderEntry *)list->data);
|
||||
headerentryname = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(headerentry->combo)->entry));
|
||||
|
@ -4138,24 +4244,26 @@ static gint compose_write_headers_from_headerlist(Compose *compose,
|
|||
Xstrdup_a(str, entstr, return -1);
|
||||
g_strstrip(str);
|
||||
if (str[0] != '\0') {
|
||||
compose_convert_header
|
||||
(buf, sizeof(buf), str,
|
||||
strlen(header) + 2, TRUE);
|
||||
if (first_address) {
|
||||
fprintf(fp, "%s: ", header);
|
||||
first_address = FALSE;
|
||||
} else {
|
||||
fprintf(fp, ",");
|
||||
}
|
||||
fprintf(fp, "%s", buf);
|
||||
if (write_header)
|
||||
g_string_append(headerstr, seperator);
|
||||
g_string_append(headerstr, str);
|
||||
write_header = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!first_address) {
|
||||
fprintf(fp, "\n");
|
||||
if (write_header) {
|
||||
gchar *buf;
|
||||
|
||||
buf = g_new0(gchar, headerstr->len * 4 + 256);
|
||||
compose_convert_header
|
||||
(buf, headerstr->len * 4 + 256, headerstr->str,
|
||||
strlen(header) + 2, TRUE);
|
||||
fprintf(fp, "%s: %s\n", header, buf);
|
||||
g_free(buf);
|
||||
}
|
||||
|
||||
g_free(header_w_colon);
|
||||
g_string_free(headerstr, TRUE);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -4212,7 +4320,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
|
|||
}
|
||||
|
||||
/* To */
|
||||
compose_write_headers_from_headerlist(compose, fp, "To");
|
||||
compose_write_headers_from_headerlist(compose, fp, "To", ", ");
|
||||
#if 0 /* NEW COMPOSE GUI */
|
||||
if (compose->use_to) {
|
||||
entry_str = gtk_entry_get_text(GTK_ENTRY(compose->to_entry));
|
||||
|
@ -4221,7 +4329,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
|
|||
#endif
|
||||
|
||||
/* Newsgroups */
|
||||
compose_write_headers_from_headerlist(compose, fp, "Newsgroups");
|
||||
compose_write_headers_from_headerlist(compose, fp, "Newsgroups", ",");
|
||||
#if 0 /* NEW COMPOSE GUI */
|
||||
if (compose->use_newsgroups) {
|
||||
entry_str = gtk_entry_get_text(GTK_ENTRY(compose->newsgroups_entry));
|
||||
|
@ -4242,7 +4350,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
|
|||
}
|
||||
#endif
|
||||
/* Cc */
|
||||
compose_write_headers_from_headerlist(compose, fp, "Cc");
|
||||
compose_write_headers_from_headerlist(compose, fp, "Cc", ", ");
|
||||
#if 0 /* NEW COMPOSE GUI */
|
||||
if (compose->use_cc) {
|
||||
str = gtk_entry_get_text(GTK_ENTRY(compose->cc_entry));
|
||||
|
@ -4250,7 +4358,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
|
|||
}
|
||||
#endif
|
||||
/* Bcc */
|
||||
compose_write_headers_from_headerlist(compose, fp, "Bcc");
|
||||
compose_write_headers_from_headerlist(compose, fp, "Bcc", ", ");
|
||||
#if 0 /* NEW COMPOSE GUI */
|
||||
if (compose->use_bcc) {
|
||||
str = gtk_entry_get_text(GTK_ENTRY(compose->bcc_entry));
|
||||
|
@ -4272,7 +4380,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
|
|||
|
||||
/* Message-ID */
|
||||
if (compose->account->gen_msgid) {
|
||||
compose_generate_msgid(compose, buf, sizeof(buf));
|
||||
compose_generate_msgid(buf, sizeof(buf));
|
||||
fprintf(fp, "Message-Id: <%s>\n", buf);
|
||||
compose->msgid = g_strdup(buf);
|
||||
}
|
||||
|
@ -4288,7 +4396,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
|
|||
}
|
||||
|
||||
/* Followup-To */
|
||||
compose_write_headers_from_headerlist(compose, fp, "Followup-To");
|
||||
compose_write_headers_from_headerlist(compose, fp, "Followup-To", ",");
|
||||
#if 0 /* NEW COMPOSE GUI */
|
||||
if (compose->use_followupto && !IS_IN_CUSTOM_HEADER("Followup-To")) {
|
||||
entry_str = gtk_entry_get_text(GTK_ENTRY(compose->followup_entry));
|
||||
|
@ -4306,7 +4414,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
|
|||
}
|
||||
#endif
|
||||
/* Reply-To */
|
||||
compose_write_headers_from_headerlist(compose, fp, "Reply-To");
|
||||
compose_write_headers_from_headerlist(compose, fp, "Reply-To", ", ");
|
||||
#if 0 /* NEW COMPOSE GUI */
|
||||
if (compose->use_replyto && !IS_IN_CUSTOM_HEADER("Reply-To")) {
|
||||
entry_str = gtk_entry_get_text(GTK_ENTRY(compose->reply_entry));
|
||||
|
@ -4380,7 +4488,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
|
|||
/* MIME */
|
||||
fprintf(fp, "Mime-Version: 1.0\n");
|
||||
if (compose_use_attach(compose)) {
|
||||
compose->boundary = generate_mime_boundary();
|
||||
compose->boundary = generate_mime_boundary(NULL);
|
||||
fprintf(fp,
|
||||
"Content-Type: multipart/mixed;\n"
|
||||
" boundary=\"%s\"\n", compose->boundary);
|
||||
|
@ -4497,7 +4605,7 @@ static void compose_convert_header(gchar *dest, gint len, gchar *src,
|
|||
conv_encode_header(dest, len, src, header_len, addr_field);
|
||||
}
|
||||
|
||||
static void compose_generate_msgid(Compose *compose, gchar *buf, gint len)
|
||||
static void compose_generate_msgid(gchar *buf, gint len)
|
||||
{
|
||||
struct tm *lt;
|
||||
time_t t;
|
||||
|
@ -4506,18 +4614,9 @@ static void compose_generate_msgid(Compose *compose, gchar *buf, gint len)
|
|||
t = time(NULL);
|
||||
lt = localtime(&t);
|
||||
|
||||
if (compose->account && compose->account->address &&
|
||||
*compose->account->address) {
|
||||
if (strchr(compose->account->address, '@'))
|
||||
addr = g_strdup(compose->account->address);
|
||||
else
|
||||
addr = g_strconcat(compose->account->address, "@",
|
||||
get_domain_name(), NULL);
|
||||
} else
|
||||
addr = g_strconcat(g_get_user_name(), "@", get_domain_name(),
|
||||
NULL);
|
||||
addr = g_strconcat("@", get_domain_name(), NULL);
|
||||
|
||||
g_snprintf(buf, len, "%04d%02d%02d%02d%02d%02d.%08x.%s",
|
||||
g_snprintf(buf, len, "%04d%02d%02d%02d%02d%02d.%08x%s",
|
||||
lt->tm_year + 1900, lt->tm_mon + 1,
|
||||
lt->tm_mday, lt->tm_hour,
|
||||
lt->tm_min, lt->tm_sec,
|
||||
|
@ -6513,7 +6612,19 @@ static void compose_insert_file_cb(gpointer data, guint action,
|
|||
|
||||
for ( tmp = file_list; tmp; tmp = tmp->next) {
|
||||
gchar *file = (gchar *) tmp->data;
|
||||
compose_insert_file(compose, file);
|
||||
gchar *filedup = g_strdup(file);
|
||||
gchar *shortfile;
|
||||
ComposeInsertResult res;
|
||||
|
||||
res = compose_insert_file(compose, file);
|
||||
shortfile = g_basename(filedup);
|
||||
if (res == COMPOSE_INSERT_READ_ERROR) {
|
||||
alertpanel_error(_("File '%s' could not be read."), shortfile);
|
||||
} else if (res == COMPOSE_INSERT_INVALID_CHARACTER) {
|
||||
alertpanel_error(_("File '%s' contained invalid characters\n"
|
||||
"for the current encoding, insertion may be incorrect."), shortfile);
|
||||
}
|
||||
g_free(filedup);
|
||||
g_free(file);
|
||||
}
|
||||
g_list_free(file_list);
|
||||
|
|
|
@ -245,7 +245,8 @@ void compose_reply (MsgInfo *msginfo,
|
|||
Compose *compose_forward (PrefsAccount *account,
|
||||
MsgInfo *msginfo,
|
||||
gboolean as_attach,
|
||||
const gchar *body);
|
||||
const gchar *body,
|
||||
gboolean no_extedit);
|
||||
Compose *compose_forward_multiple (PrefsAccount *account,
|
||||
GSList *msginfo_list);
|
||||
/* remove end */
|
||||
|
|
|
@ -502,7 +502,7 @@ static void crash_handler(int sig)
|
|||
|
||||
#ifdef SIGTERM
|
||||
if (sig == SIGTERM)
|
||||
clean_quit();
|
||||
clean_quit(NULL);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
194
src/editldap.c
194
src/editldap.c
|
@ -78,6 +78,7 @@ static struct _LDAPEdit {
|
|||
GtkWidget *entry_criteria;
|
||||
GtkWidget *spinbtn_queryage;
|
||||
GtkWidget *check_dynsearch;
|
||||
GtkWidget *check_matchoption;
|
||||
} ldapedit;
|
||||
|
||||
/**
|
||||
|
@ -372,6 +373,7 @@ static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
|
|||
GtkWidget *entry_baseDN;
|
||||
GtkWidget *check_btn;
|
||||
GtkWidget *lookdn_btn;
|
||||
GtkTooltips *toolTip;
|
||||
gint top;
|
||||
|
||||
vbox = gtk_vbox_new( FALSE, 8 );
|
||||
|
@ -400,6 +402,11 @@ static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
|
|||
gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, entry_name, _(
|
||||
"A name that you wish to call the server." ),
|
||||
NULL );
|
||||
|
||||
/* Next row */
|
||||
++top;
|
||||
label = gtk_label_new(_("Hostname"));
|
||||
|
@ -410,6 +417,15 @@ static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
|
|||
gtk_table_attach(GTK_TABLE(table), entry_server, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, entry_server, _(
|
||||
"This is the hostname of the server. For example, " \
|
||||
"\"ldap.mydomain.com\" may be appropriate for the " \
|
||||
"\"mydomain.com\" organization. An IP address may also be " \
|
||||
"used. You may specify \"localhost\" if running an LDAP " \
|
||||
"server on the same computer as Sylpheed." ),
|
||||
NULL );
|
||||
|
||||
/* Next row */
|
||||
++top;
|
||||
label = gtk_label_new(_("Port"));
|
||||
|
@ -425,9 +441,20 @@ static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
|
|||
gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, spinbtn_port, _(
|
||||
"The port number that the server listens on. Port 389 is " \
|
||||
"the default." ),
|
||||
NULL );
|
||||
|
||||
check_btn = gtk_button_new_with_label( _(" Check Server "));
|
||||
gtk_table_attach(GTK_TABLE(table), check_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, check_btn, _(
|
||||
"Press this button to test the connection to the server." ),
|
||||
NULL );
|
||||
|
||||
/* Next row */
|
||||
++top;
|
||||
label = gtk_label_new(_("Search Base"));
|
||||
|
@ -438,9 +465,25 @@ static void addressbook_edit_ldap_page_basic( gint pageNum, gchar *pageLbl ) {
|
|||
gtk_table_attach(GTK_TABLE(table), entry_baseDN, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, entry_baseDN, _(
|
||||
"This specifies the name of the directory to be searched " \
|
||||
"on the server. Examples include:\n" \
|
||||
" dc=sylpheed,dc=org\n" \
|
||||
" ou=people,dc=domainname,dc=com\n" \
|
||||
" o=Organization Name,c=Country\n"
|
||||
),
|
||||
NULL );
|
||||
|
||||
lookdn_btn = gtk_button_new_with_label( _(" ... "));
|
||||
gtk_table_attach(GTK_TABLE(table), lookdn_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, lookdn_btn, _(
|
||||
"Press this button to lookup the name of available " \
|
||||
"directory names on the server." ),
|
||||
NULL );
|
||||
|
||||
/* Signal handlers */
|
||||
g_signal_connect(G_OBJECT(check_btn), "clicked",
|
||||
G_CALLBACK(edit_ldap_server_check), NULL);
|
||||
|
@ -465,7 +508,9 @@ static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
|
|||
GtkObject *spinbtn_queryage_adj;
|
||||
GtkWidget *spinbtn_queryage;
|
||||
GtkWidget *check_dynsearch;
|
||||
GtkWidget *check_matchoption;
|
||||
GtkWidget *reset_btn;
|
||||
GtkTooltips *toolTip;
|
||||
gint top;
|
||||
|
||||
vbox = gtk_vbox_new( FALSE, 8 );
|
||||
|
@ -494,9 +539,22 @@ static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
|
|||
gtk_table_attach(GTK_TABLE(table), entry_criteria, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, entry_criteria, _(
|
||||
"A list of LDAP attribute names that should be searched " \
|
||||
"when attempting to find a name or address." ),
|
||||
NULL );
|
||||
|
||||
reset_btn = gtk_button_new_with_label( _(" Defaults "));
|
||||
gtk_table_attach(GTK_TABLE(table), reset_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, reset_btn, _(
|
||||
"This resets the attribute names to a default value " \
|
||||
"that should find most names and addresses during a " \
|
||||
"name or address search process." ),
|
||||
NULL );
|
||||
|
||||
/* Next row */
|
||||
++top;
|
||||
label = gtk_label_new(_("Max Query Age (secs)"));
|
||||
|
@ -513,6 +571,23 @@ static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
|
|||
gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, spinbtn_queryage, _(
|
||||
"This defines the maximum period of time (in seconds) that " \
|
||||
"an address search result is valid for address completion " \
|
||||
"purposes. Search results are stored in a cache until this " \
|
||||
"period of time has passed and then retired. This will " \
|
||||
"improve the response time when attempting to search for " \
|
||||
"the same name or address on subsequent address completion " \
|
||||
"requests. The cache will be searched in preference to " \
|
||||
"performing a new server search request. The default value " \
|
||||
"of 600 seconds (10 minutes), should be sufficient for most " \
|
||||
"servers. A larger value will reduce the search time for " \
|
||||
"subsequent searches. This is useful for servers that have " \
|
||||
"slow response times at the expense of more memory to cache " \
|
||||
"results." ),
|
||||
NULL );
|
||||
|
||||
/* Next row */
|
||||
++top;
|
||||
check_dynsearch = gtk_check_button_new_with_label(
|
||||
|
@ -520,6 +595,31 @@ static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
|
|||
gtk_table_attach(GTK_TABLE(table), check_dynsearch, 1, 3, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, check_dynsearch, _(
|
||||
"Check this option to include this server for dynamic " \
|
||||
"searches when using address completion." ),
|
||||
NULL );
|
||||
|
||||
/* Next row */
|
||||
++top;
|
||||
check_matchoption = gtk_check_button_new_with_label(
|
||||
_("Match names 'containing' search term") );
|
||||
gtk_table_attach(GTK_TABLE(table), check_matchoption, 1, 3, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, check_matchoption, _(
|
||||
"Searches for names and addresses can be performed either " \
|
||||
"using \"begins-with\" or \"contains\" search term. Check " \
|
||||
"this option to perform a \"contains\" search; this type of " \
|
||||
"search usually takes longer to complete. Note that for " \
|
||||
"performance reasons, address completion uses " \
|
||||
"\"begins-with\" for all searches against other address " \
|
||||
"interfaces." \
|
||||
),
|
||||
NULL );
|
||||
|
||||
/* Signal handlers */
|
||||
g_signal_connect(G_OBJECT(reset_btn), "clicked",
|
||||
G_CALLBACK(edit_ldap_search_reset), NULL);
|
||||
|
@ -527,9 +627,10 @@ static void addressbook_edit_ldap_page_search( gint pageNum, gchar *pageLbl ) {
|
|||
/* Done */
|
||||
gtk_widget_show_all(vbox);
|
||||
|
||||
ldapedit.entry_criteria = entry_criteria;
|
||||
ldapedit.spinbtn_queryage = spinbtn_queryage;
|
||||
ldapedit.check_dynsearch = check_dynsearch;
|
||||
ldapedit.entry_criteria = entry_criteria;
|
||||
ldapedit.spinbtn_queryage = spinbtn_queryage;
|
||||
ldapedit.check_dynsearch = check_dynsearch;
|
||||
ldapedit.check_matchoption = check_matchoption;
|
||||
}
|
||||
|
||||
static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl ) {
|
||||
|
@ -543,6 +644,7 @@ static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl )
|
|||
GtkWidget *spinbtn_timeout;
|
||||
GtkObject *spinbtn_maxentry_adj;
|
||||
GtkWidget *spinbtn_maxentry;
|
||||
GtkTooltips *toolTip;
|
||||
gint top;
|
||||
|
||||
vbox = gtk_vbox_new( FALSE, 8 );
|
||||
|
@ -571,6 +673,14 @@ static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl )
|
|||
gtk_table_attach(GTK_TABLE(table), entry_bindDN, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, entry_bindDN, _(
|
||||
"The LDAP user account name to be used to connect to the server. " \
|
||||
"This is usually only used for protected servers. This name " \
|
||||
"is typically formatted as: \"cn=user,dc=sylpheed,dc=com\". " \
|
||||
"This is usually left empty when performing a search." ),
|
||||
NULL );
|
||||
|
||||
/* Next row */
|
||||
++top;
|
||||
label = gtk_label_new(_("Bind Password"));
|
||||
|
@ -581,6 +691,12 @@ static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl )
|
|||
gtk_table_attach(GTK_TABLE(table), entry_bindPW, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, entry_bindPW, _(
|
||||
"The password to be used when connecting as the \"Bind DN\" " \
|
||||
"user." ),
|
||||
NULL );
|
||||
|
||||
/* Next row */
|
||||
++top;
|
||||
label = gtk_label_new(_("Timeout (secs)"));
|
||||
|
@ -596,6 +712,10 @@ static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl )
|
|||
gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, spinbtn_timeout, _(
|
||||
"The timeout period in seconds." ), NULL );
|
||||
|
||||
/* Next row */
|
||||
++top;
|
||||
label = gtk_label_new(_("Maximum Entries"));
|
||||
|
@ -611,6 +731,12 @@ static void addressbook_edit_ldap_page_extended( gint pageNum, gchar *pageLbl )
|
|||
gtk_table_attach(GTK_TABLE(table), hbox_spin, 1, 2, top, (top + 1),
|
||||
GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
|
||||
|
||||
toolTip = gtk_tooltips_new();
|
||||
gtk_tooltips_set_tip( toolTip, spinbtn_maxentry, _(
|
||||
"The maximum number of entries that should be returned " \
|
||||
"in the search result." ),
|
||||
NULL );
|
||||
|
||||
/* Done */
|
||||
gtk_widget_show_all(vbox);
|
||||
|
||||
|
@ -749,6 +875,8 @@ static void edit_ldap_clear_fields( void ) {
|
|||
GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), LDAPCTL_DFL_QUERY_AGE );
|
||||
gtk_toggle_button_set_active(
|
||||
GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), TRUE );
|
||||
gtk_toggle_button_set_active(
|
||||
GTK_TOGGLE_BUTTON( ldapedit.check_matchoption), FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -796,13 +924,25 @@ static void edit_ldap_set_fields( LdapServer *server ) {
|
|||
GTK_SPIN_BUTTON(ldapedit.spinbtn_queryage), ctl->maxQueryAge );
|
||||
gtk_toggle_button_set_active(
|
||||
GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch), server->searchFlag );
|
||||
gtk_toggle_button_set_active(
|
||||
GTK_TOGGLE_BUTTON( ldapedit.check_matchoption),
|
||||
( ctl->matchingOption == LDAPCTL_MATCH_CONTAINS ) );
|
||||
}
|
||||
|
||||
AdapterDSource *addressbook_edit_ldap( AddressIndex *addrIndex, AdapterDSource *ads ) {
|
||||
/**
|
||||
* Edit LDAP server datasource that appears addressbook.
|
||||
* \param addrIndex Address index object.
|
||||
* \param ads Data source adapter.
|
||||
* \return Update data source adapter, or <code>NULL</code> if user cancelled
|
||||
* edit with dialog.
|
||||
*/
|
||||
AdapterDSource *addressbook_edit_ldap(
|
||||
AddressIndex *addrIndex, AdapterDSource *ads )
|
||||
{
|
||||
static gboolean cancelled;
|
||||
gchar *sName, *sHost, *sBase, *sBind, *sPass, *sCrit;
|
||||
gint iPort, iMaxE, iTime, iAge;
|
||||
gboolean bSrch;
|
||||
gboolean bSrch, bMatch;
|
||||
AddressDataSource *ds = NULL;
|
||||
LdapServer *server = NULL;
|
||||
LdapControl *ctl = NULL;
|
||||
|
@ -834,17 +974,30 @@ AdapterDSource *addressbook_edit_ldap( AddressIndex *addrIndex, AdapterDSource *
|
|||
gtk_widget_hide(ldapedit.window);
|
||||
if (cancelled == TRUE) return NULL;
|
||||
|
||||
sName = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
|
||||
sHost = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
|
||||
sBase = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
|
||||
sCrit = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
|
||||
sBind = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
|
||||
sPass = gtk_editable_get_chars( GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
|
||||
iPort = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
|
||||
iTime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
|
||||
iMaxE = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ) );
|
||||
iAge = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( ldapedit.spinbtn_queryage ) );
|
||||
bSrch = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch ) );
|
||||
sName = gtk_editable_get_chars(
|
||||
GTK_EDITABLE(ldapedit.entry_name), 0, -1 );
|
||||
sHost = gtk_editable_get_chars(
|
||||
GTK_EDITABLE(ldapedit.entry_server), 0, -1 );
|
||||
sBase = gtk_editable_get_chars(
|
||||
GTK_EDITABLE(ldapedit.entry_baseDN), 0, -1 );
|
||||
sCrit = gtk_editable_get_chars(
|
||||
GTK_EDITABLE(ldapedit.entry_criteria), 0, -1 );
|
||||
sBind = gtk_editable_get_chars(
|
||||
GTK_EDITABLE(ldapedit.entry_bindDN), 0, -1 );
|
||||
sPass = gtk_editable_get_chars(
|
||||
GTK_EDITABLE(ldapedit.entry_bindPW), 0, -1 );
|
||||
iPort = gtk_spin_button_get_value_as_int(
|
||||
GTK_SPIN_BUTTON( ldapedit.spinbtn_port ) );
|
||||
iTime = gtk_spin_button_get_value_as_int(
|
||||
GTK_SPIN_BUTTON( ldapedit.spinbtn_timeout ) );
|
||||
iMaxE = gtk_spin_button_get_value_as_int(
|
||||
GTK_SPIN_BUTTON( ldapedit.spinbtn_maxentry ) );
|
||||
iAge = gtk_spin_button_get_value_as_int(
|
||||
GTK_SPIN_BUTTON( ldapedit.spinbtn_queryage ) );
|
||||
bSrch = gtk_toggle_button_get_active(
|
||||
GTK_TOGGLE_BUTTON( ldapedit.check_dynsearch ) );
|
||||
bMatch = gtk_toggle_button_get_active(
|
||||
GTK_TOGGLE_BUTTON( ldapedit.check_matchoption ) );
|
||||
|
||||
fin = FALSE;
|
||||
if( *sName == '\0' ) fin = TRUE;
|
||||
|
@ -855,8 +1008,10 @@ AdapterDSource *addressbook_edit_ldap( AddressIndex *addrIndex, AdapterDSource *
|
|||
if( ! ads ) {
|
||||
/* New server */
|
||||
server = ldapsvr_create();
|
||||
ds = addrindex_index_add_datasource( addrIndex, ADDR_IF_LDAP, server );
|
||||
ads = addressbook_create_ds_adapter( ds, ADDR_LDAP, NULL );
|
||||
ds = addrindex_index_add_datasource(
|
||||
addrIndex, ADDR_IF_LDAP, server );
|
||||
ads = addressbook_create_ds_adapter(
|
||||
ds, ADDR_LDAP, NULL );
|
||||
}
|
||||
ctl = server->control;
|
||||
addressbook_ads_set_name( ads, sName );
|
||||
|
@ -870,6 +1025,9 @@ AdapterDSource *addressbook_edit_ldap( AddressIndex *addrIndex, AdapterDSource *
|
|||
ldapctl_set_max_entries( ctl, iMaxE );
|
||||
ldapctl_set_timeout( ctl, iTime );
|
||||
ldapctl_set_max_query_age( ctl, iAge );
|
||||
ldapctl_set_matching_option(
|
||||
ctl, bMatch ?
|
||||
LDAPCTL_MATCH_CONTAINS : LDAPCTL_MATCH_BEGINWITH );
|
||||
|
||||
/* Save attributes */
|
||||
editldap_parse_criteria( sCrit, ctl );
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
* Export addressbook to HTML file.
|
||||
*/
|
||||
|
||||
#ifndef __EXPORT_HTML_H__
|
||||
#define __EXPORT_HTML_H__
|
||||
#ifndef __EXPORT_LDIF_H__
|
||||
#define __EXPORT_LDIF_H__
|
||||
|
||||
/* Function prototypes */
|
||||
void addressbook_exp_html( AddressCache *cache );
|
||||
void addressbook_exp_ldif( AddressCache *cache );
|
||||
|
||||
#endif /* __EXPORT_HTML_H__ */
|
||||
#endif /* __EXPORT_LDIF_H__ */
|
||||
|
||||
/*
|
||||
* End of Source.
|
||||
|
|
|
@ -81,8 +81,6 @@ ExportLdifCtl *exportldif_create( void ) {
|
|||
* \return ctl Export control data.
|
||||
*/
|
||||
void exportldif_free( ExportLdifCtl *ctl ) {
|
||||
GList *node;
|
||||
|
||||
g_return_if_fail( ctl != NULL );
|
||||
|
||||
g_free( ctl->path );
|
||||
|
|
181
src/filtering.c
181
src/filtering.c
|
@ -34,7 +34,9 @@
|
|||
|
||||
#define PREFSBUFSIZE 1024
|
||||
|
||||
GSList * global_processing = NULL;
|
||||
GSList * pre_global_processing = NULL;
|
||||
GSList * post_global_processing = NULL;
|
||||
GSList * filtering_rules = NULL;
|
||||
|
||||
static gboolean filtering_is_final_action(FilteringAction *filtering_action);
|
||||
|
||||
|
@ -53,27 +55,21 @@ static inline gint strlen_with_check(const gchar *expr, gint fline, const gchar
|
|||
|
||||
FilteringAction * filteringaction_new(int type, int account_id,
|
||||
gchar * destination,
|
||||
gint labelcolor)
|
||||
gint labelcolor, gint score)
|
||||
{
|
||||
FilteringAction * action;
|
||||
|
||||
action = g_new0(FilteringAction, 1);
|
||||
|
||||
/* NOTE:
|
||||
* if type is MATCHACTION_CHANGE_SCORE, account_id = (-1, 0, 1) and
|
||||
* labelcolor = the score value change
|
||||
*/
|
||||
|
||||
action->type = type;
|
||||
action->account_id = account_id;
|
||||
if (destination) {
|
||||
action->destination = g_strdup(destination);
|
||||
action->unesc_destination = matcher_unescape_str(g_strdup(destination));
|
||||
} else {
|
||||
action->destination = NULL;
|
||||
action->unesc_destination = NULL;
|
||||
}
|
||||
action->labelcolor = labelcolor;
|
||||
action->score = score;
|
||||
return action;
|
||||
}
|
||||
|
||||
|
@ -82,8 +78,6 @@ void filteringaction_free(FilteringAction * action)
|
|||
g_return_if_fail(action);
|
||||
if (action->destination)
|
||||
g_free(action->destination);
|
||||
if (action->unesc_destination)
|
||||
g_free(action->unesc_destination);
|
||||
g_free(action);
|
||||
}
|
||||
|
||||
|
@ -111,10 +105,6 @@ static FilteringAction * filteringaction_copy(FilteringAction * src)
|
|||
new->destination = g_strdup(src->destination);
|
||||
else
|
||||
new->destination = NULL;
|
||||
if (src->unesc_destination)
|
||||
new->unesc_destination = g_strdup(src->unesc_destination);
|
||||
else
|
||||
new->unesc_destination = NULL;
|
||||
new->labelcolor = src->labelcolor;
|
||||
|
||||
return new;
|
||||
|
@ -128,10 +118,6 @@ FilteringProp * filteringprop_copy(FilteringProp *src)
|
|||
new = g_new0(FilteringProp, 1);
|
||||
new->matchers = g_new0(MatcherList, 1);
|
||||
|
||||
#if 0
|
||||
new->action = g_new0(FilteringAction, 1);
|
||||
#endif
|
||||
|
||||
for (tmp = src->matchers->matchers; tmp != NULL && tmp->data != NULL;) {
|
||||
MatcherProp *matcher = (MatcherProp *)tmp->data;
|
||||
|
||||
|
@ -142,19 +128,6 @@ FilteringProp * filteringprop_copy(FilteringProp *src)
|
|||
|
||||
new->matchers->bool_and = src->matchers->bool_and;
|
||||
|
||||
#if 0
|
||||
new->action->type = src->action->type;
|
||||
new->action->account_id = src->action->account_id;
|
||||
if (src->action->destination)
|
||||
new->action->destination = g_strdup(src->action->destination);
|
||||
else
|
||||
new->action->destination = NULL;
|
||||
if (src->action->unesc_destination)
|
||||
new->action->unesc_destination = g_strdup(src->action->unesc_destination);
|
||||
else
|
||||
new->action->unesc_destination = NULL;
|
||||
new->action->labelcolor = src->action->labelcolor;
|
||||
#endif
|
||||
new->action_list = NULL;
|
||||
|
||||
for (tmp = src->action_list ; tmp != NULL ; tmp = tmp->next) {
|
||||
|
@ -200,8 +173,11 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
|
|||
case MATCHACTION_MOVE:
|
||||
dest_folder =
|
||||
folder_find_item_from_identifier(action->destination);
|
||||
if (!dest_folder)
|
||||
if (!dest_folder) {
|
||||
debug_print("*** folder not found '%s'\n",
|
||||
action->destination ?action->destination :"");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (folder_item_move_msg(dest_folder, info) == -1) {
|
||||
debug_print("*** could not move message\n");
|
||||
|
@ -214,8 +190,11 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
|
|||
dest_folder =
|
||||
folder_find_item_from_identifier(action->destination);
|
||||
|
||||
if (!dest_folder)
|
||||
if (!dest_folder) {
|
||||
debug_print("*** folder not found '%s'\n",
|
||||
action->destination ?action->destination :"");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (folder_item_copy_msg(dest_folder, info) == -1)
|
||||
return FALSE;
|
||||
|
@ -257,42 +236,20 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
|
|||
return TRUE;
|
||||
|
||||
case MATCHACTION_FORWARD:
|
||||
account = account_find_from_id(action->account_id);
|
||||
compose = compose_forward(account, info, FALSE, NULL);
|
||||
if (compose->account->protocol == A_NNTP)
|
||||
compose_entry_append(compose, action->destination,
|
||||
COMPOSE_NEWSGROUPS);
|
||||
else
|
||||
compose_entry_append(compose, action->destination,
|
||||
COMPOSE_TO);
|
||||
|
||||
val = compose_send(compose);
|
||||
if (val == 0) {
|
||||
gtk_widget_destroy(compose->window);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gtk_widget_destroy(compose->window);
|
||||
return FALSE;
|
||||
|
||||
case MATCHACTION_FORWARD_AS_ATTACHMENT:
|
||||
|
||||
account = account_find_from_id(action->account_id);
|
||||
compose = compose_forward(account, info, TRUE, NULL);
|
||||
if (compose->account->protocol == A_NNTP)
|
||||
compose_entry_append(compose, action->destination,
|
||||
COMPOSE_NEWSGROUPS);
|
||||
else
|
||||
compose_entry_append(compose, action->destination,
|
||||
COMPOSE_TO);
|
||||
compose = compose_forward(account, info,
|
||||
action->type == MATCHACTION_FORWARD ? FALSE : TRUE,
|
||||
NULL, TRUE);
|
||||
compose_entry_append(compose, action->destination,
|
||||
compose->account->protocol == A_NNTP
|
||||
? COMPOSE_NEWSGROUPS
|
||||
: COMPOSE_TO);
|
||||
|
||||
val = compose_send(compose);
|
||||
if (val == 0) {
|
||||
gtk_widget_destroy(compose->window);
|
||||
return TRUE;
|
||||
}
|
||||
gtk_widget_destroy(compose->window);
|
||||
return FALSE;
|
||||
|
||||
return val == 0 ? TRUE : FALSE;
|
||||
|
||||
case MATCHACTION_REDIRECT:
|
||||
account = account_find_from_id(action->account_id);
|
||||
|
@ -304,16 +261,12 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
|
|||
COMPOSE_TO);
|
||||
|
||||
val = compose_send(compose);
|
||||
if (val == 0) {
|
||||
gtk_widget_destroy(compose->window);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gtk_widget_destroy(compose->window);
|
||||
return FALSE;
|
||||
|
||||
return val == 0 ? TRUE : FALSE;
|
||||
|
||||
case MATCHACTION_EXECUTE:
|
||||
cmd = matching_build_command(action->unesc_destination, info);
|
||||
cmd = matching_build_command(action->destination, info);
|
||||
if (cmd == NULL)
|
||||
return FALSE;
|
||||
else {
|
||||
|
@ -322,23 +275,44 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
|
|||
}
|
||||
return TRUE;
|
||||
|
||||
case MATCHACTION_CHANGE_SCORE:
|
||||
/* NOTE:
|
||||
* action->account_id is 0 if just assignment, -1 if decrement
|
||||
* and 1 if increment by action->labelcolor
|
||||
* action->labelcolor has the score value change
|
||||
*/
|
||||
info->score = action->account_id == 1 ? info->score + action->labelcolor
|
||||
: action->account_id == -1 ? info->score - action->labelcolor
|
||||
: action->labelcolor;
|
||||
case MATCHACTION_SET_SCORE:
|
||||
info->score = action->score;
|
||||
return TRUE;
|
||||
|
||||
case MATCHACTION_CHANGE_SCORE:
|
||||
info->score += action->score;
|
||||
return TRUE;
|
||||
|
||||
case MATCHACTION_STOP:
|
||||
return TRUE;
|
||||
|
||||
case MATCHACTION_HIDE:
|
||||
info->hidden = TRUE;
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean filteringaction_apply_action_list(GSList *action_list, MsgInfo *info)
|
||||
{
|
||||
GSList *p;
|
||||
g_return_val_if_fail(action_list, FALSE);
|
||||
g_return_val_if_fail(info, FALSE);
|
||||
for (p = action_list; p && p->data; p = g_slist_next(p)) {
|
||||
FilteringAction *a = (FilteringAction *) p->data;
|
||||
if (filteringaction_apply(a, info)) {
|
||||
if (filtering_is_final_action(a))
|
||||
break;
|
||||
} else
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *info)
|
||||
{
|
||||
return matcherlist_match(filtering->matchers, info);
|
||||
|
@ -375,19 +349,8 @@ static gboolean filtering_is_final_action(FilteringAction *filtering_action)
|
|||
switch(filtering_action->type) {
|
||||
case MATCHACTION_MOVE:
|
||||
case MATCHACTION_DELETE:
|
||||
case MATCHACTION_STOP:
|
||||
return TRUE; /* MsgInfo invalid for message */
|
||||
case MATCHACTION_EXECUTE:
|
||||
case MATCHACTION_COPY:
|
||||
case MATCHACTION_MARK:
|
||||
case MATCHACTION_UNMARK:
|
||||
case MATCHACTION_LOCK:
|
||||
case MATCHACTION_UNLOCK:
|
||||
case MATCHACTION_MARK_AS_READ:
|
||||
case MATCHACTION_MARK_AS_UNREAD:
|
||||
case MATCHACTION_FORWARD:
|
||||
case MATCHACTION_FORWARD_AS_ATTACHMENT:
|
||||
case MATCHACTION_REDIRECT:
|
||||
return FALSE; /* MsgInfo still valid for message */
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -406,10 +369,6 @@ static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info)
|
|||
|
||||
if (filtering_match_condition(filtering, info)) {
|
||||
applied = filtering_apply_rule(filtering, info, &final);
|
||||
#if 0
|
||||
if (TRUE == (final = filtering_is_final_action(filtering)))
|
||||
break;
|
||||
#endif
|
||||
if (final)
|
||||
break;
|
||||
}
|
||||
|
@ -432,7 +391,8 @@ gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info)
|
|||
gchar *filteringaction_to_string(gchar *dest, gint destlen, FilteringAction *action)
|
||||
{
|
||||
const gchar *command_str;
|
||||
|
||||
gchar * quoted_dest;
|
||||
|
||||
command_str = get_matchparser_tab_str(action->type);
|
||||
|
||||
if (command_str == NULL)
|
||||
|
@ -442,7 +402,9 @@ gchar *filteringaction_to_string(gchar *dest, gint destlen, FilteringAction *act
|
|||
case MATCHACTION_MOVE:
|
||||
case MATCHACTION_COPY:
|
||||
case MATCHACTION_EXECUTE:
|
||||
g_snprintf(dest, destlen, "%s \"%s\"", command_str, action->destination);
|
||||
quoted_dest = matcher_quote_str(action->destination);
|
||||
g_snprintf(dest, destlen, "%s \"%s\"", command_str, quoted_dest);
|
||||
g_free(quoted_dest);
|
||||
return dest;
|
||||
|
||||
case MATCHACTION_DELETE:
|
||||
|
@ -452,18 +414,28 @@ gchar *filteringaction_to_string(gchar *dest, gint destlen, FilteringAction *act
|
|||
case MATCHACTION_UNLOCK:
|
||||
case MATCHACTION_MARK_AS_READ:
|
||||
case MATCHACTION_MARK_AS_UNREAD:
|
||||
case MATCHACTION_STOP:
|
||||
case MATCHACTION_HIDE:
|
||||
g_snprintf(dest, destlen, "%s", command_str);
|
||||
return dest;
|
||||
|
||||
case MATCHACTION_REDIRECT:
|
||||
case MATCHACTION_FORWARD:
|
||||
case MATCHACTION_FORWARD_AS_ATTACHMENT:
|
||||
g_snprintf(dest, destlen, "%s %d \"%s\"", command_str, action->account_id, action->destination);
|
||||
quoted_dest = matcher_quote_str(action->destination);
|
||||
g_snprintf(dest, destlen, "%s %d \"%s\"", command_str, action->account_id, quoted_dest);
|
||||
g_free(quoted_dest);
|
||||
return dest;
|
||||
|
||||
case MATCHACTION_COLOR:
|
||||
g_snprintf(dest, destlen, "%s %d", command_str, action->labelcolor);
|
||||
return dest;
|
||||
|
||||
case MATCHACTION_CHANGE_SCORE:
|
||||
case MATCHACTION_SET_SCORE:
|
||||
g_snprintf(dest, destlen, "%s %d", command_str, action->score);
|
||||
return dest;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -504,7 +476,6 @@ gchar * filteringprop_to_string(FilteringProp * prop)
|
|||
gchar *list_str;
|
||||
gchar *action_list_str;
|
||||
gchar *filtering_str;
|
||||
GSList * tmp;
|
||||
|
||||
action_list_str = filteringaction_list_to_string(prop->action_list);
|
||||
|
||||
|
@ -560,8 +531,12 @@ void prefs_filtering_clear(void)
|
|||
prefs_filtering_free_func, NULL);
|
||||
}
|
||||
|
||||
prefs_filtering_free(global_processing);
|
||||
global_processing = NULL;
|
||||
prefs_filtering_free(filtering_rules);
|
||||
filtering_rules = NULL;
|
||||
prefs_filtering_free(pre_global_processing);
|
||||
pre_global_processing = NULL;
|
||||
prefs_filtering_free(post_global_processing);
|
||||
post_global_processing = NULL;
|
||||
}
|
||||
|
||||
void prefs_filtering_clear_folder(Folder *folder)
|
||||
|
|
|
@ -29,8 +29,8 @@ struct _FilteringAction {
|
|||
gint type;
|
||||
gint account_id;
|
||||
gchar *destination;
|
||||
gchar *unesc_destination; /* for exec cmd line */
|
||||
gint labelcolor;
|
||||
gint score;
|
||||
};
|
||||
|
||||
typedef struct _FilteringAction FilteringAction;
|
||||
|
@ -46,10 +46,11 @@ typedef struct _FilteringProp FilteringProp;
|
|||
|
||||
|
||||
FilteringAction * filteringaction_new(int type, int account_id,
|
||||
gchar *destination,
|
||||
gint labelcolor);
|
||||
gchar * destination,
|
||||
gint labelcolor, gint score);
|
||||
void filteringaction_free(FilteringAction *action);
|
||||
FilteringAction * filteringaction_parse(gchar **str);
|
||||
gboolean filteringaction_apply_action_list (GSList *action_list, MsgInfo *info);
|
||||
|
||||
FilteringProp * filteringprop_new(MatcherList *matchers,
|
||||
GSList *action_list);
|
||||
|
@ -72,6 +73,8 @@ void prefs_filtering_free(GSList *prefs_filtering);
|
|||
|
||||
FilteringProp * filteringprop_copy(FilteringProp *src);
|
||||
|
||||
extern GSList * global_processing;
|
||||
extern GSList * filtering_rules;
|
||||
extern GSList * pre_global_processing;
|
||||
extern GSList * post_global_processing;
|
||||
|
||||
#endif
|
||||
|
|
807
src/folder.c
807
src/folder.c
File diff suppressed because it is too large
Load diff
92
src/folder.h
92
src/folder.h
|
@ -23,33 +23,22 @@
|
|||
#include <glib.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef struct _Folder Folder;
|
||||
typedef struct _FolderClass FolderClass;
|
||||
typedef struct _LocalFolder LocalFolder;
|
||||
typedef struct _RemoteFolder RemoteFolder;
|
||||
#if 0
|
||||
typedef struct _MaildirFolder MaildirFolder;
|
||||
#endif
|
||||
typedef struct _FolderItem FolderItem;
|
||||
typedef struct _Folder Folder;
|
||||
typedef struct _FolderClass FolderClass;
|
||||
|
||||
typedef struct _FolderItem FolderItem;
|
||||
typedef struct _FolderUpdateData FolderUpdateData;
|
||||
typedef struct _FolderItemUpdateData FolderItemUpdateData;
|
||||
typedef struct _PersistPrefs PersistPrefs;
|
||||
|
||||
#define FOLDER(obj) ((Folder *)obj)
|
||||
#define FOLDER_TYPE(obj) (FOLDER(obj)->klass->type)
|
||||
|
||||
#define FOLDER_CLASS(obj) (FOLDER(obj)->klass)
|
||||
#define LOCAL_FOLDER(obj) ((LocalFolder *)obj)
|
||||
#define REMOTE_FOLDER(obj) ((RemoteFolder *)obj)
|
||||
#define FOLDER_TYPE(obj) (FOLDER(obj)->klass->type)
|
||||
|
||||
#define FOLDER_IS_LOCAL(obj) (FOLDER_TYPE(obj) == F_MH || \
|
||||
FOLDER_TYPE(obj) == F_MBOX || \
|
||||
FOLDER_TYPE(obj) == F_MAILDIR)
|
||||
|
||||
#if 0
|
||||
#define MAILDIR_FOLDER(obj) ((MaildirFolder *)obj)
|
||||
#endif
|
||||
|
||||
#define FOLDER_ITEM(obj) ((FolderItem *)obj)
|
||||
|
||||
#define FOLDER_UPDATE_HOOKLIST "folder_update"
|
||||
|
@ -129,12 +118,13 @@ typedef void (*FolderDestroyNotify) (Folder *folder,
|
|||
typedef void (*FolderItemFunc) (FolderItem *item,
|
||||
gpointer data);
|
||||
|
||||
|
||||
#include "folder_item_prefs.h"
|
||||
|
||||
#include "prefs_account.h"
|
||||
#include "session.h"
|
||||
#include "procmsg.h"
|
||||
#include "msgcache.h"
|
||||
#include "xml.h"
|
||||
#include "prefs_account.h"
|
||||
|
||||
struct _Folder
|
||||
{
|
||||
|
@ -171,27 +161,35 @@ struct _FolderClass
|
|||
Folder *(*new_folder) (const gchar *name,
|
||||
const gchar *path);
|
||||
void (*destroy_folder) (Folder *folder);
|
||||
void (*scan_tree) (Folder *folder);
|
||||
void (*set_xml) (Folder *folder,
|
||||
XMLTag *tag);
|
||||
XMLTag *(*get_xml) (Folder *folder);
|
||||
gint (*scan_tree) (Folder *folder);
|
||||
|
||||
gint (*create_tree) (Folder *folder);
|
||||
|
||||
/* FolderItem functions */
|
||||
FolderItem *(*item_new) (Folder *folder);
|
||||
void (*item_destroy) (Folder *folder,
|
||||
void (*item_destroy) (Folder *folder,
|
||||
FolderItem *item);
|
||||
void (*item_set_xml) (Folder *folder,
|
||||
FolderItem *item,
|
||||
XMLTag *tag);
|
||||
XMLTag *(*item_get_xml) (Folder *folder,
|
||||
FolderItem *item);
|
||||
gchar *(*item_get_path) (Folder *folder,
|
||||
FolderItem *item);
|
||||
FolderItem *(*create_folder) (Folder *folder,
|
||||
FolderItem *parent,
|
||||
const gchar *name);
|
||||
gint (*rename_folder) (Folder *folder,
|
||||
gint (*rename_folder) (Folder *folder,
|
||||
FolderItem *item,
|
||||
const gchar *name);
|
||||
gint (*remove_folder) (Folder *folder,
|
||||
gint (*remove_folder) (Folder *folder,
|
||||
FolderItem *item);
|
||||
gint (*close) (Folder *folder,
|
||||
gint (*close) (Folder *folder,
|
||||
FolderItem *item);
|
||||
gint (*get_num_list) (Folder *folder,
|
||||
gint (*get_num_list) (Folder *folder,
|
||||
FolderItem *item,
|
||||
GSList **list,
|
||||
gboolean *old_uids_valid);
|
||||
|
@ -244,27 +242,6 @@ struct _FolderClass
|
|||
MsgPermFlags newflags);
|
||||
};
|
||||
|
||||
struct _LocalFolder
|
||||
{
|
||||
Folder folder;
|
||||
|
||||
gchar *rootpath;
|
||||
};
|
||||
|
||||
struct _RemoteFolder
|
||||
{
|
||||
Folder folder;
|
||||
|
||||
Session *session;
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct _MaildirFolder
|
||||
{
|
||||
LocalFolder lfolder;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct _FolderItem
|
||||
{
|
||||
SpecialFolderItemType stype;
|
||||
|
@ -316,7 +293,8 @@ struct _FolderItem
|
|||
FolderItemPrefs * prefs;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct _PersistPrefs
|
||||
{
|
||||
FolderSortKey sort_key;
|
||||
FolderSortType sort_type;
|
||||
guint collapsed : 1;
|
||||
|
@ -324,7 +302,7 @@ typedef struct {
|
|||
guint threaded : 1;
|
||||
guint hide_read_msgs : 1; /* CLAWS */
|
||||
guint ret_rcpt : 1; /* CLAWS */
|
||||
} PersistPrefs;
|
||||
};
|
||||
|
||||
struct _FolderUpdateData
|
||||
{
|
||||
|
@ -344,16 +322,14 @@ void folder_register_class (FolderClass *klass);
|
|||
Folder *folder_new (FolderClass *type,
|
||||
const gchar *name,
|
||||
const gchar *path);
|
||||
void folder_local_folder_init (Folder *folder,
|
||||
const gchar *name,
|
||||
const gchar *path);
|
||||
void folder_remote_folder_init (Folder *folder,
|
||||
const gchar *name,
|
||||
const gchar *path);
|
||||
void folder_init (Folder *folder,
|
||||
const gchar *name);
|
||||
|
||||
void folder_destroy (Folder *folder);
|
||||
void folder_local_folder_destroy (LocalFolder *lfolder);
|
||||
void folder_remote_folder_destroy(RemoteFolder *rfolder);
|
||||
|
||||
void folder_set_xml (Folder *folder,
|
||||
XMLTag *tag);
|
||||
XMLTag *folder_get_xml (Folder *folder);
|
||||
|
||||
FolderItem *folder_item_new (Folder *folder,
|
||||
const gchar *name,
|
||||
|
@ -364,6 +340,12 @@ void folder_item_remove (FolderItem *item);
|
|||
void folder_item_remove_children (FolderItem *item);
|
||||
void folder_item_destroy (FolderItem *item);
|
||||
|
||||
void folder_item_set_xml (Folder *folder,
|
||||
FolderItem *item,
|
||||
XMLTag *tag);
|
||||
XMLTag *folder_item_get_xml (Folder *folder,
|
||||
FolderItem *item);
|
||||
|
||||
void folder_set_ui_func (Folder *folder,
|
||||
FolderUIFunc func,
|
||||
gpointer data);
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "utils.h"
|
||||
#include "prefs_gtk.h"
|
||||
#include "filtering.h"
|
||||
#include "prefs_scoring.h"
|
||||
#include "folder_item_prefs.h"
|
||||
|
||||
FolderItemPrefs tmp_prefs;
|
||||
|
@ -53,10 +52,12 @@ static PrefParam param[] = {
|
|||
NULL, NULL, NULL},
|
||||
/*{"enable_thread", "TRUE", &tmp_prefs.enable_thread, P_BOOL,
|
||||
NULL, NULL, NULL},*/
|
||||
#if 0
|
||||
{"hide_score", "-9999", &tmp_prefs.kill_score, P_INT,
|
||||
NULL, NULL, NULL},
|
||||
{"important_score", "1", &tmp_prefs.important_score, P_INT,
|
||||
NULL, NULL, NULL},
|
||||
#endif
|
||||
/* MIGRATION */
|
||||
{"request_return_receipt", "", &tmp_prefs.request_return_receipt, P_BOOL,
|
||||
NULL, NULL, NULL},
|
||||
|
@ -90,6 +91,10 @@ static PrefParam param[] = {
|
|||
NULL, NULL, NULL},
|
||||
{"folder_color", "", &tmp_prefs.color, P_INT,
|
||||
NULL, NULL, NULL},
|
||||
{"enable_processing", "FALSE", &tmp_prefs.enable_processing, P_BOOL,
|
||||
NULL, NULL, NULL},
|
||||
{"newmailcheck", "TRUE", &tmp_prefs.newmailcheck, P_BOOL,
|
||||
NULL, NULL, NULL},
|
||||
{NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -162,8 +167,6 @@ static FolderItemPrefs *folder_item_prefs_clear(FolderItemPrefs *prefs)
|
|||
prefs->sort_by_subject = FALSE;
|
||||
prefs->sort_by_score = FALSE;
|
||||
prefs->sort_descending = FALSE;
|
||||
prefs->kill_score = -9999;
|
||||
prefs->important_score = 9999;
|
||||
|
||||
prefs->request_return_receipt = FALSE;
|
||||
prefs->enable_default_to = FALSE;
|
||||
|
@ -183,8 +186,11 @@ static FolderItemPrefs *folder_item_prefs_clear(FolderItemPrefs *prefs)
|
|||
prefs->save_copy_to_folder = FALSE;
|
||||
prefs->color = 0;
|
||||
|
||||
prefs->scoring = NULL;
|
||||
prefs->enable_processing = TRUE;
|
||||
prefs->processing = NULL;
|
||||
|
||||
prefs->newmailcheck = TRUE;
|
||||
|
||||
return prefs;
|
||||
}
|
||||
|
||||
|
@ -203,8 +209,6 @@ void folder_item_prefs_free(FolderItemPrefs * prefs)
|
|||
g_free(prefs->default_to);
|
||||
if (prefs->default_reply_to)
|
||||
g_free(prefs->default_reply_to);
|
||||
if (prefs->scoring != NULL)
|
||||
prefs_scoring_free(prefs->scoring);
|
||||
g_free(prefs);
|
||||
}
|
||||
|
||||
|
@ -239,18 +243,10 @@ void folder_item_prefs_copy_prefs(FolderItem * src, FolderItem * dest)
|
|||
tmp_prefs.sort_by_score = src->prefs->sort_by_score;
|
||||
tmp_prefs.sort_descending = src->prefs->sort_descending;
|
||||
tmp_prefs.enable_thread = src->prefs->enable_thread;
|
||||
tmp_prefs.kill_score = src->prefs->kill_score;
|
||||
tmp_prefs.important_score = src->prefs->important_score;
|
||||
tmp_prefs.enable_processing = src->prefs->enable_processing;
|
||||
tmp_prefs.newmailcheck = src->prefs->newmailcheck;
|
||||
|
||||
prefs_matcher_read_config();
|
||||
for (tmp = src->prefs->scoring; tmp != NULL && tmp->data != NULL;) {
|
||||
ScoringProp *prop = (ScoringProp *)tmp->data;
|
||||
|
||||
tmp_scor_list = g_slist_append(tmp_scor_list,
|
||||
scoringprop_copy(prop));
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp_prefs.scoring = tmp_scor_list;
|
||||
|
||||
for (tmp = src->prefs->processing; tmp != NULL && tmp->data != NULL;) {
|
||||
FilteringProp *prop = (FilteringProp *)tmp->data;
|
||||
|
|
|
@ -41,12 +41,11 @@ struct _FolderItemPrefs {
|
|||
|
||||
gboolean enable_thread;
|
||||
|
||||
gint kill_score;
|
||||
gint important_score;
|
||||
|
||||
GSList * scoring;
|
||||
int enable_processing;
|
||||
GSList * processing;
|
||||
|
||||
int newmailcheck;
|
||||
|
||||
gboolean request_return_receipt;
|
||||
gboolean enable_default_to;
|
||||
gchar *default_to;
|
||||
|
|
131
src/folderview.c
131
src/folderview.c
|
@ -55,7 +55,6 @@
|
|||
#include "prefs_common.h"
|
||||
#include "prefs_account.h"
|
||||
#include "prefs_filtering.h"
|
||||
#include "prefs_scoring.h"
|
||||
#include "prefs_folder_item.h"
|
||||
#include "account.h"
|
||||
#include "folder.h"
|
||||
|
@ -191,15 +190,19 @@ static void mark_all_read_cb (FolderView *folderview,
|
|||
static void folderview_new_folder_cb (FolderView *folderview,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
#if 0
|
||||
static void folderview_new_mbox_folder_cb(FolderView *folderview,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
#endif
|
||||
static void folderview_rename_folder_cb (FolderView *folderview,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
#if 0
|
||||
static void folderview_rename_mbox_folder_cb(FolderView *folderview,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
#endif
|
||||
static void folderview_delete_folder_cb (FolderView *folderview,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
|
@ -269,14 +272,13 @@ gboolean folderview_update_folder (gpointer source,
|
|||
gboolean folderview_update_item (gpointer source,
|
||||
gpointer data);
|
||||
|
||||
static void folderview_scoring_cb(FolderView *folderview, guint action,
|
||||
GtkWidget *widget);
|
||||
static void folderview_processing_cb(FolderView *folderview, guint action,
|
||||
GtkWidget *widget);
|
||||
static void folderview_move_to(FolderView *folderview, FolderItem *from_folder,
|
||||
FolderItem *to_folder);
|
||||
static void folderview_move_to_cb(FolderView *folderview);
|
||||
|
||||
#if 0
|
||||
static GtkItemFactoryEntry folderview_mbox_popup_entries[] =
|
||||
{
|
||||
{N_("/Create _new folder..."), NULL, folderview_new_mbox_folder_cb, 0, NULL},
|
||||
|
@ -290,6 +292,7 @@ static GtkItemFactoryEntry folderview_mbox_popup_entries[] =
|
|||
{N_("/_Processing..."), NULL, folderview_processing_cb, 0, NULL},
|
||||
{N_("/_Scoring..."), NULL, folderview_scoring_cb, 0, NULL}
|
||||
};
|
||||
#endif
|
||||
|
||||
static GtkItemFactoryEntry folderview_mail_popup_entries[] =
|
||||
{
|
||||
|
@ -309,7 +312,6 @@ static GtkItemFactoryEntry folderview_mail_popup_entries[] =
|
|||
{N_("/_Search folder..."), NULL, folderview_search_cb, 0, NULL},
|
||||
{N_("/_Properties..."), NULL, folderview_property_cb, 0, NULL},
|
||||
{N_("/_Processing..."), NULL, folderview_processing_cb, 0, NULL},
|
||||
{N_("/S_coring..."), NULL, folderview_scoring_cb, 0, NULL}
|
||||
};
|
||||
|
||||
static GtkItemFactoryEntry folderview_imap_popup_entries[] =
|
||||
|
@ -330,7 +332,6 @@ static GtkItemFactoryEntry folderview_imap_popup_entries[] =
|
|||
{N_("/_Search folder..."), NULL, folderview_search_cb, 0, NULL},
|
||||
{N_("/_Properties..."), NULL, folderview_property_cb, 0, NULL},
|
||||
{N_("/_Processing..."), NULL, folderview_processing_cb, 0, NULL},
|
||||
{N_("/S_coring..."), NULL, folderview_scoring_cb, 0, NULL}
|
||||
};
|
||||
|
||||
static GtkItemFactoryEntry folderview_news_popup_entries[] =
|
||||
|
@ -349,7 +350,6 @@ static GtkItemFactoryEntry folderview_news_popup_entries[] =
|
|||
{N_("/_Search folder..."), NULL, folderview_search_cb, 0, NULL},
|
||||
{N_("/_Properties..."), NULL, folderview_property_cb, 0, NULL},
|
||||
{N_("/_Processing..."), NULL, folderview_processing_cb, 0, NULL},
|
||||
{N_("/S_coring..."), NULL, folderview_scoring_cb, 0, NULL}
|
||||
};
|
||||
|
||||
GtkTargetEntry folderview_drag_types[] =
|
||||
|
@ -366,11 +366,15 @@ FolderView *folderview_create(void)
|
|||
GtkWidget *mail_popup;
|
||||
GtkWidget *news_popup;
|
||||
GtkWidget *imap_popup;
|
||||
#if 0
|
||||
GtkWidget *mbox_popup;
|
||||
#endif
|
||||
GtkItemFactory *mail_factory;
|
||||
GtkItemFactory *news_factory;
|
||||
GtkItemFactory *imap_factory;
|
||||
#if 0
|
||||
GtkItemFactory *mbox_factory;
|
||||
#endif
|
||||
gint n_entries;
|
||||
gint i;
|
||||
|
||||
|
@ -441,12 +445,14 @@ FolderView *folderview_create(void)
|
|||
n_entries,
|
||||
"<NewsFolder>", &news_factory,
|
||||
folderview);
|
||||
#if 0
|
||||
n_entries = sizeof(folderview_mbox_popup_entries) /
|
||||
sizeof(folderview_mbox_popup_entries[0]);
|
||||
mbox_popup = menu_create_items(folderview_mbox_popup_entries,
|
||||
n_entries,
|
||||
"<MboxFolder>", &mbox_factory,
|
||||
folderview);
|
||||
#endif
|
||||
|
||||
g_signal_connect(G_OBJECT(ctree), "key_press_event",
|
||||
G_CALLBACK(folderview_key_pressed),
|
||||
|
@ -485,9 +491,11 @@ FolderView *folderview_create(void)
|
|||
g_signal_connect(G_OBJECT(news_popup), "selection_done",
|
||||
G_CALLBACK(folderview_popup_close),
|
||||
folderview);
|
||||
#if 0
|
||||
g_signal_connect(G_OBJECT(mbox_popup), "selection_done",
|
||||
G_CALLBACK(folderview_popup_close),
|
||||
folderview);
|
||||
#endif
|
||||
|
||||
/* drop callback */
|
||||
gtk_drag_dest_set(ctree, GTK_DEST_DEFAULT_ALL & ~GTK_DEST_DEFAULT_HIGHLIGHT,
|
||||
|
@ -514,8 +522,10 @@ FolderView *folderview_create(void)
|
|||
folderview->imap_factory = imap_factory;
|
||||
folderview->news_popup = news_popup;
|
||||
folderview->news_factory = news_factory;
|
||||
#if 0
|
||||
folderview->mbox_popup = mbox_popup;
|
||||
folderview->mbox_factory = mbox_factory;
|
||||
#endif
|
||||
|
||||
folderview->folder_update_callback_id =
|
||||
hooks_register_hook(FOLDER_UPDATE_HOOKLIST, folderview_update_folder, (gpointer) folderview);
|
||||
|
@ -532,6 +542,8 @@ FolderView *folderview_create(void)
|
|||
|
||||
void folderview_init(FolderView *folderview)
|
||||
{
|
||||
static GdkFont *boldfont = NULL;
|
||||
static GdkFont *normalfont = NULL;
|
||||
GtkWidget *ctree = folderview->ctree;
|
||||
GtkWidget *label_new;
|
||||
GtkWidget *label_unread;
|
||||
|
@ -585,46 +597,6 @@ void folderview_init(FolderView *folderview)
|
|||
gtk_clist_set_column_widget(GTK_CLIST(ctree),COL_NEW,hbox_new);
|
||||
gtk_clist_set_column_widget(GTK_CLIST(ctree),COL_UNREAD,hbox_unread);
|
||||
|
||||
#if 0
|
||||
if (!normalfont) {
|
||||
if (gtkut_font_load(NORMAL_FONT) == NULL) {
|
||||
GtkStyle *style = gtk_style_new();
|
||||
normalfont = style->font;
|
||||
gdk_font_ref(normalfont);
|
||||
gtk_style_unref(style);
|
||||
}
|
||||
else
|
||||
normalfont = gtkut_font_load(NORMAL_FONT);
|
||||
}
|
||||
|
||||
if (!boldfont) {
|
||||
if (gtkut_font_load(BOLD_FONT) == NULL) {
|
||||
GtkStyle *style = gtk_style_new();
|
||||
boldfont = style->font;
|
||||
gdk_font_ref(boldfont);
|
||||
gtk_style_unref(style);
|
||||
}
|
||||
else
|
||||
boldfont = gtkut_font_load(BOLD_FONT);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!bold_style) {
|
||||
PangoFontDescription *font_desc;
|
||||
bold_style = gtk_style_copy(gtk_widget_get_style(ctree));
|
||||
font_desc = pango_font_description_from_string(BOLD_FONT);
|
||||
if (font_desc) {
|
||||
if (bold_style->font_desc)
|
||||
pango_font_description_free
|
||||
(bold_style->font_desc);
|
||||
bold_style->font_desc = font_desc;
|
||||
}
|
||||
bold_color_style = gtk_style_copy(bold_style);
|
||||
bold_color_style->fg[GTK_STATE_NORMAL] = folderview->color_new;
|
||||
|
||||
bold_tgtfold_style = gtk_style_copy(bold_style);
|
||||
bold_tgtfold_style->fg[GTK_STATE_NORMAL] = folderview->color_op;
|
||||
}
|
||||
if (!normal_style) {
|
||||
PangoFontDescription *font_desc;
|
||||
normal_style = gtk_style_copy(gtk_widget_get_style(ctree));
|
||||
|
@ -638,6 +610,23 @@ void folderview_init(FolderView *folderview)
|
|||
normal_color_style = gtk_style_copy(normal_style);
|
||||
normal_color_style->fg[GTK_STATE_NORMAL] = folderview->color_new;
|
||||
}
|
||||
|
||||
if (!bold_style) {
|
||||
PangoFontDescription *font_desc;
|
||||
bold_style = gtk_style_copy(gtk_widget_get_style(ctree));
|
||||
font_desc = pango_font_description_from_string(prefs_common.boldfont);
|
||||
if (font_desc) {
|
||||
if (bold_style->font_desc)
|
||||
pango_font_description_free
|
||||
(bold_style->font_desc);
|
||||
bold_style->font_desc = font_desc;
|
||||
}
|
||||
bold_color_style = gtk_style_copy(bold_style);
|
||||
bold_color_style->fg[GTK_STATE_NORMAL] = folderview->color_new;
|
||||
|
||||
bold_tgtfold_style = gtk_style_copy(bold_style);
|
||||
bold_tgtfold_style->fg[GTK_STATE_NORMAL] = folderview->color_op;
|
||||
}
|
||||
}
|
||||
|
||||
void folderview_set(FolderView *folderview)
|
||||
|
@ -895,6 +884,7 @@ gint folderview_check_new(Folder *folder)
|
|||
if (item->no_select) continue;
|
||||
if (folder && folder != item->folder) continue;
|
||||
if (!folder && !FOLDER_IS_LOCAL(item->folder)) continue;
|
||||
if (!item->prefs->newmailcheck) continue;
|
||||
|
||||
folderview_scan_tree_func(item->folder, item, NULL);
|
||||
former_new = item->new_msgs;
|
||||
|
@ -1367,9 +1357,11 @@ void folderview_new_folder(FolderView *folderview)
|
|||
g_return_if_fail(item->folder != NULL);
|
||||
|
||||
switch (FOLDER_TYPE(item->folder)) {
|
||||
#if 0
|
||||
case F_MBOX:
|
||||
folderview_new_mbox_folder_cb(folderview, 0, NULL);
|
||||
break;
|
||||
#endif
|
||||
case F_MH:
|
||||
case F_MAILDIR:
|
||||
folderview_new_folder_cb(folderview, 0, NULL);
|
||||
|
@ -1397,9 +1389,11 @@ void folderview_rename_folder(FolderView *folderview)
|
|||
if (item->stype != F_NORMAL) return;
|
||||
|
||||
switch (FOLDER_TYPE(item->folder)) {
|
||||
#if 0
|
||||
case F_MBOX:
|
||||
folderview_rename_mbox_folder_cb(folderview, 0, NULL);
|
||||
break;
|
||||
#endif
|
||||
case F_MH:
|
||||
case F_MAILDIR:
|
||||
case F_IMAP:
|
||||
|
@ -1426,7 +1420,9 @@ void folderview_delete_folder(FolderView *folderview)
|
|||
|
||||
switch (FOLDER_TYPE(item->folder)) {
|
||||
case F_MH:
|
||||
#if 0
|
||||
case F_MBOX:
|
||||
#endif
|
||||
case F_MAILDIR:
|
||||
case F_IMAP:
|
||||
folderview_delete_folder_cb(folderview, 0, NULL);
|
||||
|
@ -1510,7 +1506,7 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
|
|||
} else
|
||||
mark_all_read = search_folder = folder_property = TRUE;
|
||||
|
||||
if (FOLDER_IS_LOCAL(folder) || FOLDER_TYPE(folder) == F_IMAP || FOLDER_TYPE(folder) == F_MBOX) {
|
||||
if (FOLDER_IS_LOCAL(folder) || FOLDER_TYPE(folder) == F_IMAP /* || FOLDER_TYPE(folder) == F_MBOX */) {
|
||||
if (item->parent == NULL)
|
||||
update_tree = rescan_tree = TRUE;
|
||||
else if (item->stype == F_NORMAL)
|
||||
|
@ -1577,6 +1573,7 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
|
|||
SET_SENS(news_factory, "/Properties...", folder_property);
|
||||
SET_SENS(news_factory, "/Processing...", folder_processing);
|
||||
SET_SENS(news_factory, "/Scoring...", folder_scoring);
|
||||
#if 0
|
||||
} else if (FOLDER_TYPE(folder) == F_MBOX) {
|
||||
popup = folderview->mbox_popup;
|
||||
menu_set_insensitive_all(GTK_MENU_SHELL(popup));
|
||||
|
@ -1587,6 +1584,7 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
|
|||
SET_SENS(news_factory, "/Properties...", folder_property);
|
||||
SET_SENS(mbox_factory, "/Processing...", folder_processing);
|
||||
SET_SENS(mbox_factory, "/Scoring...", folder_scoring);
|
||||
#endif
|
||||
} else
|
||||
return FALSE;
|
||||
|
||||
|
@ -1942,6 +1940,7 @@ static void folderview_new_folder_cb(FolderView *folderview, guint action,
|
|||
folder_write_list();
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void folderview_new_mbox_folder_cb(FolderView *folderview, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
|
@ -1975,6 +1974,7 @@ static void folderview_new_mbox_folder_cb(FolderView *folderview, guint action,
|
|||
|
||||
folder_write_list();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void folderview_rename_folder_cb(FolderView *folderview, guint action,
|
||||
GtkWidget *widget)
|
||||
|
@ -2059,6 +2059,7 @@ static void folderview_rename_folder_cb(FolderView *folderview, guint action,
|
|||
folder_write_list();
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void folderview_rename_mbox_folder_cb(FolderView *folderview,
|
||||
guint action,
|
||||
GtkWidget *widget)
|
||||
|
@ -2113,6 +2114,7 @@ static void folderview_rename_mbox_folder_cb(FolderView *folderview,
|
|||
|
||||
folder_write_list();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void folderview_delete_folder_cb(FolderView *folderview, guint action,
|
||||
GtkWidget *widget)
|
||||
|
@ -2360,8 +2362,8 @@ static void folderview_new_news_group_cb(FolderView *folderview, guint action,
|
|||
folderview->opened = NULL;
|
||||
}
|
||||
|
||||
folder_item_remove(item);
|
||||
gtk_ctree_remove_node(ctree, node);
|
||||
folder_item_remove(item);
|
||||
|
||||
gnode = next;
|
||||
}
|
||||
|
@ -2429,7 +2431,6 @@ static void folderview_rm_news_group_cb(FolderView *folderview, guint action,
|
|||
}
|
||||
|
||||
folder_item_remove(item);
|
||||
gtk_ctree_remove_node(ctree, folderview->selected);
|
||||
folder_write_list();
|
||||
|
||||
prefs_filtering_delete_path(name);
|
||||
|
@ -2525,18 +2526,6 @@ static void folderview_recollapse_nodes(FolderView *folderview, GtkCTreeNode *no
|
|||
g_slist_free(done);
|
||||
}
|
||||
|
||||
static void folderview_recollapse_all_nodes(FolderView *folderview)
|
||||
{
|
||||
GSList *list = folderview->nodes_to_recollapse;
|
||||
if (!list) return;
|
||||
for (; list != NULL; list = g_slist_next(list))
|
||||
if (list->data)
|
||||
gtk_ctree_collapse(GTK_CTREE(folderview->ctree),
|
||||
GTK_CTREE_NODE(list->data));
|
||||
g_slist_free(folderview->nodes_to_recollapse);
|
||||
folderview->nodes_to_recollapse = NULL;
|
||||
}
|
||||
|
||||
static void folderview_move_to_cb(FolderView *folderview)
|
||||
{
|
||||
FolderItem *from_folder = NULL, *to_folder = NULL;
|
||||
|
@ -2634,21 +2623,6 @@ static gint folderview_compare_name(gconstpointer a, gconstpointer b)
|
|||
return strcmp2(g_basename(item->path), name);
|
||||
}
|
||||
|
||||
static void folderview_scoring_cb(FolderView *folderview, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkCTree *ctree = GTK_CTREE(folderview->ctree);
|
||||
FolderItem *item;
|
||||
|
||||
if (!folderview->selected) return;
|
||||
|
||||
item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
|
||||
g_return_if_fail(item != NULL);
|
||||
g_return_if_fail(item->folder != NULL);
|
||||
|
||||
prefs_scoring_open(item);
|
||||
}
|
||||
|
||||
static void folderview_processing_cb(FolderView *folderview, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
|
@ -2661,7 +2635,8 @@ static void folderview_processing_cb(FolderView *folderview, guint action,
|
|||
g_return_if_fail(item != NULL);
|
||||
g_return_if_fail(item->folder != NULL);
|
||||
|
||||
prefs_filtering_open(item, NULL, NULL);
|
||||
prefs_filtering_open(&item->prefs->processing,
|
||||
_("Processing configuration"), NULL, NULL);
|
||||
}
|
||||
|
||||
void folderview_set_target_folder_color(gint color_op)
|
||||
|
@ -2829,7 +2804,9 @@ static gboolean folderview_drag_motion_cb(GtkWidget *widget,
|
|||
src_item && src_item != item) {
|
||||
switch (FOLDER_TYPE(item->folder)) {
|
||||
case F_MH:
|
||||
#if 0
|
||||
case F_MBOX:
|
||||
#endif
|
||||
case F_IMAP:
|
||||
acceptable = TRUE;
|
||||
break;
|
||||
|
|
|
@ -26,9 +26,9 @@ typedef struct _FolderView FolderView;
|
|||
#include <gtk/gtkwidget.h>
|
||||
#include <gtk/gtkctree.h>
|
||||
|
||||
#include "folder.h"
|
||||
#include "mainwindow.h"
|
||||
#include "summaryview.h"
|
||||
#include "folder.h"
|
||||
|
||||
struct _FolderView
|
||||
{
|
||||
|
@ -37,12 +37,16 @@ struct _FolderView
|
|||
GtkWidget *mail_popup;
|
||||
GtkWidget *imap_popup;
|
||||
GtkWidget *news_popup;
|
||||
#if 0
|
||||
GtkWidget *mbox_popup;
|
||||
#endif
|
||||
|
||||
GtkItemFactory *mail_factory;
|
||||
GtkItemFactory *imap_factory;
|
||||
GtkItemFactory *news_factory;
|
||||
#if 0
|
||||
GtkItemFactory *mbox_factory;
|
||||
#endif
|
||||
|
||||
GtkCTreeNode *selected;
|
||||
GtkCTreeNode *opened;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
|
||||
* Copyright (C) 1999-2002 Hiroyuki Yamamoto
|
||||
* 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
|
||||
|
@ -79,6 +79,9 @@ static gboolean grouplist_recv_func (SockInfo *sock,
|
|||
gint read_bytes,
|
||||
gpointer data);
|
||||
|
||||
static gint window_deleted (GtkWidget *widget,
|
||||
GdkEventAny *event,
|
||||
gpointer data);
|
||||
static void ok_clicked (GtkWidget *widget,
|
||||
gpointer data);
|
||||
static void cancel_clicked (GtkWidget *widget,
|
||||
|
@ -172,7 +175,7 @@ static void grouplist_dialog_create(void)
|
|||
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), _("Newsgroup subscription"));
|
||||
g_signal_connect(G_OBJECT(dialog), "delete_event",
|
||||
G_CALLBACK(cancel_clicked), NULL);
|
||||
G_CALLBACK(window_deleted), NULL);
|
||||
g_signal_connect(G_OBJECT(dialog), "key_press_event",
|
||||
G_CALLBACK(key_pressed), NULL);
|
||||
MANAGE_WINDOW_SIGNALS_CONNECT(dialog);
|
||||
|
@ -484,6 +487,15 @@ static gboolean grouplist_recv_func(SockInfo *sock, gint count, gint read_bytes,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gint window_deleted(GtkWidget *widget, GdkEventAny *event, gpointer data)
|
||||
{
|
||||
ack = FALSE;
|
||||
if (gtk_main_level() > 1)
|
||||
gtk_main_quit();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void ok_clicked(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
ack = TRUE;
|
||||
|
|
|
@ -10,16 +10,19 @@ libsylpheedgtk_la_SOURCES = \
|
|||
description_window.c \
|
||||
filesel.c \
|
||||
gtkaspell.c \
|
||||
gtkutils.c \
|
||||
gtksctree.c \
|
||||
gtkshruler.c \
|
||||
gtksctree.c \
|
||||
gtkutils.c \
|
||||
gtkvscrollbutton.c \
|
||||
logwindow.c \
|
||||
manage_window.c \
|
||||
menu.c \
|
||||
pluginwindow.c \
|
||||
prefswindow.c \
|
||||
progressdialog.c \
|
||||
sslcertwindow.c \
|
||||
sylpheed-marshal.c \
|
||||
gtkvscrollbutton.c
|
||||
sylpheed-marshal.c
|
||||
|
||||
sylpheedgtkincludedir = $(pkgincludedir)/gtk
|
||||
sylpheedgtkinclude_HEADERS = \
|
||||
|
@ -29,16 +32,20 @@ sylpheedgtkinclude_HEADERS = \
|
|||
description_window.h \
|
||||
filesel.h \
|
||||
gtkaspell.h \
|
||||
gtkutils.h \
|
||||
gtksctree.h \
|
||||
gtkshruler.h \
|
||||
gtksctree.h \
|
||||
gtkutils.h \
|
||||
gtkvscrollbutton.h \
|
||||
logwindow.h \
|
||||
manage_window.h \
|
||||
menu.h \
|
||||
pluginwindow.h \
|
||||
prefswindow.h \
|
||||
gtkvscrollbutton.h \
|
||||
progressdialog.h \
|
||||
sslcertwindow.h \
|
||||
sylpheed-marshal.h \
|
||||
gtkvscrollbutton.h
|
||||
sylpheed-marshal.h
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I../common \
|
||||
|
|
|
@ -323,8 +323,6 @@ guint colorlabel_get_color_menu_active_item(GtkWidget *menu)
|
|||
GtkWidget *menuitem;
|
||||
guint color;
|
||||
|
||||
g_return_val_if_fail
|
||||
(g_object_get_data(G_OBJECT(menu), "label_color_menu"), 0);
|
||||
menuitem = gtk_menu_get_active(GTK_MENU(menu));
|
||||
color = GPOINTER_TO_UINT
|
||||
(g_object_get_data(G_OBJECT(menuitem), "color"));
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <gtk/gtkwindow.h>
|
||||
#include <gtk/gtksignal.h>
|
||||
#include <gtk/gtkscrolledwindow.h>
|
||||
#include <gtk/gtktext.h>
|
||||
#include <gtk/gtktextview.h>
|
||||
#include <gtk/gtkstyle.h>
|
||||
|
||||
#include "intl.h"
|
||||
|
@ -39,7 +39,7 @@
|
|||
|
||||
static void hide_cb (GtkWidget *widget,
|
||||
LogWindow *logwin);
|
||||
static void key_pressed (GtkWidget *widget,
|
||||
static gboolean key_pressed (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
LogWindow *logwin);
|
||||
static gboolean log_window_append (gpointer source,
|
||||
|
@ -53,6 +53,8 @@ LogWindow *log_window_create(void)
|
|||
GtkWidget *window;
|
||||
GtkWidget *scrolledwin;
|
||||
GtkWidget *text;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
|
||||
debug_print("Creating log window...\n");
|
||||
logwin = g_new0(LogWindow, 1);
|
||||
|
@ -61,13 +63,13 @@ LogWindow *log_window_create(void)
|
|||
gtk_window_set_title(GTK_WINDOW(window), _("Protocol log"));
|
||||
gtk_window_set_wmclass(GTK_WINDOW(window), "log_window", "Sylpheed");
|
||||
gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
|
||||
gtk_widget_set_usize(window, 520, 400);
|
||||
gtk_signal_connect(GTK_OBJECT(window), "delete_event",
|
||||
GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
|
||||
GTK_SIGNAL_FUNC(key_pressed), logwin);
|
||||
gtk_signal_connect(GTK_OBJECT(window), "hide",
|
||||
GTK_SIGNAL_FUNC(hide_cb), logwin);
|
||||
gtk_widget_set_size_request(window, 520, 400);
|
||||
g_signal_connect(G_OBJECT(window), "delete_event",
|
||||
G_CALLBACK(gtk_widget_hide_on_delete), NULL);
|
||||
g_signal_connect(G_OBJECT(window), "key_press_event",
|
||||
G_CALLBACK(key_pressed), logwin);
|
||||
g_signal_connect(G_OBJECT(window), "hide",
|
||||
G_CALLBACK(hide_cb), logwin);
|
||||
gtk_widget_realize(window);
|
||||
|
||||
scrolledwin = gtk_scrolled_window_new(NULL, NULL);
|
||||
|
@ -76,13 +78,14 @@ LogWindow *log_window_create(void)
|
|||
gtk_container_add(GTK_CONTAINER(window), scrolledwin);
|
||||
gtk_widget_show(scrolledwin);
|
||||
|
||||
text = gtk_text_new(gtk_scrolled_window_get_hadjustment
|
||||
(GTK_SCROLLED_WINDOW(scrolledwin)),
|
||||
gtk_scrolled_window_get_vadjustment
|
||||
(GTK_SCROLLED_WINDOW(scrolledwin)));
|
||||
text = gtk_text_view_new();
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
|
||||
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
|
||||
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
|
||||
gtk_text_buffer_get_start_iter(buffer, &iter);
|
||||
gtk_text_buffer_create_mark(buffer, "end", &iter, FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(scrolledwin), text);
|
||||
gtk_widget_show(text);
|
||||
gtk_text_freeze(GTK_TEXT(text));
|
||||
|
||||
logwin->window = window;
|
||||
logwin->scrolledwin = scrolledwin;
|
||||
|
@ -94,6 +97,7 @@ LogWindow *log_window_create(void)
|
|||
|
||||
void log_window_init(LogWindow *logwin)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GdkColormap *colormap;
|
||||
GdkColor color[3] =
|
||||
{{0, 0, 0xafff, 0}, {0, 0xefff, 0, 0}, {0, 0xefff, 0, 0}};
|
||||
|
@ -120,17 +124,27 @@ void log_window_init(LogWindow *logwin)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(logwin->text));
|
||||
gtk_text_buffer_create_tag(buffer, "message",
|
||||
"foreground-gdk", &logwin->msg_color,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag(buffer, "warn",
|
||||
"foreground-gdk", &logwin->warn_color,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag(buffer, "error",
|
||||
"foreground-gdk", &logwin->error_color,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void log_window_show(LogWindow *logwin)
|
||||
{
|
||||
GtkText *text = GTK_TEXT(logwin->text);
|
||||
GtkTextView *text = GTK_TEXT_VIEW(logwin->text);
|
||||
GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
|
||||
GtkTextMark *mark;
|
||||
|
||||
gtk_widget_hide(logwin->window);
|
||||
|
||||
gtk_text_thaw(text);
|
||||
text->vadj->value = text->vadj->upper - text->vadj->page_size;
|
||||
gtk_signal_emit_by_name(GTK_OBJECT(text->vadj), "value_changed");
|
||||
mark = gtk_text_buffer_get_mark(buffer, "end");
|
||||
gtk_text_view_scroll_mark_onscreen(text, mark);
|
||||
|
||||
gtk_widget_show(logwin->window);
|
||||
}
|
||||
|
@ -147,9 +161,12 @@ static gboolean log_window_append(gpointer source, gpointer data)
|
|||
{
|
||||
LogText *logtext = (LogText *) source;
|
||||
LogWindow *logwindow = (LogWindow *) data;
|
||||
GtkText *text;
|
||||
GtkTextView *text;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
GdkColor *color = NULL;
|
||||
gchar *head = NULL;
|
||||
const gchar *tag;
|
||||
|
||||
g_return_val_if_fail(logtext != NULL, TRUE);
|
||||
g_return_val_if_fail(logtext->text != NULL, TRUE);
|
||||
|
@ -158,27 +175,40 @@ static gboolean log_window_append(gpointer source, gpointer data)
|
|||
if (logwindow->clip && !logwindow->clip_length)
|
||||
return FALSE;
|
||||
|
||||
text = GTK_TEXT(logwindow->text);
|
||||
text = GTK_TEXT_VIEW(logwindow->text);
|
||||
buffer = gtk_text_view_get_buffer(text);
|
||||
gtk_text_buffer_get_iter_at_offset(buffer, &iter, -1);
|
||||
|
||||
switch (logtext->type) {
|
||||
case LOG_MSG:
|
||||
color = &logwindow->msg_color;
|
||||
tag = "message";
|
||||
head = "* ";
|
||||
break;
|
||||
case LOG_WARN:
|
||||
color = &logwindow->warn_color;
|
||||
tag = "warn";
|
||||
head = "** ";
|
||||
break;
|
||||
case LOG_ERROR:
|
||||
color = &logwindow->error_color;
|
||||
tag = "error";
|
||||
head = "*** ";
|
||||
break;
|
||||
default:
|
||||
tag = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (head)
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, head, -1,
|
||||
tag, NULL);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, logtext->text, -1,
|
||||
tag, NULL);
|
||||
|
||||
gtk_text_buffer_get_start_iter(buffer, &iter);
|
||||
gtk_text_buffer_place_cursor(buffer, &iter);
|
||||
|
||||
if (head) gtk_text_insert(text, NULL, color, NULL, head, -1);
|
||||
gtk_text_insert(text, NULL, color, NULL, logtext->text, -1);
|
||||
if (logwindow->clip)
|
||||
log_window_clip (GTK_WIDGET (text), logwindow->clip_length);
|
||||
|
||||
|
@ -187,46 +217,35 @@ static gboolean log_window_append(gpointer source, gpointer data)
|
|||
|
||||
static void hide_cb(GtkWidget *widget, LogWindow *logwin)
|
||||
{
|
||||
if (GTK_TEXT(logwin->text)->freeze_count == 0)
|
||||
gtk_text_freeze(GTK_TEXT(logwin->text));
|
||||
}
|
||||
|
||||
static void key_pressed(GtkWidget *widget, GdkEventKey *event,
|
||||
static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
|
||||
LogWindow *logwin)
|
||||
{
|
||||
if (event && event->keyval == GDK_Escape)
|
||||
gtk_widget_hide(logwin->window);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void log_window_clip(GtkWidget *textw, guint clip_length)
|
||||
{
|
||||
guint length;
|
||||
guint point;
|
||||
gboolean was_frozen = FALSE;
|
||||
GtkText *text = GTK_TEXT(textw);
|
||||
GtkTextView *textview = GTK_TEXT_VIEW(textw);
|
||||
GtkTextBuffer *textbuf = gtk_text_view_get_buffer(textview);
|
||||
GtkTextIter start_iter, end_iter;
|
||||
|
||||
length = gtk_text_get_length (text);
|
||||
length = gtk_text_buffer_get_char_count (textbuf);
|
||||
debug_print("Log window length: %u\n", length);
|
||||
|
||||
if (length > clip_length) {
|
||||
/* find the end of the first line after the cut off
|
||||
* point */
|
||||
point = length - clip_length;
|
||||
while (point < length && GTK_TEXT_INDEX(text, point) != '\n')
|
||||
point++;
|
||||
/* erase the text */
|
||||
if (text->freeze_count) {
|
||||
was_frozen = TRUE;
|
||||
gtk_text_thaw(text);
|
||||
}
|
||||
gtk_text_set_point (text, 0);
|
||||
gtk_text_freeze(text);
|
||||
if (!gtk_text_forward_delete (text, point + 1))
|
||||
debug_print("Error clearing log\n");
|
||||
gtk_text_thaw(text);
|
||||
gtk_text_set_point(text,
|
||||
gtk_text_get_length (GTK_TEXT (text)));
|
||||
if (was_frozen)
|
||||
gtk_text_freeze(text);
|
||||
gtk_text_buffer_get_iter_at_offset(textbuf, &end_iter, point);
|
||||
if (!gtk_text_iter_forward_to_line_end(&end_iter))
|
||||
return;
|
||||
gtk_text_buffer_get_start_iter(textbuf, &start_iter);
|
||||
gtk_text_buffer_delete(textbuf, &start_iter, &end_iter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,6 @@ static gboolean ctree_select_row(GtkCTree *ctree, GList *node, gint column, gpoi
|
|||
|
||||
if (!page->page_open) {
|
||||
page->create_widget(page, GTK_WINDOW(prefswindow->window), prefswindow->data);
|
||||
gtk_widget_show_all(page->widget);
|
||||
gtk_container_add(GTK_CONTAINER(prefswindow->notebook), page->widget);
|
||||
page->page_open = TRUE;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ ProgressDialog *progress_dialog_create(void)
|
|||
debug_print("Creating progress dialog...\n");
|
||||
progress = g_new0(ProgressDialog, 1);
|
||||
|
||||
window = gtk_window_new(GTK_WINDOW_DIALOG);
|
||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_widget_set_usize(window, 460, -1);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(window), 8);
|
||||
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
|
||||
|
|
|
@ -46,8 +46,6 @@
|
|||
#include "gtkutils.h"
|
||||
#include "utils.h"
|
||||
|
||||
PangoFontDescription *boldfont;
|
||||
|
||||
#define TR(str) (prefs_common.trans_hdr ? gettext(str) : str)
|
||||
|
||||
#if 0
|
||||
|
@ -133,6 +131,8 @@ HeaderView *headerview_create(void)
|
|||
|
||||
void headerview_init(HeaderView *headerview)
|
||||
{
|
||||
static PangoFontDescription *boldfont = NULL;
|
||||
|
||||
if (!boldfont && BOLD_FONT)
|
||||
boldfont = pango_font_description_from_string
|
||||
(BOLD_FONT);
|
||||
|
|
54
src/html.c
54
src/html.c
|
@ -551,37 +551,39 @@ static HTMLTag *html_get_tag(const gchar *str)
|
|||
|
||||
while (isspace(*tmpp)) tmpp++;
|
||||
attr_name = tmpp;
|
||||
if ((p = strchr(attr_name, '=')) == NULL) {
|
||||
g_warning("html_get_tag(): syntax error in tag: '%s'\n", str);
|
||||
return tag;
|
||||
}
|
||||
tmpp = p;
|
||||
*tmpp++ = '\0';
|
||||
while (isspace(*tmpp)) tmpp++;
|
||||
|
||||
if (*tmpp == '\0') {
|
||||
g_warning("html_get_tag(): syntax error in tag: '%s'\n", str);
|
||||
return tag;
|
||||
} else if (*tmpp == '"' || *tmpp == '\'') {
|
||||
/* name="value" */
|
||||
quote = *tmpp;
|
||||
tmpp++;
|
||||
attr_value = tmpp;
|
||||
if ((p = strchr(attr_value, quote)) == NULL) {
|
||||
g_warning("html_get_tag(): syntax error in tag: '%s'\n", str);
|
||||
return tag;
|
||||
}
|
||||
tmpp = p;
|
||||
while (*tmpp != '\0' && !isspace(*tmpp) && *tmpp != '=') tmpp++;
|
||||
if (*tmpp != '\0' && *tmpp != '=') {
|
||||
*tmpp++ = '\0';
|
||||
while (isspace(*tmpp)) tmpp++;
|
||||
} else {
|
||||
/* name=value */
|
||||
attr_value = tmpp;
|
||||
while (*tmpp != '\0' && !isspace(*tmpp)) tmpp++;
|
||||
if (*tmpp != '\0')
|
||||
*tmpp++ = '\0';
|
||||
}
|
||||
|
||||
if (*tmpp == '=') {
|
||||
*tmpp++ = '\0';
|
||||
while (isspace(*tmpp)) tmpp++;
|
||||
|
||||
if (*tmpp == '"' || *tmpp == '\'') {
|
||||
/* name="value" */
|
||||
quote = *tmpp;
|
||||
tmpp++;
|
||||
attr_value = tmpp;
|
||||
if ((p = strchr(attr_value, quote)) == NULL) {
|
||||
g_warning("html_get_tag(): syntax error in tag: '%s'\n", str);
|
||||
return tag;
|
||||
}
|
||||
tmpp = p;
|
||||
*tmpp++ = '\0';
|
||||
while (isspace(*tmpp)) tmpp++;
|
||||
} else {
|
||||
/* name=value */
|
||||
attr_value = tmpp;
|
||||
while (*tmpp != '\0' && !isspace(*tmpp)) tmpp++;
|
||||
if (*tmpp != '\0')
|
||||
*tmpp++ = '\0';
|
||||
}
|
||||
} else
|
||||
attr_value = "";
|
||||
|
||||
g_strchomp(attr_name);
|
||||
g_strdown(attr_name);
|
||||
attr = g_new(HTMLAttr, 1);
|
||||
|
|
395
src/imap.c
395
src/imap.c
|
@ -52,8 +52,11 @@
|
|||
#include "md5.h"
|
||||
#include "base64.h"
|
||||
#include "utils.h"
|
||||
#include "prefs_common.h"
|
||||
#include "inputdialog.h"
|
||||
#include "log.h"
|
||||
#include "remotefolder.h"
|
||||
#include "alertpanel.h"
|
||||
|
||||
typedef struct _IMAPFolder IMAPFolder;
|
||||
typedef struct _IMAPSession IMAPSession;
|
||||
|
@ -63,6 +66,7 @@ typedef struct _IMAPFolderItem IMAPFolderItem;
|
|||
#include "prefs_account.h"
|
||||
|
||||
#define IMAP_FOLDER(obj) ((IMAPFolder *)obj)
|
||||
#define IMAP_FOLDER_ITEM(obj) ((IMAPFolderItem *)obj)
|
||||
#define IMAP_SESSION(obj) ((IMAPSession *)obj)
|
||||
|
||||
struct _IMAPFolder
|
||||
|
@ -158,51 +162,65 @@ struct _IMAPFolderItem
|
|||
GSList *uid_list;
|
||||
};
|
||||
|
||||
static Folder *imap_folder_new(const gchar * name, const gchar * path);
|
||||
static void imap_folder_destroy(Folder * folder);
|
||||
|
||||
static IMAPSession *imap_session_new(const PrefsAccount * account);
|
||||
static void imap_session_authenticate(IMAPSession * session,
|
||||
const PrefsAccount * account);
|
||||
static void imap_session_destroy(Session * session);
|
||||
|
||||
static gchar *imap_fetch_msg(Folder * folder, FolderItem * item, gint uid);
|
||||
static gint imap_add_msg(Folder * folder,
|
||||
FolderItem * dest,
|
||||
const gchar * file, MsgFlags * flags);
|
||||
static gint imap_add_msgs(Folder * folder, FolderItem * dest,
|
||||
GSList * file_list,
|
||||
GRelation *relation);
|
||||
|
||||
static gint imap_copy_msg(Folder * folder,
|
||||
FolderItem * dest, MsgInfo * msginfo);
|
||||
static gint imap_copy_msgs(Folder *folder, FolderItem *dest,
|
||||
MsgInfoList *msglist, GRelation *relation);
|
||||
|
||||
static gint imap_remove_msg(Folder * folder, FolderItem * item, gint uid);
|
||||
static gint imap_remove_all_msg(Folder * folder, FolderItem * item);
|
||||
|
||||
static gboolean imap_is_msg_changed(Folder * folder,
|
||||
FolderItem * item, MsgInfo * msginfo);
|
||||
|
||||
static gint imap_close(Folder * folder, FolderItem * item);
|
||||
|
||||
static void imap_scan_tree(Folder * folder);
|
||||
|
||||
static gint imap_create_tree(Folder * folder);
|
||||
|
||||
static FolderItem *imap_create_folder(Folder * folder,
|
||||
FolderItem * parent,
|
||||
const gchar * name);
|
||||
static gint imap_rename_folder(Folder * folder,
|
||||
FolderItem * item, const gchar * name);
|
||||
static gint imap_remove_folder(Folder * folder, FolderItem * item);
|
||||
|
||||
|
||||
static void imap_folder_init (Folder *folder,
|
||||
const gchar *name,
|
||||
const gchar *path);
|
||||
|
||||
static Folder *imap_folder_new (const gchar *name,
|
||||
const gchar *path);
|
||||
static void imap_folder_destroy (Folder *folder);
|
||||
|
||||
static IMAPSession *imap_session_new (const PrefsAccount *account);
|
||||
static void imap_session_authenticate(IMAPSession *session,
|
||||
const PrefsAccount *account);
|
||||
static void imap_session_destroy (Session *session);
|
||||
|
||||
static gchar *imap_fetch_msg (Folder *folder,
|
||||
FolderItem *item,
|
||||
gint uid);
|
||||
static gint imap_add_msg (Folder *folder,
|
||||
FolderItem *dest,
|
||||
const gchar *file,
|
||||
MsgFlags *flags);
|
||||
static gint imap_add_msgs (Folder *folder,
|
||||
FolderItem *dest,
|
||||
GSList *file_list,
|
||||
GRelation *relation);
|
||||
|
||||
static gint imap_copy_msg (Folder *folder,
|
||||
FolderItem *dest,
|
||||
MsgInfo *msginfo);
|
||||
static gint imap_copy_msgs (Folder *folder,
|
||||
FolderItem *dest,
|
||||
MsgInfoList *msglist,
|
||||
GRelation *relation);
|
||||
|
||||
static gint imap_remove_msg (Folder *folder,
|
||||
FolderItem *item,
|
||||
gint uid);
|
||||
static gint imap_remove_all_msg (Folder *folder,
|
||||
FolderItem *item);
|
||||
|
||||
static gboolean imap_is_msg_changed (Folder *folder,
|
||||
FolderItem *item,
|
||||
MsgInfo *msginfo);
|
||||
|
||||
static gint imap_close (Folder *folder,
|
||||
FolderItem *item);
|
||||
|
||||
static gint imap_scan_tree (Folder *folder);
|
||||
|
||||
static gint imap_create_tree (Folder *folder);
|
||||
|
||||
static FolderItem *imap_create_folder (Folder *folder,
|
||||
FolderItem *parent,
|
||||
const gchar *name);
|
||||
static gint imap_rename_folder (Folder *folder,
|
||||
FolderItem *item,
|
||||
const gchar *name);
|
||||
static gint imap_remove_folder (Folder *folder,
|
||||
FolderItem *item);
|
||||
|
||||
static FolderItem *imap_folder_item_new (Folder *folder);
|
||||
static void imap_folder_item_destroy (Folder *folder,
|
||||
FolderItem *item);
|
||||
|
@ -222,7 +240,7 @@ static GSList *imap_parse_list (IMAPFolder *folder,
|
|||
const gchar *real_path,
|
||||
gchar *separator);
|
||||
|
||||
static void imap_create_missing_folders (Folder *folder);
|
||||
static void imap_create_missing_folders (Folder *folder);
|
||||
static FolderItem *imap_create_special_folder
|
||||
(Folder *folder,
|
||||
SpecialFolderItemType stype,
|
||||
|
@ -311,32 +329,32 @@ static gint imap_cmd_authenticate
|
|||
const gchar *user,
|
||||
const gchar *pass,
|
||||
IMAPAuthType type);
|
||||
static gint imap_cmd_login (IMAPSession *sock,
|
||||
static gint imap_cmd_login (IMAPSession *session,
|
||||
const gchar *user,
|
||||
const gchar *pass);
|
||||
static gint imap_cmd_logout (IMAPSession *sock);
|
||||
static gint imap_cmd_noop (IMAPSession *sock);
|
||||
static gint imap_cmd_starttls (IMAPSession *sock);
|
||||
static gint imap_cmd_namespace (IMAPSession *sock,
|
||||
static gint imap_cmd_logout (IMAPSession *session);
|
||||
static gint imap_cmd_noop (IMAPSession *session);
|
||||
static gint imap_cmd_starttls (IMAPSession *session);
|
||||
static gint imap_cmd_namespace (IMAPSession *session,
|
||||
gchar **ns_str);
|
||||
static gint imap_cmd_list (IMAPSession *session,
|
||||
const gchar *ref,
|
||||
const gchar *mailbox,
|
||||
GPtrArray *argbuf);
|
||||
static gint imap_cmd_do_select (IMAPSession *sock,
|
||||
static gint imap_cmd_do_select (IMAPSession *session,
|
||||
const gchar *folder,
|
||||
gboolean examine,
|
||||
gint *exists,
|
||||
gint *recent,
|
||||
gint *unseen,
|
||||
guint32 *uid_validity);
|
||||
static gint imap_cmd_select (IMAPSession *sock,
|
||||
static gint imap_cmd_select (IMAPSession *session,
|
||||
const gchar *folder,
|
||||
gint *exists,
|
||||
gint *recent,
|
||||
gint *unseen,
|
||||
guint32 *uid_validity);
|
||||
static gint imap_cmd_examine (IMAPSession *sock,
|
||||
static gint imap_cmd_examine (IMAPSession *session,
|
||||
const gchar *folder,
|
||||
gint *exists,
|
||||
gint *recent,
|
||||
|
@ -347,9 +365,9 @@ static gint imap_cmd_create (IMAPSession *sock,
|
|||
static gint imap_cmd_rename (IMAPSession *sock,
|
||||
const gchar *oldfolder,
|
||||
const gchar *newfolder);
|
||||
static gint imap_cmd_delete (IMAPSession *sock,
|
||||
static gint imap_cmd_delete (IMAPSession *session,
|
||||
const gchar *folder);
|
||||
static gint imap_cmd_envelope (IMAPSession *sock,
|
||||
static gint imap_cmd_envelope (IMAPSession *session,
|
||||
IMAPSet set);
|
||||
static gint imap_cmd_fetch (IMAPSession *sock,
|
||||
guint32 uid,
|
||||
|
@ -363,17 +381,18 @@ static gint imap_cmd_copy (IMAPSession *session,
|
|||
const gchar *seq_set,
|
||||
const gchar *destfolder,
|
||||
GRelation *uid_mapping);
|
||||
static gint imap_cmd_store (IMAPSession *sock,
|
||||
static gint imap_cmd_store (IMAPSession *session,
|
||||
IMAPSet set,
|
||||
gchar *sub_cmd);
|
||||
static gint imap_cmd_expunge (IMAPSession *sock);
|
||||
static gint imap_cmd_close (IMAPSession *session);
|
||||
static gint imap_cmd_expunge (IMAPSession *session,
|
||||
IMAPSet seq_set);
|
||||
static gint imap_cmd_close (IMAPSession *session);
|
||||
|
||||
static gint imap_cmd_ok (IMAPSession *session,
|
||||
GPtrArray *argbuf);
|
||||
static void imap_gen_send (IMAPSession *sock,
|
||||
static void imap_gen_send (IMAPSession *session,
|
||||
const gchar *format, ...);
|
||||
static gint imap_gen_recv (IMAPSession *sock,
|
||||
static gint imap_gen_recv (IMAPSession *session,
|
||||
gchar **ret);
|
||||
|
||||
/* misc utility functions */
|
||||
|
@ -421,7 +440,7 @@ static gchar *imap_folder_get_path (Folder *folder);
|
|||
static gchar *imap_item_get_path (Folder *folder,
|
||||
FolderItem *item);
|
||||
|
||||
FolderClass imap_class =
|
||||
static FolderClass imap_class =
|
||||
{
|
||||
F_IMAP,
|
||||
"imap",
|
||||
|
@ -430,12 +449,16 @@ FolderClass imap_class =
|
|||
/* Folder functions */
|
||||
imap_folder_new,
|
||||
imap_folder_destroy,
|
||||
NULL,
|
||||
NULL,
|
||||
imap_scan_tree,
|
||||
imap_create_tree,
|
||||
|
||||
/* FolderItem functions */
|
||||
imap_folder_item_new,
|
||||
imap_folder_item_destroy,
|
||||
NULL,
|
||||
NULL,
|
||||
imap_item_get_path,
|
||||
imap_create_folder,
|
||||
imap_rename_folder,
|
||||
|
@ -466,7 +489,7 @@ FolderClass *imap_get_class(void)
|
|||
return &imap_class;
|
||||
}
|
||||
|
||||
Folder *imap_folder_new(const gchar *name, const gchar *path)
|
||||
static Folder *imap_folder_new(const gchar *name, const gchar *path)
|
||||
{
|
||||
Folder *folder;
|
||||
|
||||
|
@ -477,7 +500,7 @@ Folder *imap_folder_new(const gchar *name, const gchar *path)
|
|||
return folder;
|
||||
}
|
||||
|
||||
void imap_folder_destroy(Folder *folder)
|
||||
static void imap_folder_destroy(Folder *folder)
|
||||
{
|
||||
gchar *dir;
|
||||
|
||||
|
@ -595,6 +618,9 @@ static IMAPSession *imap_session_get(Folder *folder)
|
|||
g_return_val_if_fail(folder != NULL, NULL);
|
||||
g_return_val_if_fail(FOLDER_CLASS(folder) == &imap_class, NULL);
|
||||
g_return_val_if_fail(folder->account != NULL, NULL);
|
||||
|
||||
if (prefs_common.work_offline)
|
||||
return NULL;
|
||||
|
||||
/* Make sure we have a session */
|
||||
if (rfolder->session != NULL) {
|
||||
|
@ -666,7 +692,7 @@ static IMAPSession *imap_session_get(Folder *folder)
|
|||
return IMAP_SESSION(session);
|
||||
}
|
||||
|
||||
IMAPSession *imap_session_new(const PrefsAccount *account)
|
||||
static IMAPSession *imap_session_new(const PrefsAccount *account)
|
||||
{
|
||||
IMAPSession *session;
|
||||
SockInfo *imap_sock;
|
||||
|
@ -741,7 +767,8 @@ IMAPSession *imap_session_new(const PrefsAccount *account)
|
|||
session_destroy(SESSION(session));
|
||||
return NULL;
|
||||
}
|
||||
if (!ssl_init_socket_with_method(SESSION(session)->sock, SSL_METHOD_TLSv1)) {
|
||||
if (!ssl_init_socket_with_method(SESSION(session)->sock,
|
||||
SSL_METHOD_TLSv1)) {
|
||||
session_destroy(SESSION(session));
|
||||
return NULL;
|
||||
}
|
||||
|
@ -763,7 +790,8 @@ IMAPSession *imap_session_new(const PrefsAccount *account)
|
|||
return session;
|
||||
}
|
||||
|
||||
void imap_session_authenticate(IMAPSession *session, const PrefsAccount *account)
|
||||
static void imap_session_authenticate(IMAPSession *session,
|
||||
const PrefsAccount *account)
|
||||
{
|
||||
gchar *pass;
|
||||
|
||||
|
@ -787,7 +815,7 @@ void imap_session_authenticate(IMAPSession *session, const PrefsAccount *account
|
|||
session->authenticated = TRUE;
|
||||
}
|
||||
|
||||
void imap_session_destroy(Session *session)
|
||||
static void imap_session_destroy(Session *session)
|
||||
{
|
||||
imap_free_capabilities(IMAP_SESSION(session));
|
||||
g_free(IMAP_SESSION(session)->mbox);
|
||||
|
@ -795,7 +823,7 @@ void imap_session_destroy(Session *session)
|
|||
session->sock = NULL;
|
||||
}
|
||||
|
||||
gchar *imap_fetch_msg(Folder *folder, FolderItem *item, gint uid)
|
||||
static gchar *imap_fetch_msg(Folder *folder, FolderItem *item, gint uid)
|
||||
{
|
||||
gchar *path, *filename;
|
||||
IMAPSession *session;
|
||||
|
@ -809,7 +837,7 @@ gchar *imap_fetch_msg(Folder *folder, FolderItem *item, gint uid)
|
|||
make_dir_hier(path);
|
||||
filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(uid), NULL);
|
||||
g_free(path);
|
||||
|
||||
|
||||
if (is_file_exist(filename)) {
|
||||
debug_print("message %d has been already cached.\n", uid);
|
||||
return filename;
|
||||
|
@ -841,7 +869,8 @@ gchar *imap_fetch_msg(Folder *folder, FolderItem *item, gint uid)
|
|||
return filename;
|
||||
}
|
||||
|
||||
gint imap_add_msg(Folder *folder, FolderItem *dest, const gchar *file, MsgFlags *flags)
|
||||
static gint imap_add_msg(Folder *folder, FolderItem *dest,
|
||||
const gchar *file, MsgFlags *flags)
|
||||
{
|
||||
gint ret;
|
||||
GSList file_list;
|
||||
|
@ -859,7 +888,7 @@ gint imap_add_msg(Folder *folder, FolderItem *dest, const gchar *file, MsgFlags
|
|||
return ret;
|
||||
}
|
||||
|
||||
gint imap_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
|
||||
static gint imap_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
|
||||
GRelation *relation)
|
||||
{
|
||||
gchar *destdir;
|
||||
|
@ -976,7 +1005,7 @@ static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest,
|
|||
for (cur = msglist; cur != NULL; cur = g_slist_next(cur)) {
|
||||
MsgInfo *msginfo = (MsgInfo *)cur->data;
|
||||
GTuples *tuples;
|
||||
|
||||
|
||||
tuples = g_relation_select(uid_mapping,
|
||||
GINT_TO_POINTER(msginfo->msgnum),
|
||||
0);
|
||||
|
@ -991,7 +1020,8 @@ static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest,
|
|||
GPOINTER_TO_INT(0));
|
||||
g_tuples_destroy(tuples);
|
||||
}
|
||||
|
||||
|
||||
g_relation_destroy(uid_mapping);
|
||||
imap_seq_set_free(seq_list);
|
||||
|
||||
g_free(destdir);
|
||||
|
@ -1002,7 +1032,7 @@ static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest,
|
|||
return -1;
|
||||
}
|
||||
|
||||
gint imap_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
|
||||
static gint imap_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
|
||||
{
|
||||
GSList msglist;
|
||||
|
||||
|
@ -1014,7 +1044,7 @@ gint imap_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
|
|||
return imap_copy_msgs(folder, dest, &msglist, NULL);
|
||||
}
|
||||
|
||||
gint imap_copy_msgs(Folder *folder, FolderItem *dest,
|
||||
static gint imap_copy_msgs(Folder *folder, FolderItem *dest,
|
||||
MsgInfoList *msglist, GRelation *relation)
|
||||
{
|
||||
MsgInfo *msginfo;
|
||||
|
@ -1041,7 +1071,7 @@ gint imap_copy_msgs(Folder *folder, FolderItem *dest,
|
|||
return ret;
|
||||
}
|
||||
|
||||
gint imap_remove_msg(Folder *folder, FolderItem *item, gint uid)
|
||||
static gint imap_remove_msg(Folder *folder, FolderItem *item, gint uid)
|
||||
{
|
||||
gint ok;
|
||||
IMAPSession *session;
|
||||
|
@ -1071,12 +1101,22 @@ gint imap_remove_msg(Folder *folder, FolderItem *item, gint uid)
|
|||
return ok;
|
||||
}
|
||||
|
||||
ok = imap_cmd_expunge(session);
|
||||
if (!session->uidplus) {
|
||||
ok = imap_cmd_expunge(session, NULL);
|
||||
} else {
|
||||
gchar *uidstr;
|
||||
|
||||
uidstr = g_strdup_printf("%u", uid);
|
||||
ok = imap_cmd_expunge(session, uidstr);
|
||||
g_free(uidstr);
|
||||
}
|
||||
if (ok != IMAP_SUCCESS) {
|
||||
log_warning(_("can't expunge\n"));
|
||||
return ok;
|
||||
}
|
||||
|
||||
IMAP_FOLDER_ITEM(item)->uid_list = g_slist_remove(
|
||||
IMAP_FOLDER_ITEM(item)->uid_list, numlist.data);
|
||||
dir = folder_item_get_path(item);
|
||||
if (is_dir_exist(dir))
|
||||
remove_numbered_files(dir, uid, uid);
|
||||
|
@ -1085,7 +1125,7 @@ gint imap_remove_msg(Folder *folder, FolderItem *item, gint uid)
|
|||
return IMAP_SUCCESS;
|
||||
}
|
||||
|
||||
gint imap_remove_all_msg(Folder *folder, FolderItem *item)
|
||||
static gint imap_remove_all_msg(Folder *folder, FolderItem *item)
|
||||
{
|
||||
gint ok;
|
||||
IMAPSession *session;
|
||||
|
@ -1109,7 +1149,7 @@ gint imap_remove_all_msg(Folder *folder, FolderItem *item)
|
|||
return ok;
|
||||
}
|
||||
|
||||
ok = imap_cmd_expunge(session);
|
||||
ok = imap_cmd_expunge(session, NULL);
|
||||
if (ok != IMAP_SUCCESS) {
|
||||
log_warning(_("can't expunge\n"));
|
||||
return ok;
|
||||
|
@ -1123,13 +1163,14 @@ gint imap_remove_all_msg(Folder *folder, FolderItem *item)
|
|||
return IMAP_SUCCESS;
|
||||
}
|
||||
|
||||
gboolean imap_is_msg_changed(Folder *folder, FolderItem *item, MsgInfo *msginfo)
|
||||
static gboolean imap_is_msg_changed(Folder *folder, FolderItem *item,
|
||||
MsgInfo *msginfo)
|
||||
{
|
||||
/* TODO: properly implement this method */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint imap_close(Folder *folder, FolderItem *item)
|
||||
static gint imap_close(Folder *folder, FolderItem *item)
|
||||
{
|
||||
gint ok;
|
||||
IMAPSession *session;
|
||||
|
@ -1142,8 +1183,7 @@ gint imap_close(Folder *folder, FolderItem *item)
|
|||
if (!session) return -1;
|
||||
|
||||
if (session->mbox) {
|
||||
if (strcmp(item->path, session->mbox))
|
||||
return -1;
|
||||
if (strcmp2(session->mbox, item->path) != 0) return -1;
|
||||
|
||||
ok = imap_cmd_close(session);
|
||||
if (ok != IMAP_SUCCESS)
|
||||
|
@ -1158,14 +1198,14 @@ gint imap_close(Folder *folder, FolderItem *item)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void imap_scan_tree(Folder *folder)
|
||||
static gint imap_scan_tree(Folder *folder)
|
||||
{
|
||||
FolderItem *item = NULL;
|
||||
IMAPSession *session;
|
||||
gchar *root_folder = NULL;
|
||||
|
||||
g_return_if_fail(folder != NULL);
|
||||
g_return_if_fail(folder->account != NULL);
|
||||
g_return_val_if_fail(folder != NULL, -1);
|
||||
g_return_val_if_fail(folder->account != NULL, -1);
|
||||
|
||||
session = imap_session_get(folder);
|
||||
if (!session) {
|
||||
|
@ -1175,13 +1215,37 @@ void imap_scan_tree(Folder *folder)
|
|||
item->folder = folder;
|
||||
folder->node = item->node = g_node_new(item);
|
||||
}
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (folder->account->imap_dir && *folder->account->imap_dir) {
|
||||
Xstrdup_a(root_folder, folder->account->imap_dir, return);
|
||||
gchar *real_path;
|
||||
GPtrArray *argbuf;
|
||||
gint ok;
|
||||
|
||||
Xstrdup_a(root_folder, folder->account->imap_dir, return -1);
|
||||
extract_quote(root_folder, '"');
|
||||
subst_char(root_folder,
|
||||
imap_get_path_separator(IMAP_FOLDER(folder),
|
||||
root_folder),
|
||||
'/');
|
||||
strtailchomp(root_folder, '/');
|
||||
debug_print("IMAP root directory: %s\n", root_folder);
|
||||
real_path = imap_get_real_path
|
||||
(IMAP_FOLDER(folder), root_folder);
|
||||
debug_print("IMAP root directory: %s\n", real_path);
|
||||
|
||||
/* check if root directory exist */
|
||||
argbuf = g_ptr_array_new();
|
||||
ok = imap_cmd_list(session, NULL, real_path, argbuf);
|
||||
if (ok != IMAP_SUCCESS ||
|
||||
search_array_str(argbuf, "LIST ") == NULL) {
|
||||
log_warning(_("root folder %s does not exist\n"), real_path);
|
||||
g_ptr_array_free(argbuf, TRUE);
|
||||
g_free(real_path);
|
||||
return -1;
|
||||
}
|
||||
g_ptr_array_free(argbuf, TRUE);
|
||||
g_free(real_path);
|
||||
}
|
||||
|
||||
if (folder->node)
|
||||
|
@ -1196,6 +1260,8 @@ void imap_scan_tree(Folder *folder)
|
|||
|
||||
imap_scan_tree_recursive(session, FOLDER_ITEM(folder->node->data));
|
||||
imap_create_missing_folders(folder);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
|
||||
|
@ -1352,6 +1418,10 @@ static GSList *imap_parse_list(IMAPFolder *folder, IMAPSession *session,
|
|||
strretchomp(buf);
|
||||
if (buf[0] != '*' || buf[1] != ' ') {
|
||||
log_print("IMAP4< %s\n", buf);
|
||||
if (sscanf(buf, "%*d %16s", buf) < 1 ||
|
||||
strcmp(buf, "OK") != 0)
|
||||
log_warning(_("error occurred while getting LIST.\n"));
|
||||
|
||||
break;
|
||||
}
|
||||
debug_print("IMAP4< %s\n", buf);
|
||||
|
@ -1412,7 +1482,7 @@ static GSList *imap_parse_list(IMAPFolder *folder, IMAPSession *session,
|
|||
return item_list;
|
||||
}
|
||||
|
||||
gint imap_create_tree(Folder *folder)
|
||||
static gint imap_create_tree(Folder *folder)
|
||||
{
|
||||
g_return_val_if_fail(folder != NULL, -1);
|
||||
g_return_val_if_fail(folder->node != NULL, -1);
|
||||
|
@ -1525,7 +1595,7 @@ static gchar *imap_item_get_path(Folder *folder, FolderItem *item)
|
|||
return path;
|
||||
}
|
||||
|
||||
FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
|
||||
static FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
|
||||
const gchar *name)
|
||||
{
|
||||
gchar *dirpath, *imap_path;
|
||||
|
@ -1621,7 +1691,8 @@ FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
|
|||
return new_item;
|
||||
}
|
||||
|
||||
gint imap_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
|
||||
static gint imap_rename_folder(Folder *folder, FolderItem *item,
|
||||
const gchar *name)
|
||||
{
|
||||
gchar *dirpath;
|
||||
gchar *newpath;
|
||||
|
@ -1703,7 +1774,7 @@ gint imap_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
gint imap_remove_folder(Folder *folder, FolderItem *item)
|
||||
static gint imap_remove_folder(Folder *folder, FolderItem *item)
|
||||
{
|
||||
gint ok;
|
||||
IMAPSession *session;
|
||||
|
@ -2027,14 +2098,15 @@ static IMAPNameSpace *imap_find_namespace_from_list(GList *ns_list,
|
|||
|
||||
if (!path) path = "";
|
||||
|
||||
Xstrcat_a(tmp_path, path, "/", return NULL);
|
||||
|
||||
for (; ns_list != NULL; ns_list = ns_list->next) {
|
||||
IMAPNameSpace *tmp_ns = ns_list->data;
|
||||
|
||||
Xstrcat_a(tmp_path, path, "/", return namespace);
|
||||
Xstrdup_a(name, tmp_ns->name, return namespace);
|
||||
if (tmp_ns->separator && tmp_ns->separator != '/')
|
||||
if (tmp_ns->separator && tmp_ns->separator != '/') {
|
||||
subst_char(tmp_path, tmp_ns->separator, '/');
|
||||
subst_char(name, tmp_ns->separator, '/');
|
||||
}
|
||||
if (strncmp(tmp_path, name, strlen(name)) == 0)
|
||||
namespace = tmp_ns;
|
||||
}
|
||||
|
@ -2124,7 +2196,7 @@ static gchar *imap_parse_atom(SockInfo *sock, gchar *src,
|
|||
|
||||
cur_pos = strchr_cpy(cur_pos + 1, '}', buf, sizeof(buf));
|
||||
len = atoi(buf);
|
||||
g_return_val_if_fail(len > 0, cur_pos);
|
||||
g_return_val_if_fail(len >= 0, cur_pos);
|
||||
|
||||
g_string_truncate(str, 0);
|
||||
cur_pos = str->str;
|
||||
|
@ -2167,7 +2239,7 @@ static gchar *imap_get_header(SockInfo *sock, gchar *cur_pos, gchar **headers,
|
|||
|
||||
cur_pos = strchr_cpy(cur_pos + 1, '}', buf, sizeof(buf));
|
||||
len = atoi(buf);
|
||||
g_return_val_if_fail(len > 0, cur_pos);
|
||||
g_return_val_if_fail(len >= 0, cur_pos);
|
||||
|
||||
g_string_truncate(str, 0);
|
||||
cur_pos = str->str;
|
||||
|
@ -2426,24 +2498,22 @@ static gint imap_status(IMAPSession *session, IMAPFolder *folder,
|
|||
gchar *real_path;
|
||||
gchar *real_path_;
|
||||
gint ok;
|
||||
GPtrArray *argbuf;
|
||||
GPtrArray *argbuf = NULL;
|
||||
gchar *str;
|
||||
|
||||
*messages = *recent = *uid_next = *uid_validity = *unseen = 0;
|
||||
|
||||
if (path == NULL)
|
||||
return -1;
|
||||
|
||||
argbuf = g_ptr_array_new();
|
||||
if (messages && recent && uid_next && uid_validity && unseen) {
|
||||
*messages = *recent = *uid_next = *uid_validity = *unseen = 0;
|
||||
argbuf = g_ptr_array_new();
|
||||
}
|
||||
|
||||
real_path = imap_get_real_path(folder, path);
|
||||
QUOTE_IF_REQUIRED(real_path_, real_path);
|
||||
imap_gen_send(session, "STATUS %s "
|
||||
"(MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)",
|
||||
real_path_);
|
||||
"(MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)",
|
||||
real_path_);
|
||||
|
||||
ok = imap_cmd_ok(session, argbuf);
|
||||
if (ok != IMAP_SUCCESS) THROW(ok);
|
||||
if (ok != IMAP_SUCCESS || !argbuf) THROW(ok);
|
||||
|
||||
str = search_array_str(argbuf, "STATUS");
|
||||
if (!str) THROW(IMAP_ERROR);
|
||||
|
@ -2477,8 +2547,10 @@ static gint imap_status(IMAPSession *session, IMAPFolder *folder,
|
|||
|
||||
catch:
|
||||
g_free(real_path);
|
||||
ptr_array_free_strings(argbuf);
|
||||
g_ptr_array_free(argbuf, TRUE);
|
||||
if (argbuf) {
|
||||
ptr_array_free_strings(argbuf);
|
||||
g_ptr_array_free(argbuf, TRUE);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
@ -2497,7 +2569,7 @@ static gboolean imap_has_capability(IMAPSession *session, const gchar *cap)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void imap_free_capabilities(IMAPSession *session)
|
||||
static void imap_free_capabilities(IMAPSession *session)
|
||||
{
|
||||
g_strfreev(session->capability);
|
||||
session->capability = NULL;
|
||||
|
@ -2743,7 +2815,8 @@ static gint imap_cmd_delete(IMAPSession *session, const gchar *folder)
|
|||
return imap_cmd_ok(session, NULL);
|
||||
}
|
||||
|
||||
static gint imap_cmd_search(IMAPSession *session, const gchar *criteria, GSList **list)
|
||||
static gint imap_cmd_search(IMAPSession *session, const gchar *criteria,
|
||||
GSList **list)
|
||||
{
|
||||
gint ok;
|
||||
gchar *uidlist;
|
||||
|
@ -2782,7 +2855,8 @@ static gint imap_cmd_search(IMAPSession *session, const gchar *criteria, GSList
|
|||
return IMAP_SUCCESS;
|
||||
}
|
||||
|
||||
static gint imap_cmd_fetch(IMAPSession *session, guint32 uid, const gchar *filename)
|
||||
static gint imap_cmd_fetch(IMAPSession *session, guint32 uid,
|
||||
const gchar *filename)
|
||||
{
|
||||
gint ok;
|
||||
gchar *buf = NULL;
|
||||
|
@ -2818,7 +2892,7 @@ static gint imap_cmd_fetch(IMAPSession *session, guint32 uid, const gchar *filen
|
|||
cur_pos = strchr_cpy(cur_pos + 1, '}', size_str, sizeof(size_str));
|
||||
RETURN_ERROR_IF_FAIL(cur_pos != NULL);
|
||||
size_num = atol(size_str);
|
||||
RETURN_ERROR_IF_FAIL(size_num > 0);
|
||||
RETURN_ERROR_IF_FAIL(size_num >= 0);
|
||||
|
||||
RETURN_ERROR_IF_FAIL(*cur_pos == '\0');
|
||||
|
||||
|
@ -2826,7 +2900,8 @@ static gint imap_cmd_fetch(IMAPSession *session, guint32 uid, const gchar *filen
|
|||
|
||||
g_free(buf);
|
||||
|
||||
if (recv_bytes_write_to_file(SESSION(session)->sock, size_num, filename) != 0)
|
||||
if (recv_bytes_write_to_file(SESSION(session)->sock,
|
||||
size_num, filename) != 0)
|
||||
return IMAP_ERROR;
|
||||
|
||||
if (imap_gen_recv(session, &buf) != IMAP_SUCCESS) {
|
||||
|
@ -2846,7 +2921,8 @@ static gint imap_cmd_fetch(IMAPSession *session, guint32 uid, const gchar *filen
|
|||
}
|
||||
|
||||
static gint imap_cmd_append(IMAPSession *session, const gchar *destfolder,
|
||||
const gchar *file, IMAPFlags flags, guint32 *new_uid)
|
||||
const gchar *file, IMAPFlags flags,
|
||||
guint32 *new_uid)
|
||||
{
|
||||
gint ok;
|
||||
gint size;
|
||||
|
@ -2908,10 +2984,7 @@ static gint imap_cmd_append(IMAPSession *session, const gchar *destfolder,
|
|||
argbuf = g_ptr_array_new();
|
||||
|
||||
ok = imap_cmd_ok(session, argbuf);
|
||||
if (ok != IMAP_SUCCESS)
|
||||
log_warning(_("can't append message to %s\n"),
|
||||
destfolder_);
|
||||
else if (argbuf->len > 0) {
|
||||
if ((ok == IMAP_SUCCESS) && (argbuf->len > 0)) {
|
||||
resp_str = g_ptr_array_index(argbuf, argbuf->len - 1);
|
||||
if (resp_str &&
|
||||
sscanf(resp_str, "%*u OK [APPENDUID %*u %u]",
|
||||
|
@ -2925,15 +2998,41 @@ static gint imap_cmd_append(IMAPSession *session, const gchar *destfolder,
|
|||
} else
|
||||
ok = imap_cmd_ok(session, NULL);
|
||||
|
||||
if (ok != IMAP_SUCCESS)
|
||||
log_warning(_("can't append message to %s\n"),
|
||||
destfolder_);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static MsgNumberList *imapset_to_numlist(IMAPSet imapset)
|
||||
{
|
||||
gchar **ranges, **range;
|
||||
guint32 low, high;
|
||||
MsgNumberList *uids = NULL;
|
||||
|
||||
ranges = g_strsplit(imapset, ",", 0);
|
||||
for (range = ranges; *range != NULL; range++) {
|
||||
printf("%s\n", *range);
|
||||
if(sscanf(*range, "%u:%u", &low, &high) == 1)
|
||||
uids = g_slist_prepend(uids, GINT_TO_POINTER(low));
|
||||
else {
|
||||
int i;
|
||||
for (i = low; i <= high; i++)
|
||||
uids = g_slist_prepend(uids, GINT_TO_POINTER(i));
|
||||
}
|
||||
}
|
||||
uids = g_slist_reverse(uids);
|
||||
g_strfreev(ranges);
|
||||
|
||||
return uids;
|
||||
}
|
||||
|
||||
static gint imap_cmd_copy(IMAPSession *session, const gchar *seq_set,
|
||||
const gchar *destfolder, GRelation *uid_mapping)
|
||||
{
|
||||
gint ok;
|
||||
gchar *destfolder_;
|
||||
GPtrArray *reply;
|
||||
|
||||
g_return_val_if_fail(session != NULL, IMAP_ERROR);
|
||||
g_return_val_if_fail(seq_set != NULL, IMAP_ERROR);
|
||||
|
@ -2942,25 +3041,48 @@ static gint imap_cmd_copy(IMAPSession *session, const gchar *seq_set,
|
|||
QUOTE_IF_REQUIRED(destfolder_, destfolder);
|
||||
imap_gen_send(session, "UID COPY %s %s", seq_set, destfolder_);
|
||||
|
||||
reply = g_ptr_array_new();
|
||||
if (uid_mapping != NULL && session->uidplus) {
|
||||
GPtrArray *reply;
|
||||
gchar *resp_str = NULL, *olduids_str, *newuids_str;
|
||||
MsgNumberList *olduids, *old_cur, *newuids, *new_cur;
|
||||
|
||||
reply = g_ptr_array_new();
|
||||
ok = imap_cmd_ok(session, reply);
|
||||
if ((ok == IMAP_SUCCESS) && (reply->len > 0)) {
|
||||
resp_str = g_ptr_array_index(reply, reply->len - 1);
|
||||
if (resp_str) {
|
||||
olduids_str = g_new0(gchar, strlen(resp_str));
|
||||
newuids_str = g_new0(gchar, strlen(resp_str));
|
||||
if (sscanf(resp_str, "%*s OK [COPYUID %*u %[0-9,:] %[0-9,:]]",
|
||||
olduids_str, newuids_str) == 2) {
|
||||
olduids = imapset_to_numlist(olduids_str);
|
||||
newuids = imapset_to_numlist(newuids_str);
|
||||
|
||||
old_cur = olduids;
|
||||
new_cur = newuids;
|
||||
while(old_cur != NULL && new_cur != NULL) {
|
||||
g_relation_insert(uid_mapping,
|
||||
GPOINTER_TO_INT(old_cur->data),
|
||||
GPOINTER_TO_INT(new_cur->data));
|
||||
old_cur = g_slist_next(old_cur);
|
||||
new_cur = g_slist_next(new_cur);
|
||||
}
|
||||
|
||||
g_slist_free(olduids);
|
||||
g_slist_free(newuids);
|
||||
}
|
||||
g_free(olduids_str);
|
||||
g_free(newuids_str);
|
||||
}
|
||||
}
|
||||
ptr_array_free_strings(reply);
|
||||
g_ptr_array_free(reply, TRUE);
|
||||
} else
|
||||
ok = imap_cmd_ok(session, NULL);
|
||||
|
||||
ok = imap_cmd_ok(session, reply);
|
||||
if (ok != IMAP_SUCCESS)
|
||||
log_warning(_("can't copy %s to %s\n"), seq_set, destfolder_);
|
||||
/*
|
||||
TODO: UIDPLUS
|
||||
|
||||
- split IMAPSets into uids
|
||||
- g_relation_insert(uid_mapping, olduid, newuid);
|
||||
|
||||
else if (imap_has_capability(session, "UIDPLUS") && reply->len > 0)
|
||||
if ((okmsginfo = g_ptr_array_index(reply, reply->len - 1)) != NULL &&
|
||||
sscanf(okmsginfo, "%*u OK [COPYUID %*u %u %u]", &olduid, &newuid) == 2 &&
|
||||
olduid == msgnum)
|
||||
*new_uid = newuid;
|
||||
*/
|
||||
ptr_array_free_strings(reply);
|
||||
g_ptr_array_free(reply, TRUE);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -3017,11 +3139,14 @@ static gint imap_cmd_store(IMAPSession *session, IMAPSet seq_set,
|
|||
return IMAP_SUCCESS;
|
||||
}
|
||||
|
||||
static gint imap_cmd_expunge(IMAPSession *session)
|
||||
static gint imap_cmd_expunge(IMAPSession *session, IMAPSet seq_set)
|
||||
{
|
||||
gint ok;
|
||||
|
||||
imap_gen_send(session, "EXPUNGE");
|
||||
if (seq_set && session->uidplus)
|
||||
imap_gen_send(session, "UID EXPUNGE %s", seq_set);
|
||||
else
|
||||
imap_gen_send(session, "EXPUNGE");
|
||||
if ((ok = imap_cmd_ok(session, NULL)) != IMAP_SUCCESS) {
|
||||
log_warning(_("error while imap command: EXPUNGE\n"));
|
||||
return ok;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
typedef enum
|
||||
{
|
||||
IMAP_AUTH_LOGIN = 1 << 0,
|
||||
IMAP_AUTH_CRAM_MD5 = 1 << 1,
|
||||
IMAP_AUTH_CRAM_MD5 = 1 << 1
|
||||
} IMAPAuthType;
|
||||
|
||||
FolderClass *imap_get_class (void);
|
||||
|
|
51
src/inc.c
51
src/inc.c
|
@ -118,7 +118,6 @@ static gint inc_dialog_delete_cb (GtkWidget *widget,
|
|||
GdkEventAny *event,
|
||||
gpointer data);
|
||||
|
||||
static gint inc_spool (void);
|
||||
static gint get_spool (FolderItem *dest,
|
||||
const gchar *mbox);
|
||||
|
||||
|
@ -152,6 +151,8 @@ static void inc_finished(MainWindow *mainwin, gboolean new_messages)
|
|||
item = cur_account && cur_account->inbox
|
||||
? folder_find_item_from_identifier(cur_account->inbox)
|
||||
: folder_get_default_inbox();
|
||||
folderview_unselect(mainwin->folderview);
|
||||
folderview_select(mainwin->folderview, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,19 +180,7 @@ void inc_mail(MainWindow *mainwin, gboolean notify)
|
|||
inc_autocheck_timer_set();
|
||||
return;
|
||||
}
|
||||
|
||||
if (prefs_common.inc_local) {
|
||||
account_new_msgs = inc_spool();
|
||||
if (account_new_msgs > 0)
|
||||
new_msgs += account_new_msgs;
|
||||
}
|
||||
} else {
|
||||
if (prefs_common.inc_local) {
|
||||
account_new_msgs = inc_spool();
|
||||
if (account_new_msgs > 0)
|
||||
new_msgs += account_new_msgs;
|
||||
}
|
||||
|
||||
account_new_msgs = inc_account_mail(cur_account, mainwin);
|
||||
if (account_new_msgs > 0)
|
||||
new_msgs += account_new_msgs;
|
||||
|
@ -275,12 +264,6 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
|
|||
inc_autocheck_timer_remove();
|
||||
main_window_lock(mainwin);
|
||||
|
||||
if (prefs_common.inc_local) {
|
||||
account_new_msgs = inc_spool();
|
||||
if (account_new_msgs > 0)
|
||||
new_msgs += account_new_msgs;
|
||||
}
|
||||
|
||||
list = account_get_list();
|
||||
if (!list) {
|
||||
inc_finished(mainwin, new_msgs > 0);
|
||||
|
@ -1098,25 +1081,14 @@ static gint inc_dialog_delete_cb(GtkWidget *widget, GdkEventAny *event,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gint inc_spool(void)
|
||||
{
|
||||
gchar *mbox;
|
||||
const gchar *logname;
|
||||
gint msgs;
|
||||
|
||||
logname = g_get_user_name();
|
||||
mbox = g_strconcat(prefs_common.spool_path
|
||||
? prefs_common.spool_path : DEFAULT_SPOOL_PATH,
|
||||
G_DIR_SEPARATOR_S, logname, NULL);
|
||||
msgs = get_spool(folder_get_default_inbox(), mbox);
|
||||
g_free(mbox);
|
||||
|
||||
return msgs;
|
||||
}
|
||||
|
||||
static gint inc_spool_account(PrefsAccount *account)
|
||||
{
|
||||
FolderItem *inbox;
|
||||
gchar *mbox;
|
||||
const gchar *logname;
|
||||
gint result;
|
||||
|
||||
logname = g_get_user_name();
|
||||
|
||||
if (account->inbox) {
|
||||
inbox = folder_find_item_from_path(account->inbox);
|
||||
|
@ -1125,7 +1097,14 @@ static gint inc_spool_account(PrefsAccount *account)
|
|||
} else
|
||||
inbox = folder_get_default_inbox();
|
||||
|
||||
return get_spool(inbox, account->local_mbox);
|
||||
if (is_file_exist(account->local_mbox))
|
||||
mbox = g_strdup(account->local_mbox);
|
||||
else
|
||||
mbox = g_strconcat(account->local_mbox,
|
||||
G_DIR_SEPARATOR_S, logname, NULL);
|
||||
result = get_spool(inbox, mbox);
|
||||
g_free(mbox);
|
||||
return result;
|
||||
}
|
||||
|
||||
static gint inc_all_spool(void)
|
||||
|
|
49
src/jpilot.c
49
src/jpilot.c
|
@ -574,31 +574,6 @@ static void free_mem_rec_header(mem_rec_header **mem_rh) {
|
|||
*mem_rh = NULL;
|
||||
}
|
||||
|
||||
/* Shamelessly copied from JPilot (libplugin.c) */
|
||||
static int jpilot_free_db_list( GList **br_list ) {
|
||||
GList *temp_list, *first;
|
||||
buf_rec *br;
|
||||
|
||||
/* Go to first entry in the list */
|
||||
first=NULL;
|
||||
for( temp_list = *br_list; temp_list; temp_list = temp_list->prev ) {
|
||||
first = temp_list;
|
||||
}
|
||||
for (temp_list = first; temp_list; temp_list = temp_list->next) {
|
||||
if (temp_list->data) {
|
||||
br=temp_list->data;
|
||||
if (br->buf) {
|
||||
free(br->buf);
|
||||
temp_list->data=NULL;
|
||||
}
|
||||
free(br);
|
||||
}
|
||||
}
|
||||
g_list_free(*br_list);
|
||||
*br_list=NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Shamelessly copied from JPilot (libplugin.c) */
|
||||
/* Read file size */
|
||||
static int jpilot_get_info_size( FILE *in, int *size ) {
|
||||
|
@ -1658,30 +1633,6 @@ GList *jpilot_get_all_persons( JPilotFile *pilotFile ) {
|
|||
return addrcache_get_all_persons( pilotFile->addressCache );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check label list for specified label name.
|
||||
* \param ai Address info to check.
|
||||
* \param lblCheck Label name to check.
|
||||
* \return Index of label in address structure. <code>-1</code> if NULL/empty
|
||||
* label name, <code>-2</code> if label not found.
|
||||
*/
|
||||
static gint jpilot_check_label( struct AddressAppInfo *ai, gchar *lblCheck ) {
|
||||
gint i;
|
||||
gchar *lblName;
|
||||
|
||||
if( lblCheck == NULL ) return -1;
|
||||
if( strlen( lblCheck ) < 1 ) return -1;
|
||||
for( i = 0; i < JPILOT_NUM_LABELS; i++ ) {
|
||||
lblName = ai->labels[i];
|
||||
if( lblName ) {
|
||||
if( strlen( lblName ) ) {
|
||||
if( g_strcasecmp( lblName, lblCheck ) == 0 ) return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that all parameters specified.
|
||||
* \param pilotFile JPilot control data.
|
||||
|
|
|
@ -55,6 +55,7 @@ LdapControl *ldapctl_create( void ) {
|
|||
ctl->maxEntries = LDAPCTL_MAX_ENTRIES;
|
||||
ctl->timeOut = LDAPCTL_DFL_TIMEOUT;
|
||||
ctl->maxQueryAge = LDAPCTL_DFL_QUERY_AGE;
|
||||
ctl->matchingOption = LDAPCTL_MATCH_BEGINWITH;
|
||||
|
||||
/* Mutex to protect control block */
|
||||
ctl->mutexCtl = g_malloc0( sizeof( pthread_mutex_t ) );
|
||||
|
@ -162,6 +163,27 @@ void ldapctl_set_max_query_age( LdapControl* ctl, const gint value ) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify matching option to be used for searches.
|
||||
* \param ctl Control object to process.
|
||||
* \param value Matching option, as follows:
|
||||
* <ul>
|
||||
* <li><code>LDAPCTL_MATCH_BEGINWITH</code> for "begins with" search</li>
|
||||
* <li><code>LDAPCTL_MATCH_CONTAINS</code> for "contains" search</li>
|
||||
* </ul>
|
||||
*/
|
||||
void ldapctl_set_matching_option( LdapControl* ctl, const gint value ) {
|
||||
if( value < LDAPCTL_MATCH_BEGINWITH ) {
|
||||
ctl->matchingOption = LDAPCTL_MATCH_BEGINWITH;
|
||||
}
|
||||
else if( value > LDAPCTL_MATCH_CONTAINS ) {
|
||||
ctl->matchingOption = LDAPCTL_MATCH_BEGINWITH;
|
||||
}
|
||||
else {
|
||||
ctl->matchingOption = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify search criteria list to be used.
|
||||
* \param ctl Control data object.
|
||||
|
@ -259,6 +281,7 @@ void ldapctl_clear( LdapControl *ctl ) {
|
|||
ctl->maxEntries = 0;
|
||||
ctl->timeOut = 0;
|
||||
ctl->maxQueryAge = 0;
|
||||
ctl->matchingOption = LDAPCTL_MATCH_BEGINWITH;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -299,6 +322,7 @@ void ldapctl_default_values( LdapControl *ctl ) {
|
|||
ctl->maxEntries = LDAPCTL_MAX_ENTRIES;
|
||||
ctl->timeOut = LDAPCTL_DFL_TIMEOUT;
|
||||
ctl->maxQueryAge = LDAPCTL_DFL_QUERY_AGE;
|
||||
ctl->matchingOption = LDAPCTL_MATCH_BEGINWITH;
|
||||
|
||||
ldapctl_default_attributes( ctl );
|
||||
}
|
||||
|
@ -325,6 +349,7 @@ void ldapctl_print( const LdapControl *ctl, FILE *stream ) {
|
|||
fprintf( stream, "max entry: %d\n", ctl->maxEntries );
|
||||
fprintf( stream, " timeout: %d\n", ctl->timeOut );
|
||||
fprintf( stream, " max age: %d\n", ctl->maxQueryAge );
|
||||
fprintf( stream, "match opt: %d\n", ctl->matchingOption );
|
||||
fprintf( stream, "crit list:\n" );
|
||||
if( ctl->listCriteria ) {
|
||||
mgu_print_dlist( ctl->listCriteria, stream );
|
||||
|
@ -377,29 +402,56 @@ void ldapctl_copy( const LdapControl *ctlFrom, LdapControl *ctlTo ) {
|
|||
ctlTo->maxEntries = ctlFrom->maxEntries;
|
||||
ctlTo->timeOut = ctlFrom->timeOut;
|
||||
ctlTo->maxQueryAge = ctlFrom->maxQueryAge;
|
||||
ctlTo->matchingOption = ctlFrom->matchingOption;
|
||||
|
||||
/* Unlock */
|
||||
pthread_mutex_unlock( ctlTo->mutexCtl );
|
||||
pthread_mutex_unlock( ctlFrom->mutexCtl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Search criteria fragment - two terms - begin with (default).
|
||||
*/
|
||||
static gchar *_criteria2BeginWith = "(&(givenName=%s*)(sn=%s*))";
|
||||
|
||||
/**
|
||||
* Search criteria fragment - two terms - contains.
|
||||
*/
|
||||
static gchar *_criteria2Contains = "(&(givenName=*%s*)(sn=*%s*))";
|
||||
|
||||
/**
|
||||
* Create an LDAP search criteria by parsing specified search term. The search
|
||||
* term may contain two names separated by the first embedded space found in
|
||||
* the search term. It is assumed that the two tokens are first name and last
|
||||
* name, or vice versa. An appropriate search criteria will be constructed.
|
||||
*
|
||||
* \param searchTerm Reference to search term to process.
|
||||
* \param searchTerm Reference to search term to process.
|
||||
* \param matchOption Set to the following:
|
||||
* <ul>
|
||||
* <li><code>LDAPCTL_MATCH_BEGINWITH</code> for "begins with" search</li>
|
||||
* <li><code>LDAPCTL_MATCH_CONTAINS</code> for "contains" search</li>
|
||||
* </ul>
|
||||
*
|
||||
* \return Formatted search criteria, or <code>NULL</code> if there is no
|
||||
* embedded spaces. The search term should be g_free() when no
|
||||
* longer required.
|
||||
*/
|
||||
static gchar *ldapctl_build_ldap_criteria( gchar *searchTerm ) {
|
||||
static gchar *ldapctl_build_ldap_criteria(
|
||||
const gchar *searchTerm, const gint matchOption )
|
||||
{
|
||||
gchar *p;
|
||||
gchar *t1;
|
||||
gchar *t2 = NULL;
|
||||
gchar *term;
|
||||
gchar *crit = NULL;
|
||||
gchar *criteriaFmt;
|
||||
|
||||
if( matchOption == LDAPCTL_MATCH_CONTAINS ) {
|
||||
criteriaFmt = _criteria2Contains;
|
||||
}
|
||||
else {
|
||||
criteriaFmt = _criteria2BeginWith;
|
||||
}
|
||||
|
||||
term = g_strdup( searchTerm );
|
||||
g_strstrip( term );
|
||||
|
@ -420,8 +472,8 @@ static gchar *ldapctl_build_ldap_criteria( gchar *searchTerm ) {
|
|||
gchar *p1, *p2;
|
||||
|
||||
g_strstrip( t2 );
|
||||
p1 = g_strdup_printf( "(&(givenName=%s*)(sn=%s*))", t1, t2 );
|
||||
p2 = g_strdup_printf( "(&(givenName=%s*)(sn=%s*))", t2, t1 );
|
||||
p1 = g_strdup_printf( criteriaFmt, t1, t2 );
|
||||
p2 = g_strdup_printf( criteriaFmt, t2, t1 );
|
||||
crit = g_strdup_printf( "(&(|%s%s)(mail=*))", p1, p2 );
|
||||
|
||||
g_free( t2 );
|
||||
|
@ -432,6 +484,17 @@ static gchar *ldapctl_build_ldap_criteria( gchar *searchTerm ) {
|
|||
return crit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search criteria fragment - single term - begin with (default).
|
||||
*/
|
||||
static gchar *_criteriaBeginWith = "(%s=%s*)";
|
||||
|
||||
/**
|
||||
* Search criteria fragment - single term - contains.
|
||||
*/
|
||||
static gchar *_criteriaContains = "(%s=*%s*)";
|
||||
|
||||
/**
|
||||
* Build a formatted LDAP search criteria string from criteria list.
|
||||
* \param ctl Control object to process.
|
||||
|
@ -441,14 +504,22 @@ static gchar *ldapctl_build_ldap_criteria( gchar *searchTerm ) {
|
|||
gchar *ldapctl_format_criteria( LdapControl *ctl, const gchar *searchVal ) {
|
||||
GList *node;
|
||||
gchar *p1, *p2, *retVal;
|
||||
gchar *criteriaFmt;
|
||||
|
||||
g_return_val_if_fail( ctl != NULL, NULL );
|
||||
g_return_val_if_fail( searchVal != NULL, NULL );
|
||||
|
||||
/* Test whether there are more that one search terms */
|
||||
retVal = ldapctl_build_ldap_criteria( searchVal );
|
||||
retVal = ldapctl_build_ldap_criteria( searchVal, ctl->matchingOption );
|
||||
if( retVal ) return retVal;
|
||||
|
||||
if( ctl->matchingOption == LDAPCTL_MATCH_CONTAINS ) {
|
||||
criteriaFmt = _criteriaContains;
|
||||
}
|
||||
else {
|
||||
criteriaFmt = _criteriaBeginWith;
|
||||
}
|
||||
|
||||
/* No - just a simple search */
|
||||
/* p1 contains previous formatted criteria */
|
||||
/* p2 contains next formatted criteria */
|
||||
|
@ -468,7 +539,7 @@ gchar *ldapctl_format_criteria( LdapControl *ctl, const gchar *searchVal ) {
|
|||
gchar *crit;
|
||||
|
||||
/* Format query criteria */
|
||||
crit = g_strdup_printf( "(%s=%s*)", attr, searchVal );
|
||||
crit = g_strdup_printf( criteriaFmt, attr, searchVal );
|
||||
|
||||
/* Append to existing criteria */
|
||||
g_free( p2 );
|
||||
|
@ -478,7 +549,7 @@ gchar *ldapctl_format_criteria( LdapControl *ctl, const gchar *searchVal ) {
|
|||
}
|
||||
else {
|
||||
/* First time through - Format query criteria */
|
||||
p2 = g_strdup_printf( "(%s=%s*)", attr, searchVal );
|
||||
p2 = g_strdup_printf( criteriaFmt, attr, searchVal );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,12 @@
|
|||
|
||||
#define LDAPCTL_DFL_ATTR_LIST "mail, cn, givenName, sn"
|
||||
|
||||
/*
|
||||
* Search matching options.
|
||||
*/
|
||||
#define LDAPCTL_MATCH_BEGINWITH 0
|
||||
#define LDAPCTL_MATCH_CONTAINS 1
|
||||
|
||||
/*
|
||||
* Data structures.
|
||||
*/
|
||||
|
@ -59,6 +65,7 @@ struct _LdapControl {
|
|||
gint maxEntries;
|
||||
gint timeOut;
|
||||
gint maxQueryAge;
|
||||
gint matchingOption;
|
||||
gchar *attribEMail;
|
||||
gchar *attribCName;
|
||||
gchar *attribFName;
|
||||
|
@ -77,6 +84,7 @@ void ldapctl_set_bind_password ( LdapControl* ctl, const gchar *value );
|
|||
void ldapctl_set_max_entries ( LdapControl* ctl, const gint value );
|
||||
void ldapctl_set_timeout ( LdapControl* ctl, const gint value );
|
||||
void ldapctl_set_max_query_age ( LdapControl* ctl, const gint value );
|
||||
void ldapctl_set_matching_option( LdapControl* ctl, const gint value );
|
||||
void ldapctl_set_criteria_list ( LdapControl* ctl, GList *value );
|
||||
GList *ldapctl_get_criteria_list( const LdapControl* ctl );
|
||||
void ldapctl_criteria_list_clear( LdapControl *ctl );
|
||||
|
|
609
src/ldapquery.c
609
src/ldapquery.c
|
@ -30,7 +30,6 @@
|
|||
#include <glib.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
#include <ldap.h>
|
||||
#include <lber.h>
|
||||
|
||||
#include "ldapquery.h"
|
||||
|
@ -40,6 +39,8 @@
|
|||
#include "addritem.h"
|
||||
#include "addrcache.h"
|
||||
|
||||
#include "ldapquery.h"
|
||||
|
||||
/*
|
||||
* Key for thread specific data.
|
||||
*/
|
||||
|
@ -54,12 +55,15 @@ LdapQuery *ldapqry_create( void ) {
|
|||
LdapQuery *qry;
|
||||
|
||||
qry = g_new0( LdapQuery, 1 );
|
||||
ADDRQUERY_TYPE(qry) = ADDRQUERY_LDAP;
|
||||
ADDRQUERY_ID(qry) = 0;
|
||||
ADDRQUERY_SEARCHTYPE(qry) = ADDRSEARCH_NONE;
|
||||
ADDRQUERY_NAME(qry) = NULL;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_SUCCESS;
|
||||
ADDRQUERY_FOLDER(qry) = NULL;
|
||||
ADDRQUERY_SEARCHVALUE(qry) = NULL;
|
||||
qry->control = NULL;
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
qry->queryType = LDAPQUERY_NONE;
|
||||
qry->queryName = NULL;
|
||||
qry->searchValue = NULL;
|
||||
qry->queryID = 0;
|
||||
qry->server = NULL;
|
||||
qry->entriesRead = 0;
|
||||
qry->elapsedTime = 0;
|
||||
qry->stopFlag = FALSE;
|
||||
|
@ -67,11 +71,10 @@ LdapQuery *ldapqry_create( void ) {
|
|||
qry->agedFlag = FALSE;
|
||||
qry->completed = FALSE;
|
||||
qry->thread = NULL;
|
||||
qry->callBackStart = NULL;
|
||||
qry->callBackEntry = NULL;
|
||||
qry->callBackEnd = NULL;
|
||||
qry->folder = NULL;
|
||||
qry->server = NULL;
|
||||
qry->ldap = NULL;
|
||||
qry->data = NULL;
|
||||
|
||||
/* Mutex to protect stop and busy flags */
|
||||
qry->mutexStop = g_malloc0( sizeof( pthread_mutex_t ) );
|
||||
|
@ -103,8 +106,8 @@ void ldapqry_set_control( LdapQuery *qry, LdapControl *ctl ) {
|
|||
* \param value Name.
|
||||
*/
|
||||
void ldapqry_set_name( LdapQuery* qry, const gchar *value ) {
|
||||
qry->queryName = mgu_replace_string( qry->queryName, value );
|
||||
g_strstrip( qry->queryName );
|
||||
ADDRQUERY_NAME(qry) = mgu_replace_string( ADDRQUERY_NAME(qry), value );
|
||||
g_strstrip( ADDRQUERY_NAME(qry) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,8 +116,8 @@ void ldapqry_set_name( LdapQuery* qry, const gchar *value ) {
|
|||
* \param value
|
||||
*/
|
||||
void ldapqry_set_search_value( LdapQuery *qry, const gchar *value ) {
|
||||
qry->searchValue = mgu_replace_string( qry->searchValue, value );
|
||||
g_strstrip( qry->searchValue );
|
||||
ADDRQUERY_SEARCHVALUE(qry) = mgu_replace_string( ADDRQUERY_SEARCHVALUE(qry), value );
|
||||
g_strstrip( ADDRQUERY_SEARCHVALUE(qry) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,7 +126,7 @@ void ldapqry_set_search_value( LdapQuery *qry, const gchar *value ) {
|
|||
* \param value Status.
|
||||
*/
|
||||
void ldapqry_set_error_status( LdapQuery* qry, const gint value ) {
|
||||
qry->retVal = value;
|
||||
ADDRQUERY_RETVAL(qry) = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,8 +139,20 @@ void ldapqry_set_error_status( LdapQuery* qry, const gint value ) {
|
|||
* <li><code>LDAPQUERY_DYNAMIC</code></li>
|
||||
* </ul>
|
||||
*/
|
||||
/*
|
||||
void ldapqry_set_query_type( LdapQuery* qry, const gint value ) {
|
||||
qry->queryType = value;
|
||||
ADDRQUERY_TYPE(qry) = value;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Specify search type.
|
||||
* \param qry Query object.
|
||||
* \param value Type.
|
||||
*/
|
||||
void ldapqry_set_search_type( LdapQuery *qry, const AddrSearchType value ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
ADDRQUERY_SEARCHTYPE(qry) = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,7 +161,7 @@ void ldapqry_set_query_type( LdapQuery* qry, const gint value ) {
|
|||
* \param value ID for the query.
|
||||
*/
|
||||
void ldapqry_set_query_id( LdapQuery* qry, const gint value ) {
|
||||
qry->queryID = value;
|
||||
ADDRQUERY_ID(qry) = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,17 +178,6 @@ void ldapqry_set_entries_read( LdapQuery* qry, const gint value ) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback function that will be executed when the search
|
||||
* starts. When called, the function will be passed this query object
|
||||
* as an argument.
|
||||
* \param qry Query object.
|
||||
* \param func Function.
|
||||
*/
|
||||
void ldapqry_set_callback_start( LdapQuery *qry, void *func ) {
|
||||
qry->callBackStart = func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback function that will be executed when each entry
|
||||
* has been read and processed. When called, the function will be passed
|
||||
|
@ -299,6 +303,26 @@ gboolean ldapqry_get_aged_flag( LdapQuery *qry ) {
|
|||
return qry->agedFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify user data for query.
|
||||
* \param qry Query object.
|
||||
* \param value Data to set.
|
||||
*/
|
||||
void ldapqry_set_data( LdapQuery *qry, const gpointer value ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
qry->data = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve user data associated with query.
|
||||
* \param qry Query object.
|
||||
* \return Data.
|
||||
*/
|
||||
gpointer ldapqry_get_data( LdapQuery *qry ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
return qry->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the LDAP control data associated with the query.
|
||||
* \param qry Query object to process.
|
||||
|
@ -319,24 +343,25 @@ void ldapqry_clear( LdapQuery *qry ) {
|
|||
g_return_if_fail( qry != NULL );
|
||||
|
||||
/* Free internal stuff */
|
||||
g_free( qry->queryName );
|
||||
g_free( qry->searchValue );
|
||||
g_free( ADDRQUERY_NAME(qry) );
|
||||
g_free( ADDRQUERY_SEARCHVALUE(qry) );
|
||||
|
||||
/* Clear pointers and value */
|
||||
qry->queryName = NULL;
|
||||
qry->searchValue = NULL;
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
qry->queryType = LDAPQUERY_NONE;
|
||||
qry->queryID = 0;
|
||||
ADDRQUERY_NAME(qry) = NULL;
|
||||
ADDRQUERY_SEARCHVALUE(qry) = NULL;
|
||||
ADDRQUERY_ID(qry) = 0;
|
||||
ADDRQUERY_SEARCHTYPE(qry) = ADDRSEARCH_NONE;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_SUCCESS;
|
||||
qry->entriesRead = 0;
|
||||
qry->elapsedTime = 0;
|
||||
qry->stopFlag = FALSE;
|
||||
qry->busyFlag = FALSE;
|
||||
qry->agedFlag = FALSE;
|
||||
qry->completed = FALSE;
|
||||
qry->callBackStart = NULL;
|
||||
qry->callBackEntry = NULL;
|
||||
qry->callBackEnd = NULL;
|
||||
qry->ldap = NULL;
|
||||
qry->data = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -348,6 +373,7 @@ void ldapqry_free( LdapQuery *qry ) {
|
|||
g_return_if_fail( qry != NULL );
|
||||
|
||||
/* Clear out internal members */
|
||||
ADDRQUERY_TYPE(qry) = ADDRQUERY_NONE;
|
||||
ldapqry_clear( qry );
|
||||
|
||||
/* Free the mutex */
|
||||
|
@ -362,7 +388,7 @@ void ldapqry_free( LdapQuery *qry ) {
|
|||
qry->mutexStop = NULL;
|
||||
|
||||
/* Do not free folder - parent server object should free */
|
||||
qry->folder = NULL;
|
||||
ADDRQUERY_FOLDER(qry) = NULL;
|
||||
|
||||
/* Do not free thread - thread should be terminated before freeing */
|
||||
qry->thread = NULL;
|
||||
|
@ -384,11 +410,12 @@ void ldapqry_print( const LdapQuery *qry, FILE *stream ) {
|
|||
|
||||
fprintf( stream, "LdapQuery:\n" );
|
||||
fprintf( stream, " control?: %s\n", qry->control ? "yes" : "no" );
|
||||
fprintf( stream, "err/status: %d\n", qry->retVal );
|
||||
fprintf( stream, "query type: %d\n", qry->queryType );
|
||||
fprintf( stream, "query name: '%s'\n", qry->queryName );
|
||||
fprintf( stream, "search val: '%s'\n", qry->searchValue );
|
||||
fprintf( stream, " queryID: %d\n", qry->queryID );
|
||||
fprintf( stream, "err/status: %d\n", ADDRQUERY_RETVAL(qry) );
|
||||
fprintf( stream, "query type: %d\n", ADDRQUERY_TYPE(qry) );
|
||||
fprintf( stream, "searchType: %d\n", ADDRQUERY_SEARCHTYPE(qry) );
|
||||
fprintf( stream, "query name: '%s'\n", ADDRQUERY_NAME(qry) );
|
||||
fprintf( stream, "search val: '%s'\n", ADDRQUERY_SEARCHVALUE(qry) );
|
||||
fprintf( stream, " queryID: %d\n", ADDRQUERY_ID(qry) );
|
||||
fprintf( stream, " entries: %d\n", qry->entriesRead );
|
||||
fprintf( stream, " elapsed: %d\n", qry->elapsedTime );
|
||||
fprintf( stream, " stop flag: %s\n", qry->stopFlag ? "yes" : "no" );
|
||||
|
@ -529,16 +556,16 @@ static GList *ldapqry_build_items_fl(
|
|||
}
|
||||
|
||||
/* Create new folder for results */
|
||||
if( qry->folder == NULL ) {
|
||||
if( ADDRQUERY_FOLDER(qry) == NULL ) {
|
||||
folder = addritem_create_item_folder();
|
||||
addritem_folder_set_name( folder, qry->queryName );
|
||||
addritem_folder_set_name( folder, ADDRQUERY_NAME(qry) );
|
||||
addritem_folder_set_remarks( folder, "" );
|
||||
addrcache_id_folder( cache, folder );
|
||||
addrcache_add_folder( cache, folder );
|
||||
qry->folder = folder;
|
||||
ADDRQUERY_FOLDER(qry) = folder;
|
||||
|
||||
/* Specify folder type and back reference */
|
||||
folder->folderType = ADDRFOLDER_LDAP_QUERY;
|
||||
folder->folderType = ADDRFOLDER_QUERY_RESULTS;
|
||||
folder->folderData = ( gpointer ) qry;
|
||||
folder->isHidden = TRUE;
|
||||
}
|
||||
|
@ -550,7 +577,7 @@ static GList *ldapqry_build_items_fl(
|
|||
addritem_person_set_last_name( person, lastName );
|
||||
addrcache_id_person( cache, person );
|
||||
addritem_person_set_external_id( person, dn );
|
||||
addrcache_folder_add_person( cache, qry->folder, person );
|
||||
addrcache_folder_add_person( cache, ADDRQUERY_FOLDER(qry), person );
|
||||
|
||||
qry->entriesRead++;
|
||||
|
||||
|
@ -644,7 +671,7 @@ static GList *ldapqry_process_single_entry(
|
|||
*/
|
||||
gboolean ldapqry_check_search( LdapQuery *qry ) {
|
||||
LdapControl *ctl;
|
||||
qry->retVal = LDAPRC_CRITERIA;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_CRITERIA;
|
||||
|
||||
/* Test for control data */
|
||||
ctl = qry->control;
|
||||
|
@ -653,14 +680,13 @@ gboolean ldapqry_check_search( LdapQuery *qry ) {
|
|||
}
|
||||
|
||||
/* Test for search value */
|
||||
if( qry->searchValue == NULL ) {
|
||||
if( ADDRQUERY_SEARCHVALUE(qry) == NULL ) {
|
||||
return FALSE;
|
||||
}
|
||||
if( strlen( qry->searchValue ) < 1 ) {
|
||||
if( strlen( ADDRQUERY_SEARCHVALUE(qry) ) < 1 ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -674,54 +700,32 @@ void ldapqry_touch( LdapQuery *qry ) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Perform the LDAP search, reading LDAP entries into cache.
|
||||
* Note that one LDAP entry can have multiple values for many of its
|
||||
* attributes. If these attributes are E-Mail addresses; these are
|
||||
* broken out into separate address items. For any other attribute,
|
||||
* only the first occurrence is read.
|
||||
*
|
||||
* Connect to LDAP server.
|
||||
* \param qry Query object to process.
|
||||
* \return Error/status code.
|
||||
*/
|
||||
static gint ldapqry_perform_search( LdapQuery *qry ) {
|
||||
static gint ldapqry_connect( LdapQuery *qry ) {
|
||||
LdapControl *ctl;
|
||||
LDAP *ld;
|
||||
LDAPMessage *result, *e;
|
||||
char **attribs;
|
||||
gchar *criteria;
|
||||
gboolean entriesFound;
|
||||
gboolean first;
|
||||
struct timeval timeout;
|
||||
gint rc;
|
||||
time_t tstart, tend;
|
||||
AddressCache *cache;
|
||||
GList *listEMail;
|
||||
|
||||
/* Initialize some variables */
|
||||
ctl = qry->control;
|
||||
cache = qry->server->addressCache;
|
||||
timeout.tv_sec = ctl->timeOut;
|
||||
timeout.tv_usec = 0L;
|
||||
entriesFound = FALSE;
|
||||
qry->elapsedTime = -1;
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
|
||||
/* Check search criteria */
|
||||
if( ! ldapqry_check_search( qry ) ) {
|
||||
return qry->retVal;
|
||||
}
|
||||
|
||||
/* Initialize connection */
|
||||
/* printf( "===ldapqry_connect===\n" ); */
|
||||
/* ldapqry_print( qry, stdout ); */
|
||||
ctl = qry->control;
|
||||
/* ldapctl_print( ctl, stdout ); */
|
||||
/* printf( "======\n" ); */
|
||||
ldapqry_touch( qry );
|
||||
tstart = qry->touchTime;
|
||||
tend = tstart - 1;
|
||||
qry->startTime = qry->touchTime;
|
||||
qry->elapsedTime = -1;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_INIT;
|
||||
if( ( ld = ldap_init( ctl->hostName, ctl->port ) ) == NULL ) {
|
||||
qry->retVal = LDAPRC_INIT;
|
||||
return qry->retVal;
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
qry->ldap = ld;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_STOP_FLAG;
|
||||
if( ldapqry_get_stop_flag( qry ) ) {
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
return qry->retVal;
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
ldapqry_touch( qry );
|
||||
|
||||
|
@ -730,6 +734,7 @@ static gint ldapqry_perform_search( LdapQuery *qry ) {
|
|||
*/
|
||||
|
||||
/* Bind to the server, if required */
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_BIND;
|
||||
if( ctl->bindDN ) {
|
||||
if( * ctl->bindDN != '\0' ) {
|
||||
/* printf( "binding...\n" ); */
|
||||
|
@ -740,51 +745,99 @@ static gint ldapqry_perform_search( LdapQuery *qry ) {
|
|||
printf( "LDAP Error: ldap_simple_bind_s: %s\n",
|
||||
ldap_err2string( rc ) );
|
||||
*/
|
||||
ldap_unbind( ld );
|
||||
qry->retVal = LDAPRC_BIND;
|
||||
return qry->retVal;
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
}
|
||||
}
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_STOP_FLAG;
|
||||
if( ldapqry_get_stop_flag( qry ) ) {
|
||||
ldap_unbind( ld );
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
return qry->retVal;
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
ldapqry_touch( qry );
|
||||
|
||||
ADDRQUERY_RETVAL(qry) = LDAP_SUCCESS;
|
||||
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to LDAP server.
|
||||
* \param qry Query object to process.
|
||||
* \return Error/status code.
|
||||
*/
|
||||
static gint ldapqry_disconnect( LdapQuery *qry ) {
|
||||
/* Disconnect */
|
||||
if( qry->ldap ) ldap_unbind( qry->ldap );
|
||||
qry->ldap = NULL;
|
||||
|
||||
ldapqry_touch( qry );
|
||||
qry->elapsedTime = qry->touchTime - qry->startTime;
|
||||
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the LDAP search, reading LDAP entries into cache.
|
||||
* Note that one LDAP entry can have multiple values for many of its
|
||||
* attributes. If these attributes are E-Mail addresses; these are
|
||||
* broken out into separate address items. For any other attribute,
|
||||
* only the first occurrence is read.
|
||||
*
|
||||
* \param qry Query object to process.
|
||||
* \return Error/status code.
|
||||
*/
|
||||
static gint ldapqry_search_retrieve( LdapQuery *qry ) {
|
||||
LdapControl *ctl;
|
||||
LDAP *ld;
|
||||
LDAPMessage *result, *e;
|
||||
char **attribs;
|
||||
gchar *criteria;
|
||||
gboolean entriesFound;
|
||||
gboolean first;
|
||||
struct timeval timeout;
|
||||
gint rc;
|
||||
AddressCache *cache;
|
||||
GList *listEMail;
|
||||
|
||||
/* Initialize some variables */
|
||||
ld = qry->ldap;
|
||||
ctl = qry->control;
|
||||
cache = qry->server->addressCache;
|
||||
timeout.tv_sec = ctl->timeOut;
|
||||
timeout.tv_usec = 0L;
|
||||
entriesFound = FALSE;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_SUCCESS;
|
||||
|
||||
/* Define all attributes we are interested in. */
|
||||
attribs = ldapctl_attribute_array( ctl );
|
||||
|
||||
/* Create LDAP search string */
|
||||
criteria = ldapctl_format_criteria( ctl, qry->searchValue );
|
||||
criteria = ldapctl_format_criteria( ctl, ADDRQUERY_SEARCHVALUE(qry) );
|
||||
/* printf( "Search criteria ::%s::\n", criteria ); */
|
||||
|
||||
/*
|
||||
* Execute the search - this step may take some time to complete
|
||||
* depending on network traffic and server response time.
|
||||
*/
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_TIMEOUT;
|
||||
rc = ldap_search_ext_s( ld, ctl->baseDN, LDAP_SCOPE_SUBTREE, criteria,
|
||||
attribs, 0, NULL, NULL, &timeout, 0, &result );
|
||||
ldapctl_free_attribute_array( attribs );
|
||||
g_free( criteria );
|
||||
criteria = NULL;
|
||||
if( rc == LDAP_TIMEOUT ) {
|
||||
ldap_unbind( ld );
|
||||
qry->retVal = LDAPRC_TIMEOUT;
|
||||
return qry->retVal;
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_SEARCH;
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
/*
|
||||
printf( "LDAP Error: ldap_search_st: %s\n", ldap_err2string( rc ) );
|
||||
*/
|
||||
ldap_unbind( ld );
|
||||
qry->retVal = LDAPRC_SEARCH;
|
||||
return qry->retVal;
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_STOP_FLAG;
|
||||
if( ldapqry_get_stop_flag( qry ) ) {
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
return qry->retVal;
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
ldapqry_touch( qry );
|
||||
|
||||
|
@ -792,11 +845,6 @@ static gint ldapqry_perform_search( LdapQuery *qry ) {
|
|||
printf( "Total results are: %d\n", ldap_count_entries( ld, result ) );
|
||||
*/
|
||||
|
||||
if( ldapqry_get_stop_flag( qry ) ) {
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
return qry->retVal;
|
||||
}
|
||||
|
||||
/* Process results */
|
||||
first = TRUE;
|
||||
while( TRUE ) {
|
||||
|
@ -828,7 +876,7 @@ static gint ldapqry_perform_search( LdapQuery *qry ) {
|
|||
|
||||
/* Process callback */
|
||||
if( qry->callBackEntry ) {
|
||||
qry->callBackEntry( qry, listEMail );
|
||||
qry->callBackEntry( qry, ADDRQUERY_ID(qry), listEMail, qry->data );
|
||||
}
|
||||
else {
|
||||
g_list_free( listEMail );
|
||||
|
@ -839,19 +887,40 @@ static gint ldapqry_perform_search( LdapQuery *qry ) {
|
|||
|
||||
/* Free up and disconnect */
|
||||
ldap_msgfree( result );
|
||||
ldap_unbind( ld );
|
||||
ldapqry_touch( qry );
|
||||
tend = qry->touchTime;
|
||||
qry->elapsedTime = tend - tstart;
|
||||
|
||||
if( entriesFound ) {
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_SUCCESS;
|
||||
}
|
||||
else {
|
||||
qry->retVal = LDAPRC_NOENTRIES;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_NOENTRIES;
|
||||
}
|
||||
|
||||
return qry->retVal;
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection, perform search and disconnect.
|
||||
* \param qry Query object to process.
|
||||
* \return Error/status code.
|
||||
*/
|
||||
static gint ldapqry_perform_search( LdapQuery *qry ) {
|
||||
/* Check search criteria */
|
||||
if( ! ldapqry_check_search( qry ) ) {
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
|
||||
/* Connect */
|
||||
qry->ldap = NULL;
|
||||
ldapqry_connect( qry );
|
||||
if( ADDRQUERY_RETVAL(qry) == LDAPRC_SUCCESS ) {
|
||||
/* Perform search */
|
||||
ldapqry_search_retrieve( qry );
|
||||
}
|
||||
/* Disconnect */
|
||||
ldapqry_disconnect( qry );
|
||||
qry->ldap = NULL;
|
||||
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -868,11 +937,6 @@ gint ldapqry_search( LdapQuery *qry ) {
|
|||
ldapqry_touch( qry );
|
||||
qry->completed = FALSE;
|
||||
|
||||
/* Process callback */
|
||||
if( qry->callBackStart ) {
|
||||
qry->callBackStart( qry );
|
||||
}
|
||||
|
||||
/* Setup pointer to thread specific area */
|
||||
pthread_setspecific( _queryThreadKey_, qry );
|
||||
|
||||
|
@ -880,10 +944,15 @@ gint ldapqry_search( LdapQuery *qry ) {
|
|||
|
||||
/* Now perform the search */
|
||||
qry->entriesRead = 0;
|
||||
qry->retVal = LDAPRC_SUCCESS;
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_SUCCESS;
|
||||
ldapqry_set_busy_flag( qry, TRUE );
|
||||
ldapqry_set_stop_flag( qry, FALSE );
|
||||
retVal = ldapqry_perform_search( qry );
|
||||
if( ADDRQUERY_SEARCHTYPE(qry) == ADDRSEARCH_LOCATE ) {
|
||||
retVal = ldapqry_perform_locate( qry );
|
||||
}
|
||||
else {
|
||||
retVal = ldapqry_perform_search( qry );
|
||||
}
|
||||
if( retVal == LDAPRC_SUCCESS ) {
|
||||
qry->server->addressCache->dataRead = TRUE;
|
||||
qry->server->addressCache->accessFlag = FALSE;
|
||||
|
@ -905,10 +974,10 @@ gint ldapqry_search( LdapQuery *qry ) {
|
|||
|
||||
/* Process callback */
|
||||
if( qry->callBackEnd ) {
|
||||
qry->callBackEnd( qry );
|
||||
qry->callBackEnd( qry, ADDRQUERY_ID(qry), ADDRQUERY_RETVAL(qry), qry->data );
|
||||
}
|
||||
|
||||
return qry->retVal;
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -924,7 +993,7 @@ gint ldapqry_read_data_th( LdapQuery *qry ) {
|
|||
ldapqry_set_stop_flag( qry, FALSE );
|
||||
ldapqry_touch( qry );
|
||||
if( ldapqry_check_search( qry ) ) {
|
||||
if( qry->retVal == LDAPRC_SUCCESS ) {
|
||||
if( ADDRQUERY_RETVAL(qry) == LDAPRC_SUCCESS ) {
|
||||
/*
|
||||
printf( "Starting LDAP search thread\n");
|
||||
*/
|
||||
|
@ -936,21 +1005,7 @@ gint ldapqry_read_data_th( LdapQuery *qry ) {
|
|||
(void *) ldapqry_search, (void *) qry );
|
||||
}
|
||||
}
|
||||
return qry->retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join the thread associated with the query. This should probably be removed
|
||||
* to prevent joining threads.
|
||||
* \param qry Query object to process.
|
||||
*/
|
||||
void ldapqry_join_threadX( LdapQuery *qry ) {
|
||||
g_return_if_fail( qry != NULL );
|
||||
|
||||
/* Wait for thread */
|
||||
/* printf( "ldapqry_join_thread::Joining thread...\n" ); */
|
||||
pthread_join( * qry->thread, NULL );
|
||||
/* printf( "ldapqry_join_thread::Thread terminated\n" ); */
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -963,7 +1018,7 @@ static void ldapqry_destroyer( void * ptr ) {
|
|||
|
||||
qry = ( LdapQuery * ) ptr;
|
||||
/*
|
||||
printf( "ldapqry_destroyer::%d::%s\n", (int) pthread_self(), qry->queryName );
|
||||
printf( "ldapqry_destroyer::%d::%s\n", (int) pthread_self(), ADDRQUERY_NAME(qry) );
|
||||
*/
|
||||
|
||||
/* Perform any destruction here */
|
||||
|
@ -986,7 +1041,7 @@ void ldapqry_cancel( LdapQuery *qry ) {
|
|||
g_return_if_fail( qry != NULL );
|
||||
|
||||
/*
|
||||
printf( "cancelling::%d::%s\n", (int) pthread_self(), qry->queryName );
|
||||
printf( "cancelling::%d::%s\n", (int) pthread_self(), ADDRQUERY_NAME(qry) );
|
||||
*/
|
||||
if( ldapqry_get_busy_flag( qry ) ) {
|
||||
if( qry->thread ) {
|
||||
|
@ -1041,14 +1096,280 @@ void ldapqry_delete_folder( LdapQuery *qry ) {
|
|||
|
||||
g_return_if_fail( qry != NULL );
|
||||
|
||||
folder = qry->folder;
|
||||
folder = ADDRQUERY_FOLDER(qry);
|
||||
if( folder ) {
|
||||
cache = qry->server->addressCache;
|
||||
folder = addrcache_remove_folder_delete( cache, folder );
|
||||
if( folder ) {
|
||||
addritem_free_item_folder( folder );
|
||||
}
|
||||
qry->folder = NULL;
|
||||
ADDRQUERY_FOLDER(qry) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a name/value pair object.
|
||||
* \param n Name.
|
||||
* \param v Value.
|
||||
* \return Initialized object.
|
||||
*/
|
||||
static NameValuePair *ldapqry_create_name_value( const gchar *n, const gchar *v ) {
|
||||
NameValuePair *nvp = g_new0( NameValuePair, 1 );
|
||||
|
||||
nvp->name = g_strdup( n );
|
||||
nvp->value = g_strdup( v );
|
||||
return nvp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free up name/value pair object.
|
||||
* \param nvp Name/value object.
|
||||
*/
|
||||
void ldapqry_free_name_value( NameValuePair *nvp ) {
|
||||
if( nvp ) {
|
||||
g_free( nvp->name );
|
||||
g_free( nvp->value );
|
||||
nvp->name = nvp->value = NULL;
|
||||
g_free( nvp );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print name/value pair object for debug.
|
||||
* \param nvp Name/value object.
|
||||
* \param stream Output stream.
|
||||
*/
|
||||
void ldapqry_print_name_value( NameValuePair *nvp, FILE *stream ) {
|
||||
if( nvp ) {
|
||||
fprintf( stream, "n/v ::%s::%s::\n", nvp->name, nvp->value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free up a list name/value pair objects.
|
||||
* \param list List of name/value objects.
|
||||
*/
|
||||
void ldapqry_free_list_name_value( GList *list ) {
|
||||
GList *node;
|
||||
|
||||
node = list;
|
||||
while( node ) {
|
||||
NameValuePair *nvp = ( NameValuePair * ) node->data;
|
||||
ldapqry_free_name_value( nvp );
|
||||
node->data = NULL;
|
||||
node = g_list_next( node );
|
||||
}
|
||||
g_list_free( list );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a list of name/value pairs from LDAP attributes.
|
||||
* \param ld LDAP handle.
|
||||
* \param e LDAP message.
|
||||
* \param attr Attribute name.
|
||||
* \param listValues List to populate.
|
||||
* \return List of attribute name/value pairs.
|
||||
*/
|
||||
static GList *ldapqry_load_attrib_values(
|
||||
LDAP *ld, LDAPMessage *entry, char *attr,
|
||||
GList *listValues )
|
||||
{
|
||||
GList *list = NULL;
|
||||
gint i;
|
||||
gchar **vals;
|
||||
NameValuePair *nvp;
|
||||
|
||||
list = listValues;
|
||||
if( ( vals = ldap_get_values( ld, entry, attr ) ) != NULL ) {
|
||||
for( i = 0; vals[i] != NULL; i++ ) {
|
||||
nvp = ldapqry_create_name_value( attr, vals[i] );
|
||||
list = g_list_append( list, nvp );
|
||||
}
|
||||
}
|
||||
ldap_value_free( vals );
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a list of all attributes.
|
||||
* \param ld LDAP handle.
|
||||
* \param e LDAP message.
|
||||
* \return List of attribute name/value pairs.
|
||||
*/
|
||||
static GList *ldapqry_fetch_attribs( LDAP *ld, LDAPMessage *e )
|
||||
{
|
||||
char *attribute;
|
||||
BerElement *ber;
|
||||
GList *listValues = NULL;
|
||||
|
||||
/* Process all attributes */
|
||||
for( attribute = ldap_first_attribute( ld, e, &ber ); attribute != NULL;
|
||||
attribute = ldap_next_attribute( ld, e, ber ) ) {
|
||||
listValues = ldapqry_load_attrib_values( ld, e, attribute, listValues );
|
||||
ldap_memfree( attribute );
|
||||
}
|
||||
|
||||
/* Free up */
|
||||
if( ber != NULL ) {
|
||||
ber_free( ber, 0 );
|
||||
}
|
||||
return listValues;
|
||||
}
|
||||
|
||||
#define CRITERIA_SINGLE "(objectclass=*)"
|
||||
|
||||
/**
|
||||
* Perform the data retrieval for a specific LDAP record.
|
||||
*
|
||||
* \param qry Query object to process.
|
||||
* \return Error/status code.
|
||||
*/
|
||||
static gint ldapqry_locate_retrieve( LdapQuery *qry ) {
|
||||
LdapControl *ctl;
|
||||
LDAP *ld;
|
||||
LDAPMessage *result, *e;
|
||||
gboolean entriesFound;
|
||||
gboolean first;
|
||||
struct timeval timeout;
|
||||
gint rc;
|
||||
gchar *dn;
|
||||
GList *listValues;
|
||||
|
||||
/* Initialize some variables */
|
||||
ld = qry->ldap;
|
||||
ctl = qry->control;
|
||||
dn = ADDRQUERY_SEARCHVALUE(qry);
|
||||
timeout.tv_sec = ctl->timeOut;
|
||||
timeout.tv_usec = 0L;
|
||||
entriesFound = FALSE;
|
||||
|
||||
/*
|
||||
* Execute the search - this step may take some time to complete
|
||||
* depending on network traffic and server response time.
|
||||
*/
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_TIMEOUT;
|
||||
rc = ldap_search_ext_s( ld, dn, LDAP_SCOPE_BASE, CRITERIA_SINGLE,
|
||||
NULL, 0, NULL, NULL, &timeout, 0, &result );
|
||||
if( rc == LDAP_TIMEOUT ) {
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_SEARCH;
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
/*
|
||||
printf( "LDAP Error: ldap_search_st: %s\n", ldap_err2string( rc ) );
|
||||
*/
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_STOP_FLAG;
|
||||
if( ldapqry_get_stop_flag( qry ) ) {
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
ldapqry_touch( qry );
|
||||
|
||||
/*
|
||||
printf( "Total results are: %d\n", ldap_count_entries( ld, result ) );
|
||||
*/
|
||||
|
||||
/* Process results */
|
||||
first = TRUE;
|
||||
while( TRUE ) {
|
||||
ldapqry_touch( qry );
|
||||
if( qry->entriesRead >= ctl->maxEntries ) break;
|
||||
|
||||
/* Test for stop */
|
||||
if( ldapqry_get_stop_flag( qry ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Retrieve entry */
|
||||
if( first ) {
|
||||
first = FALSE;
|
||||
e = ldap_first_entry( ld, result );
|
||||
}
|
||||
else {
|
||||
e = ldap_next_entry( ld, e );
|
||||
}
|
||||
if( e == NULL ) break;
|
||||
|
||||
entriesFound = TRUE;
|
||||
|
||||
/* Setup a critical section here */
|
||||
pthread_mutex_lock( qry->mutexEntry );
|
||||
|
||||
/* Process entry */
|
||||
listValues = ldapqry_fetch_attribs( ld, e );
|
||||
|
||||
/* Process callback */
|
||||
if( qry->callBackEntry ) {
|
||||
qry->callBackEntry( qry, ADDRQUERY_ID(qry), listValues, qry->data );
|
||||
}
|
||||
ldapqry_free_list_name_value( listValues );
|
||||
listValues = NULL;
|
||||
|
||||
pthread_mutex_unlock( qry->mutexEntry );
|
||||
}
|
||||
|
||||
/* Free up and disconnect */
|
||||
ldap_msgfree( result );
|
||||
|
||||
if( entriesFound ) {
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_SUCCESS;
|
||||
}
|
||||
else {
|
||||
ADDRQUERY_RETVAL(qry) = LDAPRC_NOENTRIES;
|
||||
}
|
||||
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the search to locate a specific LDAP record identified by
|
||||
* distinguished name (dn).
|
||||
*
|
||||
* \param qry Query object to process.
|
||||
* \return Error/status code.
|
||||
*/
|
||||
gint ldapqry_perform_locate( LdapQuery *qry ) {
|
||||
/* Connect */
|
||||
qry->ldap = NULL;
|
||||
ldapqry_connect( qry );
|
||||
if( ADDRQUERY_RETVAL(qry) == LDAPRC_SUCCESS ) {
|
||||
/* Perform search */
|
||||
ldapqry_locate_retrieve( qry );
|
||||
}
|
||||
/* Disconnect */
|
||||
ldapqry_disconnect( qry );
|
||||
qry->ldap = NULL;
|
||||
|
||||
/* Process callback */
|
||||
if( qry->callBackEnd ) {
|
||||
qry->callBackEnd( qry, ADDRQUERY_ID(qry), ADDRQUERY_RETVAL(qry), qry->data );
|
||||
}
|
||||
|
||||
return ADDRQUERY_RETVAL(qry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove results (folder and data) for specified LDAP query.
|
||||
* \param qry Query object to process.
|
||||
*/
|
||||
void ldapquery_remove_results( LdapQuery *qry ) {
|
||||
/* Set query as aged - will be retired on a later call */
|
||||
ldapqry_set_aged_flag( qry, TRUE );
|
||||
/*
|
||||
printf( "ldapquery_remove_results...\n" );
|
||||
printf( "testing busy flag...\n" );
|
||||
*/
|
||||
if( ldapqry_get_busy_flag( qry ) ) {
|
||||
/* Query is still busy - cancel query */
|
||||
/* printf( "\tquery is still busy running...\n" ); */
|
||||
ldapqry_set_stop_flag( qry, TRUE );
|
||||
ldapqry_cancel( qry );
|
||||
}
|
||||
else {
|
||||
/* Delete folder */
|
||||
/* printf( "\tquery can be deleted!\n" ); */
|
||||
ldapqry_delete_folder( qry );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,53 +30,41 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#include <ldap.h>
|
||||
|
||||
#include "addrquery.h"
|
||||
#include "ldapctrl.h"
|
||||
#include "ldapserver.h"
|
||||
#include "addritem.h"
|
||||
#include "addrcache.h"
|
||||
|
||||
/*
|
||||
* Constants.
|
||||
*/
|
||||
#define LDAPQUERY_NONE 0
|
||||
#define LDAPQUERY_STATIC 1
|
||||
#define LDAPQUERY_DYNAMIC 2
|
||||
|
||||
/* Error codes */
|
||||
#define LDAPRC_SUCCESS 0
|
||||
#define LDAPRC_CONNECT -1
|
||||
#define LDAPRC_INIT -2
|
||||
#define LDAPRC_BIND -3
|
||||
#define LDAPRC_SEARCH -4
|
||||
#define LDAPRC_TIMEOUT -5
|
||||
#define LDAPRC_CRITERIA -6
|
||||
#define LDAPRC_NOENTRIES -7
|
||||
|
||||
typedef struct _LdapQuery LdapQuery;
|
||||
struct _LdapQuery {
|
||||
LdapControl *control;
|
||||
gint retVal;
|
||||
gint queryType;
|
||||
gchar *queryName;
|
||||
gchar *searchValue;
|
||||
gint queryID;
|
||||
gint entriesRead;
|
||||
gint elapsedTime;
|
||||
gboolean stopFlag;
|
||||
gboolean busyFlag;
|
||||
gboolean agedFlag;
|
||||
gboolean completed;
|
||||
time_t touchTime;
|
||||
pthread_t *thread;
|
||||
AddrQueryObject obj;
|
||||
LdapControl *control;
|
||||
LdapServer *server; /* Reference to (parent) LDAP server */
|
||||
gint entriesRead;
|
||||
gint elapsedTime;
|
||||
gboolean stopFlag;
|
||||
gboolean busyFlag;
|
||||
gboolean agedFlag;
|
||||
gboolean completed;
|
||||
time_t startTime;
|
||||
time_t touchTime;
|
||||
pthread_t *thread;
|
||||
pthread_mutex_t *mutexStop;
|
||||
pthread_mutex_t *mutexBusy;
|
||||
pthread_mutex_t *mutexEntry;
|
||||
void (*callBackStart)( void * );
|
||||
void (*callBackEntry)( void *, void * );
|
||||
void (*callBackEnd)( void * );
|
||||
ItemFolder *folder; /* Reference to folder in cache */
|
||||
LdapServer *server; /* Reference to (parent) LDAP server */
|
||||
void (*callBackEntry)( void *, gint, void *, void * );
|
||||
void (*callBackEnd)( void *, gint, gint, void * );
|
||||
LDAP *ldap;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
typedef struct _NameValuePair NameValuePair;
|
||||
struct _NameValuePair {
|
||||
gchar *name;
|
||||
gchar *value;
|
||||
};
|
||||
|
||||
/* Function prototypes */
|
||||
|
@ -86,7 +74,7 @@ void ldapqry_set_control ( LdapQuery *qry, LdapControl *ctl );
|
|||
void ldapqry_set_name ( LdapQuery* qry, const gchar *value );
|
||||
void ldapqry_set_search_value ( LdapQuery *qry, const gchar *value );
|
||||
void ldapqry_set_error_status ( LdapQuery* qry, const gint value );
|
||||
void ldapqry_set_query_type ( LdapQuery* qry, const gint value );
|
||||
void ldapqry_set_search_type ( LdapQuery *qry, const AddrSearchType value );
|
||||
void ldapqry_set_query_id ( LdapQuery* qry, const gint value );
|
||||
void ldapqry_set_entries_read ( LdapQuery* qry, const gint value );
|
||||
void ldapqry_set_callback_start ( LdapQuery *qry, void *func );
|
||||
|
@ -101,15 +89,17 @@ void ldapqry_set_busy_flag ( LdapQuery *qry, const gboolean value );
|
|||
gboolean ldapqry_get_busy_flag ( LdapQuery *qry );
|
||||
void ldapqry_set_aged_flag ( LdapQuery *qry, const gboolean value );
|
||||
gboolean ldapqry_get_aged_flag ( LdapQuery *qry );
|
||||
void ldapqry_set_data ( LdapQuery *qry, const gpointer value );
|
||||
gpointer ldapqry_get_data ( LdapQuery *qry );
|
||||
|
||||
gboolean ldapqry_check_search ( LdapQuery *qry );
|
||||
void ldapqry_touch ( LdapQuery *qry );
|
||||
gint ldapqry_search ( LdapQuery *qry );
|
||||
gint ldapqry_read_data_th ( LdapQuery *qry );
|
||||
void ldapqry_join_thread ( LdapQuery *qry );
|
||||
void ldapqry_cancel ( LdapQuery *qry );
|
||||
void ldapqry_age ( LdapQuery *qry, gint maxAge );
|
||||
void ldapqry_delete_folder ( LdapQuery *qry );
|
||||
void ldapquery_remove_results ( LdapQuery *qry );
|
||||
|
||||
#endif /* USE_LDAP */
|
||||
|
||||
|
|
200
src/ldapserver.c
200
src/ldapserver.c
|
@ -310,7 +310,7 @@ void ldapsvr_print_data( LdapServer *server, FILE *stream ) {
|
|||
node = server->listQuery;
|
||||
while( node ) {
|
||||
LdapQuery *qry = node->data;
|
||||
fprintf( stream, " query: %2d : %s\n", i, qry->queryName );
|
||||
fprintf( stream, " query: %2d : %s\n", i, ADDRQUERY_NAME(qry) );
|
||||
i++;
|
||||
node = g_list_next( node );
|
||||
}
|
||||
|
@ -356,8 +356,9 @@ void ldapsvr_execute_query( LdapServer *server, LdapQuery *qry ) {
|
|||
ldapqry_initialize();
|
||||
|
||||
/* Perform query */
|
||||
/* printf( "ldapsvr_execute_query::reading with thread...\n" ); */
|
||||
/* printf( "ldapsvr_execute_query::checking query...\n" ); */
|
||||
if( ldapqry_check_search( qry ) ) {
|
||||
/* printf( "ldapsvr_execute_query::reading with thread...\n" ); */
|
||||
ldapqry_read_data_th( qry );
|
||||
/*
|
||||
if( qry->retVal == LDAPRC_SUCCESS ) {
|
||||
|
@ -380,7 +381,7 @@ void ldapsvr_stop_query_id( LdapServer *server, const gint queryID ) {
|
|||
node = server->listQuery;
|
||||
while( node ) {
|
||||
LdapQuery *qry = node->data;
|
||||
if( qry->queryID == queryID ) {
|
||||
if( ADDRQUERY_ID(qry) == queryID ) {
|
||||
/* Notify thread to stop */
|
||||
ldapqry_set_stop_flag( qry, TRUE );
|
||||
}
|
||||
|
@ -431,7 +432,8 @@ void ldapsvr_cancel_all_query( LdapServer *server ) {
|
|||
* \param searchTerm Search term to locate.
|
||||
* \return Query object, or <i>NULL</i> if none found.
|
||||
*/
|
||||
LdapQuery *ldapsvr_locate_query( LdapServer *server, const gchar *searchTerm )
|
||||
static LdapQuery *ldapsvr_locate_query(
|
||||
const LdapServer *server, const gchar *searchTerm )
|
||||
{
|
||||
LdapQuery *incomplete = NULL;
|
||||
GList *node;
|
||||
|
@ -442,7 +444,7 @@ LdapQuery *ldapsvr_locate_query( LdapServer *server, const gchar *searchTerm )
|
|||
/* Search backwards for query */
|
||||
while( node ) {
|
||||
LdapQuery *qry = node->data;
|
||||
if( g_strcasecmp( qry->searchValue, searchTerm ) == 0 ) {
|
||||
if( g_strcasecmp( ADDRQUERY_SEARCHVALUE(qry), searchTerm ) == 0 ) {
|
||||
if( qry->agedFlag ) continue;
|
||||
if( qry->completed ) {
|
||||
/* Found */
|
||||
|
@ -458,7 +460,12 @@ LdapQuery *ldapsvr_locate_query( LdapServer *server, const gchar *searchTerm )
|
|||
}
|
||||
|
||||
/**
|
||||
* Retire aged queries. Only dynamic queries are retired.
|
||||
* Retire aged queries. Only the following queries are retired:
|
||||
*
|
||||
* a) Dynamic queries.
|
||||
* b) Explicit searches that have a hidden folders.
|
||||
* c) Locate searches that have a hidden folder.
|
||||
*
|
||||
* \param server LdapServer.
|
||||
*/
|
||||
void ldapsvr_retire_query( LdapServer *server ) {
|
||||
|
@ -467,6 +474,7 @@ void ldapsvr_retire_query( LdapServer *server ) {
|
|||
GList *listQuery;
|
||||
gint maxAge;
|
||||
LdapControl *ctl;
|
||||
ItemFolder *folder;
|
||||
|
||||
/* printf( "ldapsvr_retire_query\n" ); */
|
||||
g_return_if_fail( server != NULL );
|
||||
|
@ -480,14 +488,18 @@ void ldapsvr_retire_query( LdapServer *server ) {
|
|||
LdapQuery *qry = node->data;
|
||||
|
||||
node = g_list_next( node );
|
||||
if( qry->queryType == LDAPQUERY_STATIC ) continue;
|
||||
folder = ADDRQUERY_FOLDER(qry);
|
||||
if( folder == NULL ) continue;
|
||||
if( ! folder->isHidden ) {
|
||||
if( ADDRQUERY_SEARCHTYPE(qry) == ADDRSEARCH_EXPLICIT ) continue;
|
||||
if( ADDRQUERY_SEARCHTYPE(qry) == ADDRSEARCH_LOCATE ) continue;
|
||||
}
|
||||
|
||||
/* Only dynamic queries are retired */
|
||||
ldapqry_age( qry, maxAge );
|
||||
if( qry->agedFlag ) {
|
||||
/* Delete folder associated with query */
|
||||
/*
|
||||
printf( "deleting folder... ::%s::\n", qry->queryName );
|
||||
printf( "deleting folder... ::%s::\n", ADDRQUERY_NAME(qry) );
|
||||
*/
|
||||
ldapqry_delete_folder( qry );
|
||||
listDelete = g_list_append( listDelete, qry );
|
||||
|
@ -511,6 +523,176 @@ void ldapsvr_retire_query( LdapServer *server ) {
|
|||
g_list_free( listDelete );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return results of a previous query by executing callback for each address
|
||||
* contained in specified folder.
|
||||
*
|
||||
* \param folder Address book folder to process.
|
||||
* \param req Address query request object.
|
||||
*/
|
||||
static void ldapsvr_previous_query(
|
||||
const ItemFolder *folder, const QueryRequest *req, AddrQueryObject *aqo )
|
||||
{
|
||||
AddrSearchCallbackEntry *callBack;
|
||||
GList *listEMail;
|
||||
GList *node;
|
||||
GList *nodeEM;
|
||||
gpointer sender;
|
||||
|
||||
sender = aqo;
|
||||
callBack = ( AddrSearchCallbackEntry * ) req->callBackEntry;
|
||||
if( callBack ) {
|
||||
listEMail = NULL;
|
||||
node = folder->listPerson;
|
||||
while( node ) {
|
||||
AddrItemObject *aio = node->data;
|
||||
if( aio && aio->type == ITEMTYPE_PERSON ) {
|
||||
ItemPerson *person = node->data;
|
||||
nodeEM = person->listEMail;
|
||||
while( nodeEM ) {
|
||||
ItemEMail *email = nodeEM->data;
|
||||
|
||||
nodeEM = g_list_next( nodeEM );
|
||||
listEMail = g_list_append( listEMail, email );
|
||||
}
|
||||
}
|
||||
node = g_list_next( node );
|
||||
}
|
||||
( callBack ) ( sender, req->queryID, listEMail, NULL );
|
||||
/* // g_list_free( listEMail ); */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reuse search results from a previous LDAP query. If there is a query that
|
||||
* has the same search term as specified in the query request, then the query
|
||||
* will be reused.
|
||||
*
|
||||
* \param server LDAP server object.
|
||||
* \param req Address query object.
|
||||
* \return <i>TRUE</i> if previous query was used.
|
||||
*/
|
||||
gboolean ldapsvr_reuse_previous( const LdapServer *server, const QueryRequest *req ) {
|
||||
LdapQuery *qry;
|
||||
gchar *searchTerm;
|
||||
ItemFolder *folder;
|
||||
|
||||
g_return_val_if_fail( server != NULL, FALSE );
|
||||
g_return_val_if_fail( req != NULL, FALSE );
|
||||
|
||||
searchTerm = req->searchTerm;
|
||||
|
||||
/* Test whether any queries for the same term exist */
|
||||
qry = ldapsvr_locate_query( server, searchTerm );
|
||||
if( qry ) {
|
||||
/* Touch query to ensure it hangs around for a bit longer */
|
||||
ldapqry_touch( qry );
|
||||
folder = ADDRQUERY_FOLDER(qry);
|
||||
if( folder ) {
|
||||
ldapsvr_previous_query( folder, req, ADDRQUERY_OBJECT(qry) );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new LdapQuery object that will be used to perform an dynamic
|
||||
* search request.
|
||||
*
|
||||
* \param server LdapServer.
|
||||
* \param req Query request.
|
||||
* \return LdapQuery object, or <i>NULL</i> if none created.
|
||||
*/
|
||||
LdapQuery *ldapsvr_new_dynamic_search( LdapServer *server, QueryRequest *req )
|
||||
{
|
||||
LdapQuery *qry;
|
||||
gchar *name;
|
||||
gchar *searchTerm;
|
||||
|
||||
g_return_val_if_fail( server != NULL, NULL );
|
||||
g_return_val_if_fail( req != NULL, NULL );
|
||||
|
||||
/* Retire any aged queries */
|
||||
/* // ldapsvr_retire_query( server ); */
|
||||
|
||||
searchTerm = req->searchTerm;
|
||||
|
||||
/* Construct a query */
|
||||
qry = ldapqry_create();
|
||||
ldapqry_set_query_id( qry, req->queryID );
|
||||
ldapqry_set_search_value( qry, searchTerm );
|
||||
ldapqry_set_search_type( qry, ADDRSEARCH_DYNAMIC );
|
||||
ldapqry_set_callback_entry( qry, req->callBackEntry );
|
||||
ldapqry_set_callback_end( qry, req->callBackEnd );
|
||||
|
||||
/* Name the query */
|
||||
name = g_strdup_printf( "Search for '%s'", searchTerm );
|
||||
ldapqry_set_name( qry, name );
|
||||
g_free( name );
|
||||
|
||||
/* Add query to request */
|
||||
qryreq_add_query( req, ADDRQUERY_OBJECT(qry) );
|
||||
|
||||
/* Now start the search */
|
||||
ldapsvr_add_query( server, qry );
|
||||
|
||||
return qry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new LdapQuery object that will be used to perform an explicit
|
||||
* search request.
|
||||
*
|
||||
* \param server LdapServer.
|
||||
* \param req Query request.
|
||||
* \param folder Folder that will be used to contain search results; may be NULL.
|
||||
* \return LdapQuery object, or <i>NULL</i> if none created.
|
||||
*/
|
||||
LdapQuery *ldapsvr_new_explicit_search(
|
||||
LdapServer *server, QueryRequest *req, ItemFolder *folder )
|
||||
{
|
||||
LdapQuery *qry;
|
||||
gchar *searchTerm;
|
||||
gchar *name;
|
||||
|
||||
g_return_val_if_fail( server != NULL, NULL );
|
||||
g_return_val_if_fail( req != NULL, NULL );
|
||||
searchTerm = req->searchTerm;
|
||||
|
||||
/* Retire any aged queries */
|
||||
/* // ldapsvr_retire_query( server ); */
|
||||
|
||||
/* Name the query */
|
||||
name = g_strdup_printf( "Explicit search for '%s'", searchTerm );
|
||||
|
||||
/* Construct a query */
|
||||
qry = ldapqry_create();
|
||||
ldapqry_set_query_id( qry, req->queryID );
|
||||
ldapqry_set_name( qry, name );
|
||||
ldapqry_set_search_value( qry, searchTerm );
|
||||
ldapqry_set_search_type( qry, ADDRSEARCH_EXPLICIT );
|
||||
ldapqry_set_callback_end( qry, req->callBackEnd );
|
||||
ldapqry_set_callback_entry( qry, req->callBackEntry );
|
||||
|
||||
if( folder ) {
|
||||
/* Specify folder type and back reference */
|
||||
ADDRQUERY_FOLDER(qry) = folder;
|
||||
folder->folderType = ADDRFOLDER_QUERY_RESULTS;
|
||||
folder->folderData = ( gpointer ) qry;
|
||||
}
|
||||
|
||||
/* Setup server */
|
||||
ldapsvr_add_query( server, qry );
|
||||
|
||||
/* Set up query request */
|
||||
qryreq_add_query( req, ADDRQUERY_OBJECT(qry) );
|
||||
|
||||
g_free( name );
|
||||
|
||||
return qry;
|
||||
}
|
||||
|
||||
#endif /* USE_LDAP */
|
||||
|
||||
/*
|
||||
|
|
|
@ -32,14 +32,18 @@
|
|||
#include "addritem.h"
|
||||
#include "addrcache.h"
|
||||
#include "adbookbase.h"
|
||||
#include "addrquery.h"
|
||||
|
||||
#define MGU_LDAP_CONNECT -51
|
||||
#define MGU_LDAP_INIT -52
|
||||
#define MGU_LDAP_BIND -53
|
||||
#define MGU_LDAP_SEARCH -54
|
||||
#define MGU_LDAP_TIMEOUT -55
|
||||
#define MGU_LDAP_CRITERIA -56
|
||||
#define MGU_LDAP_NOENTRIES -57
|
||||
/* Error codes */
|
||||
#define LDAPRC_SUCCESS 0
|
||||
#define LDAPRC_CONNECT -1
|
||||
#define LDAPRC_INIT -2
|
||||
#define LDAPRC_BIND -3
|
||||
#define LDAPRC_SEARCH -4
|
||||
#define LDAPRC_TIMEOUT -5
|
||||
#define LDAPRC_CRITERIA -6
|
||||
#define LDAPRC_NOENTRIES -7
|
||||
#define LDAPRC_STOP_FLAG -8
|
||||
|
||||
typedef struct _LdapServer LdapServer;
|
||||
struct _LdapServer {
|
||||
|
@ -80,6 +84,9 @@ void ldapsvr_stop_all_query ( LdapServer *server );
|
|||
void ldapsvr_cancel_all_query ( LdapServer *server );
|
||||
void ldapsvr_retire_query ( LdapServer *server );
|
||||
|
||||
gboolean ldapsvr_reuse_previous ( const LdapServer *server,
|
||||
const QueryRequest *req );
|
||||
|
||||
#endif /* USE_LDAP */
|
||||
|
||||
#endif /* __LDAPSERVER_H__ */
|
||||
|
|
245
src/logwindow.c
245
src/logwindow.c
|
@ -1,245 +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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include <gtk/gtkwindow.h>
|
||||
#include <gtk/gtksignal.h>
|
||||
#include <gtk/gtkscrolledwindow.h>
|
||||
#include <gtk/gtktextview.h>
|
||||
#include <gtk/gtkstyle.h>
|
||||
|
||||
#include "intl.h"
|
||||
#include "logwindow.h"
|
||||
#include "utils.h"
|
||||
#include "gtkutils.h"
|
||||
#include "prefs_common.h"
|
||||
#include "log.h"
|
||||
#include "hooks.h"
|
||||
|
||||
static void hide_cb (GtkWidget *widget,
|
||||
LogWindow *logwin);
|
||||
static gboolean key_pressed (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
LogWindow *logwin);
|
||||
static gboolean log_window_append (gpointer source,
|
||||
gpointer data);
|
||||
void log_window_clear (GtkWidget *text);
|
||||
|
||||
LogWindow *log_window_create(void)
|
||||
{
|
||||
LogWindow *logwin;
|
||||
GtkWidget *window;
|
||||
GtkWidget *scrolledwin;
|
||||
GtkWidget *text;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
|
||||
debug_print("Creating log window...\n");
|
||||
logwin = g_new0(LogWindow, 1);
|
||||
|
||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(window), _("Protocol log"));
|
||||
gtk_window_set_wmclass(GTK_WINDOW(window), "log_window", "Sylpheed");
|
||||
gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
|
||||
gtk_widget_set_size_request(window, 520, 400);
|
||||
g_signal_connect(G_OBJECT(window), "delete_event",
|
||||
G_CALLBACK(gtk_widget_hide_on_delete), NULL);
|
||||
g_signal_connect(G_OBJECT(window), "key_press_event",
|
||||
G_CALLBACK(key_pressed), logwin);
|
||||
g_signal_connect(G_OBJECT(window), "hide",
|
||||
G_CALLBACK(hide_cb), logwin);
|
||||
gtk_widget_realize(window);
|
||||
|
||||
scrolledwin = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
|
||||
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
|
||||
gtk_container_add(GTK_CONTAINER(window), scrolledwin);
|
||||
gtk_widget_show(scrolledwin);
|
||||
|
||||
text = gtk_text_view_new();
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
|
||||
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
|
||||
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
|
||||
gtk_text_buffer_get_start_iter(buffer, &iter);
|
||||
gtk_text_buffer_create_mark(buffer, "end", &iter, FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(scrolledwin), text);
|
||||
gtk_widget_show(text);
|
||||
|
||||
logwin->window = window;
|
||||
logwin->scrolledwin = scrolledwin;
|
||||
logwin->text = text;
|
||||
logwin->hook_id = hooks_register_hook(LOG_APPEND_TEXT_HOOKLIST, log_window_append, logwin);
|
||||
|
||||
return logwin;
|
||||
}
|
||||
|
||||
void log_window_init(LogWindow *logwin)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GdkColormap *colormap;
|
||||
GdkColor color[3] =
|
||||
{{0, 0, 0xafff, 0}, {0, 0xefff, 0, 0}, {0, 0xefff, 0, 0}};
|
||||
gboolean success[3];
|
||||
gint i;
|
||||
|
||||
gtkut_widget_disable_theme_engine(logwin->text);
|
||||
|
||||
logwin->msg_color = color[0];
|
||||
logwin->warn_color = color[1];
|
||||
logwin->error_color = color[2];
|
||||
|
||||
colormap = gdk_window_get_colormap(logwin->window->window);
|
||||
gdk_colormap_alloc_colors(colormap, color, 3, FALSE, TRUE, success);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (success[i] == FALSE) {
|
||||
GtkStyle *style;
|
||||
|
||||
g_warning("LogWindow: color allocation failed\n");
|
||||
style = gtk_widget_get_style(logwin->window);
|
||||
logwin->msg_color = logwin->warn_color =
|
||||
logwin->error_color = style->black;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(logwin->text));
|
||||
gtk_text_buffer_create_tag(buffer, "message",
|
||||
"foreground-gdk", &logwin->msg_color,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag(buffer, "warn",
|
||||
"foreground-gdk", &logwin->warn_color,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag(buffer, "error",
|
||||
"foreground-gdk", &logwin->error_color,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void log_window_show(LogWindow *logwin)
|
||||
{
|
||||
GtkTextView *text = GTK_TEXT_VIEW(logwin->text);
|
||||
GtkTextBuffer *buffer = gtk_text_view_get_buffer(text);
|
||||
GtkTextMark *mark;
|
||||
|
||||
mark = gtk_text_buffer_get_mark(buffer, "end");
|
||||
gtk_text_view_scroll_mark_onscreen(text, mark);
|
||||
|
||||
gtk_widget_show(logwin->window);
|
||||
}
|
||||
|
||||
static gboolean log_window_append(gpointer source, gpointer data)
|
||||
{
|
||||
LogText *logtext = (LogText *) source;
|
||||
LogWindow *logwindow = (LogWindow *) data;
|
||||
GtkTextView *text;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
GdkColor *color = NULL;
|
||||
gchar *head = NULL;
|
||||
const gchar *tag;
|
||||
|
||||
g_return_val_if_fail(logtext != NULL, TRUE);
|
||||
g_return_val_if_fail(logtext->text != NULL, TRUE);
|
||||
g_return_val_if_fail(logwindow != NULL, FALSE);
|
||||
|
||||
if (prefs_common.cliplog && !prefs_common.loglength)
|
||||
return FALSE;
|
||||
|
||||
text = GTK_TEXT_VIEW(logwindow->text);
|
||||
buffer = gtk_text_view_get_buffer(text);
|
||||
gtk_text_buffer_get_iter_at_offset(buffer, &iter, -1);
|
||||
|
||||
switch (logtext->type) {
|
||||
case LOG_MSG:
|
||||
color = &logwindow->msg_color;
|
||||
tag = "message";
|
||||
head = "* ";
|
||||
break;
|
||||
case LOG_WARN:
|
||||
color = &logwindow->warn_color;
|
||||
tag = "warn";
|
||||
head = "** ";
|
||||
break;
|
||||
case LOG_ERROR:
|
||||
color = &logwindow->error_color;
|
||||
tag = "error";
|
||||
head = "*** ";
|
||||
break;
|
||||
default:
|
||||
tag = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (head)
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, head, -1,
|
||||
tag, NULL);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, logtext->text, -1,
|
||||
tag, NULL);
|
||||
|
||||
gtk_text_buffer_get_start_iter(buffer, &iter);
|
||||
gtk_text_buffer_place_cursor(buffer, &iter);
|
||||
|
||||
if (prefs_common.cliplog)
|
||||
log_window_clear (GTK_WIDGET (text));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void hide_cb(GtkWidget *widget, LogWindow *logwin)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
|
||||
LogWindow *logwin)
|
||||
{
|
||||
if (event && event->keyval == GDK_Escape)
|
||||
gtk_widget_hide(logwin->window);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void log_window_clear(GtkWidget *textw)
|
||||
{
|
||||
guint length;
|
||||
guint point;
|
||||
GtkTextView *textview = GTK_TEXT_VIEW(textw);
|
||||
GtkTextBuffer *textbuf = gtk_text_view_get_buffer(textview);
|
||||
GtkTextIter start_iter, end_iter;
|
||||
|
||||
length = gtk_text_buffer_get_char_count (textbuf);
|
||||
debug_print("Log window length: %u\n", length);
|
||||
|
||||
if (length > prefs_common.loglength) {
|
||||
/* find the end of the first line after the cut off
|
||||
* point */
|
||||
point = length - prefs_common.loglength;
|
||||
gtk_text_buffer_get_iter_at_offset(textbuf, &end_iter, point);
|
||||
if (!gtk_text_iter_forward_to_line_end(&end_iter))
|
||||
return;
|
||||
gtk_text_buffer_get_start_iter(textbuf, &start_iter);
|
||||
gtk_text_buffer_delete(textbuf, &start_iter, &end_iter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,45 +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.
|
||||
*/
|
||||
|
||||
#ifndef __LOGWINDOW_H__
|
||||
#define __LOGWINDOW_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
typedef struct _LogWindow LogWindow;
|
||||
|
||||
struct _LogWindow
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *scrolledwin;
|
||||
GtkWidget *text;
|
||||
|
||||
GdkColor msg_color;
|
||||
GdkColor warn_color;
|
||||
GdkColor error_color;
|
||||
|
||||
guint hook_id;
|
||||
};
|
||||
|
||||
LogWindow *log_window_create(void);
|
||||
void log_window_init(LogWindow *logwin);
|
||||
void log_window_show(LogWindow *logwin);
|
||||
|
||||
#endif /* __LOGWINDOW_H__ */
|
222
src/main.c
222
src/main.c
|
@ -51,8 +51,8 @@
|
|||
#include "prefs_common.h"
|
||||
#include "prefs_account.h"
|
||||
#include "prefs_actions.h"
|
||||
#include "prefs_fonts.h"
|
||||
#include "prefs_spelling.h"
|
||||
#include "scoring.h"
|
||||
#include "prefs_display_header.h"
|
||||
#include "account.h"
|
||||
#include "procmsg.h"
|
||||
|
@ -73,7 +73,8 @@
|
|||
#include "plugin.h"
|
||||
|
||||
#if USE_GPGME
|
||||
# include "rfc2015.h"
|
||||
# include "sgpgme.h"
|
||||
# include "pgpmime.h"
|
||||
#endif
|
||||
#if USE_OPENSSL
|
||||
# include "ssl.h"
|
||||
|
@ -116,10 +117,6 @@ static struct RemoteCmd {
|
|||
|
||||
static void parse_cmd_opt(int argc, char *argv[]);
|
||||
|
||||
#if USE_GPGME
|
||||
static void idle_function_for_gpgme(void);
|
||||
#endif /* USE_GPGME */
|
||||
|
||||
static gint prohibit_duplicate_launch (void);
|
||||
static gchar * get_crashfile_name (void);
|
||||
static gint lock_socket_remove (void);
|
||||
|
@ -139,6 +136,7 @@ static void send_queue (void);
|
|||
static void initial_processing (FolderItem *item, gpointer data);
|
||||
static void quit_signal_handler (int sig);
|
||||
static void install_basic_sighandlers (void);
|
||||
static void exit_sylpheed (MainWindow *mainwin);
|
||||
|
||||
#if 0
|
||||
/* for gettext */
|
||||
|
@ -249,29 +247,11 @@ int main(int argc, char *argv[])
|
|||
prefs_common_read_config();
|
||||
|
||||
#if USE_GPGME
|
||||
gpg_started = FALSE;
|
||||
if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) !=
|
||||
GPGME_No_Error) { /* Also does some gpgme init */
|
||||
rfc2015_disable_all();
|
||||
debug_print("gpgme_engine_version:\n%s\n",
|
||||
gpgme_get_engine_info());
|
||||
|
||||
if (prefs_common.gpg_warning) {
|
||||
AlertValue val;
|
||||
|
||||
val = alertpanel_message_with_disable
|
||||
(_("Warning"),
|
||||
_("GnuPG is not installed properly, or needs to be upgraded.\n"
|
||||
"OpenPGP support disabled."));
|
||||
if (val & G_ALERTDISABLE)
|
||||
prefs_common.gpg_warning = FALSE;
|
||||
}
|
||||
} else
|
||||
gpg_started = TRUE;
|
||||
|
||||
gpgme_register_idle(idle_function_for_gpgme);
|
||||
sgpgme_init();
|
||||
pgpmime_init();
|
||||
#endif
|
||||
|
||||
prefs_fonts_init();
|
||||
#ifdef USE_ASPELL
|
||||
gtkaspell_checkers_init();
|
||||
prefs_spelling_init();
|
||||
|
@ -312,7 +292,6 @@ int main(int argc, char *argv[])
|
|||
folder_set_missing_folders();
|
||||
folderview_set(folderview);
|
||||
|
||||
/* prefs_scoring_read_config(); */
|
||||
prefs_matcher_read_config();
|
||||
|
||||
/* make one all-folder processing before using sylpheed */
|
||||
|
@ -333,6 +312,11 @@ int main(int argc, char *argv[])
|
|||
/* ignore SIGPIPE signal for preventing sudden death of program */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
if (cmd.online_mode == ONLINE_MODE_OFFLINE)
|
||||
main_window_toggle_work_offline(mainwin, TRUE);
|
||||
if (cmd.online_mode == ONLINE_MODE_ONLINE)
|
||||
main_window_toggle_work_offline(mainwin, FALSE);
|
||||
|
||||
if (cmd.receive_all)
|
||||
inc_all_account_mail(mainwin, FALSE,
|
||||
prefs_common.newmail_notify_manu);
|
||||
|
@ -362,11 +346,6 @@ int main(int argc, char *argv[])
|
|||
cmd.status_full_folders = NULL;
|
||||
}
|
||||
|
||||
if (cmd.online_mode == ONLINE_MODE_OFFLINE)
|
||||
main_window_toggle_work_offline(mainwin, TRUE);
|
||||
if (cmd.online_mode == ONLINE_MODE_ONLINE)
|
||||
main_window_toggle_work_offline(mainwin, FALSE);
|
||||
|
||||
prefs_toolbar_init();
|
||||
|
||||
plugin_load_all("GTK");
|
||||
|
@ -374,19 +353,93 @@ int main(int argc, char *argv[])
|
|||
static_mainwindow = mainwin;
|
||||
gtk_main();
|
||||
|
||||
exit_sylpheed(mainwin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void save_all_caches(FolderItem *item, gpointer data)
|
||||
{
|
||||
if (!item->cache)
|
||||
return;
|
||||
folder_item_write_cache(item);
|
||||
}
|
||||
|
||||
static void exit_sylpheed(MainWindow *mainwin)
|
||||
{
|
||||
gchar *filename;
|
||||
GList *list;
|
||||
|
||||
debug_print("shutting down\n");
|
||||
|
||||
inc_autocheck_timer_remove();
|
||||
|
||||
if (prefs_common.clean_on_exit)
|
||||
main_window_empty_trash(mainwin, prefs_common.ask_on_clean);
|
||||
|
||||
/* save prefs for opened folder */
|
||||
if(mainwin->folderview->opened)
|
||||
{
|
||||
FolderItem *item;
|
||||
|
||||
item = gtk_ctree_node_get_row_data(GTK_CTREE(mainwin->folderview->ctree), mainwin->folderview->opened);
|
||||
summary_save_prefs_to_folderitem(mainwin->folderview->summaryview, item);
|
||||
}
|
||||
|
||||
/* save all state before exiting */
|
||||
folder_write_list();
|
||||
folder_func_to_all_folders(save_all_caches, NULL);
|
||||
for (list = folder_get_list(); list != NULL; list = g_list_next(list)) {
|
||||
Folder *folder = FOLDER(list->data);
|
||||
|
||||
folder_tree_destroy(folder);
|
||||
}
|
||||
|
||||
main_window_get_size(mainwin);
|
||||
main_window_get_position(mainwin);
|
||||
prefs_common_save_config();
|
||||
account_save_config_all();
|
||||
addressbook_export_to_file();
|
||||
|
||||
filename = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MENU_RC, NULL);
|
||||
#warning FIXME_GTK2 gtk_item_factory_dump_rc() not existing
|
||||
#if 0
|
||||
gtk_item_factory_dump_rc(filename, NULL, TRUE);
|
||||
#endif
|
||||
gtk_accel_map_save(filename);
|
||||
g_free(filename);
|
||||
|
||||
/* delete temporary files */
|
||||
remove_all_files(get_mime_tmp_dir());
|
||||
|
||||
close_log_file();
|
||||
|
||||
/* delete crashfile */
|
||||
if (!cmd.crash)
|
||||
unlink(get_crashfile_name());
|
||||
|
||||
lock_socket_remove();
|
||||
|
||||
main_window_destroy(mainwin);
|
||||
|
||||
plugin_unload_all("GTK");
|
||||
|
||||
prefs_toolbar_done();
|
||||
|
||||
addressbook_destroy();
|
||||
|
||||
#ifdef USE_GPGME
|
||||
pgpmime_done();
|
||||
sgpgme_done();
|
||||
#endif
|
||||
|
||||
prefs_fonts_done();
|
||||
#ifdef USE_ASPELL
|
||||
prefs_spelling_done();
|
||||
gtkaspell_checkers_quit();
|
||||
#endif
|
||||
sylpheed_done();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void parse_cmd_opt(int argc, char *argv[])
|
||||
|
@ -511,13 +564,6 @@ static gint get_queued_message_num(void)
|
|||
return queue->total_msgs;
|
||||
}
|
||||
|
||||
static void save_all_caches(FolderItem *item, gpointer data)
|
||||
{
|
||||
if (!item->cache)
|
||||
return;
|
||||
folder_item_write_cache(item);
|
||||
}
|
||||
|
||||
static void initial_processing(FolderItem *item, gpointer data)
|
||||
{
|
||||
MainWindow *mainwin = (MainWindow *)data;
|
||||
|
@ -533,7 +579,8 @@ static void initial_processing(FolderItem *item, gpointer data)
|
|||
|
||||
main_window_cursor_wait(mainwin);
|
||||
|
||||
folder_item_apply_processing(item);
|
||||
if (item->prefs->enable_processing)
|
||||
folder_item_apply_processing(item);
|
||||
|
||||
debug_print("done.\n");
|
||||
STATUSBAR_POP(mainwin);
|
||||
|
@ -554,8 +601,14 @@ static void draft_all_messages(void)
|
|||
}
|
||||
}
|
||||
|
||||
void clean_quit(void)
|
||||
gboolean clean_quit(gpointer data)
|
||||
{
|
||||
static gboolean firstrun = TRUE;
|
||||
|
||||
if (!firstrun)
|
||||
return FALSE;
|
||||
firstrun = FALSE;
|
||||
|
||||
/*!< Good idea to have the main window stored in a
|
||||
* static variable so we can check that variable
|
||||
* to see if we're really allowed to do things
|
||||
|
@ -569,27 +622,19 @@ void clean_quit(void)
|
|||
* in the original spawner, and not in a spawned
|
||||
* child. */
|
||||
if (!static_mainwindow)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
draft_all_messages();
|
||||
|
||||
if (prefs_common.warn_queued_on_exit) {
|
||||
/* disable the popup */
|
||||
prefs_common.warn_queued_on_exit = FALSE;
|
||||
app_will_exit(NULL, static_mainwindow);
|
||||
prefs_common.warn_queued_on_exit = TRUE;
|
||||
prefs_common_save_config();
|
||||
} else {
|
||||
app_will_exit(NULL, static_mainwindow);
|
||||
}
|
||||
exit_sylpheed(static_mainwindow);
|
||||
exit(0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void app_will_exit(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
MainWindow *mainwin = data;
|
||||
gchar *filename;
|
||||
GList *list;
|
||||
|
||||
if (compose_get_compose_list()) {
|
||||
gint val = alertpanel(_("Notice"),
|
||||
|
@ -614,66 +659,9 @@ void app_will_exit(GtkWidget *widget, gpointer data)
|
|||
return;
|
||||
manage_window_focus_in(mainwin->window, NULL, NULL);
|
||||
}
|
||||
|
||||
inc_autocheck_timer_remove();
|
||||
|
||||
#if USE_GPGME
|
||||
gpgmegtk_free_passphrase();
|
||||
#endif
|
||||
|
||||
if (prefs_common.clean_on_exit)
|
||||
main_window_empty_trash(mainwin, prefs_common.ask_on_clean);
|
||||
|
||||
/* save prefs for opened folder */
|
||||
if(mainwin->folderview->opened)
|
||||
{
|
||||
FolderItem *item;
|
||||
|
||||
item = gtk_ctree_node_get_row_data(GTK_CTREE(mainwin->folderview->ctree), mainwin->folderview->opened);
|
||||
summary_save_prefs_to_folderitem(mainwin->folderview->summaryview, item);
|
||||
}
|
||||
|
||||
/* save all state before exiting */
|
||||
folder_write_list();
|
||||
folder_func_to_all_folders(save_all_caches, NULL);
|
||||
for (list = folder_get_list(); list != NULL; list = g_list_next(list)) {
|
||||
Folder *folder = FOLDER(list->data);
|
||||
|
||||
folder_tree_destroy(folder);
|
||||
}
|
||||
|
||||
main_window_get_size(mainwin);
|
||||
main_window_get_position(mainwin);
|
||||
prefs_common_save_config();
|
||||
account_save_config_all();
|
||||
addressbook_export_to_file();
|
||||
|
||||
filename = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MENU_RC, NULL);
|
||||
gtk_accel_map_save (filename);
|
||||
g_free(filename);
|
||||
|
||||
/* delete temporary files */
|
||||
remove_all_files(get_mime_tmp_dir());
|
||||
|
||||
close_log_file();
|
||||
|
||||
/* delete crashfile */
|
||||
if (!cmd.crash)
|
||||
unlink(get_crashfile_name());
|
||||
|
||||
lock_socket_remove();
|
||||
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
#if USE_GPGME
|
||||
static void idle_function_for_gpgme(void)
|
||||
{
|
||||
while (gtk_events_pending())
|
||||
gtk_main_iteration();
|
||||
}
|
||||
#endif /* USE_GPGME */
|
||||
|
||||
/*
|
||||
* CLAWS: want this public so crash dialog can delete the
|
||||
* lock file too
|
||||
|
@ -902,9 +890,6 @@ static void open_compose_new(const gchar *address, GPtrArray *attach_files)
|
|||
static void send_queue(void)
|
||||
{
|
||||
GList *list;
|
||||
FolderItem *def_outbox;
|
||||
|
||||
def_outbox = folder_get_default_outbox();
|
||||
|
||||
for (list = folder_get_list(); list != NULL; list = list->next) {
|
||||
Folder *folder = list->data;
|
||||
|
@ -917,10 +902,6 @@ static void send_queue(void)
|
|||
alertpanel_error(_("Some errors occurred while sending queued messages."));
|
||||
if (res)
|
||||
folder_item_scan(folder->queue);
|
||||
if (prefs_common.savemsg && folder->outbox) {
|
||||
if (folder->outbox == def_outbox)
|
||||
def_outbox = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -928,7 +909,8 @@ static void send_queue(void)
|
|||
static void quit_signal_handler(int sig)
|
||||
{
|
||||
debug_print("Quitting on signal %d\n", sig);
|
||||
clean_quit();
|
||||
|
||||
g_timeout_add(0, clean_quit, NULL);
|
||||
}
|
||||
|
||||
static void install_basic_sighandlers()
|
||||
|
|
|
@ -27,6 +27,6 @@ extern gchar *prog_version;
|
|||
extern gboolean debug_mode;
|
||||
|
||||
void app_will_exit (GtkWidget *widget, gpointer data);
|
||||
void clean_quit (void);
|
||||
gboolean clean_quit (gpointer data);
|
||||
|
||||
#endif /* __MAIN_H__ */
|
||||
|
|
169
src/mainwindow.c
169
src/mainwindow.c
|
@ -39,6 +39,7 @@
|
|||
#include <gtk/gtkhandlebox.h>
|
||||
#include <gtk/gtktoolbar.h>
|
||||
#include <gtk/gtkbutton.h>
|
||||
#include <gtk/gtktooltips.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "intl.h"
|
||||
|
@ -62,7 +63,6 @@
|
|||
#include "prefs_common.h"
|
||||
#include "prefs_actions.h"
|
||||
#include "prefs_filtering.h"
|
||||
#include "prefs_scoring.h"
|
||||
#include "prefs_account.h"
|
||||
#include "prefs_summary_column.h"
|
||||
#include "prefs_template.h"
|
||||
|
@ -86,6 +86,8 @@
|
|||
#include "pluginwindow.h"
|
||||
#include "hooks.h"
|
||||
#include "progressindicator.h"
|
||||
#include "localfolder.h"
|
||||
#include "filtering.h"
|
||||
|
||||
#define AC_LABEL_WIDTH 240
|
||||
|
||||
|
@ -136,9 +138,6 @@ static void message_window_size_allocate_cb (GtkWidget *widget,
|
|||
static void new_folder_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
static void add_mbox_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
static void rename_folder_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
|
@ -345,6 +344,9 @@ static void select_thread_cb (MainWindow *mainwin,
|
|||
static void create_filter_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
static void create_processing_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
|
||||
static void prefs_common_open_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
|
@ -358,9 +360,15 @@ static void prefs_actions_open_cb (MainWindow *mainwin,
|
|||
static void prefs_account_open_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
static void prefs_scoring_open_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
|
||||
static void prefs_pre_processing_open_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
|
||||
static void prefs_post_processing_open_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
|
||||
static void prefs_filtering_open_cb (MainWindow *mainwin,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
|
@ -425,15 +433,15 @@ static GtkItemFactoryEntry mainwin_entries[] =
|
|||
NULL, update_folderview_cb, 0, NULL},
|
||||
{N_("/_File/_Add mailbox"), NULL, NULL, 0, "<Branch>"},
|
||||
{N_("/_File/_Add mailbox/MH..."), NULL, add_mailbox_cb, 0, NULL},
|
||||
{N_("/_File/_Add mailbox/mbox..."), NULL, add_mbox_cb, 0, NULL},
|
||||
{N_("/_File/_Import mbox file..."), NULL, import_mbox_cb, 0, NULL},
|
||||
{N_("/_File/_Export to mbox file..."), NULL, export_mbox_cb, 0, NULL},
|
||||
{N_("/_File/Empty _trash"), "<shift>D", empty_trash_cb, 0, NULL},
|
||||
{N_("/_File/_Work offline"), "<control>W", toggle_work_offline_cb, 0, "<ToggleItem>"},
|
||||
{N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
|
||||
{N_("/_File/_Save as..."), "<control>S", save_as_cb, 0, NULL},
|
||||
{N_("/_File/_Print..."), NULL, print_cb, 0, NULL},
|
||||
{N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
|
||||
{N_("/_File/_Work offline"), "<control>W", toggle_work_offline_cb, 0, "<ToggleItem>"},
|
||||
{N_("/_File/---"), NULL, NULL, 0, "<Separator>"},
|
||||
/* {N_("/_File/_Close"), "<alt>W", app_exit_cb, 0, NULL}, */
|
||||
{N_("/_File/E_xit"), "<control>Q", app_exit_cb, 0, NULL},
|
||||
|
||||
|
@ -665,6 +673,15 @@ static GtkItemFactoryEntry mainwin_entries[] =
|
|||
NULL, create_filter_cb, FILTER_BY_TO, NULL},
|
||||
{N_("/_Tools/_Create filter rule/by _Subject"),
|
||||
NULL, create_filter_cb, FILTER_BY_SUBJECT, NULL},
|
||||
{N_("/_Tools/_Create processing rule"), NULL, NULL, 0, "<Branch>"},
|
||||
{N_("/_Tools/_Create processing rule/_Automatically"),
|
||||
NULL, create_processing_cb, FILTER_BY_AUTO, NULL},
|
||||
{N_("/_Tools/_Create processing rule/by _From"),
|
||||
NULL, create_processing_cb, FILTER_BY_FROM, NULL},
|
||||
{N_("/_Tools/_Create processing rule/by _To"),
|
||||
NULL, create_processing_cb, FILTER_BY_TO, NULL},
|
||||
{N_("/_Tools/_Create processing rule/by _Subject"),
|
||||
NULL, create_processing_cb, FILTER_BY_SUBJECT, NULL},
|
||||
{N_("/_Tools/---"), NULL, NULL, 0, "<Separator>"},
|
||||
{N_("/_Tools/Actio_ns"), NULL, NULL, 0, "<Branch>"},
|
||||
{N_("/_Tools/---"), NULL, NULL, 0, "<Separator>"},
|
||||
|
@ -692,8 +709,10 @@ static GtkItemFactoryEntry mainwin_entries[] =
|
|||
{N_("/_Configuration/---"), NULL, NULL, 0, "<Separator>"},
|
||||
{N_("/_Configuration/_Common preferences..."),
|
||||
NULL, prefs_common_open_cb, 0, NULL},
|
||||
{N_("/_Configuration/_Scoring..."),
|
||||
NULL, prefs_scoring_open_cb, 0, NULL},
|
||||
{N_("/_Configuration/Pre-processing..."),
|
||||
NULL, prefs_pre_processing_open_cb, 0, NULL},
|
||||
{N_("/_Configuration/Post-processing..."),
|
||||
NULL, prefs_post_processing_open_cb, 0, NULL},
|
||||
{N_("/_Configuration/_Filtering..."),
|
||||
NULL, prefs_filtering_open_cb, 0, NULL},
|
||||
{N_("/_Configuration/_Templates..."), NULL, prefs_template_open_cb, 0, NULL},
|
||||
|
@ -824,16 +843,17 @@ MainWindow *main_window_create(SeparateType type)
|
|||
gtk_widget_set_size_request(progressbar, 120, 1);
|
||||
gtk_box_pack_start(GTK_BOX(hbox_stat), progressbar, FALSE, FALSE, 0);
|
||||
|
||||
online_pixmap = stock_pixmap_widget(hbox_stat, STOCK_PIXMAP_WORK_ONLINE);
|
||||
offline_pixmap = stock_pixmap_widget(hbox_stat, STOCK_PIXMAP_WORK_OFFLINE);
|
||||
online_pixmap = stock_pixmap_widget(hbox_stat, STOCK_PIXMAP_ONLINE);
|
||||
offline_pixmap = stock_pixmap_widget(hbox_stat, STOCK_PIXMAP_OFFLINE);
|
||||
online_tip = gtk_tooltips_new();
|
||||
online_switch = gtk_button_new ();
|
||||
gtk_tooltips_set_tip(GTK_TOOLTIPS(online_tip),
|
||||
online_switch, _("Go offline"), NULL);
|
||||
gtk_tooltips_set_tip(GTK_TOOLTIPS(online_tip),online_switch,
|
||||
_("You are online. Click the icon to go offline"), NULL);
|
||||
offline_tip = gtk_tooltips_new();
|
||||
offline_switch = gtk_button_new ();
|
||||
gtk_tooltips_set_tip(GTK_TOOLTIPS(offline_tip),
|
||||
offline_switch, _("Go online"), NULL);
|
||||
gtk_tooltips_set_tip(GTK_TOOLTIPS(offline_tip),offline_switch,
|
||||
_("You are offline. Click the icon to go online"),
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER(online_switch), online_pixmap);
|
||||
gtk_button_set_relief (GTK_BUTTON(online_switch), GTK_RELIEF_NONE);
|
||||
g_signal_connect (G_OBJECT(online_switch), "clicked", G_CALLBACK(online_switch_clicked), mainwin);
|
||||
|
@ -1013,6 +1033,8 @@ MainWindow *main_window_create(SeparateType type)
|
|||
summary_init(summaryview);
|
||||
messageview_init(messageview);
|
||||
log_window_init(mainwin->logwin);
|
||||
log_window_set_clipping(mainwin->logwin, prefs_common.cliplog,
|
||||
prefs_common.loglength);
|
||||
#ifdef USE_OPENSSL
|
||||
sslcertwindow_register_hook();
|
||||
#endif
|
||||
|
@ -1035,6 +1057,12 @@ MainWindow *main_window_create(SeparateType type)
|
|||
return mainwin;
|
||||
}
|
||||
|
||||
void main_window_destroy(MainWindow *mainwin)
|
||||
{
|
||||
/* TODO : destroy other component */
|
||||
messageview_destroy(mainwin->messageview);
|
||||
}
|
||||
|
||||
void main_window_cursor_wait(MainWindow *mainwin)
|
||||
{
|
||||
|
||||
|
@ -1118,13 +1146,13 @@ void main_window_reflect_prefs_all_real(gboolean pixmap_theme_changed)
|
|||
folderview_reflect_prefs_pixmap_theme(mainwin->folderview);
|
||||
summary_reflect_prefs_pixmap_theme(mainwin->summaryview);
|
||||
|
||||
pixmap = stock_pixmap_widget(mainwin->hbox_stat, STOCK_PIXMAP_WORK_ONLINE);
|
||||
pixmap = stock_pixmap_widget(mainwin->hbox_stat, STOCK_PIXMAP_ONLINE);
|
||||
gtk_container_remove(GTK_CONTAINER(mainwin->online_switch),
|
||||
mainwin->online_pixmap);
|
||||
gtk_container_add (GTK_CONTAINER(mainwin->online_switch), pixmap);
|
||||
gtk_widget_show(pixmap);
|
||||
mainwin->online_pixmap = pixmap;
|
||||
pixmap = stock_pixmap_widget(mainwin->hbox_stat, STOCK_PIXMAP_WORK_OFFLINE);
|
||||
pixmap = stock_pixmap_widget(mainwin->hbox_stat, STOCK_PIXMAP_OFFLINE);
|
||||
gtk_container_remove(GTK_CONTAINER(mainwin->offline_switch),
|
||||
mainwin->offline_pixmap);
|
||||
gtk_container_add (GTK_CONTAINER(mainwin->offline_switch), pixmap);
|
||||
|
@ -1482,39 +1510,6 @@ void main_window_add_mailbox(MainWindow *mainwin)
|
|||
folderview_set(mainwin->folderview);
|
||||
}
|
||||
|
||||
void main_window_add_mbox(MainWindow *mainwin)
|
||||
{
|
||||
gchar *path;
|
||||
Folder *folder;
|
||||
FolderItem * item;
|
||||
|
||||
path = input_dialog(_("Add mbox mailbox"),
|
||||
_("Input the location of mailbox."),
|
||||
"mail");
|
||||
|
||||
if (!path) return;
|
||||
|
||||
if (folder_find_from_path(path)) {
|
||||
alertpanel_error(_("The mailbox `%s' already exists."), path);
|
||||
g_free(path);
|
||||
return;
|
||||
}
|
||||
|
||||
folder = folder_new(folder_get_class_from_string("mbox"),
|
||||
g_basename(path), path);
|
||||
g_free(path);
|
||||
|
||||
if (folder->klass->create_tree(folder) < 0) {
|
||||
alertpanel_error(_("Creation of the mailbox failed."));
|
||||
folder_destroy(folder);
|
||||
return;
|
||||
}
|
||||
|
||||
folder_add(folder);
|
||||
|
||||
folderview_set(mainwin->folderview);
|
||||
}
|
||||
|
||||
SensitiveCond main_window_get_current_state(MainWindow *mainwin)
|
||||
{
|
||||
SensitiveCond state = 0;
|
||||
|
@ -1596,7 +1591,6 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
|
|||
{"/File/Add mailbox" , M_UNLOCKED},
|
||||
|
||||
{"/File/Add mailbox/MH..." , M_UNLOCKED},
|
||||
{"/File/Add mailbox/mbox..." , M_UNLOCKED},
|
||||
{"/File/Export to mbox file..." , M_UNLOCKED},
|
||||
{"/File/Empty trash" , M_UNLOCKED},
|
||||
{"/File/Work offline" , M_UNLOCKED},
|
||||
|
@ -1721,7 +1715,7 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
|
|||
}
|
||||
|
||||
SET_CHECK_MENU_ACTIVE("/View/Show all headers",
|
||||
mainwin->messageview->textview->show_all_headers);
|
||||
mainwin->messageview->mimeview->textview->show_all_headers);
|
||||
SET_CHECK_MENU_ACTIVE("/View/Thread view", (state & M_THREADED) != 0);
|
||||
|
||||
#undef SET_CHECK_MENU_ACTIVE
|
||||
|
@ -1854,9 +1848,6 @@ static void main_window_set_widgets(MainWindow *mainwin, SeparateType type)
|
|||
g_signal_connect(G_OBJECT(messagewin), "delete_event",
|
||||
G_CALLBACK(message_window_close_cb),
|
||||
mainwin);
|
||||
gtk_container_add(GTK_CONTAINER(messagewin),
|
||||
GTK_WIDGET_PTR(mainwin->messageview));
|
||||
gtk_widget_realize(messagewin);
|
||||
if (messageview_is_visible(mainwin->messageview))
|
||||
gtk_widget_show(messagewin);
|
||||
}
|
||||
|
@ -1944,14 +1935,32 @@ static void main_window_set_widgets(MainWindow *mainwin, SeparateType type)
|
|||
mainwin->win.sep_message.messagewin = messagewin;
|
||||
mainwin->win.sep_message.hpaned = hpaned;
|
||||
|
||||
gtk_widget_realize(messagewin);
|
||||
gtk_widget_show_all(GTK_WIDGET_PTR(mainwin->messageview));
|
||||
gtk_widget_show_all(messagewin);
|
||||
toolbar_set_style(mainwin->messageview->toolbar->toolbar,
|
||||
mainwin->messageview->handlebox,
|
||||
prefs_common.toolbar_style);
|
||||
|
||||
break;
|
||||
case SEPARATE_BOTH:
|
||||
messageview_add_toolbar(mainwin->messageview, messagewin);
|
||||
msgview_ifactory = gtk_item_factory_from_widget(mainwin->messageview->menubar);
|
||||
menu_set_sensitive(msgview_ifactory, "/File/Close", FALSE);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(vbox_body),
|
||||
GTK_WIDGET_PTR(mainwin->summaryview),
|
||||
TRUE, TRUE, 0);
|
||||
|
||||
|
||||
mainwin->win.sep_both.folderwin = folderwin;
|
||||
mainwin->win.sep_both.messagewin = messagewin;
|
||||
|
||||
gtk_widget_realize(messagewin);
|
||||
gtk_widget_show_all(GTK_WIDGET_PTR(mainwin->messageview));
|
||||
gtk_widget_show_all(messagewin);
|
||||
toolbar_set_style(mainwin->messageview->toolbar->toolbar,
|
||||
mainwin->messageview->handlebox,
|
||||
prefs_common.toolbar_style);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1967,6 +1976,8 @@ static void main_window_set_widgets(MainWindow *mainwin, SeparateType type)
|
|||
* and mimeview icon list/ctree lose track of their visibility states */
|
||||
if (!noticeview_is_visible(mainwin->messageview->noticeview))
|
||||
gtk_widget_hide(GTK_WIDGET_PTR(mainwin->messageview->noticeview));
|
||||
if (!noticeview_is_visible(mainwin->messageview->mimeview->siginfoview))
|
||||
gtk_widget_hide(GTK_WIDGET_PTR(mainwin->messageview->mimeview->siginfoview));
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mainwin->messageview->mimeview->mime_toggle)))
|
||||
gtk_widget_hide(mainwin->messageview->mimeview->icon_mainbox);
|
||||
else
|
||||
|
@ -2157,12 +2168,6 @@ static void add_mailbox_cb(MainWindow *mainwin, guint action,
|
|||
main_window_add_mailbox(mainwin);
|
||||
}
|
||||
|
||||
static void add_mbox_cb(MainWindow *mainwin, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
main_window_add_mbox(mainwin);
|
||||
}
|
||||
|
||||
static void update_folderview_cb(MainWindow *mainwin, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
|
@ -2681,8 +2686,7 @@ static void allsel_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
|
|||
if (GTK_WIDGET_HAS_FOCUS(mainwin->summaryview->ctree))
|
||||
summary_select_all(mainwin->summaryview);
|
||||
else if (messageview_is_visible(msgview) &&
|
||||
(GTK_WIDGET_HAS_FOCUS(msgview->textview->text) ||
|
||||
GTK_WIDGET_HAS_FOCUS(msgview->mimeview->textview->text)))
|
||||
(GTK_WIDGET_HAS_FOCUS(msgview->mimeview->textview->text)))
|
||||
messageview_select_all(mainwin->messageview);
|
||||
}
|
||||
|
||||
|
@ -2695,7 +2699,13 @@ static void select_thread_cb(MainWindow *mainwin, guint action,
|
|||
static void create_filter_cb(MainWindow *mainwin, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
summary_filter_open(mainwin->summaryview, (PrefsFilterType)action);
|
||||
summary_filter_open(mainwin->summaryview, (PrefsFilterType)action, 0);
|
||||
}
|
||||
|
||||
static void create_processing_cb(MainWindow *mainwin, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
summary_filter_open(mainwin->summaryview, (PrefsFilterType)action, 1);
|
||||
}
|
||||
|
||||
static void prefs_common_open_cb(MainWindow *mainwin, guint action,
|
||||
|
@ -2704,16 +2714,28 @@ static void prefs_common_open_cb(MainWindow *mainwin, guint action,
|
|||
prefs_common_open();
|
||||
}
|
||||
|
||||
static void prefs_scoring_open_cb(MainWindow *mainwin, guint action,
|
||||
GtkWidget *widget)
|
||||
static void prefs_pre_processing_open_cb(MainWindow *mainwin, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
prefs_scoring_open(NULL);
|
||||
prefs_filtering_open(&pre_global_processing,
|
||||
_("Processing rules to apply before folder rules"),
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void prefs_post_processing_open_cb(MainWindow *mainwin, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
prefs_filtering_open(&post_global_processing,
|
||||
_("Processing rules to apply after folder rules"),
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void prefs_filtering_open_cb(MainWindow *mainwin, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
prefs_filtering_open(NULL, NULL, NULL);
|
||||
prefs_filtering_open(&filtering_rules,
|
||||
_("Filtering configuration"),
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void prefs_template_open_cb(MainWindow *mainwin, guint action,
|
||||
|
@ -2800,6 +2822,11 @@ static gboolean mainwindow_focus_in_event(GtkWidget *widget, GdkEventFocus *focu
|
|||
g_return_val_if_fail(data, FALSE);
|
||||
summary = ((MainWindow *)data)->summaryview;
|
||||
g_return_val_if_fail(summary, FALSE);
|
||||
|
||||
if (GTK_CLIST(summary->ctree)->selection &&
|
||||
g_list_length(GTK_CLIST(summary->ctree)->selection) > 1)
|
||||
return FALSE;
|
||||
|
||||
if (summary->selected != summary->displayed)
|
||||
summary_select_node(summary, summary->displayed, FALSE, TRUE);
|
||||
return FALSE;
|
||||
|
|
|
@ -136,6 +136,8 @@ struct _MainWindow
|
|||
|
||||
MainWindow *main_window_create (SeparateType type);
|
||||
|
||||
void main_window_destroy (MainWindow *mainwin);
|
||||
|
||||
void main_window_cursor_wait (MainWindow *mainwin);
|
||||
void main_window_cursor_normal (MainWindow *mainwin);
|
||||
|
||||
|
|
411
src/matcher.c
411
src/matcher.c
|
@ -28,6 +28,7 @@
|
|||
#include "intl.h"
|
||||
#include "matcher_parser.h"
|
||||
#include "prefs_gtk.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/*!
|
||||
*\brief Keyword lookup element
|
||||
|
@ -100,8 +101,8 @@ static const MatchParser matchparser_tab[] = {
|
|||
{MATCHCRITERIA_NOT_MESSAGE, "~message"},
|
||||
{MATCHCRITERIA_BODY_PART, "body_part"},
|
||||
{MATCHCRITERIA_NOT_BODY_PART, "~body_part"},
|
||||
{MATCHCRITERIA_EXECUTE, "execute"},
|
||||
{MATCHCRITERIA_NOT_EXECUTE, "~execute"},
|
||||
{MATCHCRITERIA_TEST, "test"},
|
||||
{MATCHCRITERIA_NOT_TEST, "~test"},
|
||||
|
||||
/* match type */
|
||||
{MATCHTYPE_MATCHCASE, "matchcase"},
|
||||
|
@ -110,7 +111,7 @@ static const MatchParser matchparser_tab[] = {
|
|||
{MATCHTYPE_REGEXP, "regexp"},
|
||||
|
||||
/* actions */
|
||||
{MATCHACTION_SCORE, "score"},
|
||||
{MATCHACTION_SCORE, "score"}, /* for backward compatibility */
|
||||
{MATCHACTION_MOVE, "move"},
|
||||
{MATCHACTION_COPY, "copy"},
|
||||
{MATCHACTION_DELETE, "delete"},
|
||||
|
@ -125,7 +126,10 @@ static const MatchParser matchparser_tab[] = {
|
|||
{MATCHACTION_EXECUTE, "execute"},
|
||||
{MATCHACTION_COLOR, "color"},
|
||||
{MATCHACTION_REDIRECT, "redirect"},
|
||||
{MATCHACTION_CHANGE_SCORE, "change_score"}
|
||||
{MATCHACTION_CHANGE_SCORE, "change_score"},
|
||||
{MATCHACTION_SET_SCORE, "set_score"},
|
||||
{MATCHACTION_STOP, "stop"},
|
||||
{MATCHACTION_HIDE, "hide"},
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -183,92 +187,6 @@ gint get_matchparser_tab_id(const gchar *str)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
*\brief Escape characters in a string by inserting '\' characters
|
||||
*
|
||||
*\param str String with characters to be escaped
|
||||
*
|
||||
*\return gchar * Newly allocated string with escaped characters
|
||||
*/
|
||||
gchar *matcher_escape_str(const gchar *str)
|
||||
{
|
||||
register const gchar *walk;
|
||||
register int escape;
|
||||
gchar *res;
|
||||
register char *reswalk;
|
||||
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
for (escape = 0, walk = str; *walk; walk++)
|
||||
if (*walk == '\\' || *walk == '\'' || *walk == '\"')
|
||||
escape++;
|
||||
|
||||
if (!escape)
|
||||
return g_strdup(str);
|
||||
|
||||
reswalk = res = g_new0(gchar, (walk - str) + escape + 1);
|
||||
for (walk = str; *walk; walk++, reswalk++) {
|
||||
if (*walk == '\\' || *walk == '\'' || *walk == '\"')
|
||||
*reswalk++ = '\\';
|
||||
*reswalk = *walk;
|
||||
}
|
||||
|
||||
*reswalk = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
*\brief Unescape string by replacing escaped char sequences
|
||||
* (\b, \n, etc) by their actual char. Note that this
|
||||
* function changes the contents of the buffer pointed
|
||||
* to by \a str.
|
||||
*
|
||||
*\param str Buffer containing string that needs to be escaped.
|
||||
* Note that this function changes the contents of the
|
||||
* buffer
|
||||
*
|
||||
*\return gchar * Pointer to changed buffer
|
||||
*/
|
||||
gchar *matcher_unescape_str(gchar *str)
|
||||
{
|
||||
gchar *tmp = alloca(strlen(str) + 1);
|
||||
register gchar *src = tmp;
|
||||
register gchar *dst = str;
|
||||
|
||||
strcpy(tmp, str);
|
||||
|
||||
for ( ; *src; src++) {
|
||||
if (*src != '\\')
|
||||
*dst++ = *src;
|
||||
else {
|
||||
src++;
|
||||
if (*src == 'n') /* insert control characters */
|
||||
*dst++ = '\n';
|
||||
else if (*src == 'r')
|
||||
*dst++ = '\r';
|
||||
else if (*src == 't')
|
||||
*dst++ = '\t';
|
||||
else if (*src == 'r')
|
||||
*dst++ = '\r';
|
||||
else if (*src == 'b')
|
||||
*dst++ = '\b';
|
||||
else if (*src == 'f')
|
||||
*dst++ = '\f';
|
||||
else if (*src == '\\' || *src == '\'' || *src == '\"')
|
||||
/* insert \\, \' or \" */
|
||||
*dst++ = *src;
|
||||
else {
|
||||
/* FIXME: should perhaps escape character... */
|
||||
src--;
|
||||
*dst++ = *src;
|
||||
}
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* **************** data structure allocation **************** */
|
||||
|
||||
/*!
|
||||
|
@ -342,42 +260,6 @@ MatcherProp *matcherprop_copy(const MatcherProp *src)
|
|||
return prop;
|
||||
}
|
||||
|
||||
/* ****************** wrapper for file reading ************** */
|
||||
|
||||
/*!
|
||||
*\brief Allocate a matcher structure where all strings
|
||||
* are unescaped ("unquoted")
|
||||
*
|
||||
*\param criteria One of the MATCHCRITERIA_XXX constants
|
||||
*\param header A header string
|
||||
*\param matchtype Type of matcher (MATCHTYPE_XXX)
|
||||
*\param expr Matcher string expression
|
||||
*\param value Matcher integer value
|
||||
*
|
||||
*\return MatcherProp * Pointer to newly allocated matcher
|
||||
* structure
|
||||
*/
|
||||
MatcherProp *matcherprop_unquote_new(gint criteria, const gchar *header,
|
||||
gint matchtype, const gchar *expr,
|
||||
int value)
|
||||
{
|
||||
MatcherProp *prop;
|
||||
|
||||
if (expr != NULL)
|
||||
expr = matcher_unescape_str(g_strdup(expr));
|
||||
|
||||
if (header != NULL)
|
||||
header = matcher_unescape_str(g_strdup(header));
|
||||
|
||||
prop = matcherprop_new(criteria, header, matchtype, expr, value);
|
||||
|
||||
g_free((gpointer) header);
|
||||
g_free((gpointer) expr);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
|
||||
/* ************** match ******************************/
|
||||
|
||||
/*!
|
||||
|
@ -446,7 +328,7 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str)
|
|||
*
|
||||
*\return gboolean TRUE if command was executed succesfully
|
||||
*/
|
||||
static gboolean matcherprop_match_execute(const MatcherProp *prop,
|
||||
static gboolean matcherprop_match_test(const MatcherProp *prop,
|
||||
MsgInfo *info)
|
||||
{
|
||||
gchar *file;
|
||||
|
@ -577,10 +459,10 @@ gboolean matcherprop_match(MatcherProp *prop,
|
|||
return matcherprop_string_match(prop, info->references);
|
||||
case MATCHCRITERIA_NOT_REFERENCES:
|
||||
return !matcherprop_string_match(prop, info->references);
|
||||
case MATCHCRITERIA_EXECUTE:
|
||||
return matcherprop_match_execute(prop, info);
|
||||
case MATCHCRITERIA_NOT_EXECUTE:
|
||||
return !matcherprop_match_execute(prop, info);
|
||||
case MATCHCRITERIA_TEST:
|
||||
return matcherprop_match_test(prop, info);
|
||||
case MATCHCRITERIA_NOT_TEST:
|
||||
return !matcherprop_match_test(prop, info);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -1028,8 +910,8 @@ gboolean matcherlist_match(MatcherList *matchers, MsgInfo *info)
|
|||
case MATCHCRITERIA_SIZE_GREATER:
|
||||
case MATCHCRITERIA_SIZE_SMALLER:
|
||||
case MATCHCRITERIA_SIZE_EQUAL:
|
||||
case MATCHCRITERIA_EXECUTE:
|
||||
case MATCHCRITERIA_NOT_EXECUTE:
|
||||
case MATCHCRITERIA_TEST:
|
||||
case MATCHCRITERIA_NOT_TEST:
|
||||
if (matcherprop_match(matcher, info)) {
|
||||
if (!matchers->bool_and) {
|
||||
return TRUE;
|
||||
|
@ -1057,6 +939,68 @@ gboolean matcherlist_match(MatcherList *matchers, MsgInfo *info)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
static gint quote_filter_str(gchar * result, guint size,
|
||||
const gchar * path)
|
||||
{
|
||||
const gchar * p;
|
||||
gchar * result_p;
|
||||
guint remaining;
|
||||
|
||||
result_p = result;
|
||||
remaining = size;
|
||||
|
||||
for(p = path ; * p != '\0' ; p ++) {
|
||||
|
||||
if ((* p != '\"') && (* p != '\\')) {
|
||||
if (remaining > 0) {
|
||||
* result_p = * p;
|
||||
result_p ++;
|
||||
remaining --;
|
||||
}
|
||||
else {
|
||||
result[size - 1] = '\0';
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (remaining >= 2) {
|
||||
* result_p = '\\';
|
||||
result_p ++;
|
||||
* result_p = * p;
|
||||
result_p ++;
|
||||
remaining -= 2;
|
||||
}
|
||||
else {
|
||||
result[size - 1] = '\0';
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (remaining > 0) {
|
||||
* result_p = '\0';
|
||||
}
|
||||
else {
|
||||
result[size - 1] = '\0';
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
gchar * matcher_quote_str(const gchar * src)
|
||||
{
|
||||
gchar * res;
|
||||
gint len;
|
||||
|
||||
len = strlen(src) * 2 + 1;
|
||||
res = g_malloc(len);
|
||||
quote_filter_str(res, len, src);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
*\brief Convert a matcher structure to a string
|
||||
*
|
||||
|
@ -1070,8 +1014,8 @@ gchar *matcherprop_to_string(MatcherProp *matcher)
|
|||
const gchar *criteria_str;
|
||||
const gchar *matchtype_str;
|
||||
int i;
|
||||
gchar *expr;
|
||||
|
||||
gchar * quoted_expr;
|
||||
|
||||
criteria_str = NULL;
|
||||
for (i = 0; i < (int) (sizeof(matchparser_tab) / sizeof(MatchParser)); i++) {
|
||||
if (matchparser_tab[i].id == matcher->criteria)
|
||||
|
@ -1110,11 +1054,12 @@ gchar *matcherprop_to_string(MatcherProp *matcher)
|
|||
case MATCHCRITERIA_IGNORE_THREAD:
|
||||
case MATCHCRITERIA_NOT_IGNORE_THREAD:
|
||||
return g_strdup(criteria_str);
|
||||
case MATCHCRITERIA_EXECUTE:
|
||||
case MATCHCRITERIA_NOT_EXECUTE:
|
||||
expr = matcher_escape_str(matcher->expr);
|
||||
matcher_str = g_strdup_printf("%s \"%s\"", criteria_str, expr);
|
||||
g_free((gpointer) expr);
|
||||
case MATCHCRITERIA_TEST:
|
||||
case MATCHCRITERIA_NOT_TEST:
|
||||
quoted_expr = matcher_quote_str(matcher->expr);
|
||||
matcher_str = g_strdup_printf("%s \"%s\"",
|
||||
criteria_str, quoted_expr);
|
||||
g_free(quoted_expr);
|
||||
return matcher_str;
|
||||
}
|
||||
|
||||
|
@ -1132,17 +1077,22 @@ gchar *matcherprop_to_string(MatcherProp *matcher)
|
|||
case MATCHTYPE_MATCHCASE:
|
||||
case MATCHTYPE_REGEXP:
|
||||
case MATCHTYPE_REGEXPCASE:
|
||||
expr = matcher_escape_str(matcher->expr);
|
||||
if (matcher->header)
|
||||
quoted_expr = matcher_quote_str(matcher->expr);
|
||||
if (matcher->header) {
|
||||
gchar * quoted_header;
|
||||
|
||||
quoted_header = matcher_quote_str(matcher->header);
|
||||
matcher_str = g_strdup_printf
|
||||
("%s \"%s\" %s \"%s\"",
|
||||
criteria_str, matcher->header,
|
||||
matchtype_str, expr);
|
||||
criteria_str, quoted_header,
|
||||
matchtype_str, quoted_expr);
|
||||
g_free(quoted_header);
|
||||
}
|
||||
else
|
||||
matcher_str = g_strdup_printf
|
||||
("%s %s \"%s\"", criteria_str,
|
||||
matchtype_str, expr);
|
||||
g_free((gpointer) expr);
|
||||
matchtype_str, quoted_expr);
|
||||
g_free(quoted_expr);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1187,8 +1137,27 @@ gchar *matcherlist_to_string(const MatcherList *matchers)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
#define STRLEN_ZERO(s) ((s) ? strlen(s) : 0)
|
||||
#define STRLEN_DEFAULT(s,d) ((s) ? strlen(s) : STRLEN_ZERO(d))
|
||||
|
||||
static void add_str_default(gchar ** dest,
|
||||
const gchar * s, const gchar * d)
|
||||
{
|
||||
gchar quoted_str[4096];
|
||||
const gchar * str;
|
||||
|
||||
if (s != NULL)
|
||||
str = s;
|
||||
else
|
||||
str = d;
|
||||
|
||||
quote_cmd_argument(quoted_str, sizeof(quoted_str), str);
|
||||
strcpy(* dest, quoted_str);
|
||||
|
||||
(* dest) += strlen(* dest);
|
||||
}
|
||||
|
||||
/* matching_build_command() - preferably cmd should be unescaped */
|
||||
/*!
|
||||
*\brief Build the command line to execute
|
||||
|
@ -1197,9 +1166,6 @@ gchar *matcherlist_to_string(const MatcherList *matchers)
|
|||
*\param info Message info to use for command
|
||||
*
|
||||
*\return gchar * Newly allocated string
|
||||
*
|
||||
*\warning The \a cmd string should have been unescaped using
|
||||
* #matcher_unescape_str.
|
||||
*/
|
||||
gchar *matching_build_command(const gchar *cmd, MsgInfo *info)
|
||||
{
|
||||
|
@ -1251,21 +1217,25 @@ gchar *matching_build_command(const gchar *cmd, MsgInfo *info)
|
|||
size += STRLEN_DEFAULT(info->references, no_references) - 2;
|
||||
break;
|
||||
case 'F': /* file */
|
||||
filename = folder_item_fetch_msg(info->folder,
|
||||
info->msgnum);
|
||||
if (filename == NULL)
|
||||
filename = folder_item_fetch_msg(info->folder, info->msgnum);
|
||||
|
||||
if (filename == NULL) {
|
||||
g_warning("filename is not set");
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
else {
|
||||
size += strlen(filename) - 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
else s++;
|
||||
}
|
||||
|
||||
/* as the string can be quoted, we double the result */
|
||||
size *= 2;
|
||||
|
||||
processed_cmd = g_new0(gchar, size);
|
||||
s = cmd;
|
||||
|
@ -1280,65 +1250,40 @@ gchar *matching_build_command(const gchar *cmd, MsgInfo *info)
|
|||
p++;
|
||||
break;
|
||||
case 's': /* subject */
|
||||
if (info->subject != NULL)
|
||||
strcpy(p, info->subject);
|
||||
else
|
||||
strcpy(p, no_subject);
|
||||
p += strlen(p);
|
||||
add_str_default(&p, info->subject,
|
||||
no_subject);
|
||||
break;
|
||||
case 'f': /* from */
|
||||
if (info->from != NULL)
|
||||
strcpy(p, info->from);
|
||||
else
|
||||
strcpy(p, no_from);
|
||||
p += strlen(p);
|
||||
add_str_default(&p, info->from,
|
||||
no_from);
|
||||
break;
|
||||
case 't': /* to */
|
||||
if (info->to != NULL)
|
||||
strcpy(p, info->to);
|
||||
else
|
||||
strcpy(p, no_to);
|
||||
p += strlen(p);
|
||||
add_str_default(&p, info->to,
|
||||
no_to);
|
||||
break;
|
||||
case 'c': /* cc */
|
||||
if (info->cc != NULL)
|
||||
strcpy(p, info->cc);
|
||||
else
|
||||
strcpy(p, no_cc);
|
||||
p += strlen(p);
|
||||
add_str_default(&p, info->cc,
|
||||
no_cc);
|
||||
break;
|
||||
case 'd': /* date */
|
||||
if (info->date != NULL)
|
||||
strcpy(p, info->date);
|
||||
else
|
||||
strcpy(p, no_date);
|
||||
p += strlen(p);
|
||||
add_str_default(&p, info->date,
|
||||
no_date);
|
||||
break;
|
||||
case 'i': /* message-id */
|
||||
if (info->msgid != NULL)
|
||||
strcpy(p, info->msgid);
|
||||
else
|
||||
strcpy(p, no_msgid);
|
||||
p += strlen(p);
|
||||
add_str_default(&p, info->msgid,
|
||||
no_msgid);
|
||||
break;
|
||||
case 'n': /* newsgroups */
|
||||
if (info->newsgroups != NULL)
|
||||
strcpy(p, info->newsgroups);
|
||||
else
|
||||
strcpy(p, no_newsgroups);
|
||||
p += strlen(p);
|
||||
add_str_default(&p, info->newsgroups,
|
||||
no_newsgroups);
|
||||
break;
|
||||
case 'r': /* references */
|
||||
if (info->references != NULL)
|
||||
strcpy(p, info->references);
|
||||
else
|
||||
strcpy(p, no_references);
|
||||
p += strlen(p);
|
||||
add_str_default(&p, info->references,
|
||||
no_references);
|
||||
break;
|
||||
case 'F': /* file */
|
||||
strcpy(p, filename);
|
||||
p += strlen(p);
|
||||
g_free(filename);
|
||||
if (filename != NULL)
|
||||
add_str_default(&p, filename, NULL);
|
||||
break;
|
||||
default:
|
||||
*p = '%';
|
||||
|
@ -1355,7 +1300,8 @@ gchar *matching_build_command(const gchar *cmd, MsgInfo *info)
|
|||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
g_free(filename);
|
||||
|
||||
return processed_cmd;
|
||||
}
|
||||
#undef STRLEN_DEFAULT
|
||||
|
@ -1363,31 +1309,6 @@ gchar *matching_build_command(const gchar *cmd, MsgInfo *info)
|
|||
|
||||
/* ************************************************************ */
|
||||
|
||||
/*!
|
||||
*\brief Write scoring list to file
|
||||
*
|
||||
*\param fp File
|
||||
*\param prefs_scoring List of scoring conditions
|
||||
*/
|
||||
static void prefs_scoring_write(FILE *fp, GSList *prefs_scoring)
|
||||
{
|
||||
GSList *cur;
|
||||
|
||||
for (cur = prefs_scoring; cur != NULL; cur = cur->next) {
|
||||
gchar *scoring_str;
|
||||
ScoringProp *prop;
|
||||
|
||||
prop = (ScoringProp *) cur->data;
|
||||
scoring_str = scoringprop_to_string(prop);
|
||||
if (fputs(scoring_str, fp) == EOF ||
|
||||
fputc('\n', fp) == EOF) {
|
||||
FILE_OP_ERROR("scoring config", "fputs || fputc");
|
||||
g_free(scoring_str);
|
||||
return;
|
||||
}
|
||||
g_free(scoring_str);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
*\brief Write filtering list to file
|
||||
|
@ -1432,33 +1353,20 @@ static gboolean prefs_matcher_write_func(GNode *node, gpointer data)
|
|||
FolderItem *item;
|
||||
FILE *fp = data;
|
||||
gchar *id;
|
||||
GSList *prefs_scoring;
|
||||
GSList *prefs_filtering;
|
||||
|
||||
if (node != NULL) {
|
||||
item = node->data;
|
||||
/* prevent warning */
|
||||
if (item->path == NULL)
|
||||
return FALSE;
|
||||
id = folder_item_get_identifier(item);
|
||||
if (id == NULL)
|
||||
return FALSE;
|
||||
prefs_scoring = item->prefs->scoring;
|
||||
prefs_filtering = item->prefs->processing;
|
||||
}
|
||||
else {
|
||||
item = NULL;
|
||||
id = g_strdup("global"); /* because it is g_freed */
|
||||
prefs_scoring = global_scoring;
|
||||
prefs_filtering = global_processing;
|
||||
}
|
||||
item = node->data;
|
||||
/* prevent warning */
|
||||
if (item->path == NULL)
|
||||
return FALSE;
|
||||
id = folder_item_get_identifier(item);
|
||||
if (id == NULL)
|
||||
return FALSE;
|
||||
prefs_filtering = item->prefs->processing;
|
||||
|
||||
if (prefs_filtering != NULL || prefs_scoring != NULL) {
|
||||
if (prefs_filtering != NULL) {
|
||||
fprintf(fp, "[%s]\n", id);
|
||||
|
||||
prefs_filtering_write(fp, prefs_filtering);
|
||||
prefs_scoring_write(fp, prefs_scoring);
|
||||
|
||||
fputc('\n', fp);
|
||||
}
|
||||
|
||||
|
@ -1483,7 +1391,21 @@ static void prefs_matcher_save(FILE *fp)
|
|||
g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
|
||||
prefs_matcher_write_func, fp);
|
||||
}
|
||||
prefs_matcher_write_func(NULL, fp);
|
||||
|
||||
/* pre global rules */
|
||||
fprintf(fp, "[preglobal]\n");
|
||||
prefs_filtering_write(fp, pre_global_processing);
|
||||
fputc('\n', fp);
|
||||
|
||||
/* post global rules */
|
||||
fprintf(fp, "[postglobal]\n");
|
||||
prefs_filtering_write(fp, post_global_processing);
|
||||
fputc('\n', fp);
|
||||
|
||||
/* filtering rules */
|
||||
fprintf(fp, "[filtering]\n");
|
||||
prefs_filtering_write(fp, filtering_rules);
|
||||
fputc('\n', fp);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1527,7 +1449,6 @@ void prefs_matcher_read_config(void)
|
|||
FILE *f;
|
||||
|
||||
create_matchparser_hashtab();
|
||||
prefs_scoring_clear();
|
||||
prefs_filtering_clear();
|
||||
|
||||
rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MATCHER_RC, NULL);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
/* constants generated by yacc */
|
||||
#if !defined(YYBISON) && !defined(MATCHER_ALL)
|
||||
# include "matcher_parser_lex.h"
|
||||
# include "matcher_parser_parse.h"
|
||||
#endif
|
||||
|
||||
|
@ -93,7 +94,7 @@ enum {
|
|||
MC_(HEADERS_PART), MC_(NOT_HEADERS_PART),
|
||||
MC_(MESSAGE), MC_(NOT_MESSAGE),
|
||||
MC_(BODY_PART), MC_(NOT_BODY_PART),
|
||||
MC_(EXECUTE), MC_(NOT_EXECUTE),
|
||||
MC_(TEST), MC_(NOT_TEST),
|
||||
MC_(SCORE_EQUAL),
|
||||
MC_(SIZE_GREATER),
|
||||
MC_(SIZE_SMALLER),
|
||||
|
@ -120,6 +121,9 @@ enum {
|
|||
MA_(COLOR),
|
||||
MA_(REDIRECT),
|
||||
MA_(CHANGE_SCORE),
|
||||
MA_(SET_SCORE),
|
||||
MA_(STOP),
|
||||
MA_(HIDE),
|
||||
/* boolean operations */
|
||||
MB_(OR),
|
||||
MB_(AND)
|
||||
|
@ -133,11 +137,6 @@ MatcherProp *matcherprop_new (gint criteria,
|
|||
gint matchtype,
|
||||
const gchar *expr,
|
||||
int value);
|
||||
MatcherProp *matcherprop_unquote_new (gint criteria,
|
||||
const gchar *header,
|
||||
gint matchtype,
|
||||
const gchar *expr,
|
||||
int value);
|
||||
void matcherprop_free (MatcherProp *prop);
|
||||
|
||||
MatcherProp *matcherprop_parse (gchar **str);
|
||||
|
@ -161,8 +160,6 @@ gint matcher_parse_number (gchar **str);
|
|||
gboolean matcher_parse_boolean_op (gchar **str);
|
||||
gchar *matcher_parse_regexp (gchar **str);
|
||||
gchar *matcher_parse_str (gchar **str);
|
||||
gchar *matcher_escape_str (const gchar *str);
|
||||
gchar *matcher_unescape_str (gchar *str);
|
||||
gchar *matcherprop_to_string (MatcherProp *matcher);
|
||||
gchar *matcherlist_to_string (const MatcherList *matchers);
|
||||
gchar *matching_build_command (const gchar *cmd,
|
||||
|
@ -170,6 +167,7 @@ gchar *matching_build_command (const gchar *cmd,
|
|||
|
||||
void prefs_matcher_read_config (void);
|
||||
void prefs_matcher_write_config (void);
|
||||
void *matcher_parser_scan_string (const gchar *str);
|
||||
|
||||
gchar * matcher_quote_str(const gchar * src);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#define MATCHER_PARSER_H
|
||||
|
||||
#include "filtering.h"
|
||||
#include "scoring.h"
|
||||
#include <glib.h>
|
||||
|
||||
extern FILE *matcher_parserin;
|
||||
|
@ -34,7 +33,6 @@ int matcher_parserparse (void);
|
|||
MatcherList *matcher_parser_get_cond (const gchar *str);
|
||||
MatcherProp *matcher_parser_get_prop (const gchar *str);
|
||||
FilteringProp *matcher_parser_get_filtering (const gchar *str);
|
||||
ScoringProp *matcher_parser_get_scoring (const gchar *str);
|
||||
GSList *matcher_parser_get_action_list(const gchar *str);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <string.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "matcher.h"
|
||||
#include "matcher_parser_lex.h"
|
||||
#include "matcher_parser_parse.h"
|
||||
|
||||
|
@ -75,15 +76,6 @@ void matcher_parser_init(void)
|
|||
BEGIN(string);
|
||||
string_buf_ptr = string_buf;
|
||||
}
|
||||
/* alfons - OK, the new attempt is to just swallow
|
||||
* *EVERYTHING* and make sure everything is escaped
|
||||
* when actually performing things. */
|
||||
<string>\\\" {
|
||||
/* take care of escaped \" because this means the
|
||||
* quote char should be skipped */
|
||||
add_char('\\');
|
||||
add_char('\"');
|
||||
}
|
||||
<string>\" {
|
||||
/* get out of the state: string ends. */
|
||||
BEGIN(0);
|
||||
|
@ -91,11 +83,15 @@ void matcher_parser_init(void)
|
|||
yylval.str = string_buf;
|
||||
return MATCHER_STRING;
|
||||
}
|
||||
/* put everything else in the output. */
|
||||
<string>\\. {
|
||||
/* take care of quoted characters */
|
||||
add_char(yytext[1]);
|
||||
}
|
||||
<string>. {
|
||||
add_char(yytext[0]);
|
||||
}
|
||||
\[[^\[\]]*\] {
|
||||
/* for section name in configuration file */
|
||||
BEGIN(0);
|
||||
yylval.str = yytext + 1;
|
||||
yytext[strlen(yytext) - 1] = '\0';
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "intl.h"
|
||||
#include "utils.h"
|
||||
#include "filtering.h"
|
||||
#include "scoring.h"
|
||||
#include "matcher.h"
|
||||
#include "matcher_parser.h"
|
||||
#include "matcher_parser_lex.h"
|
||||
|
@ -50,23 +49,18 @@ static GSList *action_list = NULL;
|
|||
static FilteringAction *action = NULL;
|
||||
|
||||
static FilteringProp *filtering;
|
||||
static ScoringProp *scoring = NULL;
|
||||
|
||||
static GSList **prefs_scoring = NULL;
|
||||
static GSList **prefs_filtering = NULL;
|
||||
|
||||
#if 0
|
||||
static int matcher_parser_dialog = 0;
|
||||
#endif
|
||||
static int enable_compatibility = 0;
|
||||
|
||||
enum {
|
||||
MATCHER_PARSE_NONE,
|
||||
MATCHER_PARSE_FILE,
|
||||
MATCHER_PARSE_NO_EOL,
|
||||
MATCHER_PARSE_CONDITION,
|
||||
MATCHER_PARSE_FILTERING_OR_SCORING,
|
||||
MATCHER_PARSE_FILTERING_ACTION,
|
||||
};
|
||||
|
||||
static int matcher_parse_op = MATCHER_PARSE_NONE;
|
||||
static int matcher_parse_op = MATCHER_PARSE_FILE;
|
||||
|
||||
|
||||
/* ******************************************************************** */
|
||||
|
@ -76,6 +70,9 @@ void matcher_parser_start_parsing(FILE *f)
|
|||
matcher_parserrestart(f);
|
||||
matcher_parserparse();
|
||||
}
|
||||
|
||||
|
||||
void * matcher_parser_scan_string(const char * str);
|
||||
|
||||
FilteringProp *matcher_parser_get_filtering(const gchar *str)
|
||||
{
|
||||
|
@ -87,34 +84,15 @@ FilteringProp *matcher_parser_get_filtering(const gchar *str)
|
|||
matcher_parse_op = MATCHER_PARSE_NO_EOL;
|
||||
matcher_parserrestart(NULL);
|
||||
matcher_parser_init();
|
||||
bufstate = matcher_parser_scan_string(str);
|
||||
bufstate = matcher_parser_scan_string((const char *) str);
|
||||
matcher_parser_switch_to_buffer(bufstate);
|
||||
if (matcher_parserparse() != 0)
|
||||
filtering = NULL;
|
||||
matcher_parse_op = MATCHER_PARSE_NONE;
|
||||
matcher_parse_op = MATCHER_PARSE_FILE;
|
||||
matcher_parser_delete_buffer(bufstate);
|
||||
return filtering;
|
||||
}
|
||||
|
||||
ScoringProp *matcher_parser_get_scoring(const gchar *str)
|
||||
{
|
||||
void *bufstate;
|
||||
|
||||
/* bad coding to enable the sub-grammar matching
|
||||
in yacc */
|
||||
matcher_parserlineno = 1;
|
||||
matcher_parse_op = MATCHER_PARSE_NO_EOL;
|
||||
matcher_parserrestart(NULL);
|
||||
matcher_parser_init();
|
||||
bufstate = matcher_parser_scan_string(str);
|
||||
matcher_parser_switch_to_buffer(bufstate);
|
||||
if (matcher_parserparse() != 0)
|
||||
scoring = NULL;
|
||||
matcher_parse_op = MATCHER_PARSE_NONE;
|
||||
matcher_parser_delete_buffer(bufstate);
|
||||
return scoring;
|
||||
}
|
||||
|
||||
static gboolean check_quote_symetry(gchar *str)
|
||||
{
|
||||
const gchar *walk;
|
||||
|
@ -151,7 +129,7 @@ MatcherList *matcher_parser_get_cond(const gchar *str)
|
|||
matcher_parser_init();
|
||||
bufstate = matcher_parser_scan_string(str);
|
||||
matcher_parserparse();
|
||||
matcher_parse_op = MATCHER_PARSE_NONE;
|
||||
matcher_parse_op = MATCHER_PARSE_FILE;
|
||||
matcher_parser_delete_buffer(bufstate);
|
||||
return cond;
|
||||
}
|
||||
|
@ -168,12 +146,12 @@ GSList *matcher_parser_get_action_list(const gchar *str)
|
|||
/* bad coding to enable the sub-grammar matching
|
||||
in yacc */
|
||||
matcher_parserlineno = 1;
|
||||
matcher_parse_op = MATCHER_PARSE_FILTERING_OR_SCORING;
|
||||
matcher_parse_op = MATCHER_PARSE_FILTERING_ACTION;
|
||||
matcher_parserrestart(NULL);
|
||||
matcher_parser_init();
|
||||
bufstate = matcher_parser_scan_string(str);
|
||||
matcher_parserparse();
|
||||
matcher_parse_op = MATCHER_PARSE_NONE;
|
||||
matcher_parse_op = MATCHER_PARSE_FILE;
|
||||
matcher_parser_delete_buffer(bufstate);
|
||||
return action_list;
|
||||
}
|
||||
|
@ -216,7 +194,7 @@ void matcher_parsererror(char *str)
|
|||
matchers_list = NULL;
|
||||
}
|
||||
cond = NULL;
|
||||
g_warning("scoring / filtering parsing: %i: %s\n",
|
||||
g_warning("filtering parsing: %i: %s\n",
|
||||
matcher_parserlineno, str);
|
||||
error = 1;
|
||||
}
|
||||
|
@ -245,9 +223,11 @@ int matcher_parserwrap(void)
|
|||
%token MATCHER_SCORE_LOWER MATCHER_HEADER MATCHER_NOT_HEADER
|
||||
%token MATCHER_HEADERS_PART MATCHER_NOT_HEADERS_PART MATCHER_MESSAGE
|
||||
%token MATCHER_NOT_MESSAGE MATCHER_BODY_PART MATCHER_NOT_BODY_PART
|
||||
%token MATCHER_EXECUTE MATCHER_NOT_EXECUTE MATCHER_MATCHCASE MATCHER_MATCH
|
||||
%token MATCHER_TEST MATCHER_NOT_TEST MATCHER_MATCHCASE MATCHER_MATCH
|
||||
%token MATCHER_REGEXPCASE MATCHER_REGEXP MATCHER_SCORE MATCHER_MOVE
|
||||
%token MATCHER_COPY MATCHER_DELETE MATCHER_MARK MATCHER_UNMARK MATCHER_LOCK MATCHER_UNLOCK
|
||||
%token MATCHER_COPY MATCHER_DELETE MATCHER_MARK MATCHER_UNMARK
|
||||
%token MATCHER_LOCK MATCHER_UNLOCK
|
||||
%token MATCHER_EXECUTE
|
||||
%token MATCHER_MARK_AS_READ MATCHER_MARK_AS_UNREAD MATCHER_FORWARD
|
||||
%token MATCHER_FORWARD_AS_ATTACHMENT MATCHER_EOL MATCHER_STRING
|
||||
%token MATCHER_OR MATCHER_AND
|
||||
|
@ -256,7 +236,8 @@ int matcher_parserwrap(void)
|
|||
%token MATCHER_LOCKED MATCHER_NOT_LOCKED
|
||||
%token MATCHER_COLORLABEL MATCHER_NOT_COLORLABEL
|
||||
%token MATCHER_IGNORE_THREAD MATCHER_NOT_IGNORE_THREAD
|
||||
%token MATCHER_CHANGE_SCORE
|
||||
%token MATCHER_CHANGE_SCORE MATCHER_SET_SCORE
|
||||
%token MATCHER_STOP MATCHER_HIDE
|
||||
|
||||
%start file
|
||||
|
||||
|
@ -268,9 +249,8 @@ int matcher_parserwrap(void)
|
|||
|
||||
file:
|
||||
{
|
||||
if (matcher_parse_op == MATCHER_PARSE_NONE) {
|
||||
prefs_scoring = &global_scoring;
|
||||
prefs_filtering = &global_processing;
|
||||
if (matcher_parse_op == MATCHER_PARSE_FILE) {
|
||||
prefs_filtering = &pre_global_processing;
|
||||
}
|
||||
}
|
||||
file_line_list;
|
||||
|
@ -297,17 +277,26 @@ MATCHER_SECTION MATCHER_EOL
|
|||
gchar *folder = $1;
|
||||
FolderItem *item = NULL;
|
||||
|
||||
if (matcher_parse_op == MATCHER_PARSE_NONE) {
|
||||
if (matcher_parse_op == MATCHER_PARSE_FILE) {
|
||||
enable_compatibility = 0;
|
||||
if (!strcmp(folder, "global")) {
|
||||
prefs_scoring = &global_scoring;
|
||||
prefs_filtering = &global_processing;
|
||||
} else {
|
||||
/* backward compatibility */
|
||||
enable_compatibility = 1;
|
||||
}
|
||||
else if (!strcmp(folder, "preglobal")) {
|
||||
prefs_filtering = &pre_global_processing;
|
||||
}
|
||||
else if (!strcmp(folder, "postglobal")) {
|
||||
prefs_filtering = &post_global_processing;
|
||||
}
|
||||
else if (!strcmp(folder, "filtering")) {
|
||||
prefs_filtering = &filtering_rules;
|
||||
}
|
||||
else {
|
||||
item = folder_find_item_from_identifier(folder);
|
||||
if (item != NULL) {
|
||||
prefs_scoring = &item->prefs->scoring;
|
||||
prefs_filtering = &item->prefs->processing;
|
||||
} else {
|
||||
prefs_scoring = NULL;
|
||||
prefs_filtering = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -316,8 +305,8 @@ MATCHER_SECTION MATCHER_EOL
|
|||
;
|
||||
|
||||
instruction:
|
||||
condition filtering_or_scoring MATCHER_EOL
|
||||
| condition filtering_or_scoring
|
||||
condition filtering MATCHER_EOL
|
||||
| condition filtering
|
||||
{
|
||||
if (matcher_parse_op == MATCHER_PARSE_NO_EOL)
|
||||
YYACCEPT;
|
||||
|
@ -337,7 +326,7 @@ condition filtering_or_scoring MATCHER_EOL
|
|||
}
|
||||
| filtering_action_list
|
||||
{
|
||||
if (matcher_parse_op == MATCHER_PARSE_FILTERING_OR_SCORING)
|
||||
if (matcher_parse_op == MATCHER_PARSE_FILTERING_ACTION)
|
||||
YYACCEPT;
|
||||
else {
|
||||
matcher_parsererror("parse error");
|
||||
|
@ -347,29 +336,33 @@ condition filtering_or_scoring MATCHER_EOL
|
|||
| MATCHER_EOL
|
||||
;
|
||||
|
||||
filtering_or_scoring:
|
||||
filtering:
|
||||
filtering_action_list
|
||||
{
|
||||
filtering = filteringprop_new(cond, action_list);
|
||||
|
||||
if (enable_compatibility) {
|
||||
prefs_filtering = &filtering_rules;
|
||||
if (action_list != NULL) {
|
||||
FilteringAction * first_action;
|
||||
|
||||
first_action = action_list->data;
|
||||
|
||||
if (first_action->type == MATCHACTION_CHANGE_SCORE)
|
||||
prefs_filtering = &pre_global_processing;
|
||||
}
|
||||
}
|
||||
|
||||
cond = NULL;
|
||||
action_list = NULL;
|
||||
if ((matcher_parse_op == MATCHER_PARSE_NONE) && (prefs_filtering != NULL)) {
|
||||
|
||||
if ((matcher_parse_op == MATCHER_PARSE_FILE) &&
|
||||
(prefs_filtering != NULL)) {
|
||||
*prefs_filtering = g_slist_append(*prefs_filtering,
|
||||
filtering);
|
||||
filtering = NULL;
|
||||
}
|
||||
}
|
||||
| scoring_rule
|
||||
{
|
||||
scoring = scoringprop_new(cond, score);
|
||||
cond = NULL;
|
||||
score = 0;
|
||||
if ((matcher_parse_op == MATCHER_PARSE_NONE)
|
||||
&& (prefs_scoring != NULL)) {
|
||||
*prefs_scoring = g_slist_append(*prefs_scoring, scoring);
|
||||
scoring = NULL;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
filtering_action_list:
|
||||
|
@ -441,105 +434,105 @@ MATCHER_ALL
|
|||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_ALL;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_UNREAD
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_UNREAD;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_NOT_UNREAD
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_UNREAD;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_NEW
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NEW;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_NOT_NEW
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_NEW;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_MARKED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_MARKED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_NOT_MARKED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_MARKED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_DELETED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_DELETED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_NOT_DELETED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_DELETED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_REPLIED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_REPLIED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_NOT_REPLIED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_REPLIED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_FORWARDED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_FORWARDED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_NOT_FORWARDED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_FORWARDED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_LOCKED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_LOCKED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_NOT_LOCKED
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_LOCKED;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_COLORLABEL MATCHER_INTEGER
|
||||
{
|
||||
|
@ -547,10 +540,10 @@ MATCHER_ALL
|
|||
gint value = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_COLORLABEL;
|
||||
value = atoi($2);
|
||||
if (value < 1) value = 1;
|
||||
value = strtol($2, NULL, 10);
|
||||
if (value < 0) value = 0;
|
||||
else if (value > MAX_COLORLABELS) value = MAX_COLORLABELS;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_NOT_COLORLABEL MATCHER_INTEGER
|
||||
{
|
||||
|
@ -558,24 +551,24 @@ MATCHER_ALL
|
|||
gint value = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_COLORLABEL;
|
||||
value = atoi($2);
|
||||
if (value < 1) value = 1;
|
||||
value = strtol($2, NULL, 0);
|
||||
if (value < 0) value = 0;
|
||||
else if (value > MAX_COLORLABELS) value = MAX_COLORLABELS;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_IGNORE_THREAD
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_IGNORE_THREAD;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_NOT_IGNORE_THREAD
|
||||
{
|
||||
gint criteria = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_IGNORE_THREAD;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
|
||||
}
|
||||
| MATCHER_SUBJECT match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -584,7 +577,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_SUBJECT;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_SUBJECT match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -593,7 +586,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_SUBJECT;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_FROM match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -602,7 +595,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_FROM;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_FROM match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -611,7 +604,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_FROM;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_TO match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -620,7 +613,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_TO;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_TO match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -629,7 +622,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_TO;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_CC match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -638,7 +631,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_CC;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_CC match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -647,7 +640,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_CC;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_TO_OR_CC match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -656,7 +649,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_TO_OR_CC;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_TO_AND_NOT_CC match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -665,7 +658,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_TO_AND_NOT_CC;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_AGE_GREATER MATCHER_INTEGER
|
||||
{
|
||||
|
@ -673,8 +666,8 @@ MATCHER_ALL
|
|||
gint value = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_AGE_GREATER;
|
||||
value = atoi($2);
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
value = strtol($2, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_AGE_LOWER MATCHER_INTEGER
|
||||
{
|
||||
|
@ -682,8 +675,8 @@ MATCHER_ALL
|
|||
gint value = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_AGE_LOWER;
|
||||
value = atoi($2);
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
value = strtol($2, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_NEWSGROUPS match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -692,7 +685,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NEWSGROUPS;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_NEWSGROUPS match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -701,7 +694,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_NEWSGROUPS;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_INREPLYTO match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -710,7 +703,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_INREPLYTO;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_INREPLYTO match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -719,7 +712,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_INREPLYTO;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_REFERENCES match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -728,7 +721,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_REFERENCES;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_REFERENCES match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -737,7 +730,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_REFERENCES;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_SCORE_GREATER MATCHER_INTEGER
|
||||
{
|
||||
|
@ -745,8 +738,8 @@ MATCHER_ALL
|
|||
gint value = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_SCORE_GREATER;
|
||||
value = atoi($2);
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
value = strtol($2, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_SCORE_LOWER MATCHER_INTEGER
|
||||
{
|
||||
|
@ -754,8 +747,8 @@ MATCHER_ALL
|
|||
gint value = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_SCORE_LOWER;
|
||||
value = atoi($2);
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
value = strtol($2, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_SCORE_EQUAL MATCHER_INTEGER
|
||||
{
|
||||
|
@ -763,32 +756,32 @@ MATCHER_ALL
|
|||
gint value = 0;
|
||||
|
||||
criteria = MATCHCRITERIA_SCORE_EQUAL;
|
||||
value = atoi($2);
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
value = strtol($2, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_SIZE_GREATER MATCHER_INTEGER
|
||||
{
|
||||
gint criteria = 0;
|
||||
gint value = 0;
|
||||
criteria = MATCHCRITERIA_SIZE_GREATER;
|
||||
value = atoi($2);
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
value = strtol($2, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_SIZE_SMALLER MATCHER_INTEGER
|
||||
{
|
||||
gint criteria = 0;
|
||||
gint value = 0;
|
||||
criteria = MATCHCRITERIA_SIZE_SMALLER;
|
||||
value = atoi($2);
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
value = strtol($2, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_SIZE_EQUAL MATCHER_INTEGER
|
||||
{
|
||||
gint criteria = 0;
|
||||
gint value = 0;
|
||||
criteria = MATCHCRITERIA_SIZE_EQUAL;
|
||||
value = atoi($2);
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, NULL, value);
|
||||
value = strtol($2, NULL, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, NULL, value);
|
||||
}
|
||||
| MATCHER_HEADER MATCHER_STRING
|
||||
{
|
||||
|
@ -800,7 +793,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_HEADER;
|
||||
expr = $2;
|
||||
prop = matcherprop_unquote_new(criteria, header, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, header, match_type, expr, 0);
|
||||
g_free(header);
|
||||
}
|
||||
| MATCHER_NOT_HEADER MATCHER_STRING
|
||||
|
@ -813,7 +806,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_HEADER;
|
||||
expr = $2;
|
||||
prop = matcherprop_unquote_new(criteria, header, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, header, match_type, expr, 0);
|
||||
g_free(header);
|
||||
}
|
||||
| MATCHER_HEADERS_PART match_type MATCHER_STRING
|
||||
|
@ -823,7 +816,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_HEADERS_PART;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_HEADERS_PART match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -832,7 +825,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_HEADERS_PART;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_MESSAGE match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -841,7 +834,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_MESSAGE;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_MESSAGE match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -850,7 +843,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_MESSAGE;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_BODY_PART match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -859,7 +852,7 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_BODY_PART;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_BODY_PART match_type MATCHER_STRING
|
||||
{
|
||||
|
@ -868,25 +861,25 @@ MATCHER_ALL
|
|||
|
||||
criteria = MATCHCRITERIA_NOT_BODY_PART;
|
||||
expr = $3;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, match_type, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
|
||||
}
|
||||
| MATCHER_EXECUTE MATCHER_STRING
|
||||
| MATCHER_TEST MATCHER_STRING
|
||||
{
|
||||
gint criteria = 0;
|
||||
gchar *expr = NULL;
|
||||
|
||||
criteria = MATCHCRITERIA_EXECUTE;
|
||||
criteria = MATCHCRITERIA_TEST;
|
||||
expr = $2;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, expr, 0);
|
||||
}
|
||||
| MATCHER_NOT_EXECUTE MATCHER_STRING
|
||||
| MATCHER_NOT_TEST MATCHER_STRING
|
||||
{
|
||||
gint criteria = 0;
|
||||
gchar *expr = NULL;
|
||||
|
||||
criteria = MATCHCRITERIA_NOT_EXECUTE;
|
||||
criteria = MATCHCRITERIA_NOT_TEST;
|
||||
expr = $2;
|
||||
prop = matcherprop_unquote_new(criteria, NULL, 0, expr, 0);
|
||||
prop = matcherprop_new(criteria, NULL, 0, expr, 0);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -898,7 +891,7 @@ MATCHER_EXECUTE MATCHER_STRING
|
|||
|
||||
action_type = MATCHACTION_EXECUTE;
|
||||
cmd = $2;
|
||||
action = filteringaction_new(action_type, 0, cmd, 0);
|
||||
action = filteringaction_new(action_type, 0, cmd, 0, 0);
|
||||
}
|
||||
| MATCHER_MOVE MATCHER_STRING
|
||||
{
|
||||
|
@ -907,7 +900,7 @@ MATCHER_EXECUTE MATCHER_STRING
|
|||
|
||||
action_type = MATCHACTION_MOVE;
|
||||
destination = $2;
|
||||
action = filteringaction_new(action_type, 0, destination, 0);
|
||||
action = filteringaction_new(action_type, 0, destination, 0, 0);
|
||||
}
|
||||
| MATCHER_COPY MATCHER_STRING
|
||||
{
|
||||
|
@ -916,56 +909,56 @@ MATCHER_EXECUTE MATCHER_STRING
|
|||
|
||||
action_type = MATCHACTION_COPY;
|
||||
destination = $2;
|
||||
action = filteringaction_new(action_type, 0, destination, 0);
|
||||
action = filteringaction_new(action_type, 0, destination, 0, 0);
|
||||
}
|
||||
| MATCHER_DELETE
|
||||
{
|
||||
gint action_type = 0;
|
||||
|
||||
action_type = MATCHACTION_DELETE;
|
||||
action = filteringaction_new(action_type, 0, NULL, 0);
|
||||
action = filteringaction_new(action_type, 0, NULL, 0, 0);
|
||||
}
|
||||
| MATCHER_MARK
|
||||
{
|
||||
gint action_type = 0;
|
||||
|
||||
action_type = MATCHACTION_MARK;
|
||||
action = filteringaction_new(action_type, 0, NULL, 0);
|
||||
action = filteringaction_new(action_type, 0, NULL, 0, 0);
|
||||
}
|
||||
| MATCHER_UNMARK
|
||||
{
|
||||
gint action_type = 0;
|
||||
|
||||
action_type = MATCHACTION_UNMARK;
|
||||
action = filteringaction_new(action_type, 0, NULL, 0);
|
||||
action = filteringaction_new(action_type, 0, NULL, 0, 0);
|
||||
}
|
||||
| MATCHER_LOCK
|
||||
{
|
||||
gint action_type = 0;
|
||||
|
||||
action_type = MATCHACTION_LOCK;
|
||||
action = filteringaction_new(action_type, 0, NULL, 0);
|
||||
action = filteringaction_new(action_type, 0, NULL, 0, 0);
|
||||
}
|
||||
| MATCHER_UNLOCK
|
||||
{
|
||||
gint action_type = 0;
|
||||
|
||||
action_type = MATCHACTION_UNLOCK;
|
||||
action = filteringaction_new(action_type, 0, NULL, 0);
|
||||
action = filteringaction_new(action_type, 0, NULL, 0, 0);
|
||||
}
|
||||
| MATCHER_MARK_AS_READ
|
||||
{
|
||||
gint action_type = 0;
|
||||
|
||||
action_type = MATCHACTION_MARK_AS_READ;
|
||||
action = filteringaction_new(action_type, 0, NULL, 0);
|
||||
action = filteringaction_new(action_type, 0, NULL, 0, 0);
|
||||
}
|
||||
| MATCHER_MARK_AS_UNREAD
|
||||
{
|
||||
gint action_type = 0;
|
||||
|
||||
action_type = MATCHACTION_MARK_AS_UNREAD;
|
||||
action = filteringaction_new(action_type, 0, NULL, 0);
|
||||
action = filteringaction_new(action_type, 0, NULL, 0, 0);
|
||||
}
|
||||
| MATCHER_FORWARD MATCHER_INTEGER MATCHER_STRING
|
||||
{
|
||||
|
@ -974,9 +967,10 @@ MATCHER_EXECUTE MATCHER_STRING
|
|||
gint account_id = 0;
|
||||
|
||||
action_type = MATCHACTION_FORWARD;
|
||||
account_id = atoi($2);
|
||||
account_id = strtol($2, NULL, 10);
|
||||
destination = $3;
|
||||
action = filteringaction_new(action_type, account_id, destination, 0);
|
||||
action = filteringaction_new(action_type,
|
||||
account_id, destination, 0, 0);
|
||||
}
|
||||
| MATCHER_FORWARD_AS_ATTACHMENT MATCHER_INTEGER MATCHER_STRING
|
||||
{
|
||||
|
@ -985,9 +979,10 @@ MATCHER_EXECUTE MATCHER_STRING
|
|||
gint account_id = 0;
|
||||
|
||||
action_type = MATCHACTION_FORWARD_AS_ATTACHMENT;
|
||||
account_id = atoi($2);
|
||||
account_id = strtol($2, NULL, 10);
|
||||
destination = $3;
|
||||
action = filteringaction_new(action_type, account_id, destination, 0);
|
||||
action = filteringaction_new(action_type,
|
||||
account_id, destination, 0, 0);
|
||||
}
|
||||
| MATCHER_REDIRECT MATCHER_INTEGER MATCHER_STRING
|
||||
{
|
||||
|
@ -996,9 +991,10 @@ MATCHER_EXECUTE MATCHER_STRING
|
|||
gint account_id = 0;
|
||||
|
||||
action_type = MATCHACTION_REDIRECT;
|
||||
account_id = atoi($2);
|
||||
account_id = strtol($2, NULL, 10);
|
||||
destination = $3;
|
||||
action = filteringaction_new(action_type, account_id, destination, 0);
|
||||
action = filteringaction_new(action_type,
|
||||
account_id, destination, 0, 0);
|
||||
}
|
||||
| MATCHER_COLOR MATCHER_INTEGER
|
||||
{
|
||||
|
@ -1006,35 +1002,40 @@ MATCHER_EXECUTE MATCHER_STRING
|
|||
gint color = 0;
|
||||
|
||||
action_type = MATCHACTION_COLOR;
|
||||
color = atoi($2);
|
||||
action = filteringaction_new(action_type, 0, NULL, color);
|
||||
color = strtol($2, NULL, 10);
|
||||
action = filteringaction_new(action_type, 0, NULL, color, 0);
|
||||
}
|
||||
| MATCHER_CHANGE_SCORE MATCHER_STRING
|
||||
| MATCHER_CHANGE_SCORE MATCHER_INTEGER
|
||||
{
|
||||
gint action_type = MATCHACTION_CHANGE_SCORE;
|
||||
char *last_tok = NULL;
|
||||
const gchar *first_tok;
|
||||
long int chscore;
|
||||
int change_type; /* -1 == decrement, 0 == assign, 1 == increment */
|
||||
|
||||
#define is_number(x) ( ((x) == '+') || ((x) == '-') || (isdigit((x))) )
|
||||
/* find start */
|
||||
for (first_tok = $2; *first_tok && !is_number(*first_tok); first_tok++)
|
||||
;
|
||||
#undef is_number
|
||||
|
||||
chscore = strtol(first_tok, &last_tok, 10);
|
||||
if (last_tok == first_tok || *last_tok == 0)
|
||||
chscore = 0;
|
||||
change_type = *first_tok == '+' ? 1 : *first_tok == '-' ? -1 : 0;
|
||||
action = filteringaction_new(MATCHACTION_CHANGE_SCORE, change_type,
|
||||
NULL, chscore);
|
||||
}
|
||||
;
|
||||
|
||||
scoring_rule:
|
||||
MATCHER_SCORE MATCHER_INTEGER
|
||||
{
|
||||
score = atoi($2);
|
||||
gint score = 0;
|
||||
|
||||
score = strtol($2, NULL, 10);
|
||||
action = filteringaction_new(MATCHACTION_CHANGE_SCORE, 0,
|
||||
NULL, 0, score);
|
||||
}
|
||||
/* backward compatibility */
|
||||
| MATCHER_SCORE MATCHER_INTEGER
|
||||
{
|
||||
gint score = 0;
|
||||
|
||||
score = strtol($2, NULL, 10);
|
||||
action = filteringaction_new(MATCHACTION_CHANGE_SCORE, 0,
|
||||
NULL, 0, score);
|
||||
}
|
||||
| MATCHER_SET_SCORE MATCHER_INTEGER
|
||||
{
|
||||
gint score = 0;
|
||||
|
||||
score = strtol($2, NULL, 10);
|
||||
action = filteringaction_new(MATCHACTION_SET_SCORE, 0,
|
||||
NULL, 0, score);
|
||||
}
|
||||
| MATCHER_HIDE
|
||||
{
|
||||
action = filteringaction_new(MATCHACTION_HIDE, 0, NULL, 0, 0);
|
||||
}
|
||||
| MATCHER_STOP
|
||||
{
|
||||
action = filteringaction_new(MATCHACTION_STOP, 0, NULL, 0, 0);
|
||||
}
|
||||
;
|
||||
|
|
2220
src/mbox_folder.c
2220
src/mbox_folder.c
File diff suppressed because it is too large
Load diff
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
|
||||
* Copyright (C) 1999-2001 Hiroyuki Yamamoto & The Sylpheed Claws Team
|
||||
*
|
||||
* 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 MBOX_FOLDER_H
|
||||
|
||||
#define MBOX_FOLDER_H
|
||||
|
||||
#include <glib.h>
|
||||
#include "folder.h"
|
||||
|
||||
/*
|
||||
mailfile mailfile_init(char * filename);
|
||||
char * mailfile_readmsg(mailfile f, int index);
|
||||
char * mailfile_readheader(mailfile f, int index);
|
||||
void mailfile_done(mailfile f);
|
||||
int mailfile_count(mailfile f);
|
||||
*/
|
||||
typedef struct _MBOXFolder MBOXFolder;
|
||||
|
||||
#define MBOX_FOLDER(obj) ((MBOXFolder *)obj)
|
||||
|
||||
struct _MBOXFolder
|
||||
{
|
||||
LocalFolder lfolder;
|
||||
};
|
||||
|
||||
FolderClass *mbox_get_class (void);
|
||||
gchar * mbox_get_virtual_path(FolderItem * item);
|
||||
|
||||
#endif
|
|
@ -61,11 +61,10 @@
|
|||
#include "send_message.h"
|
||||
#include "stock_pixmap.h"
|
||||
#include "hooks.h"
|
||||
#include "filtering.h"
|
||||
|
||||
static GList *messageview_list = NULL;
|
||||
|
||||
static void messageview_change_view_type(MessageView *messageview,
|
||||
MessageType type);
|
||||
static void messageview_destroy_cb (GtkWidget *widget,
|
||||
MessageView *messageview);
|
||||
static void messageview_size_allocate_cb(GtkWidget *widget,
|
||||
|
@ -128,6 +127,9 @@ static void add_address_cb (gpointer data,
|
|||
static void create_filter_cb (gpointer data,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
static void create_processing_cb (gpointer data,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
|
||||
static void about_cb (gpointer data,
|
||||
guint action,
|
||||
|
@ -271,6 +273,14 @@ static GtkItemFactoryEntry msgview_entries[] =
|
|||
NULL, create_filter_cb, FILTER_BY_TO, NULL},
|
||||
{N_("/_Tools/_Create filter rule/by _Subject"),
|
||||
NULL, create_filter_cb, FILTER_BY_SUBJECT, NULL},
|
||||
{N_("/_Tools/Create processing rule/_Automatically"),
|
||||
NULL, create_processing_cb, FILTER_BY_AUTO, NULL},
|
||||
{N_("/_Tools/Create processing rule/by _From"),
|
||||
NULL, create_processing_cb, FILTER_BY_FROM, NULL},
|
||||
{N_("/_Tools/Create processing rule/by _To"),
|
||||
NULL, create_processing_cb, FILTER_BY_TO, NULL},
|
||||
{N_("/_Tools/Create processing rule/by _Subject"),
|
||||
NULL, create_processing_cb, FILTER_BY_SUBJECT, NULL},
|
||||
{N_("/_Tools/---"), NULL, NULL, 0, "<Separator>"},
|
||||
{N_("/_Tools/Actio_ns"), NULL, NULL, 0, "<Branch>"},
|
||||
|
||||
|
@ -283,22 +293,16 @@ MessageView *messageview_create(MainWindow *mainwin)
|
|||
MessageView *messageview;
|
||||
GtkWidget *vbox;
|
||||
HeaderView *headerview;
|
||||
TextView *textview;
|
||||
MimeView *mimeview;
|
||||
NoticeView *noticeview;
|
||||
|
||||
debug_print("Creating message view...\n");
|
||||
messageview = g_new0(MessageView, 1);
|
||||
|
||||
messageview->type = MVIEW_TEXT;
|
||||
|
||||
headerview = headerview_create();
|
||||
|
||||
noticeview = noticeview_create(mainwin);
|
||||
|
||||
textview = textview_create();
|
||||
textview->messageview = messageview;
|
||||
|
||||
mimeview = mimeview_create(mainwin);
|
||||
mimeview->textview = textview_create();
|
||||
mimeview->textview->messageview = messageview;
|
||||
|
@ -309,20 +313,14 @@ MessageView *messageview_create(MainWindow *mainwin)
|
|||
FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET_PTR(noticeview),
|
||||
FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET_PTR(textview),
|
||||
TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox),
|
||||
GTK_WIDGET_PTR(mimeview), TRUE, TRUE, 0);
|
||||
gtk_widget_show(vbox);
|
||||
|
||||
/* to remove without destroyed */
|
||||
gtk_widget_ref(GTK_WIDGET_PTR(textview));
|
||||
gtk_widget_ref(GTK_WIDGET_PTR(mimeview));
|
||||
gtk_widget_ref(GTK_WIDGET_PTR(mimeview->textview));
|
||||
|
||||
messageview->vbox = vbox;
|
||||
messageview->new_window = FALSE;
|
||||
messageview->window = NULL;
|
||||
messageview->headerview = headerview;
|
||||
messageview->textview = textview;
|
||||
messageview->mimeview = mimeview;
|
||||
messageview->noticeview = noticeview;
|
||||
messageview->mainwin = mainwin;
|
||||
|
@ -395,8 +393,8 @@ MessageView *messageview_create_with_new_window(MainWindow *mainwin)
|
|||
|
||||
messageview_add_toolbar(msgview, window);
|
||||
|
||||
gtk_widget_grab_focus(msgview->textview->text);
|
||||
gtk_widget_show_all(window);
|
||||
gtk_widget_grab_focus(msgview->mimeview->textview->text);
|
||||
gtk_widget_show(window);
|
||||
|
||||
msgview->new_window = TRUE;
|
||||
msgview->window = window;
|
||||
|
@ -412,7 +410,6 @@ MessageView *messageview_create_with_new_window(MainWindow *mainwin)
|
|||
void messageview_init(MessageView *messageview)
|
||||
{
|
||||
headerview_init(messageview->headerview);
|
||||
textview_init(messageview->textview);
|
||||
mimeview_init(messageview->mimeview);
|
||||
/*messageview_set_font(messageview);*/
|
||||
|
||||
|
@ -454,6 +451,8 @@ static gint disposition_notification_send(MsgInfo *msginfo)
|
|||
FolderItem *queue, *outbox;
|
||||
gint num;
|
||||
gchar *path;
|
||||
gchar *addr;
|
||||
gchar *addrp;
|
||||
|
||||
if ((!msginfo->returnreceiptto) &&
|
||||
(!msginfo->dispositionnotificationto))
|
||||
|
@ -465,7 +464,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
|
|||
else
|
||||
to = msginfo->returnreceiptto;
|
||||
|
||||
ok = get_header_from_msginfo(msginfo, buf, sizeof(buf),
|
||||
ok = procheader_get_header_from_msginfo(msginfo, buf, sizeof(buf),
|
||||
"Return-Path:");
|
||||
if (ok == 0) {
|
||||
gchar *to_addr = g_strdup(to);
|
||||
|
@ -532,7 +531,12 @@ static gint disposition_notification_send(MsgInfo *msginfo)
|
|||
FILE_OP_ERROR(tmp, "chmod");
|
||||
g_warning("can't change file mode\n");
|
||||
}
|
||||
|
||||
|
||||
addr = g_strdup(to);
|
||||
|
||||
extract_address(addr);
|
||||
addrp = addr;
|
||||
|
||||
/* write queue headers */
|
||||
fprintf(fp, "AF:\n");
|
||||
fprintf(fp, "NF:0\n");
|
||||
|
@ -550,7 +554,9 @@ static gint disposition_notification_send(MsgInfo *msginfo)
|
|||
else
|
||||
fprintf(fp, "SSV:\n");
|
||||
fprintf(fp, "SSH:\n");
|
||||
fprintf(fp, "R:<%s>\n", to);
|
||||
fprintf(fp, "R:<%s>\n", addrp);
|
||||
|
||||
g_free(addrp);
|
||||
|
||||
/* check whether we need to save the message */
|
||||
outbox = account_get_special_folder(account, F_OUTBOX);
|
||||
|
@ -623,22 +629,55 @@ GList *messageview_get_window_list(void)
|
|||
return messageview_list;
|
||||
}
|
||||
|
||||
void messageview_show(MessageView *messageview, MsgInfo *msginfo,
|
||||
static gboolean find_encrypted_func(GNode *node, gpointer data)
|
||||
{
|
||||
MimeInfo *mimeinfo = (MimeInfo *) node->data;
|
||||
MimeInfo **encinfo = (MimeInfo **) data;
|
||||
|
||||
if (privacy_mimeinfo_is_encrypted(mimeinfo)) {
|
||||
*encinfo = mimeinfo;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static MimeInfo *find_encrypted_part(MimeInfo *rootinfo)
|
||||
{
|
||||
MimeInfo *encinfo = NULL;
|
||||
|
||||
g_node_traverse(rootinfo->node, G_IN_ORDER, G_TRAVERSE_ALL, -1,
|
||||
find_encrypted_func, &encinfo);
|
||||
|
||||
return encinfo;
|
||||
}
|
||||
|
||||
gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
|
||||
gboolean all_headers)
|
||||
{
|
||||
gchar *file;
|
||||
MimeInfo *mimeinfo;
|
||||
MimeInfo *mimeinfo, *encinfo;
|
||||
|
||||
g_return_if_fail(msginfo != NULL);
|
||||
g_return_val_if_fail(msginfo != NULL, -1);
|
||||
|
||||
mimeinfo = procmime_scan_message(msginfo);
|
||||
g_return_if_fail(mimeinfo != NULL);
|
||||
if (!mimeinfo) {
|
||||
textview_show_error(messageview->mimeview->textview);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((encinfo = find_encrypted_part(mimeinfo)) != NULL) {
|
||||
debug_print("decrypting message part\n");
|
||||
if (privacy_mimeinfo_decrypt(encinfo) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
file = procmsg_get_message_file_path(msginfo);
|
||||
if (!file) {
|
||||
g_warning("can't get message file path.\n");
|
||||
procmime_mimeinfo_free_all(mimeinfo);
|
||||
return;
|
||||
textview_show_error(messageview->mimeview->textview);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (messageview->msginfo != msginfo) {
|
||||
|
@ -648,17 +687,9 @@ void messageview_show(MessageView *messageview, MsgInfo *msginfo,
|
|||
headerview_show(messageview->headerview, messageview->msginfo);
|
||||
|
||||
messageview->all_headers = all_headers;
|
||||
textview_set_all_headers(messageview->textview, all_headers);
|
||||
textview_set_all_headers(messageview->mimeview->textview, all_headers);
|
||||
|
||||
if (mimeinfo->mime_type != MIME_TEXT) {
|
||||
messageview_change_view_type(messageview, MVIEW_MIME);
|
||||
mimeview_show_message(messageview->mimeview, mimeinfo, file);
|
||||
} else {
|
||||
messageview_change_view_type(messageview, MVIEW_TEXT);
|
||||
textview_show_message(messageview->textview, mimeinfo, file);
|
||||
procmime_mimeinfo_free_all(mimeinfo);
|
||||
}
|
||||
mimeview_show_message(messageview->mimeview, mimeinfo, file);
|
||||
|
||||
if ((messageview->msginfo->dispositionnotificationto ||
|
||||
messageview->msginfo->returnreceiptto) &&
|
||||
|
@ -668,41 +699,8 @@ void messageview_show(MessageView *messageview, MsgInfo *msginfo,
|
|||
noticeview_hide(messageview->noticeview);
|
||||
|
||||
g_free(file);
|
||||
}
|
||||
|
||||
static void messageview_change_view_type(MessageView *messageview,
|
||||
MessageType type)
|
||||
{
|
||||
TextView *textview = messageview->textview;
|
||||
MimeView *mimeview = messageview->mimeview;
|
||||
gboolean hadfocus = GTK_WIDGET_HAS_FOCUS(textview->text);
|
||||
|
||||
if (messageview->type == type) return;
|
||||
|
||||
if (type == MVIEW_MIME) {
|
||||
gtkut_container_remove
|
||||
(GTK_CONTAINER(GTK_WIDGET_PTR(messageview)),
|
||||
GTK_WIDGET_PTR(textview));
|
||||
gtk_box_pack_start(GTK_BOX(messageview->vbox),
|
||||
GTK_WIDGET_PTR(mimeview), TRUE, TRUE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(mimeview->vbox),
|
||||
GTK_WIDGET_PTR(textview));
|
||||
} else if (type == MVIEW_TEXT) {
|
||||
gtkut_container_remove
|
||||
(GTK_CONTAINER(GTK_WIDGET_PTR(messageview)),
|
||||
GTK_WIDGET_PTR(mimeview));
|
||||
|
||||
if (mimeview->vbox == GTK_WIDGET_PTR(textview)->parent)
|
||||
gtkut_container_remove(GTK_CONTAINER(mimeview->vbox),
|
||||
GTK_WIDGET_PTR(textview));
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(messageview->vbox),
|
||||
GTK_WIDGET_PTR(textview), TRUE, TRUE, 0);
|
||||
} else
|
||||
return;
|
||||
if (hadfocus) gtk_widget_grab_focus(textview->text);
|
||||
|
||||
messageview->type = type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void messageview_reflect_prefs_pixmap_theme(void)
|
||||
|
@ -721,16 +719,14 @@ void messageview_clear(MessageView *messageview)
|
|||
{
|
||||
procmsg_msginfo_free(messageview->msginfo);
|
||||
messageview->msginfo = NULL;
|
||||
messageview_change_view_type(messageview, MVIEW_TEXT);
|
||||
messageview->filtered = FALSE;
|
||||
mimeview_clear(messageview->mimeview);
|
||||
headerview_clear(messageview->headerview);
|
||||
textview_clear(messageview->textview);
|
||||
noticeview_hide(messageview->noticeview);
|
||||
}
|
||||
|
||||
void messageview_destroy(MessageView *messageview)
|
||||
{
|
||||
GtkWidget *textview = GTK_WIDGET_PTR(messageview->textview);
|
||||
GtkWidget *mimeview = GTK_WIDGET_PTR(messageview->mimeview);
|
||||
|
||||
debug_print("destroy messageview\n");
|
||||
|
@ -740,7 +736,6 @@ void messageview_destroy(MessageView *messageview)
|
|||
messageview->msginfo_update_callback_id);
|
||||
|
||||
headerview_destroy(messageview->headerview);
|
||||
textview_destroy(messageview->textview);
|
||||
mimeview_destroy(messageview->mimeview);
|
||||
noticeview_destroy(messageview->noticeview);
|
||||
|
||||
|
@ -755,16 +750,30 @@ void messageview_destroy(MessageView *messageview)
|
|||
|
||||
g_free(messageview);
|
||||
|
||||
gtk_widget_unref(textview);
|
||||
gtk_widget_unref(mimeview);
|
||||
}
|
||||
|
||||
void messageview_delete(MessageView *msgview)
|
||||
{
|
||||
MsgInfo *msginfo = (MsgInfo *) msgview->msginfo;
|
||||
FolderItem *trash = folder_get_default_trash();
|
||||
FolderItem *trash = NULL;
|
||||
PrefsAccount *ac = NULL;
|
||||
|
||||
g_return_if_fail(msginfo != NULL);
|
||||
|
||||
/* to get the trash folder, we have to choose either
|
||||
* the folder's or account's trash default - we prefer
|
||||
* the one in the account prefs */
|
||||
if (msginfo->folder) {
|
||||
if (NULL != (ac = account_find_from_item(msginfo->folder)))
|
||||
trash = account_get_special_folder(ac, F_TRASH);
|
||||
if (!trash && msginfo->folder->folder)
|
||||
trash = msginfo->folder->folder->trash;
|
||||
/* if still not found, use the default */
|
||||
if (!trash)
|
||||
trash = folder_get_default_trash();
|
||||
}
|
||||
|
||||
g_return_if_fail(trash != NULL);
|
||||
|
||||
if (prefs_common.immediate_exec)
|
||||
|
@ -805,32 +814,20 @@ void messageview_quote_color_set(void)
|
|||
|
||||
void messageview_set_font(MessageView *messageview)
|
||||
{
|
||||
textview_set_font(messageview->textview, NULL);
|
||||
}
|
||||
|
||||
TextView *messageview_get_current_textview(MessageView *messageview)
|
||||
{
|
||||
TextView *text = NULL;
|
||||
|
||||
if (messageview->type == MVIEW_TEXT)
|
||||
text = messageview->textview;
|
||||
else if (messageview->type == MVIEW_MIME) {
|
||||
if (gtk_notebook_get_current_page
|
||||
(GTK_NOTEBOOK(messageview->mimeview->notebook)) == 0)
|
||||
text = messageview->textview;
|
||||
else if (messageview->mimeview->type == MIMEVIEW_TEXT)
|
||||
text = messageview->mimeview->textview;
|
||||
}
|
||||
text = messageview->mimeview->textview;
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
MimeInfo *messageview_get_selected_mime_part(MessageView *messageview)
|
||||
{
|
||||
if (messageview->type == MVIEW_MIME)
|
||||
return mimeview_get_selected_part(messageview->mimeview);
|
||||
|
||||
return NULL;
|
||||
return mimeview_get_selected_part(messageview->mimeview);
|
||||
}
|
||||
|
||||
void messageview_copy_clipboard(MessageView *messageview)
|
||||
|
@ -859,13 +856,21 @@ void messageview_select_all(MessageView *messageview)
|
|||
|
||||
void messageview_set_position(MessageView *messageview, gint pos)
|
||||
{
|
||||
textview_set_position(messageview->textview, pos);
|
||||
TextView *text;
|
||||
|
||||
text = messageview_get_current_textview(messageview);
|
||||
if (text)
|
||||
textview_set_position(text, pos);
|
||||
}
|
||||
|
||||
gboolean messageview_search_string(MessageView *messageview, const gchar *str,
|
||||
gboolean case_sens)
|
||||
{
|
||||
return textview_search_string(messageview->textview, str, case_sens);
|
||||
TextView *text;
|
||||
|
||||
text = messageview_get_current_textview(messageview);
|
||||
if (text)
|
||||
return textview_search_string(text, str, case_sens);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -873,8 +878,11 @@ gboolean messageview_search_string_backward(MessageView *messageview,
|
|||
const gchar *str,
|
||||
gboolean case_sens)
|
||||
{
|
||||
return textview_search_string_backward(messageview->textview,
|
||||
str, case_sens);
|
||||
TextView *text;
|
||||
|
||||
text = messageview_get_current_textview(messageview);
|
||||
return textview_search_string_backward(text,
|
||||
str, case_sens);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -964,7 +972,6 @@ void messageview_toggle_view_real(MessageView *messageview)
|
|||
gtkut_container_remove(GTK_CONTAINER(container), vpaned);
|
||||
gtk_widget_reparent(GTK_WIDGET_PTR(messageview), container);
|
||||
menu_set_sensitive(ifactory, "/View/Expand Summary View", FALSE);
|
||||
gtk_widget_grab_focus(GTK_WIDGET(messageview->textview->text));
|
||||
} else {
|
||||
gtk_widget_reparent(GTK_WIDGET_PTR(messageview), vpaned);
|
||||
gtk_container_add(GTK_CONTAINER(container), vpaned);
|
||||
|
@ -1060,15 +1067,11 @@ gchar *messageview_get_selection(MessageView *msgview)
|
|||
g_return_val_if_fail(msgview != NULL, NULL);
|
||||
|
||||
textview = messageview_get_current_textview(msgview);
|
||||
if (textview) {
|
||||
edit = GTK_TEXT_VIEW(textview->text);
|
||||
body_pos = textview->body_pos;
|
||||
} else {
|
||||
edit = GTK_TEXT_VIEW(msgview->mimeview->textview->text);
|
||||
body_pos = msgview->mimeview->textview->body_pos;
|
||||
}
|
||||
g_return_val_if_fail(textview != NULL, NULL);
|
||||
|
||||
edit = GTK_EDITABLE(textview->text);
|
||||
g_return_val_if_fail(edit != NULL, NULL);
|
||||
body_pos = textview->body_pos;
|
||||
|
||||
textbuf = gtk_text_view_get_buffer(edit);
|
||||
|
||||
|
@ -1205,12 +1208,14 @@ static void reply_cb(gpointer data, guint action, GtkWidget *widget)
|
|||
MsgInfo *msginfo;
|
||||
gchar *text = NULL;
|
||||
ComposeMode mode = (ComposeMode)action;
|
||||
TextView *textview;
|
||||
|
||||
msginfo = messageview->msginfo;
|
||||
mlist = g_slist_append(NULL, msginfo);
|
||||
|
||||
textview = messageview_get_current_textview(messageview);
|
||||
text = gtkut_editable_get_selection
|
||||
(GTK_EDITABLE(messageview->textview->text));
|
||||
(GTK_EDITABLE(textview->text));
|
||||
if (text && *text == '\0') {
|
||||
g_free(text);
|
||||
text = NULL;
|
||||
|
@ -1272,7 +1277,7 @@ static void reply_cb(gpointer data, guint action, GtkWidget *widget)
|
|||
}
|
||||
break;
|
||||
case COMPOSE_FORWARD_INLINE:
|
||||
compose_forward(NULL, msginfo, FALSE, text);
|
||||
compose_forward(NULL, msginfo, FALSE, text, FALSE);
|
||||
break;
|
||||
case COMPOSE_FORWARD_AS_ATTACH:
|
||||
compose_forward_multiple(NULL, mlist);
|
||||
|
@ -1326,17 +1331,26 @@ static void add_address_cb(gpointer data, guint action, GtkWidget *widget)
|
|||
static void create_filter_cb(gpointer data, guint action, GtkWidget *widget)
|
||||
{
|
||||
MessageView *messageview = (MessageView *)data;
|
||||
gchar *header = NULL;
|
||||
gchar *key = NULL;
|
||||
|
||||
FolderItem * item;
|
||||
|
||||
if (!messageview->msginfo) return;
|
||||
|
||||
item = messageview->msginfo->folder;
|
||||
summary_msginfo_filter_open(item, messageview->msginfo,
|
||||
(PrefsFilterType)action, 0);
|
||||
}
|
||||
|
||||
procmsg_get_filter_keyword(messageview->msginfo, &header, &key,
|
||||
(PrefsFilterType)action);
|
||||
prefs_filtering_open(NULL, header, key);
|
||||
|
||||
g_free(header);
|
||||
g_free(key);
|
||||
static void create_processing_cb(gpointer data, guint action,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
MessageView *messageview = (MessageView *)data;
|
||||
FolderItem * item;
|
||||
|
||||
if (!messageview->msginfo) return;
|
||||
|
||||
item = messageview->msginfo->folder;
|
||||
summary_msginfo_filter_open(item, messageview->msginfo,
|
||||
(PrefsFilterType)action, 1);
|
||||
}
|
||||
|
||||
static void about_cb(gpointer data, guint action, GtkWidget *widget)
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <glib.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
typedef struct _MessageView MessageView;
|
||||
typedef struct _MessageView MessageView;
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "headerview.h"
|
||||
|
@ -34,17 +34,10 @@ typedef struct _MessageView MessageView;
|
|||
#include "procmime.h"
|
||||
#include "toolbar.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MVIEW_TEXT,
|
||||
MVIEW_MIME
|
||||
} MessageType;
|
||||
|
||||
struct _MessageView
|
||||
{
|
||||
GtkWidget *vbox;
|
||||
|
||||
MessageType type;
|
||||
gboolean new_window;
|
||||
GtkWidget *window;
|
||||
|
||||
|
@ -54,7 +47,6 @@ struct _MessageView
|
|||
GtkWidget *menubar;
|
||||
|
||||
HeaderView *headerview;
|
||||
TextView *textview;
|
||||
MimeView *mimeview;
|
||||
NoticeView *noticeview;
|
||||
|
||||
|
@ -79,7 +71,7 @@ MessageView *messageview_create (MainWindow *mainwin);
|
|||
MessageView *messageview_create_with_new_window (MainWindow *mainwin);
|
||||
|
||||
void messageview_init (MessageView *messageview);
|
||||
void messageview_show (MessageView *messageview,
|
||||
gint messageview_show (MessageView *messageview,
|
||||
MsgInfo *msginfo,
|
||||
gboolean all_headers);
|
||||
void messageview_clear (MessageView *messageview);
|
||||
|
|
189
src/mh.c
189
src/mh.c
|
@ -44,51 +44,70 @@
|
|||
#include "utils.h"
|
||||
#include "codeconv.h"
|
||||
|
||||
static void mh_folder_init(Folder * folder,
|
||||
const gchar * name, const gchar * path);
|
||||
static void mh_folder_init (Folder *folder,
|
||||
const gchar *name,
|
||||
const gchar *path);
|
||||
|
||||
static Folder *mh_folder_new(const gchar * name, const gchar * path);
|
||||
static void mh_folder_destroy(Folder * folder);
|
||||
static gchar *mh_fetch_msg(Folder * folder, FolderItem * item, gint num);
|
||||
static MsgInfo *mh_get_msginfo(Folder * folder,
|
||||
FolderItem * item, gint num);
|
||||
static gint mh_add_msg(Folder * folder,
|
||||
FolderItem * dest,
|
||||
const gchar * file,
|
||||
MsgFlags * flags);
|
||||
static gint mh_add_msgs(Folder * folder,
|
||||
FolderItem * dest, GSList * file_list, GRelation *relation);
|
||||
static gint mh_copy_msg(Folder * folder,
|
||||
FolderItem * dest, MsgInfo * msginfo);
|
||||
static gint mh_remove_msg(Folder * folder, FolderItem * item, gint num);
|
||||
static gint mh_remove_all_msg(Folder * folder, FolderItem * item);
|
||||
static gboolean mh_is_msg_changed(Folder * folder,
|
||||
FolderItem * item, MsgInfo * msginfo);
|
||||
static Folder *mh_folder_new (const gchar *name,
|
||||
const gchar *path);
|
||||
static void mh_folder_destroy (Folder *folder);
|
||||
static gchar *mh_fetch_msg (Folder *folder,
|
||||
FolderItem *item,
|
||||
gint num);
|
||||
static MsgInfo *mh_get_msginfo (Folder *folder,
|
||||
FolderItem *item,
|
||||
gint num);
|
||||
static gint mh_add_msg (Folder *folder,
|
||||
FolderItem *dest,
|
||||
const gchar *file,
|
||||
MsgFlags *flags);
|
||||
static gint mh_add_msgs (Folder *folder,
|
||||
FolderItem *dest,
|
||||
GSList *file_list,
|
||||
GRelation *relation);
|
||||
static gint mh_copy_msg (Folder *folder,
|
||||
FolderItem *dest,
|
||||
MsgInfo *msginfo);
|
||||
static gint mh_remove_msg (Folder *folder,
|
||||
FolderItem *item,
|
||||
gint num);
|
||||
static gint mh_remove_all_msg (Folder *folder,
|
||||
FolderItem *item);
|
||||
static gboolean mh_is_msg_changed (Folder *folder,
|
||||
FolderItem *item,
|
||||
MsgInfo *msginfo);
|
||||
|
||||
static gint mh_get_num_list(Folder * folder,
|
||||
FolderItem * item, GSList ** list, gboolean *old_uids_valid);
|
||||
static void mh_scan_tree(Folder * folder);
|
||||
static gint mh_get_num_list (Folder *folder,
|
||||
FolderItem *item,
|
||||
GSList **list,
|
||||
gboolean *old_uids_valid);
|
||||
static gint mh_scan_tree (Folder *folder);
|
||||
|
||||
static gint mh_create_tree(Folder * folder);
|
||||
static FolderItem *mh_create_folder(Folder * folder,
|
||||
FolderItem * parent,
|
||||
const gchar * name);
|
||||
static gint mh_rename_folder(Folder * folder,
|
||||
FolderItem * item, const gchar * name);
|
||||
static gint mh_remove_folder(Folder * folder, FolderItem * item);
|
||||
static gint mh_create_tree (Folder *folder);
|
||||
static FolderItem *mh_create_folder (Folder *folder,
|
||||
FolderItem *parent,
|
||||
const gchar *name);
|
||||
static gint mh_rename_folder (Folder *folder,
|
||||
FolderItem *item,
|
||||
const gchar *name);
|
||||
static gint mh_remove_folder (Folder *folder,
|
||||
FolderItem *item);
|
||||
|
||||
static gchar *mh_get_new_msg_filename(FolderItem * dest);
|
||||
static gchar *mh_get_new_msg_filename (FolderItem *dest);
|
||||
|
||||
static MsgInfo *mh_parse_msg(const gchar * file, FolderItem * item);
|
||||
static MsgInfo *mh_parse_msg (const gchar *file,
|
||||
FolderItem *item);
|
||||
static void mh_remove_missing_folder_items (Folder *folder);
|
||||
static void mh_scan_tree_recursive(FolderItem * item);
|
||||
static gchar *mh_filename_from_utf8 (const gchar *path);
|
||||
static gchar *mh_filename_to_utf8 (const gchar *path);
|
||||
static void mh_scan_tree_recursive (FolderItem *item);
|
||||
|
||||
static gboolean mh_rename_folder_func(GNode * node, gpointer data);
|
||||
static gchar *mh_item_get_path(Folder *folder, FolderItem *item);
|
||||
static gboolean mh_rename_folder_func (GNode *node,
|
||||
gpointer data);
|
||||
static gchar *mh_item_get_path (Folder *folder,
|
||||
FolderItem *item);
|
||||
|
||||
FolderClass mh_class =
|
||||
static FolderClass mh_class =
|
||||
{
|
||||
F_MH,
|
||||
"mh",
|
||||
|
@ -97,12 +116,16 @@ FolderClass mh_class =
|
|||
/* Folder functions */
|
||||
mh_folder_new,
|
||||
mh_folder_destroy,
|
||||
folder_local_set_xml,
|
||||
folder_local_get_xml,
|
||||
mh_scan_tree,
|
||||
mh_create_tree,
|
||||
|
||||
/* FolderItem functions */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
mh_item_get_path,
|
||||
mh_create_folder,
|
||||
mh_rename_folder,
|
||||
|
@ -133,7 +156,7 @@ FolderClass *mh_get_class(void)
|
|||
return &mh_class;
|
||||
}
|
||||
|
||||
Folder *mh_folder_new(const gchar *name, const gchar *path)
|
||||
static Folder *mh_folder_new(const gchar *name, const gchar *path)
|
||||
{
|
||||
Folder *folder;
|
||||
|
||||
|
@ -160,7 +183,6 @@ void mh_get_last_num(Folder *folder, FolderItem *item)
|
|||
gchar *path;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
struct stat s;
|
||||
gint max = 0;
|
||||
gint num;
|
||||
|
||||
|
@ -183,8 +205,7 @@ void mh_get_last_num(Folder *folder, FolderItem *item)
|
|||
|
||||
while ((d = readdir(dp)) != NULL) {
|
||||
if ((num = to_number(d->d_name)) >= 0 &&
|
||||
stat(d->d_name, &s) == 0 &&
|
||||
S_ISREG(s.st_mode)) {
|
||||
dirent_is_regular_file(d)) {
|
||||
if (max < num)
|
||||
max = num;
|
||||
}
|
||||
|
@ -201,7 +222,6 @@ gint mh_get_num_list(Folder *folder, FolderItem *item, GSList **list, gboolean *
|
|||
gchar *path;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
struct stat s;
|
||||
gint num, nummsgs = 0;
|
||||
|
||||
g_return_val_if_fail(item != NULL, -1);
|
||||
|
@ -224,11 +244,9 @@ gint mh_get_num_list(Folder *folder, FolderItem *item, GSList **list, gboolean *
|
|||
}
|
||||
|
||||
while ((d = readdir(dp)) != NULL) {
|
||||
if ((num = to_number(d->d_name)) >= 0 &&
|
||||
stat(d->d_name, &s) == 0 &&
|
||||
S_ISREG(s.st_mode)) {
|
||||
if ((num = to_number(d->d_name)) >= 0) {
|
||||
*list = g_slist_prepend(*list, GINT_TO_POINTER(num));
|
||||
nummsgs++;
|
||||
nummsgs++;
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
|
@ -236,7 +254,7 @@ gint mh_get_num_list(Folder *folder, FolderItem *item, GSList **list, gboolean *
|
|||
return nummsgs;
|
||||
}
|
||||
|
||||
gchar *mh_fetch_msg(Folder *folder, FolderItem *item, gint num)
|
||||
static gchar *mh_fetch_msg(Folder *folder, FolderItem *item, gint num)
|
||||
{
|
||||
gchar *path;
|
||||
gchar *file;
|
||||
|
@ -255,7 +273,7 @@ gchar *mh_fetch_msg(Folder *folder, FolderItem *item, gint num)
|
|||
return file;
|
||||
}
|
||||
|
||||
MsgInfo *mh_get_msginfo(Folder *folder, FolderItem *item, gint num)
|
||||
static MsgInfo *mh_get_msginfo(Folder *folder, FolderItem *item, gint num)
|
||||
{
|
||||
MsgInfo *msginfo;
|
||||
gchar *file;
|
||||
|
@ -275,7 +293,7 @@ MsgInfo *mh_get_msginfo(Folder *folder, FolderItem *item, gint num)
|
|||
return msginfo;
|
||||
}
|
||||
|
||||
gchar *mh_get_new_msg_filename(FolderItem *dest)
|
||||
static gchar *mh_get_new_msg_filename(FolderItem *dest)
|
||||
{
|
||||
gchar *destfile;
|
||||
gchar *destpath;
|
||||
|
@ -301,7 +319,7 @@ gchar *mh_get_new_msg_filename(FolderItem *dest)
|
|||
return destfile;
|
||||
}
|
||||
|
||||
gint mh_add_msg(Folder *folder, FolderItem *dest, const gchar *file, MsgFlags *flags)
|
||||
static gint mh_add_msg(Folder *folder, FolderItem *dest, const gchar *file, MsgFlags *flags)
|
||||
{
|
||||
gint ret;
|
||||
GSList file_list;
|
||||
|
@ -319,7 +337,7 @@ gint mh_add_msg(Folder *folder, FolderItem *dest, const gchar *file, MsgFlags *f
|
|||
return ret;
|
||||
}
|
||||
|
||||
gint mh_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
|
||||
static gint mh_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
|
||||
GRelation *relation)
|
||||
{
|
||||
gchar *destfile;
|
||||
|
@ -357,7 +375,7 @@ gint mh_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
|
|||
return dest->last_num;
|
||||
}
|
||||
|
||||
gint mh_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
|
||||
static gint mh_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
|
||||
{
|
||||
gchar *srcfile;
|
||||
gchar *destfile;
|
||||
|
@ -423,7 +441,7 @@ gint mh_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
|
|||
return dest->last_num;
|
||||
}
|
||||
|
||||
gint mh_remove_msg(Folder *folder, FolderItem *item, gint num)
|
||||
static gint mh_remove_msg(Folder *folder, FolderItem *item, gint num)
|
||||
{
|
||||
gchar *file;
|
||||
|
||||
|
@ -442,7 +460,7 @@ gint mh_remove_msg(Folder *folder, FolderItem *item, gint num)
|
|||
return 0;
|
||||
}
|
||||
|
||||
gint mh_remove_all_msg(Folder *folder, FolderItem *item)
|
||||
static gint mh_remove_all_msg(Folder *folder, FolderItem *item)
|
||||
{
|
||||
gchar *path;
|
||||
gint val;
|
||||
|
@ -457,7 +475,8 @@ gint mh_remove_all_msg(Folder *folder, FolderItem *item)
|
|||
return val;
|
||||
}
|
||||
|
||||
gboolean mh_is_msg_changed(Folder *folder, FolderItem *item, MsgInfo *msginfo)
|
||||
static gboolean mh_is_msg_changed(Folder *folder, FolderItem *item,
|
||||
MsgInfo *msginfo)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
|
@ -469,12 +488,12 @@ gboolean mh_is_msg_changed(Folder *folder, FolderItem *item, MsgInfo *msginfo)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void mh_scan_tree(Folder *folder)
|
||||
static gint mh_scan_tree(Folder *folder)
|
||||
{
|
||||
FolderItem *item;
|
||||
gchar *rootpath;
|
||||
|
||||
g_return_if_fail(folder != NULL);
|
||||
g_return_val_if_fail(folder != NULL, -1);
|
||||
|
||||
if (!folder->node) {
|
||||
item = folder_item_new(folder, folder->name, NULL);
|
||||
|
@ -486,13 +505,15 @@ void mh_scan_tree(Folder *folder)
|
|||
rootpath = folder_item_get_path(item);
|
||||
if (change_dir(rootpath) < 0) {
|
||||
g_free(rootpath);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
g_free(rootpath);
|
||||
|
||||
mh_create_tree(folder);
|
||||
mh_remove_missing_folder_items(folder);
|
||||
mh_scan_tree_recursive(item);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAKE_DIR_IF_NOT_EXIST(dir) \
|
||||
|
@ -508,7 +529,7 @@ void mh_scan_tree(Folder *folder)
|
|||
} \
|
||||
}
|
||||
|
||||
gint mh_create_tree(Folder *folder)
|
||||
static gint mh_create_tree(Folder *folder)
|
||||
{
|
||||
gchar *rootpath;
|
||||
|
||||
|
@ -529,7 +550,7 @@ gint mh_create_tree(Folder *folder)
|
|||
|
||||
#undef MAKE_DIR_IF_NOT_EXIST
|
||||
|
||||
gchar *mh_item_get_path(Folder *folder, FolderItem *item)
|
||||
static gchar *mh_item_get_path(Folder *folder, FolderItem *item)
|
||||
{
|
||||
gchar *folder_path, *path;
|
||||
|
||||
|
@ -559,8 +580,8 @@ gchar *mh_item_get_path(Folder *folder, FolderItem *item)
|
|||
return path;
|
||||
}
|
||||
|
||||
FolderItem *mh_create_folder(Folder *folder, FolderItem *parent,
|
||||
const gchar *name)
|
||||
static FolderItem *mh_create_folder(Folder *folder, FolderItem *parent,
|
||||
const gchar *name)
|
||||
{
|
||||
gchar *path, *real_name;
|
||||
gchar *fullpath;
|
||||
|
@ -611,7 +632,8 @@ FolderItem *mh_create_folder(Folder *folder, FolderItem *parent,
|
|||
return new_item;
|
||||
}
|
||||
|
||||
gint mh_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
|
||||
static gint mh_rename_folder(Folder *folder, FolderItem *item,
|
||||
const gchar *name)
|
||||
{
|
||||
gchar *real_name;
|
||||
gchar *oldpath;
|
||||
|
@ -664,7 +686,7 @@ gint mh_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
gint mh_remove_folder(Folder *folder, FolderItem *item)
|
||||
static gint mh_remove_folder(Folder *folder, FolderItem *item)
|
||||
{
|
||||
gchar *path;
|
||||
|
||||
|
@ -690,32 +712,32 @@ static MsgInfo *mh_parse_msg(const gchar *file, FolderItem *item)
|
|||
MsgInfo *msginfo;
|
||||
MsgFlags flags;
|
||||
|
||||
flags.perm_flags = MSG_NEW|MSG_UNREAD;
|
||||
flags.tmp_flags = 0;
|
||||
|
||||
g_return_val_if_fail(item != NULL, NULL);
|
||||
g_return_val_if_fail(file != NULL, NULL);
|
||||
|
||||
flags.perm_flags = MSG_NEW|MSG_UNREAD;
|
||||
flags.tmp_flags = 0;
|
||||
|
||||
if (item->stype == F_QUEUE) {
|
||||
MSG_SET_TMP_FLAGS(flags, MSG_QUEUED);
|
||||
} else if (item->stype == F_DRAFT) {
|
||||
MSG_SET_TMP_FLAGS(flags, MSG_DRAFT);
|
||||
}
|
||||
|
||||
if (stat(file, &s) < 0) {
|
||||
FILE_OP_ERROR(file, "stat");
|
||||
return NULL;
|
||||
}
|
||||
if (!S_ISREG(s.st_mode))
|
||||
return NULL;
|
||||
|
||||
msginfo = procheader_parse_file(file, flags, FALSE, FALSE);
|
||||
if (!msginfo) return NULL;
|
||||
|
||||
msginfo->msgnum = atoi(file);
|
||||
msginfo->folder = item;
|
||||
|
||||
if (stat(file, &s) < 0) {
|
||||
FILE_OP_ERROR(file, "stat");
|
||||
msginfo->size = 0;
|
||||
msginfo->mtime = 0;
|
||||
} else {
|
||||
msginfo->size = s.st_size;
|
||||
msginfo->mtime = s.st_mtime;
|
||||
}
|
||||
msginfo->size = s.st_size;
|
||||
msginfo->mtime = s.st_mtime;
|
||||
|
||||
return msginfo;
|
||||
}
|
||||
|
@ -817,15 +839,16 @@ static void mh_scan_tree_recursive(FolderItem *item)
|
|||
utf8entry = g_strdup(utf8name);
|
||||
entry = mh_filename_from_utf8(utf8entry);
|
||||
|
||||
if (stat(entry, &s) < 0) {
|
||||
FILE_OP_ERROR(entry, "stat");
|
||||
g_free(entry);
|
||||
g_free(utf8entry);
|
||||
g_free(utf8name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISDIR(s.st_mode)) {
|
||||
if (
|
||||
#ifdef HAVE_DIRENT_D_TYPE
|
||||
d->d_type == DT_DIR ||
|
||||
(d->d_type == DT_UNKNOWN &&
|
||||
#endif
|
||||
stat(entry, &s) == 0 && S_ISDIR(s.st_mode)
|
||||
#ifdef HAVE_DIRENT_D_TYPE
|
||||
)
|
||||
#endif
|
||||
) {
|
||||
FolderItem *new_item = NULL;
|
||||
GNode *node;
|
||||
|
||||
|
|
4
src/mh.h
4
src/mh.h
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
|
||||
* Copyright (C) 1999-2002 Hiroyuki Yamamoto
|
||||
* 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
|
||||
|
@ -23,7 +23,7 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include "folder.h"
|
||||
#include "procmsg.h"
|
||||
#include "localfolder.h"
|
||||
|
||||
typedef struct _MHFolder MHFolder;
|
||||
|
||||
|
|
723
src/mimeview.c
723
src/mimeview.c
File diff suppressed because it is too large
Load diff
|
@ -37,6 +37,7 @@ typedef struct _MimeViewer MimeViewer;
|
|||
#include "textview.h"
|
||||
#include "messageview.h"
|
||||
#include "procmime.h"
|
||||
#include "noticeview.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -48,8 +49,6 @@ struct _MimeView
|
|||
{
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *paned;
|
||||
GtkWidget *notebook;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *scrolledwin;
|
||||
GtkWidget *ctree;
|
||||
GtkWidget *mime_notebook;
|
||||
|
@ -83,6 +82,9 @@ struct _MimeView
|
|||
MainWindow *mainwin;
|
||||
GtkTooltips *tooltips;
|
||||
gint oldsize;
|
||||
|
||||
NoticeView *siginfoview;
|
||||
MimeInfo *siginfo;
|
||||
};
|
||||
|
||||
struct _MimeViewerFactory
|
||||
|
@ -114,12 +116,11 @@ void mimeview_show_message (MimeView *mimeview,
|
|||
const gchar *file);
|
||||
void mimeview_destroy (MimeView *mimeview);
|
||||
void mimeview_update (MimeView *mimeview);
|
||||
void mimeview_clear (MimeView *mimeview);
|
||||
|
||||
MimeInfo *mimeview_get_selected_part (MimeView *mimeview);
|
||||
|
||||
#if USE_GPGME
|
||||
void mimeview_check_signature (MimeView *mimeview);
|
||||
#endif
|
||||
void mimeview_check_signature (MimeView *mimeview);
|
||||
void mimeview_pass_key_press_event (MimeView *mimeview,
|
||||
GdkEventKey *event);
|
||||
|
||||
|
|
|
@ -434,6 +434,7 @@ MsgInfo *msgcache_get_msg_by_id(MsgCache *cache, const gchar *msgid)
|
|||
MsgInfo *msginfo;
|
||||
|
||||
g_return_val_if_fail(cache != NULL, NULL);
|
||||
g_return_val_if_fail(msgid != NULL, NULL);
|
||||
|
||||
msginfo = g_hash_table_lookup(cache->msgid_table, msgid);
|
||||
if(!msginfo)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue