From 27d3d6cb9738150bc944ae17ebe8fc8a6396012e Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Thu, 12 Apr 2007 19:28:29 +0000 Subject: [PATCH] Test checkin of some modules --- file/BorderPanel.java | 67 + file/CHANGELOG | 33 + file/CbButton.java | 264 + file/CbColorButton.java | 51 + file/CbColorWindow.java | 226 + file/CbImageChooser.java | 233 + file/CbScrollbar.java | 345 ++ file/CbSlider.java | 233 + file/ErrorWindow.java | 34 + file/FileManager.java | 4504 +++++++++++++++++ file/FileManager.java.bak | 3497 +++++++++++++ file/FixedFrame.java | 46 + file/GrayPanel.java | 10 + file/Hierarchy.java | 345 ++ file/Hierarchy.java.bak | 345 ++ file/LinedPanel.java | 39 + file/Makefile | 4 + file/MultiColumn.java | 583 +++ file/MultiColumn.java.bak | 578 +++ file/QuickSort.java | 77 + file/ResizePanel.java | 169 + file/StaticTextField.java | 24 + file/StringSplitter.java | 103 + file/TabbedPanel.java | 185 + file/ToolbarLayout.java | 333 ++ file/Util.java | 148 + file/acl_security.pl | 143 + file/chmod.cgi | 92 + file/config | 5 + file/config-*-linux | 16 + file/config-irix | 9 + file/config-solaris | 10 + file/config.info | 8 + file/config.info.ca | 8 + file/config.info.de | 4 + file/config.info.es | 4 + file/config.info.fa | 6 + file/config.info.it | 4 + file/config.info.tr | 4 + file/copy.cgi | 49 + file/defaultacl | 33 + file/delete.cgi | 26 + file/edit_html.cgi | 54 + file/extract.cgi | 21 + file/file-lib.pl | 452 ++ file/filesystems.cgi | 64 + file/getattrs.cgi | 36 + file/getext.cgi | 25 + file/getext.cgi.bak | 24 + file/getfacl.cgi | 45 + file/images/.xvpics/preview.gif | Bin 0 -> 641 bytes file/images/Thumbs.db | Bin 0 -> 38400 bytes file/images/acl.gif | Bin 0 -> 193 bytes file/images/add.gif | Bin 0 -> 118 bytes file/images/all.gif | Bin 0 -> 155 bytes file/images/attr.gif | Bin 0 -> 180 bytes file/images/binary.gif | Bin 0 -> 97 bytes file/images/cancel.gif | Bin 0 -> 107 bytes file/images/config.gif | Bin 0 -> 167 bytes file/images/copy.gif | Bin 0 -> 113 bytes file/images/cut.gif | Bin 0 -> 119 bytes file/images/delete.gif | Bin 0 -> 99 bytes file/images/device.gif | Bin 0 -> 90 bytes file/images/dir.gif | Bin 0 -> 88 bytes file/images/down.gif | Bin 0 -> 128 bytes file/images/edit.gif | Bin 0 -> 138 bytes file/images/ext.gif | Bin 0 -> 1159 bytes file/images/extract.gif | Bin 0 -> 1165 bytes file/images/file.gif | Bin 0 -> 1754 bytes file/images/find.gif | Bin 0 -> 94 bytes file/images/goto.gif | Bin 0 -> 93 bytes file/images/html.gif | Bin 0 -> 1372 bytes file/images/icon.gif | Bin 0 -> 266 bytes file/images/image.gif | Bin 0 -> 124 bytes file/images/makelink.gif | Bin 0 -> 127 bytes file/images/mdir.gif | Bin 0 -> 169 bytes file/images/mkdir.gif | Bin 0 -> 106 bytes file/images/mount.gif | Bin 0 -> 221 bytes file/images/new.gif | Bin 0 -> 85 bytes file/images/open.gif | Bin 0 -> 114 bytes file/images/paste.gif | Bin 0 -> 152 bytes file/images/pipe.gif | Bin 0 -> 107 bytes file/images/preview.gif | Bin 0 -> 412 bytes file/images/props.gif | Bin 0 -> 117 bytes file/images/refresh.gif | Bin 0 -> 92 bytes file/images/rename.gif | Bin 0 -> 144 bytes file/images/replace.gif | Bin 0 -> 155 bytes file/images/ret.gif | Bin 0 -> 229 bytes file/images/run.gif | Bin 0 -> 130 bytes file/images/save.gif | Bin 0 -> 92 bytes file/images/sdir.gif | Bin 0 -> 180 bytes file/images/search.gif | Bin 0 -> 131 bytes file/images/share.gif | Bin 0 -> 132 bytes file/images/smallicon.gif | Bin 0 -> 194 bytes file/images/smdir.gif | Bin 0 -> 181 bytes file/images/sub.gif | Bin 0 -> 96 bytes file/images/sudir.gif | Bin 0 -> 186 bytes file/images/symlink.gif | Bin 0 -> 87 bytes file/images/text.gif | Bin 0 -> 91 bytes file/images/udir.gif | Bin 0 -> 171 bytes file/images/unknown.gif | Bin 0 -> 79 bytes file/images/upload.gif | Bin 0 -> 154 bytes file/images/view.gif | Bin 0 -> 138 bytes file/index.cgi | 126 + file/index.cgi.bak | 79 + file/irix-getfacl.pl | 53 + file/irix-setfacl.pl | 40 + file/lang.cgi | 21 + file/lang/bg | 322 ++ file/lang/ca | 424 ++ file/lang/de | 345 ++ file/lang/en | 424 ++ file/lang/es | 345 ++ file/lang/fa | 383 ++ file/lang/fr | 229 + file/lang/it | 321 ++ file/lang/ja_JP.UTF-8 | 226 + file/lang/ja_JP.euc | 226 + file/lang/ko_KR.UTF-8 | 226 + file/lang/ko_KR.euc | 226 + file/lang/pl | 326 ++ file/lang/pt | 146 + file/lang/pt_BR | 282 ++ file/lang/ru_RU | 268 + file/lang/ru_SU | 299 ++ file/lang/sk | 297 ++ file/lang/sv | 153 + file/lang/tr | 290 ++ file/lang/tr.bak | 198 + file/lang/uk_UA | 269 + file/lang/zh_CN | 323 ++ file/lang/zh_CN.UTF-8 | 323 ++ file/lang/zh_TW.Big5 | 197 + file/lang/zh_TW.UTF-8 | 197 + file/list.cgi | 47 + file/list_exports.cgi | 95 + file/list_shares.cgi | 45 + file/log_parser.pl | 45 + file/makelink.cgi | 26 + file/mkdir.cgi | 24 + file/module.info | 25 + file/mount.cgi | 48 + file/move.cgi | 29 + file/preview.cgi | 124 + file/rename.cgi | 24 + file/root.cgi | 8 + file/save.cgi | 39 + file/save_export.cgi | 144 + file/save_html.cgi | 36 + file/save_share.cgi | 101 + file/search.cgi | 63 + file/setattrs.cgi | 44 + file/setext.cgi | 23 + file/setfacl.cgi | 45 + file/show.cgi | 161 + file/size.cgi | 49 + file/unicode.pl | 17 + file/unicode/zh_TW.Big5 | 324 ++ file/upform.cgi | 39 + file/upload.cgi | 76 + file/upload2.cgi | 38 + file/xinha | 1 + mailboxes/CHANGELOG | 37 + mailboxes/Makefile | 2 + mailboxes/acl_security.pl | 124 + mailboxes/boxes-lib.pl | 2282 +++++++++ mailboxes/config | 50 + mailboxes/config.info | 76 + mailboxes/config.info.ca | 76 + mailboxes/config.info.de | 54 + mailboxes/config_info.pl | 20 + mailboxes/defaultacl | 5 + mailboxes/delete_all.cgi | 38 + mailboxes/delete_mail.cgi | 213 + mailboxes/detach.cgi | 123 + mailboxes/find.cgi | 34 + mailboxes/folders-lib.pl | 2450 +++++++++ mailboxes/images/attach.gif | Bin 0 -> 77 bytes mailboxes/images/boxes.gif | Bin 0 -> 367 bytes mailboxes/images/error.gif | Bin 0 -> 457 bytes mailboxes/images/icon.gif | Bin 0 -> 367 bytes mailboxes/images/p1.gif | Bin 0 -> 55 bytes mailboxes/images/p2.gif | Bin 0 -> 55 bytes mailboxes/images/read.gif | Bin 0 -> 63 bytes mailboxes/images/smallicon.gif | Bin 0 -> 190 bytes mailboxes/images/special.gif | Bin 0 -> 62 bytes mailboxes/index.cgi | 100 + mailboxes/lang/ca | 383 ++ mailboxes/lang/de | 318 ++ mailboxes/lang/en | 383 ++ mailboxes/lang/es | 102 + mailboxes/lang/fr | 105 + mailboxes/lang/it | 353 ++ mailboxes/lang/ja_JP.UTF-8 | 78 + mailboxes/lang/ja_JP.euc | 78 + mailboxes/lang/ja_JP.jis | 78 + mailboxes/lang/ko_KR.UTF-8 | 80 + mailboxes/lang/ko_KR.euc | 80 + mailboxes/lang/pl | 95 + mailboxes/lang/pt | 36 + mailboxes/lang/sv | 75 + mailboxes/lang/tr | 356 ++ mailboxes/lang/zh_CN | 106 + mailboxes/lang/zh_CN.UTF-8 | 106 + mailboxes/lang/zh_TW.Big5 | 265 + mailboxes/lang/zh_TW.UTF-8 | 265 + mailboxes/list_mail.cgi | 245 + mailboxes/log_parser.pl | 45 + mailboxes/mail_search.cgi | 207 + mailboxes/mailboxes-lib.pl | 1034 ++++ mailboxes/makelang.pl | 54 + mailboxes/module.info | 11 + mailboxes/reply_mail.cgi | 555 ++ mailboxes/search_form.cgi | 54 + mailboxes/send_mail.cgi | 288 ++ mailboxes/useradmin_update.pl | 94 + mailboxes/view_mail.cgi | 367 ++ mailboxes/xinha/Xinha.css | 257 + mailboxes/xinha/XinhaCore.js | 3473 +++++++++++++ mailboxes/xinha/contrib/lc_parse_strings.php | 264 + mailboxes/xinha/contrib/php-xinha.php | 202 + mailboxes/xinha/examples/Extended.html | 299 ++ mailboxes/xinha/examples/custom.css | 40 + mailboxes/xinha/examples/dynamic.css | 56 + .../xinha/examples/ext_example-body.html | 202 + mailboxes/xinha/examples/ext_example-dest.php | 23 + mailboxes/xinha/examples/ext_example-menu.php | 331 ++ mailboxes/xinha/examples/ext_example.html | 16 + mailboxes/xinha/examples/full_example.css | 48 + mailboxes/xinha/examples/full_example.js | 97 + mailboxes/xinha/examples/simple_example.html | 138 + mailboxes/xinha/examples/stylist.css | 31 + mailboxes/xinha/examples/testbed.html | 191 + mailboxes/xinha/htmlarea.js | 23 + mailboxes/xinha/images/de/bold.gif | Bin 0 -> 57 bytes mailboxes/xinha/images/de/italic.gif | Bin 0 -> 63 bytes mailboxes/xinha/images/de/underline.gif | Bin 0 -> 69 bytes mailboxes/xinha/images/ed_about.gif | Bin 0 -> 76 bytes mailboxes/xinha/images/ed_align.gif | Bin 0 -> 3388 bytes mailboxes/xinha/images/ed_align_center.gif | Bin 0 -> 61 bytes mailboxes/xinha/images/ed_align_justify.gif | Bin 0 -> 60 bytes mailboxes/xinha/images/ed_align_left.gif | Bin 0 -> 60 bytes mailboxes/xinha/images/ed_align_right.gif | Bin 0 -> 61 bytes mailboxes/xinha/images/ed_blank.gif | Bin 0 -> 56 bytes mailboxes/xinha/images/ed_buttons_main.gif | Bin 0 -> 6629 bytes mailboxes/xinha/images/ed_charmap.gif | Bin 0 -> 134 bytes mailboxes/xinha/images/ed_clearfonts.gif | Bin 0 -> 134 bytes mailboxes/xinha/images/ed_color_bg.gif | Bin 0 -> 172 bytes mailboxes/xinha/images/ed_color_fg.gif | Bin 0 -> 164 bytes mailboxes/xinha/images/ed_copy.gif | Bin 0 -> 97 bytes mailboxes/xinha/images/ed_custom.gif | Bin 0 -> 50 bytes mailboxes/xinha/images/ed_cut.gif | Bin 0 -> 78 bytes mailboxes/xinha/images/ed_delete.gif | Bin 0 -> 80 bytes mailboxes/xinha/images/ed_format_bold.gif | Bin 0 -> 57 bytes mailboxes/xinha/images/ed_format_italic.gif | Bin 0 -> 67 bytes mailboxes/xinha/images/ed_format_strike.gif | Bin 0 -> 66 bytes mailboxes/xinha/images/ed_format_sub.gif | Bin 0 -> 67 bytes mailboxes/xinha/images/ed_format_sup.gif | Bin 0 -> 67 bytes .../xinha/images/ed_format_underline.gif | Bin 0 -> 69 bytes mailboxes/xinha/images/ed_help.gif | Bin 0 -> 55 bytes mailboxes/xinha/images/ed_hr.gif | Bin 0 -> 53 bytes mailboxes/xinha/images/ed_html.gif | Bin 0 -> 64 bytes mailboxes/xinha/images/ed_image.gif | Bin 0 -> 125 bytes mailboxes/xinha/images/ed_indent_less.gif | Bin 0 -> 84 bytes mailboxes/xinha/images/ed_indent_more.gif | Bin 0 -> 84 bytes mailboxes/xinha/images/ed_killword.gif | Bin 0 -> 151 bytes mailboxes/xinha/images/ed_left_to_right.gif | Bin 0 -> 72 bytes mailboxes/xinha/images/ed_link.gif | Bin 0 -> 78 bytes mailboxes/xinha/images/ed_list_bullet.gif | Bin 0 -> 72 bytes mailboxes/xinha/images/ed_list_num.gif | Bin 0 -> 76 bytes mailboxes/xinha/images/ed_overwrite.gif | Bin 0 -> 100 bytes mailboxes/xinha/images/ed_paste.gif | Bin 0 -> 126 bytes mailboxes/xinha/images/ed_print.gif | Bin 0 -> 117 bytes mailboxes/xinha/images/ed_redo.gif | Bin 0 -> 67 bytes mailboxes/xinha/images/ed_right_to_left.gif | Bin 0 -> 75 bytes mailboxes/xinha/images/ed_rmformat.gif | Bin 0 -> 105 bytes mailboxes/xinha/images/ed_save.gif | Bin 0 -> 128 bytes mailboxes/xinha/images/ed_save.png | Bin 0 -> 230 bytes mailboxes/xinha/images/ed_saveas.gif | Bin 0 -> 104 bytes mailboxes/xinha/images/ed_selectall.gif | Bin 0 -> 150 bytes mailboxes/xinha/images/ed_show_border.gif | Bin 0 -> 88 bytes mailboxes/xinha/images/ed_splitblock.gif | Bin 0 -> 82 bytes mailboxes/xinha/images/ed_splitcel.gif | Bin 0 -> 111 bytes mailboxes/xinha/images/ed_undo.gif | Bin 0 -> 67 bytes mailboxes/xinha/images/ed_word_cleaner.gif | Bin 0 -> 652 bytes mailboxes/xinha/images/fr/bold.gif | Bin 0 -> 128 bytes mailboxes/xinha/images/fr/strikethrough.gif | Bin 0 -> 131 bytes mailboxes/xinha/images/fr/underline.gif | Bin 0 -> 134 bytes .../xinha/images/fullscreen_maximize.gif | Bin 0 -> 87 bytes .../xinha/images/fullscreen_minimize.gif | Bin 0 -> 87 bytes mailboxes/xinha/images/insert_table.gif | Bin 0 -> 104 bytes mailboxes/xinha/images/insertfilelink.gif | Bin 0 -> 148 bytes mailboxes/xinha/images/insertmacro.png | Bin 0 -> 638 bytes mailboxes/xinha/images/tidy.gif | Bin 0 -> 375 bytes mailboxes/xinha/images/toggle_borders.gif | Bin 0 -> 73 bytes mailboxes/xinha/images/xinha_logo.gif | Bin 0 -> 3006 bytes mailboxes/xinha/lang/b5.js | 29 + mailboxes/xinha/lang/ch.js | 56 + mailboxes/xinha/lang/cz.js | 50 + mailboxes/xinha/lang/da.js | 30 + mailboxes/xinha/lang/de.js | 163 + mailboxes/xinha/lang/ee.js | 50 + mailboxes/xinha/lang/el.js | 55 + mailboxes/xinha/lang/es.js | 40 + mailboxes/xinha/lang/fa.js | 167 + mailboxes/xinha/lang/fi.js | 38 + mailboxes/xinha/lang/fr.js | 167 + mailboxes/xinha/lang/gb.js | 29 + mailboxes/xinha/lang/he.js | 64 + mailboxes/xinha/lang/hu.js | 64 + mailboxes/xinha/lang/it.js | 55 + mailboxes/xinha/lang/ja.js | 169 + mailboxes/xinha/lang/lt.js | 53 + mailboxes/xinha/lang/lv.js | 42 + mailboxes/xinha/lang/nb.js | 78 + mailboxes/xinha/lang/nl.js | 64 + mailboxes/xinha/lang/pl.js | 125 + mailboxes/xinha/lang/pt_br.js | 32 + mailboxes/xinha/lang/ro.js | 63 + mailboxes/xinha/lang/ru.js | 185 + mailboxes/xinha/lang/sh.js | 140 + mailboxes/xinha/lang/si.js | 50 + mailboxes/xinha/lang/sr.js | 140 + mailboxes/xinha/lang/sv.js | 116 + mailboxes/xinha/lang/vn.js | 56 + mailboxes/xinha/license.txt | 30 + .../xinha/modules/ColorPicker/ColorPicker.js | 522 ++ mailboxes/xinha/modules/CreateLink/link.html | 136 + mailboxes/xinha/modules/CreateLink/link.js | 84 + mailboxes/xinha/modules/Dialogs/dialog.js | 62 + .../xinha/modules/Dialogs/inline-dialog.js | 204 + .../xinha/modules/Dialogs/panel-dialog.js | 76 + mailboxes/xinha/modules/Dialogs/popupwin.js | 120 + .../xinha/modules/FullScreen/full-screen.js | 136 + mailboxes/xinha/modules/FullScreen/lang/de.js | 6 + mailboxes/xinha/modules/FullScreen/lang/fr.js | 5 + mailboxes/xinha/modules/FullScreen/lang/ja.js | 5 + mailboxes/xinha/modules/FullScreen/lang/nb.js | 6 + mailboxes/xinha/modules/FullScreen/lang/pl.js | 6 + mailboxes/xinha/modules/FullScreen/lang/ru.js | 6 + mailboxes/xinha/modules/FullScreen/lang/sv.js | 6 + mailboxes/xinha/modules/Gecko/Gecko.js | 386 ++ .../xinha/modules/Gecko/paraHandlerBest.js | 293 ++ .../xinha/modules/Gecko/paraHandlerDirty.js | 116 + mailboxes/xinha/modules/GetHtml/DOMwalk.js | 168 + .../modules/GetHtml/TransformInnerHTML.js | 143 + .../modules/InsertImage/insert_image.html | 174 + .../xinha/modules/InsertImage/insert_image.js | 107 + .../modules/InsertTable/insert_table.html | 157 + .../xinha/modules/InsertTable/insert_table.js | 63 + .../InternetExplorer/InternetExplorer.js | 203 + mailboxes/xinha/popups/about.html | 296 ++ mailboxes/xinha/popups/blank.html | 2 + mailboxes/xinha/popups/editor_help.html | 62 + mailboxes/xinha/popups/popup.css | 39 + mailboxes/xinha/popups/popup.js | 102 + mailboxes/xinha/popups/select_color.html | 359 ++ mailboxes/xinha/release-notes.txt | 63 + 358 files changed, 47126 insertions(+) create mode 100755 file/BorderPanel.java create mode 100644 file/CHANGELOG create mode 100644 file/CbButton.java create mode 100644 file/CbColorButton.java create mode 100644 file/CbColorWindow.java create mode 100644 file/CbImageChooser.java create mode 100644 file/CbScrollbar.java create mode 100644 file/CbSlider.java create mode 100644 file/ErrorWindow.java create mode 100644 file/FileManager.java create mode 100644 file/FileManager.java.bak create mode 100644 file/FixedFrame.java create mode 100644 file/GrayPanel.java create mode 100644 file/Hierarchy.java create mode 100644 file/Hierarchy.java.bak create mode 100644 file/LinedPanel.java create mode 100644 file/Makefile create mode 100644 file/MultiColumn.java create mode 100644 file/MultiColumn.java.bak create mode 100644 file/QuickSort.java create mode 100644 file/ResizePanel.java create mode 100644 file/StaticTextField.java create mode 100644 file/StringSplitter.java create mode 100644 file/TabbedPanel.java create mode 100644 file/ToolbarLayout.java create mode 100644 file/Util.java create mode 100644 file/acl_security.pl create mode 100755 file/chmod.cgi create mode 100644 file/config create mode 100644 file/config-*-linux create mode 100644 file/config-irix create mode 100644 file/config-solaris create mode 100644 file/config.info create mode 100755 file/config.info.ca create mode 100644 file/config.info.de create mode 100644 file/config.info.es create mode 100644 file/config.info.fa create mode 100755 file/config.info.it create mode 100644 file/config.info.tr create mode 100755 file/copy.cgi create mode 100644 file/defaultacl create mode 100755 file/delete.cgi create mode 100755 file/edit_html.cgi create mode 100755 file/extract.cgi create mode 100644 file/file-lib.pl create mode 100755 file/filesystems.cgi create mode 100755 file/getattrs.cgi create mode 100755 file/getext.cgi create mode 100755 file/getext.cgi.bak create mode 100755 file/getfacl.cgi create mode 100644 file/images/.xvpics/preview.gif create mode 100755 file/images/Thumbs.db create mode 100644 file/images/acl.gif create mode 100644 file/images/add.gif create mode 100644 file/images/all.gif create mode 100644 file/images/attr.gif create mode 100644 file/images/binary.gif create mode 100644 file/images/cancel.gif create mode 100644 file/images/config.gif create mode 100644 file/images/copy.gif create mode 100644 file/images/cut.gif create mode 100644 file/images/delete.gif create mode 100644 file/images/device.gif create mode 100644 file/images/dir.gif create mode 100644 file/images/down.gif create mode 100644 file/images/edit.gif create mode 100644 file/images/ext.gif create mode 100644 file/images/extract.gif create mode 100644 file/images/file.gif create mode 100644 file/images/find.gif create mode 100644 file/images/goto.gif create mode 100755 file/images/html.gif create mode 100644 file/images/icon.gif create mode 100644 file/images/image.gif create mode 100644 file/images/makelink.gif create mode 100644 file/images/mdir.gif create mode 100644 file/images/mkdir.gif create mode 100644 file/images/mount.gif create mode 100644 file/images/new.gif create mode 100644 file/images/open.gif create mode 100644 file/images/paste.gif create mode 100644 file/images/pipe.gif create mode 100644 file/images/preview.gif create mode 100644 file/images/props.gif create mode 100644 file/images/refresh.gif create mode 100644 file/images/rename.gif create mode 100644 file/images/replace.gif create mode 100644 file/images/ret.gif create mode 100644 file/images/run.gif create mode 100644 file/images/save.gif create mode 100644 file/images/sdir.gif create mode 100644 file/images/search.gif create mode 100644 file/images/share.gif create mode 100644 file/images/smallicon.gif create mode 100644 file/images/smdir.gif create mode 100644 file/images/sub.gif create mode 100644 file/images/sudir.gif create mode 100644 file/images/symlink.gif create mode 100644 file/images/text.gif create mode 100644 file/images/udir.gif create mode 100644 file/images/unknown.gif create mode 100644 file/images/upload.gif create mode 100644 file/images/view.gif create mode 100755 file/index.cgi create mode 100755 file/index.cgi.bak create mode 100755 file/irix-getfacl.pl create mode 100755 file/irix-setfacl.pl create mode 100755 file/lang.cgi create mode 100644 file/lang/bg create mode 100644 file/lang/ca create mode 100644 file/lang/de create mode 100644 file/lang/en create mode 100644 file/lang/es create mode 100644 file/lang/fa create mode 100644 file/lang/fr create mode 100644 file/lang/it create mode 100644 file/lang/ja_JP.UTF-8 create mode 100644 file/lang/ja_JP.euc create mode 100644 file/lang/ko_KR.UTF-8 create mode 100644 file/lang/ko_KR.euc create mode 100644 file/lang/pl create mode 100644 file/lang/pt create mode 100644 file/lang/pt_BR create mode 100644 file/lang/ru_RU create mode 100644 file/lang/ru_SU create mode 100644 file/lang/sk create mode 100644 file/lang/sv create mode 100644 file/lang/tr create mode 100644 file/lang/tr.bak create mode 100644 file/lang/uk_UA create mode 100644 file/lang/zh_CN create mode 100644 file/lang/zh_CN.UTF-8 create mode 100644 file/lang/zh_TW.Big5 create mode 100644 file/lang/zh_TW.UTF-8 create mode 100755 file/list.cgi create mode 100755 file/list_exports.cgi create mode 100755 file/list_shares.cgi create mode 100644 file/log_parser.pl create mode 100755 file/makelink.cgi create mode 100755 file/mkdir.cgi create mode 100644 file/module.info create mode 100755 file/mount.cgi create mode 100755 file/move.cgi create mode 100755 file/preview.cgi create mode 100755 file/rename.cgi create mode 100755 file/root.cgi create mode 100755 file/save.cgi create mode 100755 file/save_export.cgi create mode 100755 file/save_html.cgi create mode 100755 file/save_share.cgi create mode 100755 file/search.cgi create mode 100755 file/setattrs.cgi create mode 100755 file/setext.cgi create mode 100755 file/setfacl.cgi create mode 100755 file/show.cgi create mode 100755 file/size.cgi create mode 100755 file/unicode.pl create mode 100644 file/unicode/zh_TW.Big5 create mode 100755 file/upform.cgi create mode 100755 file/upload.cgi create mode 100755 file/upload2.cgi create mode 120000 file/xinha create mode 100644 mailboxes/CHANGELOG create mode 100644 mailboxes/Makefile create mode 100644 mailboxes/acl_security.pl create mode 100644 mailboxes/boxes-lib.pl create mode 100644 mailboxes/config create mode 100644 mailboxes/config.info create mode 100644 mailboxes/config.info.ca create mode 100644 mailboxes/config.info.de create mode 100644 mailboxes/config_info.pl create mode 100644 mailboxes/defaultacl create mode 100755 mailboxes/delete_all.cgi create mode 100755 mailboxes/delete_mail.cgi create mode 100755 mailboxes/detach.cgi create mode 100755 mailboxes/find.cgi create mode 100644 mailboxes/folders-lib.pl create mode 100644 mailboxes/images/attach.gif create mode 100644 mailboxes/images/boxes.gif create mode 100644 mailboxes/images/error.gif create mode 100644 mailboxes/images/icon.gif create mode 100644 mailboxes/images/p1.gif create mode 100644 mailboxes/images/p2.gif create mode 100644 mailboxes/images/read.gif create mode 100644 mailboxes/images/smallicon.gif create mode 100644 mailboxes/images/special.gif create mode 100755 mailboxes/index.cgi create mode 100644 mailboxes/lang/ca create mode 100644 mailboxes/lang/de create mode 100644 mailboxes/lang/en create mode 100644 mailboxes/lang/es create mode 100644 mailboxes/lang/fr create mode 100755 mailboxes/lang/it create mode 100644 mailboxes/lang/ja_JP.UTF-8 create mode 100644 mailboxes/lang/ja_JP.euc create mode 100644 mailboxes/lang/ja_JP.jis create mode 100644 mailboxes/lang/ko_KR.UTF-8 create mode 100644 mailboxes/lang/ko_KR.euc create mode 100644 mailboxes/lang/pl create mode 100644 mailboxes/lang/pt create mode 100644 mailboxes/lang/sv create mode 100644 mailboxes/lang/tr create mode 100644 mailboxes/lang/zh_CN create mode 100644 mailboxes/lang/zh_CN.UTF-8 create mode 100644 mailboxes/lang/zh_TW.Big5 create mode 100644 mailboxes/lang/zh_TW.UTF-8 create mode 100755 mailboxes/list_mail.cgi create mode 100644 mailboxes/log_parser.pl create mode 100755 mailboxes/mail_search.cgi create mode 100644 mailboxes/mailboxes-lib.pl create mode 100755 mailboxes/makelang.pl create mode 100644 mailboxes/module.info create mode 100755 mailboxes/reply_mail.cgi create mode 100755 mailboxes/search_form.cgi create mode 100755 mailboxes/send_mail.cgi create mode 100644 mailboxes/useradmin_update.pl create mode 100755 mailboxes/view_mail.cgi create mode 100644 mailboxes/xinha/Xinha.css create mode 100644 mailboxes/xinha/XinhaCore.js create mode 100644 mailboxes/xinha/contrib/lc_parse_strings.php create mode 100644 mailboxes/xinha/contrib/php-xinha.php create mode 100644 mailboxes/xinha/examples/Extended.html create mode 100644 mailboxes/xinha/examples/custom.css create mode 100644 mailboxes/xinha/examples/dynamic.css create mode 100644 mailboxes/xinha/examples/ext_example-body.html create mode 100644 mailboxes/xinha/examples/ext_example-dest.php create mode 100644 mailboxes/xinha/examples/ext_example-menu.php create mode 100644 mailboxes/xinha/examples/ext_example.html create mode 100644 mailboxes/xinha/examples/full_example.css create mode 100644 mailboxes/xinha/examples/full_example.js create mode 100644 mailboxes/xinha/examples/simple_example.html create mode 100644 mailboxes/xinha/examples/stylist.css create mode 100644 mailboxes/xinha/examples/testbed.html create mode 100644 mailboxes/xinha/htmlarea.js create mode 100644 mailboxes/xinha/images/de/bold.gif create mode 100644 mailboxes/xinha/images/de/italic.gif create mode 100644 mailboxes/xinha/images/de/underline.gif create mode 100644 mailboxes/xinha/images/ed_about.gif create mode 100644 mailboxes/xinha/images/ed_align.gif create mode 100644 mailboxes/xinha/images/ed_align_center.gif create mode 100644 mailboxes/xinha/images/ed_align_justify.gif create mode 100644 mailboxes/xinha/images/ed_align_left.gif create mode 100644 mailboxes/xinha/images/ed_align_right.gif create mode 100644 mailboxes/xinha/images/ed_blank.gif create mode 100644 mailboxes/xinha/images/ed_buttons_main.gif create mode 100644 mailboxes/xinha/images/ed_charmap.gif create mode 100644 mailboxes/xinha/images/ed_clearfonts.gif create mode 100644 mailboxes/xinha/images/ed_color_bg.gif create mode 100644 mailboxes/xinha/images/ed_color_fg.gif create mode 100644 mailboxes/xinha/images/ed_copy.gif create mode 100644 mailboxes/xinha/images/ed_custom.gif create mode 100644 mailboxes/xinha/images/ed_cut.gif create mode 100644 mailboxes/xinha/images/ed_delete.gif create mode 100644 mailboxes/xinha/images/ed_format_bold.gif create mode 100644 mailboxes/xinha/images/ed_format_italic.gif create mode 100644 mailboxes/xinha/images/ed_format_strike.gif create mode 100644 mailboxes/xinha/images/ed_format_sub.gif create mode 100644 mailboxes/xinha/images/ed_format_sup.gif create mode 100644 mailboxes/xinha/images/ed_format_underline.gif create mode 100644 mailboxes/xinha/images/ed_help.gif create mode 100644 mailboxes/xinha/images/ed_hr.gif create mode 100644 mailboxes/xinha/images/ed_html.gif create mode 100644 mailboxes/xinha/images/ed_image.gif create mode 100644 mailboxes/xinha/images/ed_indent_less.gif create mode 100644 mailboxes/xinha/images/ed_indent_more.gif create mode 100644 mailboxes/xinha/images/ed_killword.gif create mode 100644 mailboxes/xinha/images/ed_left_to_right.gif create mode 100644 mailboxes/xinha/images/ed_link.gif create mode 100644 mailboxes/xinha/images/ed_list_bullet.gif create mode 100644 mailboxes/xinha/images/ed_list_num.gif create mode 100644 mailboxes/xinha/images/ed_overwrite.gif create mode 100644 mailboxes/xinha/images/ed_paste.gif create mode 100644 mailboxes/xinha/images/ed_print.gif create mode 100644 mailboxes/xinha/images/ed_redo.gif create mode 100644 mailboxes/xinha/images/ed_right_to_left.gif create mode 100644 mailboxes/xinha/images/ed_rmformat.gif create mode 100644 mailboxes/xinha/images/ed_save.gif create mode 100644 mailboxes/xinha/images/ed_save.png create mode 100644 mailboxes/xinha/images/ed_saveas.gif create mode 100644 mailboxes/xinha/images/ed_selectall.gif create mode 100644 mailboxes/xinha/images/ed_show_border.gif create mode 100644 mailboxes/xinha/images/ed_splitblock.gif create mode 100644 mailboxes/xinha/images/ed_splitcel.gif create mode 100644 mailboxes/xinha/images/ed_undo.gif create mode 100644 mailboxes/xinha/images/ed_word_cleaner.gif create mode 100644 mailboxes/xinha/images/fr/bold.gif create mode 100644 mailboxes/xinha/images/fr/strikethrough.gif create mode 100644 mailboxes/xinha/images/fr/underline.gif create mode 100644 mailboxes/xinha/images/fullscreen_maximize.gif create mode 100644 mailboxes/xinha/images/fullscreen_minimize.gif create mode 100644 mailboxes/xinha/images/insert_table.gif create mode 100644 mailboxes/xinha/images/insertfilelink.gif create mode 100644 mailboxes/xinha/images/insertmacro.png create mode 100644 mailboxes/xinha/images/tidy.gif create mode 100644 mailboxes/xinha/images/toggle_borders.gif create mode 100644 mailboxes/xinha/images/xinha_logo.gif create mode 100644 mailboxes/xinha/lang/b5.js create mode 100644 mailboxes/xinha/lang/ch.js create mode 100644 mailboxes/xinha/lang/cz.js create mode 100644 mailboxes/xinha/lang/da.js create mode 100644 mailboxes/xinha/lang/de.js create mode 100644 mailboxes/xinha/lang/ee.js create mode 100644 mailboxes/xinha/lang/el.js create mode 100644 mailboxes/xinha/lang/es.js create mode 100644 mailboxes/xinha/lang/fa.js create mode 100644 mailboxes/xinha/lang/fi.js create mode 100644 mailboxes/xinha/lang/fr.js create mode 100644 mailboxes/xinha/lang/gb.js create mode 100644 mailboxes/xinha/lang/he.js create mode 100644 mailboxes/xinha/lang/hu.js create mode 100644 mailboxes/xinha/lang/it.js create mode 100644 mailboxes/xinha/lang/ja.js create mode 100644 mailboxes/xinha/lang/lt.js create mode 100644 mailboxes/xinha/lang/lv.js create mode 100644 mailboxes/xinha/lang/nb.js create mode 100644 mailboxes/xinha/lang/nl.js create mode 100644 mailboxes/xinha/lang/pl.js create mode 100644 mailboxes/xinha/lang/pt_br.js create mode 100644 mailboxes/xinha/lang/ro.js create mode 100644 mailboxes/xinha/lang/ru.js create mode 100644 mailboxes/xinha/lang/sh.js create mode 100644 mailboxes/xinha/lang/si.js create mode 100644 mailboxes/xinha/lang/sr.js create mode 100644 mailboxes/xinha/lang/sv.js create mode 100644 mailboxes/xinha/lang/vn.js create mode 100644 mailboxes/xinha/license.txt create mode 100644 mailboxes/xinha/modules/ColorPicker/ColorPicker.js create mode 100644 mailboxes/xinha/modules/CreateLink/link.html create mode 100644 mailboxes/xinha/modules/CreateLink/link.js create mode 100644 mailboxes/xinha/modules/Dialogs/dialog.js create mode 100644 mailboxes/xinha/modules/Dialogs/inline-dialog.js create mode 100644 mailboxes/xinha/modules/Dialogs/panel-dialog.js create mode 100644 mailboxes/xinha/modules/Dialogs/popupwin.js create mode 100644 mailboxes/xinha/modules/FullScreen/full-screen.js create mode 100644 mailboxes/xinha/modules/FullScreen/lang/de.js create mode 100644 mailboxes/xinha/modules/FullScreen/lang/fr.js create mode 100644 mailboxes/xinha/modules/FullScreen/lang/ja.js create mode 100644 mailboxes/xinha/modules/FullScreen/lang/nb.js create mode 100644 mailboxes/xinha/modules/FullScreen/lang/pl.js create mode 100644 mailboxes/xinha/modules/FullScreen/lang/ru.js create mode 100644 mailboxes/xinha/modules/FullScreen/lang/sv.js create mode 100644 mailboxes/xinha/modules/Gecko/Gecko.js create mode 100644 mailboxes/xinha/modules/Gecko/paraHandlerBest.js create mode 100644 mailboxes/xinha/modules/Gecko/paraHandlerDirty.js create mode 100644 mailboxes/xinha/modules/GetHtml/DOMwalk.js create mode 100644 mailboxes/xinha/modules/GetHtml/TransformInnerHTML.js create mode 100644 mailboxes/xinha/modules/InsertImage/insert_image.html create mode 100644 mailboxes/xinha/modules/InsertImage/insert_image.js create mode 100644 mailboxes/xinha/modules/InsertTable/insert_table.html create mode 100644 mailboxes/xinha/modules/InsertTable/insert_table.js create mode 100644 mailboxes/xinha/modules/InternetExplorer/InternetExplorer.js create mode 100644 mailboxes/xinha/popups/about.html create mode 100644 mailboxes/xinha/popups/blank.html create mode 100644 mailboxes/xinha/popups/editor_help.html create mode 100644 mailboxes/xinha/popups/popup.css create mode 100644 mailboxes/xinha/popups/popup.js create mode 100644 mailboxes/xinha/popups/select_color.html create mode 100644 mailboxes/xinha/release-notes.txt diff --git a/file/BorderPanel.java b/file/BorderPanel.java new file mode 100755 index 000000000..67306e5ce --- /dev/null +++ b/file/BorderPanel.java @@ -0,0 +1,67 @@ +import java.awt.*; + +class BorderPanel extends Panel +{ + int border = 5; // size of border + Color col1 = Util.light_edge; + Color col2 = Util.dark_edge; + Color body; + + BorderPanel() + { + } + + BorderPanel(int w) + { + border = w; + } + + BorderPanel(int w, Color cb) + { + border = w; + body = cb; + } + + BorderPanel(int w, Color c1, Color c2) + { + border = w; + col1 = c1; col2 = c2; + } + + BorderPanel(int w, Color c1, Color c2, Color cb) + { + border = w; + col1 = c1; col2 = c2; body = cb; + } + + BorderPanel(Color c1, Color c2) + { + col1 = c1; col2 = c2; + } + + public Insets insets() + { + return new Insets(border+2, border+2, border+2, border+2); + } + + public void paint(Graphics g) + { + if (body != null) { + g.setColor(body); + g.fillRect(0, 0, size().width, size().height); + } + super.paint(g); + int w = size().width-1, h = size().height-1; + g.setColor(col1); + for(int i=0; i= 0 && y >= 0 && x < size().width && y < size().height) { + if (callback != null) + callback.click(this); + select(); + } + indent = false; + repaint(); + return true; + } + + public Dimension preferredSize() + { + return new Dimension(pwidth, pheight); + } + + public Dimension minimumSize() + { + return preferredSize(); + } + + private Dimension imgSize(int mw, int mh) + { + float ws = (float)mw/(float)iwidth, + hs = (float)mh/(float)iheight; + float s = ws < hs ? ws : hs; + if (s > 1) s = 1; + return new Dimension((int)(iwidth*s), (int)(iheight*s)); + } +} + + +interface CbButtonCallback +{ + void click(CbButton b); +} + + +class CbButtonGroup +{ + Vector buttons = new Vector(); + + void add(CbButton b) + { + buttons.addElement(b); + } + + void select(CbButton b) + { + for(int i=0; i num) lvisible = num; + checkValue(); + repaint(); + } + + public int getValue() { return value; } + + public void setValue(int v) + { + value = v; + checkValue(); + repaint(); + } + + private void checkValue() + { + if (value < 0) value = 0; + else if (value > num-lvisible) value = num-lvisible; + } + + public void paint(Graphics g) + { + if (num == 0) return; + int w = size().width, h = size().height; + boolean ins = inside && !(arrow1.inside || arrow2.inside); + Color c1 = ins ? hc1 : lc1, c2 = ins ? hc2 : lc2, + c3 = ins ? hc3 : lc3; + g.setColor(bc); + g.fillRect(0, 0, w, h); + g.setColor(c3); + g.drawLine(0, 0, w-1, 0); g.drawLine(0, 0, 0, h-1); + g.setColor(c1); + g.drawLine(w-1, h-1, w-1, 0); g.drawLine(w-1, h-1, 0, h-1); + + if (orient == VERTICAL) { + int va = h-w*2; + y1 = w+va*value/num; + y2 = w+va*(value+lvisible)/num-1; + g.setColor(c2); + g.fillRect(1, y1, w-2, y2-y1); + g.setColor(indent ? c3 : c1); + g.drawLine(1, y1, w-2, y1); + g.drawLine(1, y1, 1, y2-1); + g.setColor(indent ? c1 : c3); + g.drawLine(w-2, y2-1, w-2, y1); + g.drawLine(w-2, y2-1, 1, y2-1); + if (ins) { + g.drawLine(w-3, y2-2, w-3, y1+1); + g.drawLine(w-3, y2-2, 2, y2-2); + } + } + else if (orient == HORIZONTAL) { + int va = w-h*2; + x1 = h+va*value/num; + x2 = h+va*(value+lvisible)/num-1; + g.setColor(c2); + g.fillRect(x1, 1, x2-x1, h-2); + g.setColor(indent ? c3 : c1); + g.drawLine(x1, 1, x1, h-2); + g.drawLine(x1, 1, x2-1, 1); + g.setColor(indent ? c1 : c3); + g.drawLine(x2-1, h-2, x1, h-2); + g.drawLine(x2-1, h-2, x2-1, 1); + if (ins) { + g.drawLine(x2-2, h-3, x1+1, h-3); + g.drawLine(x2-2, h-3, x2-2, 2); + } + } + } + + /**Called by arrows to move the slider + */ + void arrowClick(int d) + { + int oldvalue = value; + value += d; + checkValue(); + if (value != oldvalue) { + callback.moved(this, value); + repaint(); + } + } + + public void reshape(int nx, int ny, int nw, int nh) + { + super.reshape(nx, ny, nw, nh); + if (orient == VERTICAL) { + arrow1.reshape(1, 1, nw-2, nw-1); + arrow2.reshape(1, nh-nw-1, nw-2, nw-1); + } + else { + arrow1.reshape(1, 1, nh-1, nh-2); + arrow2.reshape(nw-nh-1, 1, nh-1, nh-2); + } + repaint(); + } + + public Dimension preferredSize() + { + return orient==VERTICAL ? new Dimension(16, 100) + : new Dimension(100, 16); + } + + public Dimension minimumSize() + { + return preferredSize(); + } + + public boolean mouseDown(Event e, int mx, int my) + { + if (orient == VERTICAL) { + // move up/down one page, or start dragging + if (my < y1) arrowClick(-lvisible); + else if (my > y2) arrowClick(lvisible); + else { + indent = true; + drag = my-y1; + repaint(); + } + } + else { + // move left/right one page, or start dragging + if (mx < x1) arrowClick(-lvisible); + else if (mx > x2) arrowClick(lvisible); + else { + indent = true; + drag = mx-x1; + repaint(); + } + } + return true; + } + + public boolean mouseDrag(Event e, int mx, int my) + { + if (indent) { + int w = size().width, h = size().height; + int oldvalue = value; + if (orient == VERTICAL) { + int va = h-w*2, ny = my-drag-w; + value = ny*num/va; + } + else { + int va = w-h*2, nx = mx-drag-h; + value = nx*num/va; + } + checkValue(); + if (value != oldvalue) { + callback.moving(this, value); + repaint(); + } + } + return indent; + } + + public boolean mouseUp(Event e, int mx, int my) + { + if (indent) { + indent = false; + repaint(); + callback.moved(this, value); + return true; + } + return false; + } + +/* + public boolean mouseEnter(Event e, int mx, int my) + { + inside = true; + repaint(); + return true; + } + + public boolean mouseExit(Event e, int mx, int my) + { + inside = false; + repaint(); + return true; + } +*/ +} + +class CbScrollbarArrow extends Canvas implements Runnable +{ + int mode; + CbScrollbar scrollbar; + boolean inside, indent; + Thread th; + + CbScrollbarArrow(CbScrollbar p, int m) + { + scrollbar = p; + mode = m; + } + + public void paint(Graphics g) + { + int w = size().width, h = size().height; + Color c1 = inside ? scrollbar.hc1 : scrollbar.lc1, + c2 = inside ? scrollbar.hc2 : scrollbar.lc2, + c3 = inside ? scrollbar.hc3 : scrollbar.lc3; + g.setColor(scrollbar.bc); + g.fillRect(0, 0, w, h); + int xp[] = new int[3], yp[] = new int[3]; + // blank, dark, light + if (mode == 0) { + // up arrow + xp[0] = w/2; xp[1] = w-1; xp[2] = 0; + yp[0] = 0; yp[1] = h-1; yp[2] = h-1; + } + else if (mode == 1) { + // down arrow + xp[0] = 0; xp[1] = w/2; xp[2] = w-1; + yp[0] = 0; yp[1] = h-1; yp[2] = 0; + } + else if (mode == 2) { + // left arrow + xp[0] = 0; xp[1] = w-1; xp[2] = w-1; + yp[0] = h/2; yp[1] = h-1; yp[2] = 0; + } + else if (mode == 3) { + // right arrow + xp[0] = 0; xp[1] = w-1; xp[2] = 0; + yp[0] = 0; yp[1] = h/2; yp[2] = h-1; + } + g.setColor(c2); + g.fillPolygon(xp, yp, 3); + g.setColor(indent ? c1 : c3); + g.drawLine(xp[1], yp[1], xp[2], yp[2]); + g.setColor(indent ? c3 : c1); + g.drawLine(xp[0], yp[0], xp[2], yp[2]); + } + + public boolean mouseDown(Event e, int mx, int my) + { + indent = true; + repaint(); + (th = new Thread(this)).start(); + return true; + } + + public boolean mouseUp(Event e, int mx, int my) + { + indent = false; + repaint(); + if (th != null) th.stop(); + return true; + } + + /**Thread for doing repeated scrolling + */ + public void run() + { + int stime = 500; + while(true) { + scrollbar.arrowClick(mode%2 == 0 ? -1 : 1); + try { Thread.sleep(stime); } catch(Exception e) { } + stime = 100; + } + } +} + + +// CbScrollbarCallback +// Methods for reporting the movement of the scrollbar to another object +interface CbScrollbarCallback +{ + /**Called when the scrollbar stops moving. This happens when an + * arrow is clicked, the scrollbar is moved by a page, or the user + * lets go of the scrollbar after dragging it. + * @param sb The scrollar that has been moved + * @param v The new value + */ + void moved(CbScrollbar sb, int v); + + /**Called upon every pixel movement of the scrollbar when it is + * being dragged, but NOT when moved() is called. + * @param sb The scrollar that has been moved + * @param v The new value + */ + void moving(CbScrollbar sb, int v); +} + + diff --git a/file/CbSlider.java b/file/CbSlider.java new file mode 100644 index 000000000..52a37d5bf --- /dev/null +++ b/file/CbSlider.java @@ -0,0 +1,233 @@ +import java.awt.*; + +class CbSlider extends Canvas +{ + int dir, min, max, pos; + CbSliderCallback callback; + int px, py; + Color lc1 = Util.light_edge, lc2 = Util.body, lc3 = Util.dark_edge; + Color hc1 = Util.light_edge_hi, hc2 = Util.body_hi, hc3 = Util.dark_edge_hi; + int ticks = 0; + boolean inside = false, dragging = false; + int dragx; + + /**Create a new slider + * @param d 0=horizontal, 1=vertical + * @param mi Minimum value + * @param ma Maximum value + * @param p Current value + */ + public CbSlider(int d, int mi, int ma, int p) + { + this(d, mi, ma, p, null); + } + + /**Create a new slider + * @param d 0=horizontal, 1=vertical + * @param mi Minimum value + * @param ma Maximum value + * @param p Current value + * @param cb Object to call back to + */ + public CbSlider(int d, int mi, int ma, int p, CbSliderCallback cb) + { + dir = d; min = mi; max = ma; + pos = p; + callback = cb; + } + + /**Toggle drawing of tick-marks on the slider track + * @param t The number of units/tick, or 0 to disable + */ + public void setTicks(int t) + { + ticks = t; + repaint(); + } + + /**Returns the current slider position + */ + public int getPosition() { return pos; } + + /**Sets the current slider position + */ + public void setPosition(int p) + { + if (pos != p) { + pos = p; + repaint(); + } + } + + /**Returns the current minimum slider value + */ + public int getMinimum() { return min; } + + /**Sets the minimum slider value + * @param mi The new minimum + */ + public void setMinimum(int mi) + { + min = mi; + checkPos(); + repaint(); + } + + /**Returns the current maximum slider value + */ + public int getMaximum() { return max; } + + /**Sets the maximum slider value + * @param mx The new maximum + */ + public void setMaximum(int mx) + { + max = mx; + checkPos(); + repaint(); + } + + public void paint(Graphics g) + { + Color c1 = inside ? hc1 : lc1, + c2 = inside ? hc2 : lc2, + c3 = inside ? hc3 : lc3; + + // draw slider track + int w = size().width, h = size().height; + g.setColor(c2); + g.fillRect(0, 0, w, h); + g.setColor(c3); + g.drawLine(8, h/2, w-8, h/2); + g.setColor(c1); + g.drawLine(8, h/2+1, w-8, h/2+1); + + // draw border + g.setColor(c1); + g.drawLine(0, 0, w-1, 0); + g.drawLine(0, 0, 0, h-1); + g.setColor(c3); + g.drawLine(w-1, h-1, w-1, 0); + g.drawLine(w-1, h-1, 0, h-1); + if (inside) { + g.drawLine(w-2, h-2, w-2, 0); + g.drawLine(w-2, h-2, 0, h-2); + } + + // draw tick marks + if (ticks != 0) { + int mm = max-min; + for(int i=0; i<=mm; i+=ticks) { + int tx = ((w-16)*i / mm) + 8; + g.setColor(c3); + g.drawLine(tx, h/2, tx, h/2-6); + } + } + + // draw slider + px = ((w-16)*pos / (max - min)) + 8; + py = h/2; + g.setColor(c2); + int xpt[] = { px-3, px-3, px, px+3, px+3 }; + int ypt[] = { py+5, py-4, py-6, py-4, py+5 }; + g.fillPolygon(xpt, ypt, 5); + g.setColor(dragging ? c3 : c1); + g.drawLine(px-3, py+5, px-3, py-4); + g.drawLine(px-3, py-4, px, py-6); + g.setColor(dragging ? c1 : c3); + g.drawLine(px-3, py+5, px+3, py+5); + g.drawLine(px+3, py+5, px+3, py-4); + } + + public void update(Graphics g) { paint(g); } + + public boolean mouseEnter(Event e, int x, int y) + { + inside = true; + repaint(); + return true; + } + + public boolean mouseDown(Event e, int x, int y) + { + int step = ticks==0 ? (max-min)/10 : ticks; + if (x < px-3) { + // move one tick to the left + pos -= step; + } + else if (x > px+3) { + // move one tick to the right + pos += step; + } + else { + // start dragging + dragging = true; + dragx = x-px; + } + checkPos(); + if (callback != null) + callback.moved(this, pos); + repaint(); + return true; + } + + public boolean mouseDrag(Event e, int x, int y) + { + if (dragging) { + px = x-dragx; + pos = (px-8)*(max - min) / (size().width-16); + checkPos(); + if (callback != null) + callback.moving(this, pos); + repaint(); + } + return dragging; + } + + public boolean mouseUp(Event e, int x, int y) + { + if (dragging) { + dragging = false; + if (callback != null) + callback.moved(this, pos); + repaint(); + return true; + } + return false; + } + + public boolean mouseExit(Event e, int x, int y) + { + inside = false; + repaint(); + return true; + } + + protected void checkPos() + { + if (pos < min) pos = min; + else if (pos > max) pos = max; + } + + public Dimension preferredSize() + { + return new Dimension(100, 20); + } + + public Dimension minimumSize() { return preferredSize(); } +} + +interface CbSliderCallback +{ + /**Callled back when the slider stops at a new position + * @param s The slider being moved + * @param p New position + */ + public void moved(CbSlider s, int p); + + /**Callled back whenever the slider is being dragged + * @param s The slider being moved + * @param p New position + */ + public void moving(CbSlider s, int p); +} diff --git a/file/ErrorWindow.java b/file/ErrorWindow.java new file mode 100644 index 000000000..dd655461f --- /dev/null +++ b/file/ErrorWindow.java @@ -0,0 +1,34 @@ +import java.awt.*; +import java.util.*; + +class ErrorWindow extends FixedFrame implements CbButtonCallback +{ + CbButton ok; + + ErrorWindow(String m) + { + setLayout(new BorderLayout()); + Panel cen = new BorderPanel(1); + StringTokenizer tok = new StringTokenizer(m, "\r\n"); + cen.setLayout(new GridLayout(tok.countTokens(), 1)); + while(tok.hasMoreTokens()) { + cen.add(new Label(tok.nextToken())); + } + add("Center", cen); + Panel bot = new GrayPanel(); + bot.setLayout(new FlowLayout(FlowLayout.CENTER)); + bot.add(new CbButton("Ok", this)); + add("South", bot); + pack(); + show(); + setTitle("Error"); + Util.recursiveBackground(this, Util.body); + } + + public void click(CbButton b) + { + dispose(); + } +} + + diff --git a/file/FileManager.java b/file/FileManager.java new file mode 100644 index 000000000..fcbc2b4cc --- /dev/null +++ b/file/FileManager.java @@ -0,0 +1,4504 @@ +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.applet.*; +import java.net.*; +import java.util.*; +import netscape.javascript.JSObject; + +// A java filemanager that allows the user to manipulate files on the +// Webmin server. Layout is similar to the windows explorer - directory +// tree on the left, files on the right, action buttons on the top. +public class FileManager extends Applet + implements CbButtonCallback, HierarchyCallback, MultiColumnCallback +{ + // top buttons + CbButton ret_b, config_b, down_b, edit_b, refresh_b, props_b, + copy_b, cut_b, paste_b, delete_b, new_b, upload_b, mkdir_b, + makelink_b, rename_b, share_b, mount_b, search_b, acl_b, + attr_b, ext_b, preview_b, extract_b, hnew_b; + + // Directory tree + Hierarchy dirs; + FileNode root; + Hashtable nodemap = new Hashtable(); + + // File list + MultiColumn files; + TextField pathname; + CbButton history_b; + RemoteFile showing_files; + RemoteFile showing_list[]; + Vector history_list = new Vector(); + + // Copying and pasting + RemoteFile cut_buffer[]; + boolean cut_mode; + + static final String monmap[] = { "Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", + "Sep", "Oct", "Nov", "Dec" }; + String accroot[]; + String accnoroot[]; + Hashtable lang = new Hashtable(); + Hashtable stab = new Hashtable(), + ntab = new Hashtable(); + boolean sambamode; + int nfsmode; + String trust; + String extra; + String images; + int iconsize; + + boolean got_filesystems, + acl_support, attr_support, ext_support; + Hashtable mounts = new Hashtable(); + Vector fslist = new Vector(); + boolean read_only = false; + + // Standard font for all text + Font fixed; + + // Font for button labels + Font small_fixed; + + // Full session cookie + String session; + + // Archive parameter + String archive; + + // Chroot directory for tree + String chroot; + + // File attributes that can be edited + boolean can_perms, can_users; + + // Symlimks are automatically followed + boolean follow_links; + + // Can search file contents + boolean search_contents; + + // Use text editor for HTML + boolean force_text; + + public void init() + { + setLayout(new BorderLayout()); + + // Create fonts from specified size + fixed = make_font("fixed", 12); + small_fixed = make_font("small_fixed", 10); + + Util.setFont(small_fixed); + StringTokenizer tok = new StringTokenizer(getParameter("root"), " "); + accroot = new String[tok.countTokens()]; + for(int i=0; tok.hasMoreTokens(); i++) + accroot[i] = tok.nextToken(); + if (getParameter("noroot") != null) { + tok = new StringTokenizer(getParameter("noroot"), " "); + accnoroot = new String[tok.countTokens()]; + for(int i=0; tok.hasMoreTokens(); i++) + accnoroot[i] = tok.nextToken(); + } + else { + accnoroot = new String[0]; + } + trust = getParameter("trust"); + session = getParameter("session"); + extra = getParameter("extra"); + if (extra == null) extra = ""; + images = getParameter("images"); + if (images == null) images = "images"; + iconsize = Integer.parseInt(getParameter("iconsize")); + archive = getParameter("doarchive"); + if (archive == null) archive = "0"; + chroot = getParameter("chroot"); + if (chroot == null) chroot = "/"; + String can_perms_str = getParameter("canperms"); + can_perms = can_perms_str == null || !can_perms_str.equals("0"); + String can_users_str = getParameter("canusers"); + can_users = can_users_str == null || !can_users_str.equals("0"); + String search_contents_str = getParameter("contents"); + search_contents = search_contents_str == null || + !search_contents_str.equals("0"); + String force_text_str = getParameter("force_text"); + if (force_text_str != null && force_text_str.equals("1")) + force_text = true; + + // download language strings + String l[] = get_text("lang.cgi"); + if (l.length < 1 || l[0].indexOf('=') < 0) { + String err = "Failed to get language list : "+join_array(l); + new ErrorWindow(err); + throw new Error(err); + } + for(int i=0; i= 0) + lang.put(l[i].substring(0, eq), l[i].substring(eq+1)); + } + + // list samba file shares + String s[] = get_text("list_shares.cgi"); + if (s[0].equals("1")) { + for(int i=1; i 0 || s == 0 && ss.length > 1) { + // At least one non-.. file was selected + boolean parentsel = false; + for(int i=0; i 4) + new ErrorWindow(text("edit_enormal")); + else if ((f.path.toLowerCase().endsWith(".htm") || + f.path.toLowerCase().endsWith(".html")) && + !force_text) { + // Open HTML editor + try { + JSObject win = JSObject.getWindow(this); + String params[] = { f.path, "" }; + win.call("htmledit", params); + } + catch(Exception e) { + new ErrorWindow(text("html_efailed", + e.getMessage())); + } + } + else { + // Open text editor + new EditorWindow(f, this); + } + } + else if (b == down_b) { + // Force download of the selected file + if (f == null) return; + download_file(f); + } + else if (b == preview_b) { + // Open preview window for selected file + if (f == null) return; + if (f.type == RemoteFile.DIR) + new ErrorWindow(text("preview_eimage")); + else + new PreviewWindow(this, f); + } + else if (b == refresh_b) { + // Refesh the selected directory (and thus any subdirs) + if (d == null) return; + d.refresh(); + show_files(d.file); + } + else if (b == props_b) { + // Display the properties window + if (f == null) return; + new PropertiesWindow(f, this); + } + else if (b == acl_b) { + // Display the ACL window (if filesystem supports them) + if (f == null) return; + FileSystem filefs = find_filesys(f); + if (filefs == null) return; + if (filefs.acls) + new ACLWindow(this, f); + else + new ErrorWindow(text("eacl_efs", filefs.mount)); + } + else if (b == attr_b) { + // Display the attributes window (if filesystem supports them) + if (f == null) return; + FileSystem filefs = find_filesys(f); + if (filefs == null) return; + if (filefs.attrs) + new AttributesWindow(this, f); + else + new ErrorWindow(text("attr_efs", filefs.mount)); + } + else if (b == ext_b) { + // Display EXT attributes window (if filesystem supports them) + if (f == null) return; + FileSystem filefs = find_filesys(f); + if (filefs == null) return; + if (filefs.ext) + new EXTWindow(this, f); + else + new ErrorWindow(text("ext_efs", filefs.mount)); + } + else if (b == copy_b) { + // Copy the selected files + if (f == null) return; + cut_buffer = ff; + cut_mode = false; + } + else if (b == cut_b) { + // Cut the selected file + if (f == null) return; + cut_buffer = ff; + cut_mode = true; + } + else if (b == paste_b) { + // Paste the copied file + if (cut_buffer == null) { + new ErrorWindow(text("paste_ecopy")); + return; + } + + // Check for existing file clashes + // XXX + + // Go through all the files to paste + for(int i=0; i 0) { + new HistoryWindow(this); + } + } + } + + boolean under_root_dir(String p, String roots[]) + { + boolean can = false; + int l = p.length(); + for(int r=0; r= rl && p.substring(0, rl).equals(roots[r])) + can = true; + else if (l < rl && roots[r].substring(0, l).equals(p)) + can = true; + } + return can; + } + + // Download some file to the user's browser, if possible + void download_file(RemoteFile f) + { + if (f.type == RemoteFile.DIR && !archive.equals("0")) + new DownloadDirWindow(this, f); + else if (f.type == RemoteFile.DIR || f.type > 4) + new ErrorWindow(text("view_enormal2")); + else + open_file_window(f, true, 0); + } + + // Returns the object for some directory, or null if not found. + RemoteFile find_directory(String p, boolean fill) + { + boolean can = under_root_dir(p, accroot) && + !under_root_dir(p, accnoroot); + if (!can) { + new ErrorWindow(text("find_eaccess", p)); + return null; + } + FileNode posnode = root; + RemoteFile pos = posnode.file; + StringTokenizer tok = new StringTokenizer(p, "/"); + while(tok.hasMoreTokens()) { + String fn = tok.nextToken(); + if (fn.equals("")) continue; + RemoteFile fl[] = pos.list(); + if (fl == null) return null; + if (fill) { + posnode.open = true; + posnode.fill(); + } + boolean found = false; + for(int i=0; i= l+1 && + f.path.substring(0, l+1).equals(fs.mount+"/")) || + fs.mount.equals("/")) { + filefs = fs; + } + } + return filefs; + } + + public boolean action(Event e, Object o) + { + if (e.target == pathname) { + // A new path was entered.. cd to it + String p = pathname.getText().trim(); + if (p.equals("")) return true; + find_directory(p, true); + + // Add to the history + if (!history_list.contains(p)) { + history_list.insertElementAt(p, 0); + } + return true; + } + return false; + } + + // singleClick + // Called on a single click on a list item + public void singleClick(MultiColumn list, int num) + { + } + + // doubleClick + // Called upon double-clicking on a list item + public void doubleClick(MultiColumn list, int num) + { + if (num == 0) { + // Go to parent directory + if (showing_files.directory != null) { + ((FileNode)nodemap.get(showing_files)).open = false; + show_files(showing_files.directory); + dirs.select((FileNode)nodemap.get(showing_files)); + dirs.redraw(); + } + return; + } + RemoteFile d = showing_list[num-1]; + if (d.type == 0) { + // Open this directory + FileNode pn = (FileNode)nodemap.get(showing_files); + pn.fill(); + pn.open = true; + FileNode fn = (FileNode)nodemap.get(d); + if (show_files(d)) { + fn.fill(); + fn.open = true; + dirs.select(fn); + dirs.redraw(); + } + } + else if (d.type <= 4) { + // Direct the browser to this file + open_file_window(d, list.last_event.shiftDown(), 0); + } + } + + // Called when the user clicks on a column heading so that it can + // be sorted. + public void headingClicked(MultiColumn list, int col) + { + if (col == 0) + return; // ignore click on icon column? + if (col == list.sortcol) { + list.sortingArrow(col, list.sortdir == 2 ? 1 : 2); + } + else { + list.sortingArrow(col, 1); + } + + // Re-show the list in the new order, but with the same files selected + int ss[] = files.allSelected(); + RemoteFile ssf[] = new RemoteFile[ss.length]; + for(int i=0; i 0) { + new ErrorWindow(text("eopen", l[0])); + return; + } + + // Open for real + if (download) { + getAppletContext().showDocument( + new URL(getDocumentBase(), urlstr)); + } + else { + getAppletContext().showDocument( + new URL(getDocumentBase(), urlstr), "show"); + } + } + catch(Exception e) { } + } + + static String urlize(String s) + { + StringBuffer rv = new StringBuffer(); + for(int i=0; i= 128) + rv.append("%"+Integer.toString(c, 16)); + else + rv.append(c); + } + return rv.toString(); + } + + static String un_urlize(String s) + { + StringBuffer rv = new StringBuffer(); + for(int i=0; i= 0) { + rv = rv.substring(0, idx)+ + ns+rv.substring(idx+os.length()); + pos = idx+ns.length()+1; + } + return rv; + } +} + +// A node in the directory tree +class FileNode extends HierarchyNode +{ + FileManager parent; + RemoteFile file; + boolean known; + + FileNode(RemoteFile file) + { + this.file = file; + parent = file.parent; + setimage(); + ch = new Vector(); + text = file.name; + parent.nodemap.put(file, this); + } + + // Create the nodes for subdirectories + void fill() + { + if (!known) { + RemoteFile l[] = file.list(); + if (l == null) return; + ch.removeAllElements(); + for(int i=0; i 0) { + ch.insertElementAt(n, i); + break; + } + } + } + + void setimage() + { + im = parent.get_image(file.shared() && file.mounted() ? "smdir.gif" : + file.shared() && file.mountpoint() ? "sudir.gif" : + file.shared() ? "sdir.gif" : + file.mounted() ? "mdir.gif" : + file.mountpoint() ? "udir.gif" : + "dir.gif"); + } + + // Forces a re-load from the server + void refresh() + { + known = false; + file.list = null; + fill(); + } +} + +class RemoteFile +{ + static final int DIR = 0; + static final int TEXT = 1; + static final int IMAGE = 2; + static final int BINARY = 3; + static final int UNKNOWN = 4; + static final int SYMLINK = 5; + static final int DEVICE = 6; + static final int PIPE = 7; + static final String[] tmap = { "dir.gif", "text.gif", "image.gif", + "binary.gif", "unknown.gif", + "symlink.gif", "device.gif", + "pipe.gif" }; + + FileManager parent; + String path, name; + int type; + String user, group; + long size; + int perms; + long modified; + String linkto; + RemoteFile list[]; + RemoteFile directory; + + // Parse a line of text to a file object + RemoteFile(FileManager parent, String line, RemoteFile d) + { + this.parent = parent; + StringTokenizer tok = new StringTokenizer(line, "\t"); + if (tok.countTokens() < 7) { + String err = "Invalid file line : "+line; + new ErrorWindow(err); + throw new Error(err); + } + path = tok.nextToken(); + path = parent.replace_str(path, "\\t", "\t"); + path = parent.replace_str(path, "\\\\", "\\"); + type = Integer.parseInt(tok.nextToken()); + user = tok.nextToken(); + group = tok.nextToken(); + size = Long.parseLong(tok.nextToken()); + perms = Integer.parseInt(tok.nextToken()); + modified = Long.parseLong(tok.nextToken())*1000; + if (type == 5) linkto = tok.nextToken(); + directory = d; + if (path.equals("/")) name = "/"; + else name = path.substring(path.lastIndexOf('/')+1); + } + + // Create a new, empty file object + RemoteFile() { } + + // Returns a list of files in this directory + RemoteFile[] list() + { + if (list == null) { + String l[] = parent.get_text("list.cgi?dir="+ + parent.urlize(path)); + if (l[0].length() > 0) { + //list = new RemoteFile[0]; + // Error reading the remote directory! + new ErrorWindow(parent.text("list_edir", path, l[0])); + list = null; + } + else { + list = new RemoteFile[l.length-3]; + for(int i=3; i 0 && offset == 0) { + nlist[i] = f; + offset++; + } + nlist[i+offset] = list[i]; + } + if (offset == 0) nlist[list.length] = f; + list = nlist; + } + + void delete(RemoteFile f) + { + RemoteFile nlist[] = new RemoteFile[list.length-1]; + for(int i=0,j=0; i= 0) { + // Length is known + buf = new byte[uc.getContentLength()]; + int got = 0; + while(got < buf.length) + got += is.read(buf, got, buf.length-got); + } + else { + // Length is unknown .. read till the end + buf = new byte[0]; + while(true) { + byte data[] = new byte[16384]; + int got; + try { got = is.read(data); } + catch(EOFException ex) { break; } + if (got <= 0) break; + byte nbuf[] = new byte[buf.length + got]; + System.arraycopy(buf, 0, nbuf, 0, buf.length); + System.arraycopy(data, 0, nbuf, buf.length, got); + buf = nbuf; + } + } + String s = new String(buf, 0); + if (s.indexOf("\r\n") != -1) { + dosmode.setState(true); + s = FileManager.replace_str(s, "\r\n", "\n"); + } + edit.setText(s); + is.close(); + file.size = buf.length; + } + catch(Exception e) { e.printStackTrace(); } + } + + // Creating a new file + EditorWindow(String f, FileManager p) + { + super(500, 300); + filemgr = p; + makeUI(true); + setTitle(filemgr.text("edit_title2")); + name.setText(f.equals("/") ? f : f+"/"); + name.select(name.getText().length(), name.getText().length()); + } + + void makeUI(boolean add_name) + { + setLayout(new BorderLayout()); + if (add_name) { + Panel np = new Panel(); + np.setLayout(new BorderLayout()); + np.add("West", new Label(filemgr.text("edit_filename"))); + np.add("Center", name = new TextField()); + name.setFont(filemgr.fixed); + add("North", np); + } + add("Center", edit = new TextArea(20, 80)); + edit.setFont(filemgr.fixed); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.RIGHT)); + bot.add(dosmode = new Checkbox("DOS mode")); + bot.add(goto_b = new CbButton(filemgr.get_image("goto.gif"), + filemgr.text("edit_goto"), + CbButton.LEFT, this)); + bot.add(find_b = new CbButton(filemgr.get_image("find.gif"), + filemgr.text("edit_find"), + CbButton.LEFT, this)); + bot.add(new Label(" ")); + bot.add(save_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("save"), + CbButton.LEFT, this)); + bot.add(saveclose_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("edit_saveclose"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("close"), + CbButton.LEFT, this)); + add("South", bot); + Util.recursiveBody(this); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == save_b || b == saveclose_b) { + RemoteFile par = null, already = null; + String save_path; + if (file == null) { + // Locate the filemgr directory + save_path = filemgr.trim_path(name.getText()); + int sl = save_path.lastIndexOf('/'); + par = filemgr.find_directory( + save_path.substring(0, sl), false); + if (par == null) return; + already = par.find(save_path.substring(sl+1)); + if (already != null && + (already.type == 0 || already.type == 5)) { + new ErrorWindow( + filemgr.text("edit_eover", save_path)); + return; + } + } + else save_path = file.path; + + // Save the file back again + String s = edit.getText(), line; + s = FileManager.replace_str(s, "\r\n", "\n"); + try { + if (dosmode.getState()) { + // Convert to DOS newlines + s = FileManager.replace_str(s, "\n", "\r\n"); + } + URL u = new URL(filemgr.getDocumentBase(), + "save.cgi"+filemgr.urlize(save_path)+ + "?rand="+System.currentTimeMillis()+ + "&trust="+filemgr.trust+ + "&length="+s.length()+ + filemgr.extra); + URLConnection uc = u.openConnection(); + uc.setRequestProperty("Content-type", "text/plain"); + filemgr.set_cookie(uc); + uc.setDoOutput(true); + OutputStream os = uc.getOutputStream(); + byte buf[] = new byte[s.length()]; + s.getBytes(0, buf.length, buf, 0); + os.write(buf); + os.close(); + BufferedReader is = + new BufferedReader(new InputStreamReader( + uc.getInputStream())); + String err = is.readLine(); + if (err.length() > 0) { + new ErrorWindow( + filemgr.text("edit_esave", err)); + is.close(); + return; + } + line = is.readLine(); + is.close(); + } + catch(Exception e) { e.printStackTrace(); return; } + + if (file == null) { + // Create and insert or replace the file object + file = new RemoteFile(filemgr, line, par); + if (already != null) { + // A file with this name exists + already.type = file.type; + already.user = file.user; + already.group = file.group; + already.size = file.size; + already.perms = file.perms; + already.modified = file.modified; + } + else { + // Add to the list + par.add(file); + } + } + else { + file.size = s.length(); + file.modified = System.currentTimeMillis(); + } + filemgr.show_files(filemgr.showing_files); + if (b == saveclose_b) + dispose(); + } + else if (b == cancel_b) { + // Just close + dispose(); + } + else if (b == goto_b) { + // Open a dialog asking which line to go to + if (goto_window != null) + goto_window.toFront(); + else + goto_window = new GotoWindow(this); + } + else if (b == find_b) { + // Open the search (and replace) dialog + if (find_window != null) + find_window.toFront(); + else + find_window = new FindReplaceWindow(this); + } + } + + public void dispose() + { + super.dispose(); + if (goto_window != null) goto_window.dispose(); + if (find_window != null) find_window.dispose(); + } +} + +class GotoWindow extends FixedFrame implements CbButtonCallback +{ + EditorWindow editor; + FileManager filemgr; + TextField line; + CbButton goto_b, cancel_b; + + GotoWindow(EditorWindow e) + { + editor = e; + filemgr = e.filemgr; + + setLayout(new BorderLayout()); + add("West", new Label(filemgr.text("edit_gotoline"))); + add("Center", line = new TextField(10)); + line.setFont(filemgr.fixed); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.RIGHT)); + bot.add(goto_b = new CbButton(filemgr.get_image("goto.gif"), + filemgr.text("edit_goto"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("close"), + CbButton.LEFT, this)); + add("South", bot); + Util.recursiveBody(this); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == goto_b) { + // Go to the chose line, if it exists + int lnum; + try { lnum = Integer.parseInt(line.getText()); } + catch(Exception e) { return; } + + String txt = editor.edit.getText(); + int c, l = 0; + for(c=0; c= 0) { + String sel = edittxt.substring(st, en); + if (sel.equals(findtxt)) { + // Replace the selected + editor.edit.setText(edittxt.substring(0, st)+ + replace.getText()+ + edittxt.substring(en)); + editor.edit.select(st, st); + return; + } + } + click(find_b); + } + else if (b == all_b) { + // Replace all occurrances of the text in the editor + int pos = 0; + int len = findtxt.length(); + int st = editor.edit.getSelectionStart(), + en = editor.edit.getSelectionEnd(); + while((pos = edittxt.indexOf(findtxt, pos)) != -1) { + edittxt = edittxt.substring(0, pos)+ + replace.getText()+ + edittxt.substring(pos+len); + pos += len; + } + editor.edit.setText(edittxt); + editor.edit.select(st, en); // put back old selection + } + else if (b == cancel_b) { + // Just close the window + dispose(); + } + } + + public void dispose() + { + super.dispose(); + editor.find_window = null; + } +} + +class PropertiesWindow extends FixedFrame implements CbButtonCallback +{ + RemoteFile file; + FileManager filemgr; + CbButton save_b, cancel_b, size_b; + + TextField linkto; + TextField user, group; + Checkbox setuid, setgid; + PermissionsPanel user_p, group_p, other_p; + Checkbox sticky; + Choice rec_mode; + TextField octal; + + TextField bytes, files, dirs; + + PropertiesWindow(RemoteFile f, FileManager p) + { + file = f; + filemgr = p; + + // Create UI + setTitle(f.path); + setLayout(new BorderLayout()); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.RIGHT)); + if (file.type == 0) { + bot.add(size_b = new CbButton(filemgr.get_image("refresh.gif"), + filemgr.text("info_getsize"), + CbButton.LEFT, this)); + } + if (filemgr.can_perms || filemgr.can_users) { + bot.add(save_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("save"), + CbButton.LEFT, this)); + } + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + + Panel mid = new Panel(); + mid.setLayout(new BorderLayout()); + TabbedPanel tab = null; + add("Center", mid); + + // Create file details section + Panel det = new LinedPanel(filemgr.text("info_file")), + dl = new Panel(), dr = new Panel(); + setup_leftright(det, dl, dr); + add_item(filemgr.text("info_path"), + new Label(file.path), dl, dr); + add_item(filemgr.text("info_type"), + new Label(filemgr.text("file_type"+file.type)), dl, dr); + add_item(filemgr.text("info_size"), + new Label(String.valueOf(file.size)),dl,dr); + add_item(filemgr.text("info_mod"), + new Label(String.valueOf(new Date(file.modified))), dl, dr); + if (file.type == 5) { + add_item(filemgr.text("info_link"), + linkto = new TextField(file.linkto, 30), dl, dr); + linkto.setFont(filemgr.fixed); + } + mid = add_panel(mid, det); + + if (filemgr.can_perms) { + // Create permissions section + Panel per = new LinedPanel(filemgr.text("info_perms")), + pl = new Panel(), pr = new Panel(); + setup_leftright(per, pl, pr); + add_item(filemgr.text("info_user"), + user_p = new PermissionsPanel(file, 64, filemgr), pl, pr); + add_item(filemgr.text("info_group"), + group_p = new PermissionsPanel(file, 8, filemgr), pl, pr); + add_item(filemgr.text("info_other"), + other_p = new PermissionsPanel(file, 1, filemgr), pl,pr); + if (file.type == 0) { + add_item(filemgr.text("info_sticky"), + sticky = new Checkbox(filemgr.text("info_sticky2")), + pl,pr); + sticky.setState((file.perms&01000) != 0); + } + add_item(filemgr.text("info_octal"), + octal = new TextField(4), pl, pr); + octal.setFont(filemgr.fixed); + octal.setEditable(false); + mid = add_panel(mid, per); + } + + if (filemgr.can_users) { + // Create ownership section + Panel own = new LinedPanel(filemgr.text("info_own")), + ol = new Panel(), or = new Panel(); + setup_leftright(own, ol, or); + add_item(filemgr.text("info_user"), + user = new TextField(file.user, 10), ol, or); + user.setFont(filemgr.fixed); + if (file.type != 0) { + add_item(filemgr.text("info_setuid"), + setuid = new Checkbox(filemgr.text("info_setuid2")), + ol, or); + setuid.setState((file.perms & 0x800) != 0); + } + add_item(filemgr.text("info_group"), + group = new TextField(file.group, 10), ol, or); + group.setFont(filemgr.fixed); + if (file.type == 0) + add_item(filemgr.text("info_setgid"), + setgid = new Checkbox(filemgr.text("info_setgid2")), + ol, or); + else + add_item(filemgr.text("info_setgid"), + setgid = new Checkbox(filemgr.text("info_setgid3")), + ol, or); + setgid.setState((file.perms & 0x400) != 0); + mid = add_panel(mid, own); + } + + if (file.type == 0) { + // Create directory size section, initially empty + Panel szp = new LinedPanel(filemgr.text("info_sizeheader")), + sl = new Panel(), sr = new Panel(); + setup_leftright(szp, sl, sr); + add_item(filemgr.text("info_bytes"), + bytes = new TextField("", 10), sl, sr); + bytes.setFont(filemgr.fixed); + bytes.setEditable(false); + add_item(filemgr.text("info_files"), + files = new TextField("", 10), sl, sr); + files.setFont(filemgr.fixed); + files.setEditable(false); + add_item(filemgr.text("info_dirs"), + dirs = new TextField("", 10), sl, sr); + dirs.setFont(filemgr.fixed); + dirs.setEditable(false); + mid = add_panel(mid, szp); + } + + if (file.type == 0 && (filemgr.can_perms || filemgr.can_users)) { + // Create recursion section + Panel rec = new LinedPanel(filemgr.text("info_apply")); + rec.setLayout(new BorderLayout()); + rec_mode = new Choice(); + for(int i=1; i<=3; i++) + rec_mode.addItem(filemgr.text("info_apply"+i)); + rec.add("Center", rec_mode); + mid = add_panel(mid, rec); + } + + set_octal(); + Util.recursiveBody(this); + pack(); + show(); + } + + Panel add_panel(Panel p, Component c) + { + p.add("North", c); + Panel np = new Panel(); + np.setLayout(new BorderLayout()); + p.add("Center", np); + return np; + } + + public void click(CbButton b) + { + if (b == save_b) { + // Update the file + int perms = get_perms(); + String user_str = user != null ? user.getText() : null; + String group_str = group != null ? group.getText() : null; + int rec = 0; + if (file.type == 0 && rec_mode != null) + rec = rec_mode.getSelectedIndex(); + String rv[] = filemgr.get_text( + "chmod.cgi?path="+filemgr.urlize(file.path)+ + (perms < 0 ? "" : "&perms="+perms)+ + (user_str == null ? "" : + "&user="+filemgr.urlize(user_str))+ + (group_str == null ? "" : + "&group="+filemgr.urlize(group_str))+ + "&rec="+rec+ + (linkto==null ? "" : + "&linkto="+filemgr.urlize(linkto.getText()))); + if (rv[0].length() > 0) { + // Something went wrong + new ErrorWindow(filemgr.text("info_efailed", + file.path, rv[0])); + } + else { + // Update all changed file objects + if (linkto != null) + file.linkto = linkto.getText(); + else if (rec == 0) + update_file(file, perms, false); + else if (rec == 1) { + // Update files in this directory + update_file(file, perms, false); + recurse_files(file, perms, false); + } + else if (rec == 2) { + // Update files and subdirs + update_file(file, perms, false); + recurse_files(file, perms, true); + } + + // Update directory list + int os = filemgr.files.selected(); + filemgr.show_files(filemgr.showing_files); + filemgr.files.select(os); + dispose(); + } + } + else if (b == size_b) { + // Get the size of the directory recursively + String l[] = filemgr.get_text("size.cgi?dir="+ + filemgr.urlize(file.path)); + if (l[0].length() > 0) { + new ErrorWindow(filemgr.text("info_size", l[0])); + } + StringTokenizer tok = new StringTokenizer(l[1], " "); + String bytes_str = tok.nextToken(); + files.setText(tok.nextToken()); + dirs.setText(tok.nextToken()); + bytes.setText(tok.nextToken()+" "+tok.nextToken()); + } + else { + // Just close + dispose(); + } + } + + void update_file(RemoteFile f, int perms, boolean perms_only) + { + f.user = user.getText(); + f.group = group.getText(); + if (perms_only) + f.perms = (perms & 0777) | (f.perms & 037777777000); + else + f.perms = perms; + } + + void recurse_files(RemoteFile f, int perms, boolean do_subs) + { + if (f.list == null) return; + for(int i=0; i 1 ? "delete_mtitle" : + ff[0].type == 0 ? "delete_dtitle" : + "delete_ftitle")); + + setLayout(new BorderLayout()); + if (ff.length > 1) { + add("North", new Label(filemgr.text("delete_mdesc"))); + Panel mp = new Panel(); + mp.setLayout(new GridLayout(ff.length, 1)); + for(int i=0; i 0) { + new ErrorWindow(filemgr.text("delete_efailed", + file.path, rv[0])); + break; + } + else { + // done the deed.. update data structures + RemoteFile pf = file.directory; + pf.delete(file); + if (filemgr.showing_files == pf) { + // Need to refresh the list as well.. + need_reshow = true; + } + + FileNode node = (FileNode)filemgr.nodemap.get( + file); + FileNode pnode = (FileNode)filemgr.nodemap.get( + pf); + if (node != null) { + // Take the directory out of the tree.. + pnode.ch.removeElement(node); + need_redraw = true; + } + } + } + if (need_reshow) filemgr.show_files(filemgr.showing_files); + if (need_redraw) filemgr.dirs.redraw(); + dispose(); + } + else if (b == cancel_b) + dispose(); + } +} + +class MkdirWindow extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + TextField dir; + CbButton create_b, cancel_b; + + MkdirWindow(String d, FileManager p) + { + filemgr = p; + setTitle(filemgr.text("mkdir_title")); + setLayout(new BorderLayout()); + add("West", new Label(filemgr.text("mkdir_dir"))); + add("Center", dir = new TextField(d.equals("/") ? "/" : d+"/", 40)); + dir.setFont(filemgr.fixed); + dir.select(dir.getText().length(), dir.getText().length()); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.CENTER)); + bot.add(create_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("create"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + Util.recursiveBody(this); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == create_b) { + // Find the filemgr directory + String path = dir.getText(); + path = filemgr.trim_path(path); + int sl = path.lastIndexOf('/'); + RemoteFile par = filemgr.find_directory( + path.substring(0, sl), false); + if (par.find(path.substring(sl+1)) != null) { + new ErrorWindow(filemgr.text("mkdir_eexists", path)); + return; + } + String rv[] = filemgr.get_text("mkdir.cgi?dir="+ + filemgr.urlize(path)); + if (rv[0].length() > 0) { + new ErrorWindow(filemgr.text("mkdir_efailed", rv[0])); + return; + } + RemoteFile file = new RemoteFile(filemgr, rv[1], par); + par.add(file); + FileNode parnode = (FileNode)filemgr.nodemap.get(par); + if (parnode != null) { + // Update the tree + parnode.add(new FileNode(file)); + filemgr.dirs.redraw(); + } + filemgr.show_files(filemgr.showing_files); + dispose(); + } + else dispose(); + } +} + +class LinkWindow extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + TextField from, to; + CbButton create_b, cancel_b; + + LinkWindow(String d, FileManager p) + { + filemgr = p; + setLayout(new BorderLayout()); + setTitle(filemgr.text("link_title")); + Panel l = new Panel(), r = new Panel(); + l.setLayout(new GridLayout(0, 1)); + l.add(new Label(filemgr.text("link_from"))); + l.add(new Label(filemgr.text("link_to"))); + r.setLayout(new GridLayout(0, 1)); + r.add(from = new TextField(d.equals("/") ? "/" : d+"/", 40)); + from.setFont(filemgr.fixed); + from.select(from.getText().length(), from.getText().length()); + r.add(to = new TextField()); + to.setFont(filemgr.fixed); + add("West", l); add("Center", r); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.CENTER)); + bot.add(create_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("create"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + Util.recursiveBody(this); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == create_b) { + // Check inputs + String from_str = from.getText().trim(); + if (!from_str.startsWith("/")) { + new ErrorWindow(filemgr.text("link_efrom", from_str)); + return; + } + int sl = from_str.lastIndexOf('/'); + String par_str = from_str.substring(0, sl), + file_str = from_str.substring(sl+1); + RemoteFile par = filemgr.find_directory(par_str, false); + if (par == null) return; + if (par.find(file_str) != null) { + new ErrorWindow(filemgr.text("link_eexists", from_str)); + return; + } + + // Create the actual link + String rv[] = filemgr.get_text("makelink.cgi?from="+ + filemgr.urlize(from_str)+"&to="+ + filemgr.urlize(to.getText())); + if (rv[0].length() > 0) { + new ErrorWindow(filemgr.text("link_efailed", rv[0])); + return; + } + RemoteFile file = new RemoteFile(filemgr, rv[1], par); + par.add(file); + filemgr.show_files(filemgr.showing_files); + dispose(); + } + else if (b == cancel_b) + dispose(); + } +} + +class RenameWindow extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + RemoteFile file; + TextField oldname, newname; + CbButton rename_b, cancel_b; + + RenameWindow(FileManager p, RemoteFile f) + { + filemgr = p; file = f; + setLayout(new BorderLayout()); + setTitle(filemgr.text("rename_title", file.path)); + Panel l = new Panel(), r = new Panel(); + l.setLayout(new GridLayout(0, 1)); + l.add(new Label(filemgr.text("rename_old"))); + l.add(new Label(filemgr.text("rename_new"))); + r.setLayout(new GridLayout(0, 1)); + r.add(oldname = new TextField(file.name, 20)); + oldname.setEditable(false); + oldname.setFont(filemgr.fixed); + r.add(newname = new TextField(file.name, 20)); + newname.select(file.name.length(), file.name.length()); + newname.setFont(filemgr.fixed); + add("West", l); add("Center", r); + + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.CENTER)); + bot.add(rename_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("rename_ok"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + pack(); + show(); + Util.recursiveBody(this); + } + + public void click(CbButton b) + { + if (b == rename_b) { + // Work out destination file and directory + String newstr = newname.getText().trim(); + if (newstr.length() == 0) return; + RemoteFile destdir; + String newpath; + if (newstr.indexOf('/') >= 0) { + // Different dir + if (newstr.startsWith("/")) { + // Some absolute path + newpath = newstr; + } + else { + // Relative to this dir + newpath = file.directory.path+"/"+newstr; + } + int sl = newpath.lastIndexOf('/'); + String newdir = sl == 0 ? "/" : newpath.substring(0,sl); + destdir = filemgr.find_directory(newdir, false); + } + else { + // Same dir + destdir = file.directory; + int sl = file.path.lastIndexOf('/'); + newpath = file.path.substring(0, sl)+"/"+newstr; + } + + // Work out filename only + int sl = newpath.lastIndexOf('/'); + newstr = newpath.substring(sl+1); + + // Check for an existing file + RemoteFile already = destdir.find(newstr); + if (already != null) { + new ErrorWindow(filemgr.text("rename_eexists", newstr)); + return; + } + + // Rename the real file + String rv[] = filemgr.get_text( + "rename.cgi?old="+filemgr.urlize(file.path)+ + "&new="+filemgr.urlize(newpath)); + if (rv[0].length() > 0) { + new ErrorWindow(filemgr.text("rename_efailed", rv[0])); + return; + } + + // Update data structure + file.name = newstr; + file.path = newpath; + file.directory.delete(file); + destdir.list(); + destdir.add(file); + file.directory = destdir; + file.list = null; + FileNode parnode = (FileNode)filemgr.nodemap.get(file.directory); + FileNode filenode = (FileNode)filemgr.nodemap.get(file); + if (parnode != null && filenode != null) { + // Need to refresh tree + filenode.text = file.name; + parnode.ch.removeElement(filenode); + parnode.add(filenode); + dispose(); + filemgr.dirs.redraw(); + } + + filemgr.show_files(filemgr.showing_files); + dispose(); + } + else if (b == cancel_b) + dispose(); + } +} + +class OverwriteWindow extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + RemoteFile src, already; + TextField newname; + CbButton ok, cancel; + int idx; + boolean mode; + + OverwriteWindow(FileManager p, RemoteFile a, RemoteFile s, int i) + { + filemgr = p; src = s; already = a; idx = i; + mode = filemgr.cut_mode; + setLayout(new BorderLayout()); + setTitle(filemgr.text("over_title")); + add("North", + new MultiLabel(filemgr.text("over_msg", already.path), 30, 0)); + add("West", new Label(filemgr.text("over_new"))); + add("East", newname = new TextField(a.name, 30)); + newname.setFont(filemgr.fixed); + + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.RIGHT)); + bot.add(ok = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("over_ok"), + CbButton.LEFT, this)); + bot.add(cancel = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + Util.recursiveBody(this); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == cancel) + dispose(); + else if (b == ok && newname.getText().length() > 0) { + // paste the file, but with a new name + RemoteFile ap = already.directory; + RemoteFile newalready = ap.find(newname.getText()); + if (newalready == src) { + new ErrorWindow(filemgr.text("paste_eself")); + return; + } + if (newalready != null && (newalready.type == 0 || + newalready.type == 5)) { + new ErrorWindow( + filemgr.text("paste_eover", newalready.path)); + return; + } + String dpath = (ap.path.equals("/") ? "/" : + ap.path+"/")+newname.getText(); + RemoteFile nf = filemgr.paste_file(src, already.directory, + dpath, newalready, mode); + if (filemgr.cut_mode && nf != null) { + // Paste from the destination path from now on + filemgr.cut_buffer[idx] = nf; + } + dispose(); + } + } +} + +class SambaShare +{ + String path; + boolean available; + boolean writable; + int guest; + String comment; + + SambaShare(String l) + { + StringSplitter tok = new StringSplitter(l, ':'); + path = tok.nextToken(); + available = tok.nextToken().equals("1"); + writable = tok.nextToken().equals("1"); + guest = Integer.parseInt(tok.nextToken()); + comment = tok.nextToken(); + } + + SambaShare(String p, boolean a, boolean w, int g, String c) + { + path = p; + available = a; + writable = w; + guest = g; + comment = c; + } + + String params() + { + return "path="+FileManager.urlize(path)+ + "&available="+(available ? 1 : 0)+ + "&writable="+(writable ? 1 : 0)+ + "&guest="+guest+ + "&comment="+FileManager.urlize(comment); + } +} + +class DFSAdminExport +{ + String path; + String desc; + String ro, rw, root; + + DFSAdminExport(String l) + { + StringSplitter tok = new StringSplitter(l, ':'); + path = tok.nextToken(); + ro = tok.nextToken(); + rw = tok.nextToken(); + root = tok.nextToken(); + desc = tok.nextToken(); + } + + DFSAdminExport(String p, String d, String ro, String rw, String root) + { + path = p; + desc = d; + this.ro = ro; + this.rw = rw; + this.root = root; + } + + String[] split(String s) + { + StringTokenizer stok = new StringTokenizer(s, " "); + String rv[] = new String[stok.countTokens()]; + for(int i=0; i 1)); + add_item(name, p, l, r); + TextField t = new TextField(v.equals("-") ? "" : v, 25); + t.setFont(filemgr.fixed); + add_item("", t, l, r); + return t; + } + + Choice squashbox(int s) + { + Choice rv = new Choice(); + rv.addItem(filemgr.text("share_s0")); + rv.addItem(filemgr.text("share_s1")); + rv.addItem(filemgr.text("share_s2")); + rv.select(s); + return rv; + } + + Choice robox(boolean r) + { + Choice rv = new Choice(); + rv.addItem(filemgr.text("share_lrw")); + rv.addItem(filemgr.text("share_lro")); + rv.select(r ? 1 : 0); + return rv; + } + + Panel opts_panel(Component ro, Component squash) + { + Panel p = new Panel(); + p.setLayout(new BorderLayout()); + p.add("West", ro); + p.add("East", squash); + return p; + } + + void export_options(LinuxExport e) + { + int c = 0; + for(int i=0; i 0) + c++; + e.host = new String[c]; + e.ro = new boolean[c]; + e.squash = new int[c]; + for(int i=0,j=0; i 0) { + e.host[j] = host[i].getText(); + e.ro[j] = lro[i].getSelectedIndex() == 1; + e.squash[j] = squash[i].getSelectedIndex(); + j++; + } + } + } + +} + +class SearchWindow extends FixedFrame + implements CbButtonCallback,MultiColumnCallback +{ + TabbedPanel tab; + MultiColumn list; + CbButton search_b, cancel_b, down_b; + FileManager filemgr; + TextField dir, match, user, group; + Checkbox uany, usel, gany, gsel; + Choice type; + Checkbox sany, smore, sless; + TextField more, less; + Checkbox xon, xoff; + String types[] = { "", "f", "d", "l", "p" }; + TextField cont; + RemoteFile results[]; + + SearchWindow(String d, FileManager p) + { + filemgr = p; + setTitle(filemgr.text("search_title")); + + // setup UI + setLayout(new BorderLayout()); + tab = new TabbedPanel(); + Panel search = new Panel(); + search.setLayout(new BorderLayout()); + tab.addItem(filemgr.text("search_crit"), search); + Panel l = new Panel(), r = new Panel(); + l.setLayout(new GridLayout(0, 1)); + r.setLayout(new GridLayout(0, 1)); + + String cols[] = { "", filemgr.text("right_name"), + filemgr.text("right_size") }; + float widths[] = { .07f, .78f, .15f }; + list = new MultiColumn(cols, this); + list.setWidths(widths); + list.setDrawLines(false); + list.setFont(filemgr.fixed); + tab.addItem(filemgr.text("search_list"), list); + + add_item(filemgr.text("search_dir"), dir = new TextField(d, 30), l, r); + dir.setFont(filemgr.fixed); + + // Filename + add_item(filemgr.text("search_match"), match = new TextField(20), l, r); + match.setFont(filemgr.fixed); + + if (filemgr.search_contents) { + // File contents + add_item(filemgr.text("search_cont"), + cont = new TextField(30), l, r); + cont.setFont(filemgr.fixed); + } + + // User or group owners + if (filemgr.can_users) { + Panel up = new Panel(); + up.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 1)); + CheckboxGroup ug = new CheckboxGroup(); + up.add(uany = new Checkbox(filemgr.text("search_any"), ug, true)); + up.add(usel = new Checkbox("", ug, false)); + up.add(user = new TextField(10)); + user.setFont(filemgr.fixed); + add_item(filemgr.text("search_user"), up, l, r); + + Panel gp = new Panel(); + gp.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 1)); + CheckboxGroup gg = new CheckboxGroup(); + gp.add(gany = new Checkbox(filemgr.text("search_any"), gg, true)); + gp.add(gsel = new Checkbox("", gg, false)); + gp.add(group = new TextField(10)); + group.setFont(filemgr.fixed); + add_item(filemgr.text("search_group"), gp, l, r); + } + + // File type + if (!filemgr.follow_links) { + type = new Choice(); + for(int i=0; i 0) + url += "&type="+types[type.getSelectedIndex()]; + if (usel != null && usel.getState()) { + String u = user.getText().trim(); + if (u.length() == 0) { + new ErrorWindow(filemgr.text("search_euser")); + return; + } + url += "&user="+filemgr.urlize(u); + } + if (gsel != null && gsel.getState()) { + String g = group.getText().trim(); + if (g.length() == 0) { + new ErrorWindow(filemgr.text("search_egroup")); + return; + } + url += "&group="+filemgr.urlize(g); + } + if (smore.getState()) { + String m = more.getText().trim(); + try { Integer.parseInt(m); } + catch(Exception e) { + new ErrorWindow(filemgr.text("search_esize")); + return; + } + url += "&size=%2B"+m+"c"; + } + else if (sless.getState()) { + String l = less.getText().trim(); + try { Integer.parseInt(l); } + catch(Exception e) { + new ErrorWindow(filemgr.text("search_esize")); + return; + } + url += "&size=%2D"+l+"c"; + } + if (xon != null && xon.getState()) + url += "&xdev=1"; + if (cont != null && cont.getText().trim().length() > 0) + url += "&cont="+filemgr.urlize(cont.getText()); + + // send off the search + setCursor(WAIT_CURSOR); + String f[] = filemgr.get_text(url); + if (f[0].length() > 0) { + new ErrorWindow(f[0]); + return; + } + Object rows[][] = new Object[f.length-1][]; + results = new RemoteFile[f.length-1]; + for(int i=1; i= 0) { + ACLEntry e = (ACLEntry)acllist.elementAt(idx); + ACLEditor ed = (ACLEditor)edmap.get(e); + if (ed == null) + edmap.put(e, new ACLEditor(this, e)); + else { + ed.toFront(); + ed.requestFocus(); + } + } + } + + public void singleClick(MultiColumn list, int num) + { + } + + public void headingClicked(MultiColumn list, int col) + { + } +} + +class AttributesWindow extends FixedFrame + implements CbButtonCallback,MultiColumnCallback +{ + FileManager filemgr; + RemoteFile file; + Vector attrlist = new Vector(); + Hashtable edmap = new Hashtable(); + + CbButton ok, cancel, add; + MultiColumn attrtable; + + AttributesWindow(FileManager p, RemoteFile f) + { + super(400, 300); + setTitle(p.text("attr_title", f.path)); + filemgr = p; + file = f; + + // Get the attributes + String a[] = filemgr.get_text( + "getattrs.cgi?file="+filemgr.urlize(file.path)); + if (a[0].length() != 0) { + new ErrorWindow(filemgr.text("attr_eattrs", a[0])); + return; + } + + // Create the UI + setLayout(new BorderLayout()); + String titles[] = { filemgr.text("attr_name"), + filemgr.text("attr_value") }; + attrtable = new MultiColumn(titles, this); + for(int i=1; i= 0) { + FileAttribute at = (FileAttribute)attrlist.elementAt(idx); + AttributeEditor ed = (AttributeEditor)edmap.get(at); + if (ed == null) + edmap.put(at, new AttributeEditor(this, at)); + else { + ed.toFront(); + ed.requestFocus(); + } + } + } + + public void singleClick(MultiColumn list, int num) + { + } + + public void headingClicked(MultiColumn list, int col) + { + } +} + +class FileAttribute +{ + String name; + String value; + + FileAttribute(String l, FileManager f) + { + int eq = l.indexOf('='); + name = f.un_urlize(l.substring(0, eq)); + value = f.un_urlize(l.substring(eq+1)); + } + + FileAttribute(String n, String v) + { + name = n; + value = v; + } + + String[] getRow() + { + return new String[] { name, value }; + } +} + +class AttributeEditor extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + AttributesWindow attrwin; + FileAttribute attr; + boolean creating; + CbButton ok, del; + TextField name; + TextArea value; + + AttributeEditor(AttributesWindow w, FileAttribute a) + { + attrwin = w; + attr = a; + filemgr = w.filemgr; + creating = false; + makeUI(); + } + + AttributeEditor(AttributesWindow w) + { + attrwin = w; + attr = new FileAttribute("", ""); + filemgr = w.filemgr; + creating = true; + makeUI(); + } + + void makeUI() + { + setTitle(filemgr.text(creating ? "attr_create" : "attr_edit")); + setLayout(new BorderLayout()); + + Panel top = new Panel(); + top.setLayout(new GridLayout(1, 2)); + top.add(new Label(filemgr.text("attr_name"))); + top.add(name = new TextField(attr.name, 20)); + name.setFont(filemgr.fixed); + add("North", top); + + Panel mid = new Panel(); + mid.setLayout(new GridLayout(1, 2)); + mid.add(new Label(filemgr.text("attr_value"))); + mid.add(value = new TextArea(attr.value, 5, 20)); + add("Center", mid); + + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.RIGHT)); + bot.add(ok = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("save"), + CbButton.LEFT, this)); + if (!creating) + bot.add(del = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("delete"), + CbButton.LEFT, this)); + add("South", bot); + + Util.recursiveBody(this); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == ok) { + // Update or add the attribute + if (name.getText().length() == 0) { + new ErrorWindow(filemgr.text("attr_ename")); + return; + } + attr.name = name.getText(); + attr.value = value.getText(); + if (creating) { + // Add to the attribs table + attrwin.attrlist.addElement(attr); + attrwin.attrtable.addItem(attr.getRow()); + } + else { + // Update the table + int idx = attrwin.attrlist.indexOf(attr); + attrwin.attrtable.modifyItem(attr.getRow(), idx); + } + dispose(); + } + else if (b == del) { + // Remove this entry + int idx = attrwin.attrlist.indexOf(attr); + attrwin.attrlist.removeElementAt(idx); + attrwin.attrtable.deleteItem(idx); + dispose(); + } + } + + public void dispose() + { + attrwin.edmap.remove(attr); + super.dispose(); + } +} + +class EXTWindow extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + RemoteFile file; + + CbButton ok, cancel; + Checkbox cbs[]; + + String attrs[] = { "A", "a", "c", "d", "i", "s", "S", "u" }; + Hashtable attrmap = new Hashtable(); + + EXTWindow(FileManager p, RemoteFile f) + { + super(); + setTitle(p.text("ext_title", f.path)); + filemgr = p; + file = f; + + // Get the attributes + String a[] = filemgr.get_text( + "getext.cgi?file="+filemgr.urlize(file.path)); + if (a[0].length() != 0) { + new ErrorWindow(filemgr.text("ext_eattrs", a[0])); + return; + } + for(int i=0; i max || !tok.hasMoreTokens()) { + v.addElement(line); + line = null; + } + } + setLayout(new GridLayout(v.size(), 1, 0, 0)); + for(int i=0; i= 0) + lang.put(l[i].substring(0, eq), l[i].substring(eq+1)); + } + + // list samba file shares + String s[] = get_text("list_shares.cgi"); + if (s[0].equals("1")) { + for(int i=1; i 1) + return new CbButton(get_image(f), this); + else + return new CbButton(get_image(f), t, CbButton.ABOVE, this); + } + + // Gets an image from the images directory + Image get_image(String img) + { + return getImage(getDocumentBase(), "images/"+img); + } + + String[] get_text(String url) + { + try { + long now = System.currentTimeMillis(); + if (url.indexOf('?') > 0) url += "&rand="+now; + else url += "?rand="+now; + url += "&trust="+trust; + URL u = new URL(getDocumentBase(), url); + Vector lv = new Vector(); + LineInputStream is = new LineInputStream(u.openStream()); + while(true) + try { lv.addElement(is.gets()); } + catch(EOFException eof) { break; } + is.close(); + String rv[] = new String[lv.size()]; + lv.copyInto(rv); + return rv; + } + catch(Exception e) { + e.printStackTrace(); + //return null; + String err[] = { e.getMessage() }; + return err; + } + } + + // Fill the multicolumn list with files from some directory + boolean show_files(RemoteFile f) + { + RemoteFile fl[] = f.list(); + if (fl == null) return false; + files.clear(); + Object rows[][] = new Object[fl.length+1][]; + long now = System.currentTimeMillis(); + + // Sort listing by chosen column + if (f != showing_files) { + // Directory has changed .. assume sort by name + files.sortingArrow(1, 1); + } + else if (files.sortdir != 0) { + // Sort by chosen order + RemoteFile fls[] = new RemoteFile[fl.length]; + System.arraycopy(fl, 0, fls, 0, fl.length); + QuickSort.sort(fls, files.sortcol, files.sortdir); + fl = fls; + } + + // Create parent directory row + rows[0] = new Object[6]; + rows[0][0] = get_image("dir.gif"); + rows[0][1] = ".."; + rows[0][2] = rows[0][3] = rows[0][4] = rows[0][5] = ""; + + // Create file rows + Date n = new Date(now); + for(int i=0; i 0 || s == 0 && ss.length > 1) { + // At least one non-.. file was selected + boolean parentsel = false; + for(int i=0; i 4) + new ErrorWindow(text("edit_enormal")); + else + new EditorWindow(f, this); + } + else if (b == down_b) { + // Force download of the selected file + if (f == null) return; + if (f.type == 0 || f.type > 4) + new ErrorWindow(text("view_enormal2")); + else + show_file(f, true); + } + else if (b == refresh_b) { + // Refesh the selected directory (and thus any subdirs) + d.known = false; + d.file.list = null; + d.fill(); + show_files(d.file); + } + else if (b == props_b) { + // Display the properties window + if (f == null) return; + new PropertiesWindow(f, this); + } + else if (b == acl_b) { + // Display the ACL window (if filesystem supports them) + if (f == null) return; + FileSystem filefs = find_filesys(f); + if (filefs == null) return; + if (filefs.acls) + new ACLWindow(this, f); + else + new ErrorWindow(text("eacl_efs", filefs.mount)); + } + else if (b == attr_b) { + // Display the attributes window (if filesystem supports them) + if (f == null) return; + FileSystem filefs = find_filesys(f); + if (filefs == null) return; + if (filefs.attrs) + new AttributesWindow(this, f); + else + new ErrorWindow(text("attr_efs", filefs.mount)); + } + else if (b == ext_b) { + // Display EXT attributes window (if filesystem supports them) + if (f == null) return; + FileSystem filefs = find_filesys(f); + if (filefs == null) return; + if (filefs.ext) + new EXTWindow(this, f); + else + new ErrorWindow(text("ext_efs", filefs.mount)); + } + else if (b == copy_b) { + // Copy the selected files + if (f == null) return; + cut_buffer = ff; + cut_mode = false; + } + else if (b == cut_b) { + // Cut the selected file + if (f == null) return; + cut_buffer = ff; + cut_mode = true; + } + else if (b == paste_b) { + // Paste the copied file + if (cut_buffer == null) { + new ErrorWindow(text("paste_ecopy")); + return; + } + + // Check for existing file clashes + // XXX + + // Go through all the files to paste + for(int i=0; i= rl && p.substring(0, rl).equals(accroot[r])) + can = true; + else if (l < rl && accroot[r].substring(0, l).equals(p)) + can = true; + } + if (!can) { + new ErrorWindow(text("find_eaccess", p)); + return null; + } + FileNode posnode = root; + RemoteFile pos = posnode.file; + StringTokenizer tok = new StringTokenizer(p, "/"); + while(tok.hasMoreTokens()) { + String fn = tok.nextToken(); + if (fn.equals("")) continue; + RemoteFile fl[] = pos.list(); + if (fl == null) return null; + if (fill) { + posnode.open = true; + posnode.fill(); + } + boolean found = false; + for(int i=0; i= l+1 && + f.path.substring(0, l+1).equals(fs.mount+"/")) || + fs.mount.equals("/")) { + filefs = fs; + } + } + return filefs; + } + + public boolean action(Event e, Object o) + { + if (e.target == pathname) { + // A new path was entered.. cd to it + String p = pathname.getText().trim(); + if (p.equals("")) return true; + find_directory(p, true); + return true; + } + return false; + } + + // singleClick + // Called on a single click on a list item + public void singleClick(MultiColumn list, int num) + { + } + + // doubleClick + // Called upon double-clicking on a list item + public void doubleClick(MultiColumn list, int num) + { + if (num == 0) { + // Go to parent directory + if (showing_files.directory != null) { + ((FileNode)nodemap.get(showing_files)).open = false; + show_files(showing_files.directory); + dirs.select((FileNode)nodemap.get(showing_files)); + dirs.redraw(); + } + return; + } + RemoteFile d = showing_list[num-1]; + if (d.type == 0) { + // Open this directory + FileNode pn = (FileNode)nodemap.get(showing_files); + pn.fill(); + pn.open = true; + FileNode fn = (FileNode)nodemap.get(d); + if (show_files(d)) { + fn.fill(); + fn.open = true; + dirs.select(fn); + dirs.redraw(); + } + } + else if (d.type <= 4) { + // Direct the browser to this file + show_file(d, list.last_event.shiftDown()); + } + } + + // Called when the user clicks on a column heading so that it can + // be sorted. + public void headingClicked(MultiColumn list, int col) + { + if (col == 0) + return; // ignore click on icon column? + if (col == list.sortcol) { + list.sortingArrow(col, list.sortdir == 2 ? 1 : 2); + } + else { + list.sortingArrow(col, 1); + } + + // Re-show the list in the new order, but with the same files selected + int ss[] = files.allSelected(); + RemoteFile ssf[] = new RemoteFile[ss.length]; + for(int i=0; i 0) { + ch.insertElementAt(n, i); + break; + } + } + } + +} + +class RemoteFile +{ + static final int DIR = 0; + static final int TEXT = 1; + static final int IMAGE = 2; + static final int BINARY = 3; + static final int UNKNOWN = 4; + static final int SYMLINK = 5; + static final int DEVICE = 6; + static final int PIPE = 7; + static final String[] tmap = { "dir.gif", "text.gif", "image.gif", + "binary.gif", "unknown.gif", + "symlink.gif", "device.gif", + "pipe.gif" }; + + FileManager parent; + String path, name; + int type; + String user, group; + long size; + int perms; + long modified; + String linkto; + RemoteFile list[]; + RemoteFile directory; + + // Parse a line of text to a file object + RemoteFile(FileManager parent, String line, RemoteFile d) + { + this.parent = parent; + StringTokenizer tok = new StringTokenizer(line, "\t"); + path = tok.nextToken(); + type = Integer.parseInt(tok.nextToken()); + user = tok.nextToken(); + group = tok.nextToken(); + size = Long.parseLong(tok.nextToken()); + perms = Integer.parseInt(tok.nextToken()); + modified = Long.parseLong(tok.nextToken())*1000; + if (type == 5) linkto = tok.nextToken(); + directory = d; + if (path.equals("/")) name = "/"; + else name = path.substring(path.lastIndexOf('/')+1); + } + + // Create a new, empty file object + RemoteFile() { } + + // Returns a list of files in this directory + RemoteFile[] list() + { + if (list == null) { + String l[] = parent.get_text("list.cgi?dir="+ + parent.urlize(path)); + if (l[0].length() > 0) { + //list = new RemoteFile[0]; + // Error reading the remote directory! + new ErrorWindow(parent.text("list_edir", path, l[0])); + list = null; + } + else { + list = new RemoteFile[l.length-3]; + for(int i=3; i 0 && offset == 0) { + nlist[i] = f; + offset++; + } + nlist[i+offset] = list[i]; + } + if (offset == 0) nlist[list.length] = f; + list = nlist; + } + + void delete(RemoteFile f) + { + RemoteFile nlist[] = new RemoteFile[list.length-1]; + for(int i=0,j=0; i= 0) { + // Length is known + buf = new byte[uc.getContentLength()]; + int got = 0; + while(got < buf.length) + got += is.read(buf, got, buf.length-got); + } + else { + // Length is unknown .. read till the end + buf = new byte[0]; + while(true) { + byte data[] = new byte[16384]; + int got; + try { got = is.read(data); } + catch(EOFException ex) { break; } + if (got <= 0) break; + byte nbuf[] = new byte[buf.length + got]; + System.arraycopy(buf, 0, nbuf, 0, buf.length); + System.arraycopy(data, 0, nbuf, buf.length, got); + buf = nbuf; + } + } + edit.setText(new String(buf, 0)); + is.close(); + file.size = buf.length; + } + catch(Exception e) { e.printStackTrace(); } + } + + // Creating a new file + EditorWindow(String f, FileManager p) + { + super(500, 300); + filemgr = p; + makeUI(true); + setTitle(filemgr.text("edit_title2")); + name.setText(f.equals("/") ? f : f+"/"); + name.select(name.getText().length(), name.getText().length()); + } + + void makeUI(boolean add_name) + { + setLayout(new BorderLayout()); + if (add_name) { + Panel np = new Panel(); + np.setLayout(new BorderLayout()); + np.add("West", new Label(filemgr.text("edit_filename"))); + np.add("Center", name = new TextField()); + add("North", np); + } + add("Center", edit = new TextArea(20, 80)); + edit.setFont(new Font("courier", Font.PLAIN, 14)); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.RIGHT)); + bot.add(goto_b = new CbButton(filemgr.get_image("goto.gif"), + filemgr.text("edit_goto"), + CbButton.LEFT, this)); + bot.add(find_b = new CbButton(filemgr.get_image("find.gif"), + filemgr.text("edit_find"), + CbButton.LEFT, this)); + bot.add(new Label(" ")); + bot.add(save_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("save"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == save_b) { + RemoteFile par = null, already = null; + String save_path; + if (file == null) { + // Locate the filemgr directory + save_path = filemgr.trim_path(name.getText()); + int sl = save_path.lastIndexOf('/'); + par = filemgr.find_directory( + save_path.substring(0, sl), false); + if (par == null) return; + already = par.find(save_path.substring(sl+1)); + if (already != null && + (already.type == 0 || already.type == 5)) { + new ErrorWindow( + filemgr.text("edit_eover", save_path)); + return; + } + } + else save_path = file.path; + + // Save the file back again + String s = edit.getText(), line; + try { + URL u = new URL(filemgr.getDocumentBase(), + "save.cgi"+filemgr.urlize(save_path)+ + "?rand="+System.currentTimeMillis()+ + "&trust="+filemgr.trust); + URLConnection uc = u.openConnection(); + uc.setDoOutput(true); + OutputStream os = uc.getOutputStream(); + byte buf[] = new byte[s.length()]; + s.getBytes(0, buf.length, buf, 0); + os.write(buf); + os.close(); + LineInputStream is = new LineInputStream( + uc.getInputStream()); + String err = is.gets(); + if (err.length() > 0) { + new ErrorWindow( + filemgr.text("edit_esave", err)); + is.close(); + return; + } + line = is.gets(); + is.close(); + } + catch(Exception e) { e.printStackTrace(); return; } + + if (file == null) { + // Create and insert or replace the file object + file = new RemoteFile(filemgr, line, par); + if (already != null) { + // A file with this name exists + already.type = file.type; + already.user = file.user; + already.group = file.group; + already.size = file.size; + already.perms = file.perms; + already.modified = file.modified; + } + else { + // Add to the list + par.add(file); + } + } + else { + file.size = s.length(); + file.modified = System.currentTimeMillis(); + } + filemgr.show_files(filemgr.showing_files); + dispose(); + } + else if (b == cancel_b) { + // Just close + dispose(); + } + else if (b == goto_b) { + // Open a dialog asking which line to go to + if (goto_window != null) + goto_window.toFront(); + else + goto_window = new GotoWindow(this); + } + else if (b == find_b) { + // Open the search (and replace) dialog + if (find_window != null) + find_window.toFront(); + else + find_window = new FindReplaceWindow(this); + } + } + + public void dispose() + { + super.dispose(); + if (goto_window != null) goto_window.dispose(); + if (find_window != null) find_window.dispose(); + } +} + +class GotoWindow extends FixedFrame implements CbButtonCallback +{ + EditorWindow editor; + FileManager filemgr; + TextField line; + CbButton goto_b, cancel_b; + + GotoWindow(EditorWindow e) + { + editor = e; + filemgr = e.filemgr; + + setLayout(new BorderLayout()); + add("West", new Label(filemgr.text("edit_gotoline"))); + add("Center", line = new TextField(10)); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.RIGHT)); + bot.add(goto_b = new CbButton(filemgr.get_image("goto.gif"), + filemgr.text("edit_goto"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("close"), + CbButton.LEFT, this)); + add("South", bot); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == goto_b) { + // Go to the chose line, if it exists + int lnum; + try { lnum = Integer.parseInt(line.getText()); } + catch(Exception e) { return; } + + String txt = editor.edit.getText(); + int c, l = 0; + for(c=0; c= 0) { + String sel = edittxt.substring(st, en); + if (sel.equals(findtxt)) { + // Replace the selected + editor.edit.setText(edittxt.substring(0, st)+ + replace.getText()+ + edittxt.substring(en)); + editor.edit.select(st, st); + return; + } + } + click(find_b); + } + else if (b == all_b) { + // Replace all occurrances of the text in the editor + int pos = 0; + int len = findtxt.length(); + int st = editor.edit.getSelectionStart(), + en = editor.edit.getSelectionEnd(); + while((pos = edittxt.indexOf(findtxt, pos)) != -1) { + edittxt = edittxt.substring(0, pos)+ + replace.getText()+ + edittxt.substring(pos+len); + pos += len; + } + editor.edit.setText(edittxt); + editor.edit.select(st, en); // put back old selection + } + else if (b == cancel_b) { + // Just close the window + dispose(); + } + } + + public void dispose() + { + super.dispose(); + editor.find_window = null; + } +} + +class PropertiesWindow extends FixedFrame implements CbButtonCallback +{ + RemoteFile file; + FileManager filemgr; + CbButton save_b, cancel_b; + + TextField linkto; + TextField user, group; + Checkbox setuid, setgid; + PermissionsPanel user_p, group_p, other_p; + Checkbox sticky; + Choice rec_mode; + TextField octal; + + PropertiesWindow(RemoteFile f, FileManager p) + { + file = f; + filemgr = p; + + // Create UI + setTitle(f.path); + setLayout(new BorderLayout()); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.RIGHT)); + bot.add(save_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("save"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + + Panel mid = new Panel(); + mid.setLayout(new BorderLayout()); + TabbedPanel tab = null; + add("Center", mid); + + // Create file details section + Panel det = new LinedPanel(filemgr.text("info_file")), + dl = new Panel(), dr = new Panel(); + setup_leftright(det, dl, dr); + add_item(filemgr.text("info_path"), + new Label(file.path), dl, dr); + add_item(filemgr.text("info_type"), + new Label(filemgr.text("file_type"+file.type)), dl, dr); + add_item(filemgr.text("info_size"), + new Label(String.valueOf(file.size)),dl,dr); + add_item(filemgr.text("info_mod"), + new Label(String.valueOf(new Date(file.modified))), dl, dr); + if (file.type == 5) + add_item(filemgr.text("info_link"), + linkto = new TextField(file.linkto, 30), dl, dr); + mid = add_panel(mid, det); + + // Create permissions section + Panel per = new LinedPanel(filemgr.text("info_perms")), + pl = new Panel(), pr = new Panel(); + setup_leftright(per, pl, pr); + add_item(filemgr.text("info_user"), + user_p = new PermissionsPanel(file, 64, filemgr), pl, pr); + add_item(filemgr.text("info_group"), + group_p = new PermissionsPanel(file, 8, filemgr), pl, pr); + add_item(filemgr.text("info_other"), + other_p = new PermissionsPanel(file, 1, filemgr), pl,pr); + if (file.type == 0) { + add_item(filemgr.text("info_sticky"), sticky = new Checkbox( + filemgr.text("info_sticky2")), pl,pr); + sticky.setState((file.perms&01000) != 0); + } + add_item(filemgr.text("info_octal"), octal = new TextField(4), pl, pr); + octal.setEditable(false); + mid = add_panel(mid, per); + + // Create ownership section + Panel own = new LinedPanel(filemgr.text("info_own")), + ol = new Panel(), or = new Panel(); + setup_leftright(own, ol, or); + add_item(filemgr.text("info_user"), + user = new TextField(file.user, 10), ol, or); + if (file.type != 0) { + add_item(filemgr.text("info_setuid"), + setuid = new Checkbox(filemgr.text("info_setuid2")), + ol, or); + setuid.setState((file.perms & 0x800) != 0); + } + add_item(filemgr.text("info_group"), + group = new TextField(file.group, 10), ol, or); + if (file.type == 0) + add_item(filemgr.text("info_setgid"), + setgid = new Checkbox(filemgr.text("info_setgid2")), ol, or); + else + add_item(filemgr.text("info_setgid"), + setgid = new Checkbox(filemgr.text("info_setgid3")), ol, or); + setgid.setState((file.perms & 0x400) != 0); + mid = add_panel(mid, own); + + if (file.type == 0) { + // Create recursion section + Panel rec = new LinedPanel(filemgr.text("info_apply")); + rec.setLayout(new BorderLayout()); + rec_mode = new Choice(); + for(int i=1; i<=3; i++) + rec_mode.addItem(filemgr.text("info_apply"+i)); + rec.add("Center", rec_mode); + mid = add_panel(mid, rec); + } + + set_octal(); + pack(); + show(); + } + + Panel add_panel(Panel p, Component c) + { + p.add("North", c); + Panel np = new Panel(); + np.setLayout(new BorderLayout()); + p.add("Center", np); + return np; + } + + public void click(CbButton b) + { + if (b == save_b) { + // Update the file + int perms = get_perms(); + int rec = 0; + if (file.type == 0) + rec = rec_mode.getSelectedIndex(); + String rv[] = filemgr.get_text( + "chmod.cgi?path="+filemgr.urlize(file.path)+ + "&perms="+perms+"&user="+user.getText()+ + "&group="+group.getText()+"&rec="+rec+ + (linkto==null ? "" : "&linkto="+linkto.getText())); + if (rv[0].length() > 0) { + // Something went wrong + new ErrorWindow(filemgr.text("info_efailed", + file.path, rv[0])); + } + else { + // Update all changed file objects + if (linkto != null) + file.linkto = linkto.getText(); + else if (rec == 0) + update_file(file, perms, false); + else if (rec == 1) { + // Update files in this directory + update_file(file, perms, false); + recurse_files(file, perms, false); + } + else if (rec == 2) { + // Update files and subdirs + update_file(file, perms, false); + recurse_files(file, perms, true); + } + + // Update directory list + int os = filemgr.files.selected(); + filemgr.show_files(filemgr.showing_files); + filemgr.files.select(os); + dispose(); + } + } + else { + // Just close + dispose(); + } + } + + void update_file(RemoteFile f, int perms, boolean perms_only) + { + f.user = user.getText(); + f.group = group.getText(); + if (perms_only) + f.perms = (perms & 0777) | (f.perms & 037777777000); + else + f.perms = perms; + } + + void recurse_files(RemoteFile f, int perms, boolean do_subs) + { + if (f.list == null) return; + for(int i=0; i 1 ? "delete_mtitle" : + ff[0].type == 0 ? "delete_dtitle" : + "delete_ftitle")); + + setLayout(new BorderLayout()); + if (ff.length > 1) { + add("North", new Label(filemgr.text("delete_mdesc"))); + Panel mp = new Panel(); + mp.setLayout(new GridLayout(ff.length, 1)); + for(int i=0; i 0) { + new ErrorWindow(filemgr.text("delete_efailed", + file.path, rv[0])); + break; + } + else { + // done the deed.. update data structures + RemoteFile pf = file.directory; + pf.delete(file); + if (filemgr.showing_files == pf) { + // Need to refresh the list as well.. + need_reshow = true; + } + + FileNode node = (FileNode)filemgr.nodemap.get( + file); + FileNode pnode = (FileNode)filemgr.nodemap.get( + pf); + if (node != null) { + // Take the directory out of the tree.. + pnode.ch.removeElement(node); + need_redraw = true; + } + } + } + if (need_reshow) filemgr.show_files(filemgr.showing_files); + if (need_redraw) filemgr.dirs.redraw(); + dispose(); + } + else if (b == cancel_b) + dispose(); + } +} + +class MkdirWindow extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + TextField dir; + CbButton create_b, cancel_b; + + MkdirWindow(String d, FileManager p) + { + filemgr = p; + setTitle(filemgr.text("mkdir_title")); + setLayout(new BorderLayout()); + add("West", new Label(filemgr.text("mkdir_dir"))); + add("Center", dir = new TextField(d.equals("/") ? "/" : d+"/", 40)); + dir.select(dir.getText().length(), dir.getText().length()); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.CENTER)); + bot.add(create_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("create"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == create_b) { + // Find the filemgr directory + String path = dir.getText(); + path = filemgr.trim_path(path); + int sl = path.lastIndexOf('/'); + RemoteFile par = filemgr.find_directory( + path.substring(0, sl), false); + if (par.find(path.substring(sl+1)) != null) { + new ErrorWindow(filemgr.text("mkdir_eexists", path)); + return; + } + String rv[] = filemgr.get_text("mkdir.cgi?dir="+ + filemgr.urlize(path)); + if (rv[0].length() > 0) { + new ErrorWindow(filemgr.text("mkdir_efailed", rv[0])); + return; + } + RemoteFile file = new RemoteFile(filemgr, rv[1], par); + par.add(file); + FileNode parnode = (FileNode)filemgr.nodemap.get(par); + if (parnode != null) { + // Update the tree + parnode.add(new FileNode(file)); + filemgr.dirs.redraw(); + } + filemgr.show_files(filemgr.showing_files); + dispose(); + } + else dispose(); + } +} + +class LinkWindow extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + TextField from, to; + CbButton create_b, cancel_b; + + LinkWindow(String d, FileManager p) + { + filemgr = p; + setLayout(new BorderLayout()); + setTitle(filemgr.text("link_title")); + Panel l = new Panel(), r = new Panel(); + l.setLayout(new GridLayout(0, 1)); + l.add(new Label(filemgr.text("link_from"))); + l.add(new Label(filemgr.text("link_to"))); + r.setLayout(new GridLayout(0, 1)); + r.add(from = new TextField(d.equals("/") ? "/" : d+"/", 40)); + from.select(from.getText().length(), from.getText().length()); + r.add(to = new TextField()); + add("West", l); add("Center", r); + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.CENTER)); + bot.add(create_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("create"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == create_b) { + // Check inputs + String from_str = from.getText().trim(); + int sl = from_str.lastIndexOf('/'); + String par_str = from_str.substring(0, sl), + file_str = from_str.substring(sl+1); + RemoteFile par = filemgr.find_directory(par_str, false); + if (par == null) return; + if (par.find(file_str) != null) { + new ErrorWindow(filemgr.text("link_eexists", from_str)); + return; + } + + // Create the actual link + String rv[] = filemgr.get_text("makelink.cgi?from="+ + filemgr.urlize(from_str)+"&to="+ + filemgr.urlize(to.getText())); + if (rv[0].length() > 0) { + new ErrorWindow(filemgr.text("link_efailed", rv[0])); + return; + } + RemoteFile file = new RemoteFile(filemgr, rv[1], par); + par.add(file); + filemgr.show_files(filemgr.showing_files); + dispose(); + } + else if (b == cancel_b) + dispose(); + } +} + +class RenameWindow extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + RemoteFile file; + TextField oldname, newname; + CbButton rename_b, cancel_b; + + RenameWindow(FileManager p, RemoteFile f) + { + filemgr = p; file = f; + setLayout(new BorderLayout()); + setTitle(filemgr.text("rename_title", file.path)); + Panel l = new Panel(), r = new Panel(); + l.setLayout(new GridLayout(0, 1)); + l.add(new Label(filemgr.text("rename_old"))); + l.add(new Label(filemgr.text("rename_new"))); + r.setLayout(new GridLayout(0, 1)); + r.add(oldname = new TextField(file.name, 20)); + oldname.setEditable(false); + r.add(newname = new TextField(file.name, 20)); + newname.select(file.name.length(), file.name.length()); + add("West", l); add("Center", r); + + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.CENTER)); + bot.add(rename_b = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("rename_ok"), + CbButton.LEFT, this)); + bot.add(cancel_b = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("cancel"), + CbButton.LEFT, this)); + add("South", bot); + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == rename_b) { + // Check for an existing file + String newstr = newname.getText().trim(); + if (newstr.length() == 0) return; + RemoteFile already = file.directory.find(newstr); + if (already != null) { + new ErrorWindow(filemgr.text("rename_eexists", newstr)); + return; + } + + // Rename the real file + int sl = file.path.lastIndexOf('/'); + String newpath = file.path.substring(0, sl)+"/"+newstr; + String rv[] = filemgr.get_text( + "rename.cgi?old="+filemgr.urlize(file.path)+ + "&new="+filemgr.urlize(newpath)); + if (rv[0].length() > 0) { + new ErrorWindow(filemgr.text("rename_efailed", rv[0])); + return; + } + + // Update data structure + file.name = newstr; + file.path = newpath; + file.directory.delete(file); + file.directory.add(file); + file.list = null; + FileNode parnode = (FileNode)filemgr.nodemap.get(file.directory); + FileNode filenode = (FileNode)filemgr.nodemap.get(file); + if (parnode != null && filenode != null) { + filenode.text = file.name; + parnode.ch.removeElement(filenode); + parnode.add(filenode); + dispose(); + filemgr.dirs.redraw(); + } + + filemgr.show_files(filemgr.showing_files); + dispose(); + } + else if (b == cancel_b) + dispose(); + } +} + +class MultiLabel extends BorderPanel +{ + public MultiLabel(String s, int max) + { + this(s, max, 1); + } + + public MultiLabel(String s, int max, int b) + { + super(b); + Vector v = new Vector(); + StringTokenizer tok = new StringTokenizer(s.trim(), " \t"); + String line = null; + while(tok.hasMoreTokens()) { + String w = tok.nextToken(); + line = (line == null ? w : line+" "+w); + if (line.length() > max || !tok.hasMoreTokens()) { + v.addElement(line); + line = null; + } + } + setLayout(new GridLayout(v.size(), 1, 0, 0)); + for(int i=0; i 0) { + // paste the file, but with a new name + RemoteFile ap = already.directory; + RemoteFile newalready = ap.find(newname.getText()); + if (newalready == src) { + new ErrorWindow(filemgr.text("paste_eself")); + return; + } + if (newalready != null && (newalready.type == 0 || + newalready.type == 5)) { + new ErrorWindow( + filemgr.text("paste_eover", newalready.path)); + return; + } + String dpath = (ap.path.equals("/") ? "/" : + ap.path+"/")+newname.getText(); + RemoteFile nf = filemgr.paste_file(src, already.directory, + dpath, newalready, mode); + if (filemgr.cut_mode && nf != null) { + // Paste from the destination path from now on + filemgr.cut_buffer[idx] = nf; + } + dispose(); + } + } +} + +class SambaShare +{ + String path; + boolean available; + boolean writable; + int guest; + String comment; + + SambaShare(String l) + { + StringSplitter tok = new StringSplitter(l, ':'); + path = tok.nextToken(); + available = tok.nextToken().equals("1"); + writable = tok.nextToken().equals("1"); + guest = Integer.parseInt(tok.nextToken()); + comment = tok.nextToken(); + } + + SambaShare(String p, boolean a, boolean w, int g, String c) + { + path = p; + available = a; + writable = w; + guest = g; + comment = c; + } + + String params() + { + return "path="+FileManager.urlize(path)+ + "&available="+(available ? 1 : 0)+ + "&writable="+(writable ? 1 : 0)+ + "&guest="+guest+ + "&comment="+FileManager.urlize(comment); + } +} + +class DFSAdminExport +{ + String path; + String desc; + String ro, rw, root; + + DFSAdminExport(String l) + { + StringSplitter tok = new StringSplitter(l, ':'); + path = tok.nextToken(); + ro = tok.nextToken(); + rw = tok.nextToken(); + root = tok.nextToken(); + desc = tok.nextToken(); + } + + DFSAdminExport(String p, String d, String ro, String rw, String root) + { + path = p; + desc = d; + this.ro = ro; + this.rw = rw; + this.root = root; + } + + String[] split(String s) + { + StringTokenizer stok = new StringTokenizer(s, " "); + String rv[] = new String[stok.countTokens()]; + for(int i=0; i 1)); + add_item(name, p, l, r); + TextField t = new TextField(v.equals("-") ? "" : v, 25); + add_item("", t, l, r); + return t; + } + + Choice squashbox(int s) + { + Choice rv = new Choice(); + rv.addItem(filemgr.text("share_s0")); + rv.addItem(filemgr.text("share_s1")); + rv.addItem(filemgr.text("share_s2")); + rv.select(s); + return rv; + } + + Choice robox(boolean r) + { + Choice rv = new Choice(); + rv.addItem(filemgr.text("share_lrw")); + rv.addItem(filemgr.text("share_lro")); + rv.select(r ? 1 : 0); + return rv; + } + + Panel opts_panel(Component ro, Component squash) + { + Panel p = new Panel(); + p.setLayout(new BorderLayout()); + p.add("West", ro); + p.add("East", squash); + return p; + } + + void export_options(LinuxExport e) + { + int c = 0; + for(int i=0; i 0) + c++; + e.host = new String[c]; + e.ro = new boolean[c]; + e.squash = new int[c]; + for(int i=0,j=0; i 0) { + e.host[j] = host[i].getText(); + e.ro[j] = lro[i].getSelectedIndex() == 1; + e.squash[j] = squash[i].getSelectedIndex(); + j++; + } + } + } + +} + +class SearchWindow extends FixedFrame + implements CbButtonCallback,MultiColumnCallback +{ + TabbedPanel tab; + MultiColumn list; + CbButton search_b, cancel_b; + FileManager filemgr; + TextField dir, match, user, group; + Checkbox uany, usel, gany, gsel; + Choice type; + Checkbox sany, smore, sless; + TextField more, less; + Checkbox xon, xoff; + String types[] = { "", "f", "d", "l", "p" }; + RemoteFile results[]; + + SearchWindow(String d, FileManager p) + { + filemgr = p; + setTitle(filemgr.text("search_title")); + + // setup UI + setLayout(new BorderLayout()); + tab = new TabbedPanel(); + Panel search = new Panel(); + search.setLayout(new BorderLayout()); + tab.addItem(filemgr.text("search_crit"), search); + Panel l = new Panel(), r = new Panel(); + l.setLayout(new GridLayout(0, 1)); + r.setLayout(new GridLayout(0, 1)); + + String cols[] = { "", filemgr.text("right_name"), + filemgr.text("right_size") }; + float widths[] = { .07f, .78f, .15f }; + list = new MultiColumn(cols, this); + list.setWidths(widths); + list.setDrawLines(false); + tab.addItem(filemgr.text("search_list"), list); + + add_item(filemgr.text("search_dir"), dir = new TextField(d, 30), l, r); + + add_item(filemgr.text("search_match"), match = new TextField(20), l, r); + + Panel up = new Panel(); + up.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 1)); + CheckboxGroup ug = new CheckboxGroup(); + up.add(uany = new Checkbox(filemgr.text("search_any"), ug, true)); + up.add(usel = new Checkbox("", ug, false)); + up.add(user = new TextField(10)); + add_item(filemgr.text("search_user"), up, l, r); + + Panel gp = new Panel(); + gp.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 1)); + CheckboxGroup gg = new CheckboxGroup(); + gp.add(gany = new Checkbox(filemgr.text("search_any"), gg, true)); + gp.add(gsel = new Checkbox("", gg, false)); + gp.add(group = new TextField(10)); + add_item(filemgr.text("search_group"), gp, l, r); + + type = new Choice(); + for(int i=0; i 0) + url += "&type="+types[type.getSelectedIndex()]; + if (usel.getState()) { + String u = user.getText().trim(); + if (u.length() == 0) { + new ErrorWindow(filemgr.text("search_euser")); + return; + } + url += "&user="+filemgr.urlize(u); + } + if (gsel.getState()) { + String g = group.getText().trim(); + if (g.length() == 0) { + new ErrorWindow(filemgr.text("search_egroup")); + return; + } + url += "&group="+filemgr.urlize(g); + } + if (smore.getState()) { + String m = more.getText().trim(); + try { Integer.parseInt(m); } + catch(Exception e) { + new ErrorWindow(filemgr.text("search_esize")); + return; + } + url += "&size=%2B"+m+"c"; + } + else if (sless.getState()) { + String l = less.getText().trim(); + try { Integer.parseInt(l); } + catch(Exception e) { + new ErrorWindow(filemgr.text("search_esize")); + return; + } + url += "&size=%2D"+l+"c"; + } + if (xon.getState()) + url += "&xdev=1"; + + // send off the search + setCursor(WAIT_CURSOR); + String f[] = filemgr.get_text(url); + if (f[0].length() > 0) { + new ErrorWindow(f[0]); + return; + } + Object rows[][] = new Object[f.length-1][]; + results = new RemoteFile[f.length-1]; + for(int i=1; i= 0) { + ACLEntry e = (ACLEntry)acllist.elementAt(idx); + ACLEditor ed = (ACLEditor)edmap.get(e); + if (ed == null) + edmap.put(e, new ACLEditor(this, e)); + else { + ed.toFront(); + ed.requestFocus(); + } + } + } + + public void singleClick(MultiColumn list, int num) + { + } + + public void headingClicked(MultiColumn list, int col) + { + } +} + +class AttributesWindow extends FixedFrame + implements CbButtonCallback,MultiColumnCallback +{ + FileManager filemgr; + RemoteFile file; + Vector attrlist = new Vector(); + Hashtable edmap = new Hashtable(); + + CbButton ok, cancel, add; + MultiColumn attrtable; + + AttributesWindow(FileManager p, RemoteFile f) + { + super(400, 300); + setTitle(p.text("attr_title", f.path)); + filemgr = p; + file = f; + + // Get the attributes + String a[] = filemgr.get_text( + "getattrs.cgi?file="+filemgr.urlize(file.path)); + if (a[0].length() != 0) { + new ErrorWindow(filemgr.text("attr_eattrs", a[0])); + return; + } + + // Create the UI + setLayout(new BorderLayout()); + String titles[] = { filemgr.text("attr_name"), + filemgr.text("attr_value") }; + attrtable = new MultiColumn(titles, this); + for(int i=1; i= 0) { + FileAttribute at = (FileAttribute)attrlist.elementAt(idx); + AttributeEditor ed = (AttributeEditor)edmap.get(at); + if (ed == null) + edmap.put(at, new AttributeEditor(this, at)); + else { + ed.toFront(); + ed.requestFocus(); + } + } + } + + public void singleClick(MultiColumn list, int num) + { + } + + public void headingClicked(MultiColumn list, int col) + { + } +} + +class FileAttribute +{ + String name; + String value; + + FileAttribute(String l, FileManager f) + { + int eq = l.indexOf('='); + name = f.un_urlize(l.substring(0, eq)); + value = f.un_urlize(l.substring(eq+1)); + } + + FileAttribute(String n, String v) + { + name = n; + value = v; + } + + String[] getRow() + { + return new String[] { name, value }; + } +} + +class AttributeEditor extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + AttributesWindow attrwin; + FileAttribute attr; + boolean creating; + CbButton ok, del; + TextField name; + TextArea value; + + AttributeEditor(AttributesWindow w, FileAttribute a) + { + attrwin = w; + attr = a; + filemgr = w.filemgr; + creating = false; + makeUI(); + } + + AttributeEditor(AttributesWindow w) + { + attrwin = w; + attr = new FileAttribute("", ""); + filemgr = w.filemgr; + creating = true; + makeUI(); + } + + void makeUI() + { + setTitle(filemgr.text(creating ? "attr_create" : "attr_edit")); + setLayout(new BorderLayout()); + + Panel top = new Panel(); + top.setLayout(new GridLayout(1, 2)); + top.add(new Label(filemgr.text("attr_name"))); + top.add(name = new TextField(attr.name, 20)); + add("North", top); + + Panel mid = new Panel(); + mid.setLayout(new GridLayout(1, 2)); + mid.add(new Label(filemgr.text("attr_value"))); + mid.add(value = new TextArea(attr.value, 5, 20)); + add("Center", mid); + + Panel bot = new Panel(); + bot.setLayout(new FlowLayout(FlowLayout.RIGHT)); + bot.add(ok = new CbButton(filemgr.get_image("save.gif"), + filemgr.text("save"), + CbButton.LEFT, this)); + if (!creating) + bot.add(del = new CbButton(filemgr.get_image("cancel.gif"), + filemgr.text("delete"), + CbButton.LEFT, this)); + add("South", bot); + + pack(); + show(); + } + + public void click(CbButton b) + { + if (b == ok) { + // Update or add the attribute + if (name.getText().length() == 0) { + new ErrorWindow(filemgr.text("attr_ename")); + return; + } + attr.name = name.getText(); + attr.value = value.getText(); + if (creating) { + // Add to the attribs table + attrwin.attrlist.addElement(attr); + attrwin.attrtable.addItem(attr.getRow()); + } + else { + // Update the table + int idx = attrwin.attrlist.indexOf(attr); + attrwin.attrtable.modifyItem(attr.getRow(), idx); + } + dispose(); + } + else if (b == del) { + // Remove this entry + int idx = attrwin.attrlist.indexOf(attr); + attrwin.attrlist.removeElementAt(idx); + attrwin.attrtable.deleteItem(idx); + dispose(); + } + } + + public void dispose() + { + attrwin.edmap.remove(attr); + super.dispose(); + } +} + +class EXTWindow extends FixedFrame implements CbButtonCallback +{ + FileManager filemgr; + RemoteFile file; + + CbButton ok, cancel; + Checkbox cbs[]; + + String attrs[] = { "A", "a", "c", "d", "i", "s", "S", "u" }; + Hashtable attrmap = new Hashtable(); + + EXTWindow(FileManager p, RemoteFile f) + { + super(); + setTitle(p.text("ext_title", f.path)); + filemgr = p; + file = f; + + // Get the attributes + String a[] = filemgr.get_text( + "getext.cgi?file="+filemgr.urlize(file.path)); + if (a[0].length() != 0) { + new ErrorWindow(filemgr.text("ext_eattrs", a[0])); + return; + } + for(int i=0; i= 0 && yy <= height) { + // Draw this node + if (n.im != null) + bg.drawImage(n.im, xx, yy, this); + if (sel == n) { + // Select this node + bg.setColor(Util.body); + bg.fillRect(xx+17, yy+2, tw+2, 13); + bg.setColor(Util.text); + } + bg.drawString(n.text, xx+18, yy+12); + } + if (n.ch != null && n.open && yy <= height) { + // Mark this node + bg.drawLine(xx+18, yy+14, xx+17+tw, yy+14); + + // Draw subnodes + yy += 16; + for(int i=0; i= n.x) + return n; + if (n.ch == null || !n.open) + return null; + for(int i=0; i= 0 && yy <= height) { + // Draw this node + if (n.im != null) + bg.drawImage(n.im, xx, yy, this); + if (sel == n) { + // Select this node + bg.setColor(Color.lightGray); + bg.fillRect(xx+17, yy+2, tw+2, 13); + bg.setColor(Color.black); + } + bg.drawString(n.text, xx+18, yy+12); + } + if (n.ch != null && n.open && yy <= height) { + // Mark this node + bg.drawLine(xx+18, yy+14, xx+17+tw, yy+14); + + // Draw subnodes + yy += 16; + for(int i=0; i= n.x) + return n; + if (n.ch == null || !n.open) + return null; + for(int i=0; i= top+r) { + top = s-1; + if (top > list[0].size() - r) + top = list[0].size() - r; + sb.setValue(top); + repaint(); + } + } + + // deleteItem + // Remove one row from the list + void deleteItem(int n) + { + for(int i=0; i 0) { + System.arraycopy(sels, 0, nsels, 0, i); + System.arraycopy(sels, i+1, nsels, i, + nsels.length-i); + sel = nsels[0]; + } + break; + } + } + repaint(); + compscroll(); + } + + // clear + // Remove everything from the list + void clear() + { + for(int i=0; i= top && sels[i] <= bot) { + bg.setColor(sels[i] == sel ? Util.body + : lighterGray); + bg.fillRect(0, th+(sels[i]-top)*rowh, + width, rowh); + } + } + } + + // Draw each column + for(int i=0; i w-3) + s = s.substring(0, s.length()-1); + if (!enabled) + bg.setColor(Util.body); + else if (colors != null) + bg.setColor(colors[j][i]); + bg.drawString(s, x+1, th+(j+1-top)*rowh-fd); + } + else if (o instanceof Image) { + // Render image in column + Image im = (Image)o; + bg.drawImage(im, x+1, th+(j-top)*rowh, this); + } + } + } + } + + // mouseDown + // Select a list item or a column to drag + public boolean mouseDown(Event e, int x, int y) + { + if (!enabled) { + return true; + } + x -= in.left; + y -= in.top; + coldrag = -1; + if (y < th) { + // Click in title bar + for(int i=0; i 0 && Math.abs(cpos[i] - x) < 3) { + // clicked on a column separator + coldrag = i; + } + else if (x >= cpos[i] && x < cpos[i+1]) { + // clicked in a title + callback.headingClicked(this, i); + } + } + } + else { + // Item chosen from list + int row = (y-th)/rowh + top; + if (row < list[0].size()) { + // Double-click? + boolean dclick = false; + if (e.when-last < 1000 && sel == row) + dclick = true; + else + last = e.when; + + if (e.shiftDown() && multiselect && sel != -1) { + // Select all from last selection to this one + int zero = sels[0]; + if (zero < row) { + sels = new int[row-zero+1]; + for(int i=zero; i<=row; i++) + sels[i-zero] = i; + } + else { + sels = new int[zero-row+1]; + for(int i=zero; i>=row; i--) + sels[zero-i] = i; + } + } + else if (e.controlDown() && multiselect) { + // Add this one to selection + int nsels[] = new int[sels.length + 1]; + System.arraycopy(sels, 0, nsels, 0,sels.length); + nsels[sels.length] = row; + sels = nsels; + } + else { + // Select one row only, and de-select others + sels = new int[1]; + sels[0] = row; + } + sel = row; + repaint(); + last_event = e; + if (callback != null) { + // Callback the right function + if (dclick) callback.doubleClick(this, row); + else callback.singleClick(this, row); + } + else { + // Send an event + getParent().postEvent( + new Event(this, + Event.ACTION_EVENT, + dclick?"Double":"Single")); + } + } + } + return true; + } + + // mouseDrag + // If a column is selected, change it's width + public boolean mouseDrag(Event e, int x, int y) + { + if (!enabled) { + return true; + } + x -= in.left; + y -= in.top; + if (coldrag != -1) { + if (x > cpos[coldrag-1]+3 && x < cpos[coldrag+1]-3) { + cpos[coldrag] = x; + cwidth[coldrag-1] = (cpos[coldrag]-cpos[coldrag-1]) / + (float)width; + cwidth[coldrag] = (cpos[coldrag+1]-cpos[coldrag]) / + (float)width; + repaint(); + } + } + return true; + } + + public void moved(CbScrollbar s, int v) + { + moving(s, v); + } + + public void moving(CbScrollbar s, int v) + { + top = sb.getValue(); + compscroll(); + repaint(); + } + + // compscroll + // Re-compute the size of the scrollbar + private void compscroll() + { + if (fnm == null) + return; // not visible + int r = rows(); + int c = list[0].size() - r; + sb.setValues(top, r==0?1:r, list[0].size()); + } + + // rows + // Returns the number of rows visible in the list + private int rows() + { + return Math.min(height/rowh - 1, list[0].size()); + } + + public Dimension minimumSize() + { + return new Dimension(400, 100); + } + + public Dimension preferredSize() + { + return minimumSize(); + } +} + +// MultiColumnCallback +// Objects implementing this interface can be passed to the MultiColumn +// class, to have their singleClick() and doubleClick() functions called in +// response to single or double click in the list. +interface MultiColumnCallback +{ + // singleClick + // Called on a single click on a list item + void singleClick(MultiColumn list, int num); + + // doubleClick + // Called upon double-clicking on a list item + void doubleClick(MultiColumn list, int num); + + // headingClicked + // Called when a column heading is clicked on + void headingClicked(MultiColumn list, int col); +} + diff --git a/file/MultiColumn.java.bak b/file/MultiColumn.java.bak new file mode 100644 index 000000000..65ec79571 --- /dev/null +++ b/file/MultiColumn.java.bak @@ -0,0 +1,578 @@ +// MultiColumn +// A List box that supports multiple columns. +import java.awt.*; +import java.util.Vector; + +public class MultiColumn extends BorderPanel implements CbScrollbarCallback +{ + MultiColumnCallback callback; // what to call back to + String title[]; // column titles + boolean adjustable = true; + boolean drawlines = true; + Color colors[][] = null; + boolean enabled = true; + boolean multiselect = false; + int cpos[]; // column x positions + float cwidth[]; // proportional column widths + Vector list[]; // columns of the list + CbScrollbar sb; // scrollbar at the right side + int width, height; // size, minus the scrollbar + Insets in; // used space around the border + int sbwidth; // width of the scrollbar + int th; // height of title bar + Image bim; // backing image + Graphics bg; // backing graphics + Font font = new Font("timesRoman", Font.PLAIN, 12); + FontMetrics fnm; // drawing font size + int coldrag = -1; // column being resized + int sel = -1; // selected row + int sels[] = new int[0]; // all selected rows + int top = 0; // first row displayed + long last; // last mouse click time + int rowh = 16; // row height + Event last_event; // last event that triggered callback + int sortcol; // Column currently being sorted + int sortdir; // Sort direction (0=none, 1=up, 2=down) + + // Create a new list with the given column titles + MultiColumn(String t[]) + { + super(3, new Color(50,50,50), new Color(220,220,220)); + title = new String[t.length]; + for(int i=0; i= top+r) { + top = s-1; + if (top > list[0].size() - r) + top = list[0].size() - r; + sb.setValue(top); + repaint(); + } + } + + // deleteItem + // Remove one row from the list + void deleteItem(int n) + { + for(int i=0; i 0) { + System.arraycopy(sels, 0, nsels, 0, i); + System.arraycopy(sels, i+1, nsels, i, + nsels.length-i); + sel = nsels[0]; + } + break; + } + } + repaint(); + compscroll(); + } + + // clear + // Remove everything from the list + void clear() + { + for(int i=0; i= top && sels[i] <= bot) { + bg.setColor(sels[i] == sel ? Color.lightGray + : lighterGray); + bg.fillRect(0, th+(sels[i]-top)*rowh, + width, rowh); + } + } + } + + // Draw each column + for(int i=0; i w-3) + s = s.substring(0, s.length()-1); + if (!enabled) + bg.setColor(Color.lightGray); + else if (colors != null) + bg.setColor(colors[j][i]); + bg.drawString(s, x+1, th+(j+1-top)*rowh-fd); + } + else if (o instanceof Image) { + // Render image in column + Image im = (Image)o; + bg.drawImage(im, x+1, th+(j-top)*rowh, this); + } + } + } + } + + // mouseDown + // Select a list item or a column to drag + public boolean mouseDown(Event e, int x, int y) + { + if (!enabled) { + return true; + } + x -= in.left; + y -= in.top; + coldrag = -1; + if (y < th) { + // Click in title bar + for(int i=0; i 0 && Math.abs(cpos[i] - x) < 3) { + // clicked on a column separator + coldrag = i; + } + else if (x >= cpos[i] && x < cpos[i+1]) { + // clicked in a title + callback.headingClicked(this, i); + } + } + } + else { + // Item chosen from list + int row = (y-th)/rowh + top; + if (row < list[0].size()) { + // Double-click? + boolean dclick = false; + if (e.when-last < 1000 && sel == row) + dclick = true; + else + last = e.when; + + if (e.shiftDown() && multiselect && sel != -1) { + // Select all from last selection to this one + int zero = sels[0]; + if (zero < row) { + sels = new int[row-zero+1]; + for(int i=zero; i<=row; i++) + sels[i-zero] = i; + } + else { + sels = new int[zero-row+1]; + for(int i=zero; i>=row; i--) + sels[zero-i] = i; + } + } + else if (e.controlDown() && multiselect) { + // Add this one to selection + int nsels[] = new int[sels.length + 1]; + System.arraycopy(sels, 0, nsels, 0,sels.length); + nsels[sels.length] = row; + sels = nsels; + } + else { + // Select one row only, and de-select others + sels = new int[1]; + sels[0] = row; + } + sel = row; + repaint(); + last_event = e; + if (callback != null) { + // Callback the right function + if (dclick) callback.doubleClick(this, row); + else callback.singleClick(this, row); + } + else { + // Send an event + getParent().postEvent( + new Event(this, + Event.ACTION_EVENT, + dclick?"Double":"Single")); + } + } + } + return true; + } + + // mouseDrag + // If a column is selected, change it's width + public boolean mouseDrag(Event e, int x, int y) + { + if (!enabled) { + return true; + } + x -= in.left; + y -= in.top; + if (coldrag != -1) { + if (x > cpos[coldrag-1]+3 && x < cpos[coldrag+1]-3) { + cpos[coldrag] = x; + cwidth[coldrag-1] = (cpos[coldrag]-cpos[coldrag-1]) / + (float)width; + cwidth[coldrag] = (cpos[coldrag+1]-cpos[coldrag]) / + (float)width; + repaint(); + } + } + return true; + } + + public void moved(CbScrollbar s, int v) + { + moving(s, v); + } + + public void moving(CbScrollbar s, int v) + { + top = sb.getValue(); + compscroll(); + repaint(); + } + + // compscroll + // Re-compute the size of the scrollbar + private void compscroll() + { + if (fnm == null) + return; // not visible + int r = rows(); + int c = list[0].size() - r; + sb.setValues(top, r==0?1:r, list[0].size()); + } + + // rows + // Returns the number of rows visible in the list + private int rows() + { + return Math.min(height/rowh - 1, list[0].size()); + } + + public Dimension minimumSize() + { + return new Dimension(400, 100); + } + + public Dimension preferredSize() + { + return minimumSize(); + } +} + +// MultiColumnCallback +// Objects implementing this interface can be passed to the MultiColumn +// class, to have their singleClick() and doubleClick() functions called in +// response to single or double click in the list. +interface MultiColumnCallback +{ + // singleClick + // Called on a single click on a list item + void singleClick(MultiColumn list, int num); + + // doubleClick + // Called upon double-clicking on a list item + void doubleClick(MultiColumn list, int num); + + // headingClicked + // Called when a column heading is clicked on + void headingClicked(MultiColumn list, int col); +} + diff --git a/file/QuickSort.java b/file/QuickSort.java new file mode 100644 index 000000000..9f8858e41 --- /dev/null +++ b/file/QuickSort.java @@ -0,0 +1,77 @@ +public class QuickSort +{ + static int col, dir; + + // Sorts entire array + public static void sort(RemoteFile array[], int c, int d) + { + col = c; + dir = d; + psort(array, 0, array.length - 1); + } + + // Sorts partial array + public static void psort(RemoteFile array[], int start, int end) + { + int p; + if (end > start) + { + p = partition(array, start, end); + psort(array, start, p-1); + psort(array, p+1, end); + } + } + + protected static int compare(RemoteFile a, RemoteFile b) { + long rv = 0; + if (col == 1) + rv = a.name.compareTo(b.name); + else if (col == 2) + rv = a.size - b.size; + else if (col == 3) + rv = a.user.compareTo(b.user); + else if (col == 4) + rv = a.group.compareTo(b.group); + else + rv = a.modified - b.modified; + rv = rv < 0 ? -1 : rv > 0 ? 1 : 0; + return (int)(dir == 2 ? -rv : rv); + } + + protected static int partition(RemoteFile array[], int start, int end) + { + int left, right; + RemoteFile partitionElement; + + // Arbitrary partition start...there are better ways... + partitionElement = array[end]; + + left = start - 1; + right = end; + for (;;) + { + while (compare(partitionElement, array[++left]) == 1) + { + if (left == end) break; + } + while (compare(partitionElement, array[--right]) == -1) + { + if (right == start) break; + } + if (left >= right) break; + swap(array, left, right); + } + swap(array, left, end); + + return left; + } + + protected static void swap(RemoteFile array[], int i, int j) + { + RemoteFile temp; + temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } +} + diff --git a/file/ResizePanel.java b/file/ResizePanel.java new file mode 100644 index 000000000..7555204ca --- /dev/null +++ b/file/ResizePanel.java @@ -0,0 +1,169 @@ +// ResizePanel +// A panel with two parts, arranged either vertically or horizontally, +// whose midpoint is adjustable +import java.awt.*; +import java.util.Vector; + +public class ResizePanel extends Panel implements LayoutManager +{ + Component one, two; + int pos = -1; + double ratio; + boolean vertical; + boolean dragging; + int border = 100; + + // Provide two components where component one initially occupies rt fraction of + // parent area. When vertical=true components are layed out one above the other + public ResizePanel(Component one, Component two, double rt, boolean vertical) + { + this.one = one; + this.two = two; + this.vertical = vertical; + ratio = rt; + setLayout(this); + add(one); + add(two); + } + + public void paint(Graphics g) + { + Dimension s = size(); + if (vertical) + { + // Draw horizontal bar between vertically aligned components + pos = (int)(s.height * ratio); + g.setColor(Color.white); + g.drawLine(0, pos-2, 0, pos+1); + g.drawLine(0, pos-2, s.width-2, pos-2); + g.setColor(Color.black); + g.drawLine(s.width-1, pos+2, s.width-1, pos-1); + g.drawLine(s.width-1, pos+2, 1, pos+2); + } + else + { + // Draw vertical divider bar + pos = (int)(s.width * ratio); + g.setColor(Color.white); + g.drawLine(pos-2, 0, pos+1, 0); + g.drawLine(pos-2, 0, pos-2, s.height-2); + g.setColor(Color.black); + g.drawLine(pos+2, s.height-1, pos-1, s.height-1); + g.drawLine(pos+2, s.height-1, pos+2, 1); + } + } + + // Detect mouse click on divider bar + public boolean mouseDown(Event evt, int x, int y) + { + int sh; + Dimension s = size(); + if (vertical && y >= pos-2 && y <= pos+2) + { + // Started dragging + dragging = true; + } + if (!vertical && x >= pos-2 && x <= pos+2) + { + // Started dragging + dragging = true; + } + return dragging; + } + + // Move division point on mouse drag + public boolean mouseDrag(Event evt, int x, int y) + { + if (dragging) + { + Dimension s = size(); + if (vertical) + { + if (y < border) + pos = border; + else if (y > s.height - border) + pos = s.height - border; + else + pos = y; + ratio = (double)pos / (double)s.height; + } + else + { + if (x < border) + pos = border; + else if (x > s.width - border) + pos = s.width - border; + else + pos = x; + ratio = (double)pos / (double)s.width; + } + layoutContainer(this); + repaint(); + } + return dragging; + } + + // No longer dragging on mouse button release + public boolean mouseUp(Event evt, int x, int y) + { + boolean o = dragging; + dragging = false; + return o; + } + + public void addLayoutComponent(String name, Component comp) + { + } + + // Arrange components within container + public void layoutContainer(Container parent) + { + Dimension s = parent.size(); + if (vertical) + { + pos = (int)(s.height * ratio); + one.reshape(0, 0, s.width, pos-3); + one.layout(); + two.reshape(0, pos+3, s.width, s.height - pos - 5); + two.layout(); + } + else + { + pos = (int)(s.width * ratio); + one.reshape(0, 0, pos-3, s.height); + one.layout(); + two.reshape(pos+3, 0, s.width - pos - 5, s.height); + two.layout(); + } + } + + // Determine minimum size for ResizePanel + public Dimension minimumLayoutSize(Container parent) + { + Dimension d1 = one.minimumSize(), + d2 = two.minimumSize(); + + if (vertical) + { + // Largest of the widths, sum of the heights + return new Dimension(d1.width > d2.width ? d1.width : d2.width, + d1.height + d2.height); + } + else + { + // Largest of the heights, sum of the widths + return new Dimension(d1.width + d2.width, + d1.height > d2.height ? d1.height : d2.height); + } + } + + public Dimension preferredLayoutSize(Container parent) + { + return minimumLayoutSize(parent); + } + + public void removeLayoutComponent(Component comp) + { + } +} + diff --git a/file/StaticTextField.java b/file/StaticTextField.java new file mode 100644 index 000000000..57fd490c6 --- /dev/null +++ b/file/StaticTextField.java @@ -0,0 +1,24 @@ +import java.awt.*; + +// StaticTextField +// A text field that is set to be non-editable by default +class StaticTextField extends TextField +{ + StaticTextField() + { + super(); + setEditable(false); + } + + StaticTextField(String s) + { + super(s); + setEditable(false); + } + + StaticTextField(String s, int i) + { + super(s,i); + setEditable(false); + } +} diff --git a/file/StringSplitter.java b/file/StringSplitter.java new file mode 100644 index 000000000..48ba1e631 --- /dev/null +++ b/file/StringSplitter.java @@ -0,0 +1,103 @@ +import java.util.Vector; + +// StringSplitter +// A stringsplitter object splits a string into a number of substrings, +// each separated by one separator character. Separator characters can be +// included in the string by escaping them with a \ +public class StringSplitter +{ + Vector parts = new Vector(); + int pos = 0; + + StringSplitter(String str, char sep) + { + this(str, sep, true); + } + + StringSplitter(String str, char sep, boolean escape) + { + StringBuffer current; + + parts.addElement(current = new StringBuffer()); + for(int i=0; iToolbarLayout.LEFT, ToolbarLayout.RIGHT, + * or ToolbarLayout.CENTER. + * @param align the alignment value + */ + public ToolbarLayout(int align) { + this(align, 5, 5); + } + + /** + * Creates a new ToolbarLayout with the indicated alignment + * and the indicated horizontal and vertical gaps. + *

+ * The value of the alignment argument must be one of + * ToolbarLayout.LEFT, ToolbarLayout.RIGHT, + * or ToolbarLayout.CENTER. + * @param align the alignment value. + * @param hgap the horizontal gap between components. + * @param vgap the vertical gap between components. + */ + public ToolbarLayout(int align, int hgap, int vgap) { + this.align = align; + this.hgap = hgap; + this.vgap = vgap; + } + + /** + * Gets the alignment for this layout. + * Possible values are ToolbarLayout.LEFT, + * ToolbarLayout.RIGHT, or ToolbarLayout.CENTER. + * @return the alignment value for this layout. + * @see ToolbarLayout#setAlignment + */ + public int getAlignment() { + return align; + } + + /** + * Sets the alignment for this layout. + * Possible values are ToolbarLayout.LEFT, + * ToolbarLayout.RIGHT, and ToolbarLayout.CENTER. + * @param align the alignment value. + * @see ToolbarLayout#getAlignment + */ + public void setAlignment(int align) { + this.align = align; + } + + /** + * Gets the horizontal gap between components. + * @return the horizontal gap between components. + * @see ToolbarLayout#setHgap + */ + public int getHgap() { + return hgap; + } + + /** + * Sets the horizontal gap between components. + * @param hgap the horizontal gap between components + * @see ToolbarLayout#getHgap + */ + public void setHgap(int hgap) { + this.hgap = hgap; + } + + /** + * Gets the vertical gap between components. + * @return the vertical gap between components. + * @see ToolbarLayout#setVgap + */ + public int getVgap() { + return vgap; + } + + /** + * Sets the vertical gap between components. + * @param vgap the vertical gap between components + * @see ToolbarLayout#getVgap + */ + public void setVgap(int vgap) { + this.vgap = vgap; + } + + /** + * Adds the specified component to the layout. Sets the orientation to be horizontal. + * @param name the name of the component + * @param comp the component to be added + */ + public void addLayoutComponent(String name, Component comp) { + } + + /** + * Removes the specified component from the layout. Not used by + * this class. + * @param comp the component to remove + * @see java.awt.Container#removeAll + */ + public void removeLayoutComponent(Component comp) { + } + + /** + * Returns the preferred dimensions for this layout given the components + * in the specified target container. This method is the difference + * between ToolbarLayout and FlowLayout. + * @param target the component which needs to be laid out + * @return the preferred dimensions to lay out the + * subcomponents of the specified container. + * @see Container + * @see #minimumLayoutSize + * @see java.awt.Container#getPreferredSize + */ + public Dimension preferredLayoutSize(Container target) { + synchronized (target.getTreeLock()) { + Dimension dim = new Dimension(0, 0); + int nmembers = target.getComponentCount(); + + Insets insets = target.getInsets(); + + int numRows = 1; //the number of rows + int rowSumWidth = insets.left + insets.right; //the width of the row so far + int rowMaxWidth = target.getSize().width; //the width that the ToolbarLayout is in + int rowHeight = 0; //the height of each row + int numOnRow = 0; //the number of components on the row + + for (int i = 0 ; i < nmembers ; i++) { + Component m = target.getComponent(i); + if (m.isVisible()) { + Dimension d = m.getPreferredSize(); + rowHeight = Math.max(rowHeight, d.height); //make each row the height of the biggest component of all + if (i > 0) { + rowSumWidth += hgap;//add on the pre-spacing if this is not the first component + } + rowSumWidth += d.width; //add the width of the component + + //if it overflowed and if there are components already on this row then bump this component to next row + if ((rowSumWidth + hgap) > rowMaxWidth) { + if (numOnRow > 0) { + numRows++; + rowSumWidth = insets.left + insets.right + d.width; + numOnRow = 0;//reset the number of components on the next row (we ++ no matter what later) + } + } + numOnRow++;//add this component to the count of the number on the row + } + } + dim.width = rowMaxWidth; + dim.height = insets.top + insets.bottom + numRows*rowHeight + vgap*(numRows + 1); + return dim; + } + } + + /** + * Returns the minimum dimensions needed to layout the components + * contained in the specified target container. + * @param target the component which needs to be laid out + * @return the minimum dimensions to lay out the + * subcomponents of the specified container. + * @see #preferredLayoutSize + * @see java.awt.Container + * @see java.awt.Container#doLayout + */ + public Dimension minimumLayoutSize(Container target) { + synchronized (target.getTreeLock()) { + Dimension dim = new Dimension(0, 0); + int nmembers = target.getComponentCount(); + + for (int i = 0 ; i < nmembers ; i++) { + Component m = target.getComponent(i); + if (m.isVisible()) { + Dimension d = m.getMinimumSize(); + dim.height = Math.max(dim.height, d.height); + if (i > 0) { + dim.width += hgap; + } + dim.width += d.width; + } + } + Insets insets = target.getInsets(); + dim.width += insets.left + insets.right + hgap*2; + dim.height += insets.top + insets.bottom + vgap*2; + return dim; + } + } + + /** + * Centers the elements in the specified row, if there is any slack. + * @param target the component which needs to be moved + * @param x the x coordinate + * @param y the y coordinate + * @param width the width dimensions + * @param height the height dimensions + * @param rowStart the beginning of the row + * @param rowEnd the the ending of the row + */ + private void moveComponents(Container target, int x, int y, int width, int height, int rowStart, int rowEnd) { + synchronized (target.getTreeLock()) { + switch (align) { + case LEFT: + break; + case CENTER: + x += width / 2; + break; + case RIGHT: + x += width; + break; + } + for (int i = rowStart ; i < rowEnd ; i++) { + Component m = target.getComponent(i); + if (m.isVisible()) { + m.setLocation(x, y + (height - m.size().height) / 2); + x += hgap + m.size().width; + } + } + } + } + + /** + * Lays out the container. This method lets each component take + * its preferred size by reshaping the components in the + * target container in order to satisfy the constraints of + * this ToolbarLayout object. + * @param target the specified component being laid out. + * @see Container + * @see java.awt.Container#doLayout + */ + public void layoutContainer(Container target) { + synchronized (target.getTreeLock()) { + Insets insets = target.getInsets(); + int maxwidth = target.size().width - (insets.left + insets.right + hgap*2); + int nmembers = target.getComponentCount(); + int x = 0, y = insets.top + vgap; + int rowh = 0, start = 0; + + for (int i = 0 ; i < nmembers ; i++) { + Component m = target.getComponent(i); + if (m.isVisible()) { + Dimension d = m.getPreferredSize(); + m.setSize(d.width, d.height); + if ((x == 0) || ((x + d.width) <= maxwidth)) { + if (x > 0) { + x += hgap; + } + x += d.width; + rowh = Math.max(rowh, d.height); + } else { + moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh, start, i); + x = d.width; + y += vgap + rowh; + rowh = d.height; + start = i; + } + } + } + moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh, start, nmembers); + } + } + + /** + * Returns a string representation of this ToolbarLayout + * object and its values. + * @return a string representation of this layout. + */ + public String toString() { + String str = ""; + switch (align) { + case LEFT: str = ",align=left"; break; + case CENTER: str = ",align=center"; break; + case RIGHT: str = ",align=right"; break; + } + return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + str + "]"; + } +} diff --git a/file/Util.java b/file/Util.java new file mode 100644 index 000000000..95d9a7d02 --- /dev/null +++ b/file/Util.java @@ -0,0 +1,148 @@ +import java.awt.*; +import java.awt.image.*; + +class Util +{ + static Frame fr; + static Graphics g; + static Font f; + static FontMetrics fnm; + static Toolkit tk; + + static Color light_edge = Color.white; + static Color dark_edge = Color.black; + static Color body = Color.lightGray; + static Color body_hi = new Color(210, 210, 210); + static Color light_edge_hi = Color.white; + static Color dark_edge_hi = Color.darkGray; + static Color dark_bg = new Color(150, 150, 150); + static Color text = Color.black; + static Color light_bg = Color.white; + + static + { + fr = new Frame(); + fr.addNotify(); + g = fr.getGraphics(); + setFont(new Font("TimesRoman", Font.PLAIN, 8)); + tk = Toolkit.getDefaultToolkit(); + } + + static boolean waitForImage(Image i) + { + MediaTracker mt = new MediaTracker(fr); + mt.addImage(i, 0); + try { mt.waitForAll(); } catch(Exception e) { return false; } + return !mt.isErrorAny(); + } + + static boolean waitForImage(Image i, int w, int h) + { + MediaTracker mt = new MediaTracker(fr); + mt.addImage(i, w, h, 0); + try { mt.waitForAll(); } catch(Exception e) { return false; } + return !mt.isErrorAny(); + } + + static int getWidth(Image i) + { + waitForImage(i); + return i.getWidth(fr); + } + + static int getHeight(Image i) + { + waitForImage(i); + return i.getHeight(fr); + } + + static Image createImage(int w, int h) + { + return fr.createImage(w, h); + } + + static Image createImage(ImageProducer p) + { + return fr.createImage(p); + } + + static Object createObject(String name) + { + try { + Class c = Class.forName(name); + return c.newInstance(); + } + catch(Exception e) { + System.err.println("Failed to create object "+name+" : "+ + e.getClass().getName()); + System.exit(1); + } + return null; + } + + /**Create a new instance of some object + */ + static Object createObject(Object o) + { + try { return o.getClass().newInstance(); } + catch(Exception e) { + System.err.println("Failed to reproduce object "+o+" : "+ + e.getClass().getName()); + System.exit(1); + } + return null; + } + + + static void dottedRect(Graphics g, int x1, int y1, + int x2, int y2, int s) + { + int i, s2 = s*2, t; + if (x2 < x1) { t = x1; x1 = x2; x2 = t; } + if (y2 < y1) { t = y1; y1 = y2; y2 = t; } + for(i=x1; i<=x2; i+=s2) + g.drawLine(i, y1, i+s > x2 ? x2 : i+s, y1); + for(i=y1; i<=y2; i+=s2) + g.drawLine(x2, i, x2, i+s > y2 ? y2 : i+s); + for(i=x2; i>=x1; i-=s2) + g.drawLine(i, y2, i-s < x1 ? x1 : i-s, y2); + for(i=y2; i>=y1; i-=s2) + g.drawLine(x1, i, x1, i-s < y1 ? y1 : i-s); + } + + static void recursiveLayout(Container c) + { + c.layout(); + for(int i=0; i $text{'acl_user'}\n"; +local $u = $_[0]->{'uid'} < 0 ? '' : getpwuid($_[0]->{'uid'}); +printf " %s\n", + $_[0]->{'uid'} < 0 ? 'checked' : '', $text{'acl_user_def'}; +printf "\n", + $_[0]->{'uid'} < 0 ? '' : 'checked'; +print " ", + &user_chooser_button("uid", 0)," \n"; + +print " $text{'acl_umask'}\n"; +print " \n"; + +print " $text{'acl_follow'} \n"; +printf " $text{'yes'}\n", + $_[0]->{'follow'} == 1 ? "checked" : ""; +printf " $text{'acl_fyes'}\n", + $_[0]->{'follow'} == 2 ? "checked" : ""; +printf " $text{'no'} \n", + $_[0]->{'follow'} == 0 ? "checked" : ""; + +print " $text{'acl_ro'} \n"; +printf " $text{'yes'}\n", + $_[0]->{'ro'} ? "checked" : ""; +printf " $text{'no'} \n", + $_[0]->{'ro'} ? "" : "checked"; + +print " $text{'acl_max'}\n"; +printf " %s\n", + $_[0]->{'max'} ? "" : "checked", $text{'acl_unlim'}; +printf "\n", + $_[0]->{'max'} ? "checked" : ""; +printf " %s \n", + $_[0]->{'max'}, $text{'acl_b'}; + +print " $text{'acl_archive'} \n"; +printf " $text{'yes'}\n", + $_[0]->{'archive'} == 1 ? "checked" : ""; +printf " $text{'acl_archmax'}\n", + $_[0]->{'archive'} == 2 ? "checked" : ""; +printf " %s\n", + $_[0]->{'archmax'}, $text{'acl_b'}; +printf " $text{'no'} \n", + $_[0]->{'archive'} == 0 ? "checked" : ""; + +print " $text{'acl_unarchive'} \n"; +printf " %s\n", + $_[0]->{'unarchive'} == 2 ? "checked" : "", $text{'acl_unarchive2'}; +printf " %s\n", + $_[0]->{'unarchive'} == 1 ? "checked" : "", $text{'acl_unarchive1'}; +printf " %s \n", + $_[0]->{'unarchive'} == 0 ? "checked" : "", $text{'acl_unarchive0'}; + +print " $text{'acl_dostounix'} \n"; +printf " %s\n", + $_[0]->{'dostounix'} == 1 ? "checked" : "", $text{'yes'}; +printf " %s \n", + $_[0]->{'dostounix'} == 0 ? "checked" : "", $text{'no'}; + +print " $text{'acl_buttons'} \n"; +foreach $b (@file_buttons) { + printf " %s
\n", + $b, $_[0]->{'button_'.$b} ? "checked" : "", + $text{'acl_button_'.$b}; + } +print " \n"; + +print " $text{'acl_noperms'}\n"; +print "",&ui_radio("noperms", int($_[0]->{'noperms'}), + [ [ 0, $text{'yes'} ], [ 1, $text{'no'} ] ]),"\n"; + +print "$text{'acl_nousers'}\n"; +print "",&ui_radio("nousers", int($_[0]->{'nousers'}), + [ [ 0, $text{'yes'} ], [ 1, $text{'no'} ] ])," \n"; + +print " $text{'acl_filesystems'}\n"; +print "",&ui_yesno_radio("filesystems", + int($_[0]->{'filesystems'})),"\n"; + +print "$text{'acl_contents'}\n"; +print "",&ui_yesno_radio("contents", + int($_[0]->{'contents'}))," \n"; + +print " $text{'acl_chroot'}\n"; +printf "\n", + $_[0]->{'chroot'}; + +print " $text{'acl_dirs'}
$text{'acl_relto'}\n"; +print "
\n"; +printf " %s
\n", + $_[0]->{'home'} ? 'checked' : '', $text{'acl_home'}; +printf " %s\n", + $_[0]->{'goto'} ? 'checked' : '', $text{'acl_goto'}; + +print " $text{'acl_nodirs'}
$text{'acl_relto'}\n"; +print "
\n"; +} + +# acl_security_save(&options) +# Parse the form for security options for the file module +sub acl_security_save +{ +$_[0]->{'uid'} = $in{'uid_def'} ? -1 : getpwnam($in{'uid'}); +$in{'root'} =~ s/\r//g; +local @root = split(/\s+/, $in{'root'}); +map { s/\/+/\//g } @root; +map { s/([^\/])\/+$/$1/ } @root; +$_[0]->{'root'} = join(" ", @root); +$in{'noroot'} =~ s/\r//g; +local @noroot = split(/\s+/, $in{'noroot'}); +map { s/\/+/\//g } @noroot; +map { s/([^\/])\/+$/$1/ } @noroot; +$_[0]->{'noroot'} = join(" ", @noroot); +$_[0]->{'follow'} = $in{'follow'}; +$_[0]->{'ro'} = $in{'ro'}; +$in{'umask'} =~ /^[0-7]{3}$/ || &error("Invalid umask"); +$_[0]->{'umask'} = $in{'umask'}; +$_[0]->{'home'} = $in{'home'}; +$_[0]->{'goto'} = $in{'goto'}; +$_[0]->{'max'} = $in{'max_def'} ? undef : $in{'max'}; +$_[0]->{'archive'} = $in{'archive'}; +$_[0]->{'archmax'} = $in{'archmax'}; +foreach $b (@file_buttons) { + $_[0]->{"button_$b"} = $in{"button_$b"}; + } +$_[0]->{'unarchive'} = $in{'unarchive'}; +$_[0]->{'dostounix'} = $in{'dostounix'}; +$_[0]->{'chroot'} = $in{'chroot'}; +$_[0]->{'noperms'} = $in{'noperms'}; +$_[0]->{'nousers'} = $in{'nousers'}; +$_[0]->{'filesystems'} = $in{'filesystems'}; +$_[0]->{'contents'} = $in{'contents'}; +} + diff --git a/file/chmod.cgi b/file/chmod.cgi new file mode 100755 index 000000000..914b5c1e2 --- /dev/null +++ b/file/chmod.cgi @@ -0,0 +1,92 @@ +#!/usr/local/bin/perl +# chmod.cgi +# Change the ownership and permissions on a file + +require './file-lib.pl'; +$disallowed_buttons{'info'} && &error($text{'ebutton'}); +&ReadParse(); +&webmin_log($in{'linkto'} ? "relink" : "chmod", undef, $in{'path'}, \%in); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +!$access{'ro'} && &can_access($in{'path'}) || + &failure(&text('chmod_eaccess', $in{'path'})); + +if (defined($in{'user'})) { + $uid = $in{'user'} =~ /^\d+$/ ? $in{'user'} : + defined(%user_to_uid) ? $user_to_uid{$in{'user'}} : + getpwnam($in{'user'}); + &failure(&text('chmod_euser', $in{'user'})) if (!defined($uid)); + $gid = $in{'group'} =~ /^\d+$/ ? $in{'group'} : + defined(%group_to_gid) ? $group_to_gid{$in{'group'}} : + getgrnam($in{'group'}); + &failure(&text('chmod_egroup', $in{'group'})) if (!defined($gid)); + } + +if ($in{'linkto'}) { + # Just changing the link target + $follow && &failure($text{'chmod_efollow'}); + &lock_file($in{'path'}); + unlink($in{'path'}); + symlink($in{'linkto'}, $in{'path'}) || + &failure(&text('chmod_elink', $1)); + &unlock_file($in{'path'}); + } +elsif ($in{'rec'} == 0) { + # Just this file + &update($in{'path'}, 0); + } +elsif ($in{'rec'} == 1) { + # This directory and all its files + &update($in{'path'}, 0); + opendir(DIR, $in{'path'}); + foreach $f (readdir(DIR)) { + next if ($f eq "." || $f eq ".."); + next if (-l $full); + &update("$in{'path'}/$f", 1) if (!-d $full); + } + closedir(DIR); + } +elsif ($in{'rec'} == 2) { + # Directory and all subdirectories + &update($in{'path'}, 0); + &recurse($in{'path'}); + } +print "\n"; + +sub recurse +{ +local(@files, $f, $full); +opendir(DIR, $_[0]); +@files = readdir(DIR); +closedir(DIR); +foreach $f (@files) { + $full = "$_[0]/$f"; + next if ($f eq "." || $f eq ".."); + next if (-l $full); + &update($full, !-d $full); + &recurse($full) if (-d $full); + } +} + +sub failure +{ +print @_,"\n"; +exit; +} + +# update(file, perms_only) +sub update +{ +local $perms = $in{'perms'}; +if (defined($perms)) { + if ($_[1]) { + @st = stat($_[0]); + $perms = ($perms & 0777) | ($st[2] & 037777777000); + } + chmod($perms, $_[0]) || &failure(&text('chmod_echmod', $!)); + } +if (defined($uid)) { + chown($uid, $gid, $_[0]) || &failure(&text('chmod_echown', $!)); + } +} + diff --git a/file/config b/file/config new file mode 100644 index 000000000..ca12645bf --- /dev/null +++ b/file/config @@ -0,0 +1,5 @@ +hide_dot_files=0 +iconsize=0 +nocharset=0 +extract=1 +force_text=0 diff --git a/file/config-*-linux b/file/config-*-linux new file mode 100644 index 000000000..172d018c9 --- /dev/null +++ b/file/config-*-linux @@ -0,0 +1,16 @@ +xfs_acl=&has_command("getfacl") && &has_command("setfacl") +ext2_acl=&has_command("getfacl") && &has_command("setfacl") +ext3_acl=&has_command("getfacl") && &has_command("setfacl") +reiserfs_acl=&has_command("getfacl") && &has_command("setfacl") +xfs_attr=&has_command("attr") +ext2_attr=&has_command("attr") +ext3_attr=&has_command("attr") +ext2_ext=&has_command("lsattr") && &has_command("chattr") +ext3_ext=&has_command("lsattr") && &has_command("chattr") +getfacl=getfacl +setfacl=setfacl --set-file=- +hide_dot_files=0 +iconsize=0 +nocharset=0 +extract=1 +force_text=0 diff --git a/file/config-irix b/file/config-irix new file mode 100644 index 000000000..fe0330a71 --- /dev/null +++ b/file/config-irix @@ -0,0 +1,9 @@ +xfs_acl=&has_command("chacl") +xfs_attr=&has_command("attr") +getfacl=./irix-getfacl.pl +setfacl=./irix-setfacl.pl +hide_dot_files=0 +iconsize=0 +nocharset=0 +extract=1 +force_text=0 diff --git a/file/config-solaris b/file/config-solaris new file mode 100644 index 000000000..1f3020c15 --- /dev/null +++ b/file/config-solaris @@ -0,0 +1,10 @@ +ufs_acl=&has_command("getfacl") && &has_command("setfacl") +nfs_acl=&has_command("getfacl") && &has_command("setfacl") +lofs_acl=&has_command("getfacl") && &has_command("setfacl") +getfacl=getfacl +setfacl=setfacl -f - +hide_dot_files=0 +iconsize=0 +nocharset=0 +extract=1 +force_text=0 diff --git a/file/config.info b/file/config.info new file mode 100644 index 000000000..9d062a2e2 --- /dev/null +++ b/file/config.info @@ -0,0 +1,8 @@ +hide_dot_files=Show files starting with a dot?,1,0-Yes,1-No +iconsize=Size of buttons in toolbar,1,1-Small,0-Large with labels +nocharset=Attempt to use proper character set?,1,0-Yes,1-No +extract=Extract .class files from JAR?,1,1-Yes,0-No +width=Width for scaled images,3,Default (300 pixels) +fixed=Font size for text,3,Default (12 points) +small_fixed=Font size for buttons,3,Default (10 points) +force_text=Editor for HTML files,1,1-Text editor,0-HTML editor diff --git a/file/config.info.ca b/file/config.info.ca new file mode 100755 index 000000000..06bfec82c --- /dev/null +++ b/file/config.info.ca @@ -0,0 +1,8 @@ +hide_dot_files=Mostra els fitxers que comencen amb un punt,1,0-Sí,1-No +iconsize=Mida dels botons a la barra d'eines,1,1-Petita,0-Gran amb etiquetes +nocharset=Intenta fer servir el joc de caràcters apropiat,1,0-Sí,1-No +extract=Extreu els fitxers .class del JAR?,1,1-Sí,0-No +width=Amplada de les imatges escalades,3,Per defecte (300 píxels) +fixed=Mida de la tipografia del text,3,Per defecte (12 punts) +small_fixed=Mida de la tipografia dels botons,3,Per defecte (10 punts) +force_text=Editor de fitxers HTML,1,1-Editor de text,0-Editor HTML diff --git a/file/config.info.de b/file/config.info.de new file mode 100644 index 000000000..5b2fccec1 --- /dev/null +++ b/file/config.info.de @@ -0,0 +1,4 @@ +hide_dot_files=Zeige Dateien mit einem Punkt am Anfang?,1,0-Ja,1-Nein +iconsize=Größe der Buttons in der Toolbar,1,1-Klein,0-Groß mit Bildunterschrift +nocharset=Versuche passende Zeichensätze zu benutzen?,1,0-Ja,1-Nein +extract=.class-Dateien aus dem JAR extrahieren?,1,1-Ja,0-Nein diff --git a/file/config.info.es b/file/config.info.es new file mode 100644 index 000000000..8ae5a5e2c --- /dev/null +++ b/file/config.info.es @@ -0,0 +1,4 @@ +hide_dot_files=¿Mostrar archivos que comienzan con punto?,1,0-Sí,1-No +iconsize=Tamaño de botones en la barra de herramientas,1,1-Pequeño,0-Grande con etiquetas +nocharset=¿Intentar usar el juego de caracteres apropiado?,1,0-Sí,1-No +extract=¿Extraer archivos .class del JAR?,1,1-Sí,0-No diff --git a/file/config.info.fa b/file/config.info.fa new file mode 100644 index 000000000..6cef9a777 --- /dev/null +++ b/file/config.info.fa @@ -0,0 +1,6 @@ + +hide_dot_files=آيا پرونده‌هايي Ú©Ù‡ با ÙŠÚ© نقطه آغاز مي‌شوند نمايش داده شوند؟,1,0-بله,1-خير +iconsize=اندازه دگمه‌ها در نوار ابزار,1,1-Ú©ÙˆÚ†Ú©,0-بزرگ به همراه برچسبها +nocharset=آيا مي‌خواهيد از مجموعه کاراکترهاي خاص Ø§Ø³ØªÙØ§Ø¯Ù‡ کنيد؟,1,0-بله,1-خير +extract=آيا پرونده‌هاي .class از پرونده‌هاي JAR استخراج شوند؟,1,1-بله,0-خير + diff --git a/file/config.info.it b/file/config.info.it new file mode 100755 index 000000000..8c8f49c3f --- /dev/null +++ b/file/config.info.it @@ -0,0 +1,4 @@ +hide_dot_files=Visualizza i file che iniziano con un punto?,1,0-Si,1-No +iconsize=Dimensioni dei pulsanti nella barra degli strumenti,1,1-Piccoli,0-Grandi con etichette +nocharset=Tenta di usare il set di caratteri appropriato?,1,0-Si,1-No +extract=Estrarre i file .class dall'archivio JAR?,1,1-Si,0-No diff --git a/file/config.info.tr b/file/config.info.tr new file mode 100644 index 000000000..6dab86798 --- /dev/null +++ b/file/config.info.tr @@ -0,0 +1,4 @@ +hide_dot_files=Nokta ile baþlayan dosyalar gösterilsin mi?,1,0-Evet,1-Hayýr +iconsize=Araç çubuðundaki butonlarýn boyutu,1,1-Küçük,0-Geniþ ve etiketli +nocharset=Uygun karakter seti kullanýlmaya çalýþýlsýn mý?,1,0-Evet,1-Hayýr +extract=JAR'daki .class dosyalarý açýlsýn mý?,1,1-Evet,0-Hayýr diff --git a/file/copy.cgi b/file/copy.cgi new file mode 100755 index 000000000..f3a8ada85 --- /dev/null +++ b/file/copy.cgi @@ -0,0 +1,49 @@ +#!/usr/local/bin/perl +# copy.cgi +# Copy some file or directory + +require './file-lib.pl'; +$disallowed_buttons{'copy'} && &error($text{'ebutton'}); +&ReadParse(); +&webmin_log("copy", undef, $in{'from'}, \%in); +print "Content-type: text/plain\n\n"; +if ($access{'ro'} || !&can_access($in{'from'})) { + print &text('copy_efrom', $in{'from'}),"\n"; + exit; + } +if (!&can_access($in{'to'})) { + print &text('copy_eto', $in{'to'}),"\n"; + exit; + } +if (-l &unmake_chroot($in{'from'})) { + # Remake the link + &switch_acl_uid_and_chroot(); + &lock_file($in{'to'}); + if (!symlink(readlink($in{'from'}), $in{'to'})) { + print &text('copy_elink', $!),"\n"; + exit; + } + &unlock_file($in{'to'}); + $err = undef; + $info = $in{'to'}; + } +else { + &switch_acl_uid(); + ($ok, $err) = ©_source_dest(&unmake_chroot($in{'from'}), &unmake_chroot($in{'to'})); + $err = undef if ($ok); + $info = &unmake_chroot($in{'to'}); + } +if ($err) { + print $err,"\n"; + } +else { + print "\n"; + print &file_info_line($info),"\n"; + } + +sub split_dir +{ +$_[0] =~ /^(.*\/)([^\/]+)$/; +return ($1, $2); +} + diff --git a/file/defaultacl b/file/defaultacl new file mode 100644 index 000000000..f8f93ec25 --- /dev/null +++ b/file/defaultacl @@ -0,0 +1,33 @@ +noconfig=0 +user=0 +root=/ +follow=0 +umask=022 +log=0 +ro=0 +goto=1 +archive=1 +button_save=1 +button_edit=1 +button_info=1 +button_acl=1 +button_attr=1 +button_ext=1 +button_search=1 +button_delete=1 +button_new=1 +button_upload=1 +button_mkdir=1 +button_makelink=1 +button_rename=1 +button_sharing=1 +button_mount=1 +button_copy=1 +button_preview=1 +unarchive=1 +dostounix=1 +chroot=/ +noperms=0 +nousers=0 +filesystems=1 +contents=1 diff --git a/file/delete.cgi b/file/delete.cgi new file mode 100755 index 000000000..6efc36603 --- /dev/null +++ b/file/delete.cgi @@ -0,0 +1,26 @@ +#!/usr/local/bin/perl +# delete.cgi +# Delete some file or directory + +require './file-lib.pl'; +$disallowed_buttons{'delete'} && &error($text{'ebutton'}); +&ReadParse(); +&webmin_log("delete", undef, $in{'file'}, \%in); +print "Content-type: text/plain\n\n"; +if ($access{'ro'} || !&can_access($in{'file'})) { + print &text('delete_eaccess', $in{'file'}),"\n"; + exit; + } +if (-r &unmake_chroot($in{'file'}) && !-d &unmake_chroot($in{'file'})) { + &switch_acl_uid_and_chroot(); + $rv = unlink($in{'file'}); + if (!$rv) { print "$!\n"; } + else { print "\n"; } + } +else { + &switch_acl_uid(); + ($ok, $err) = &unlink_file(&unmake_chroot($in{'file'})); + if (!$ok) { print "$err\n"; } + else { print "\n"; } + } + diff --git a/file/edit_html.cgi b/file/edit_html.cgi new file mode 100755 index 000000000..8ccf55d3b --- /dev/null +++ b/file/edit_html.cgi @@ -0,0 +1,54 @@ +#!/usr/local/bin/perl +# Show an HTML editor window + +require './file-lib.pl'; +do '../ui-lib.pl'; +$disallowed_buttons{'edit'} && &error($text{'ebutton'}); +&ReadParse(); +&popup_header($in{'file'} ? $text{'html_title'} : $text{'html_title2'}, + undef, "onload='initEditor()'"); + +# Output HTMLarea init code +print < + _editor_url = "$gconfig{'webprefix'}/$module_name/xinha/"; + _editor_lang = "en"; + + + + +EOF + +# Read the file +&switch_acl_uid_and_chroot(); +$data = &read_file_contents($in{'file'}); + +# Output text area +print &ui_form_start("save_html.cgi", "form-data"); +if ($in{'file'}) { + # Editing existing file + print &ui_hidden("file", $in{'file'}),"\n"; + $pc = 95; + } +else { + # Creating new, so prompt for path + print $text{'edit_filename'}," ", + &ui_textbox("file", $in{'dir'}, 70),"
\n"; + $pc = 90; + } +print "\n"; +print &ui_submit($text{'html_save'}); +print &ui_form_end(); + +&popup_footer(); + + diff --git a/file/extract.cgi b/file/extract.cgi new file mode 100755 index 000000000..5570bb3d6 --- /dev/null +++ b/file/extract.cgi @@ -0,0 +1,21 @@ +#!/usr/local/bin/perl +# Extract a zip, tar, tar.gz or tar.bz file on the server + +require './file-lib.pl'; +&ReadParse(); +print "Content-type: text/plain\n\n"; + +# Check permissions +$disallowed_buttons{'upload'} && &error($text{'ebutton'}); +if (!&can_access($in{'file'})) { + print &text('extract_eperm', $in{'file'}),"\n"; + exit(0); + } + +# Go for it +&webmin_log("extract", undef, $in{'file'}); +$realfile = &unmake_chroot($in{'file'}); +&switch_acl_uid(); +$err = &extract_archive($in{'file'}, $in{'delete'}); +print $err,"\n"; + diff --git a/file/file-lib.pl b/file/file-lib.pl new file mode 100644 index 000000000..fdee1032c --- /dev/null +++ b/file/file-lib.pl @@ -0,0 +1,452 @@ +# file-lib.pl +# Common functions for file manager CGIs + +do '../web-lib.pl'; +&ReadParse(\%prein, 'GET'); +if ($prein{'trust'}) { + &open_trust_db(); + if ($trustdb{$prein{'trust'}}) { + $trust_unknown_referers = 1; + $trustdb{$prein{'trust'}} = time(); + } + dbmclose(%trustdb); + } +&init_config(); +do '../ui-lib.pl'; + +@file_buttons = ( "save", "preview", "edit", "info", "acl", "attr", "ext", "search", + "delete", "new", "upload", "mkdir", "makelink", + "rename", "sharing", "mount", "copy" ); + +if ($module_info{'usermin'}) { + # Usermin gets the allowed list from the module config + &switch_to_remote_user(); + &create_user_config_dirs(); + $hide_dot_files = $userconfig{'hide_dot_files'}; + $follow = int($config{'follow'}); + $real_home_dir = &simplify_path(&resolve_links($remote_user_info[7])); + $upload_max = $config{'max'}; + + if ($config{'home_only'} == 1) { + @allowed_roots = ( $real_home_dir, + split(/\s+/, $config{'root'}) ); + } + elsif ($config{'home_only'} == 2) { + @allowed_roots = split(/\s+/, $config{'root'}); + } + else { + @allowed_roots = ( "/" ); + } + @denied_roots = split(/\s+/, $config{'noroot'}); + + if ($config{'archive'} eq 'y') { + $archive = 1; + } + elsif ($config{'archive'} eq 'n') { + $archive = 0; + } + else { + $archive = 2; + $archmax = $config{'archive'}; + } + $unarchive = 1; + $dostounix = 1; + $chroot = "/"; + + @disallowed_buttons = ( ); + foreach $k (keys %config) { + if ($k =~ /^button_(.*)/ && $config{$k} == 0) { + push(@disallowed_buttons, $1); + } + } + $canperms = 1; + $canusers = 1; + $contents = 1; + } +else { + # Webmin gets the list of allowed directories from the ACL + %access = &get_module_acl(); + $hide_dot_files = $config{'hide_dot_files'}; + $follow = int($access{'follow'}); + $upload_max = $access{'max'}; + + @allowed_roots = split(/\s+/, $access{'root'}); + if ($access{'home'}) { + local @u = getpwnam($remote_user); + if (@u) { + push(@allowed_roots, + &simplify_path(&resolve_links($u[7]))); + } + } + @denied_roots = split(/\s+/, $access{'noroot'}); + + $archive = $access{'archive'}; + $archmax = $access{'archmax'}; + $unarchive = $access{'unarchive'}; + $dostounix = $access{'dostounix'}; + $chroot = $access{'chroot'}; + $access{'button_search'} = 0 if (!&has_command("find")); + $access{'button_makelink'} = 0 if (!&supports_symlinks()); + $access{'button_info'} = 0 if (!&supports_users()); + + @disallowed_buttons = grep { !$access{'button_'.$_} } @file_buttons; + if (&is_readonly_mode()) { + # Force read-only mode for file manager if global readonly + # is in effect. + $access{'ro'} = 1; + } + $canperms = $access{'noperms'} ? 0 : 1; + $canusers = $access{'nousers'} ? 0 : 1; + $contents = $access{'contents'}; + } +%disallowed_buttons = map { $_, 1 } @disallowed_buttons; + +$icon_map = ( "c", 1, "txt", 1, + "pl", 1, "cgi", 1, + "html", 1, "htm", 1, + "gif", 2, "jpg", 2, + "tar", 3 + ); + +# file_info_line(path, [displaypath]) +# Returns a line of text containing encoded details of some file +sub file_info_line +{ +local @st; +local $islink = (-l $_[0]); +local $f = $islink && &must_follow($_[0]); +local @st = $f ? stat($_[0]) : lstat($_[0]); +local $ext = $_[0] =~ /\S+\.([^\.\/]+)$/ ? $1 : undef; +local $dp = $_[1] || $_[0]; +$dp =~ s/\\/\\\\/g; +$dp =~ s/\t/\\t/g; +return undef if ($dp =~ /\r|\n/); +if (!@st) { + # Work around a broken stat function on large files on redhat 7.x + &has_command("stat") || return undef; + local $out = `stat -t '$_[0]'`; + return undef if ($?); + $out =~ /^(.*)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/; + local $type = defined($icon_map{$ext}) ? $icon_map{$ext} : 4; + local $user = defined(%uid_to_user) ? $uid_to_user{$5} : getpwuid($5); + $user = $5 if (!$user); + local $group = defined(%gid_to_group) ? $gid_to_group{$6} :getgrgid($6); + $group = $6 if (!$group); + local $size = $2; + local $mtime = $13; + local $mode = hex($4); + return sprintf ("%s\t%u\t%s\t%s\t%u\t%u\t%u\t%s", + $dp, $type, $user, $group, $size, $mode, $mtime, undef); + } +local $type = $islink && !$f ? 5 : + -d _ ? 0 : + -b _ ? 6 : + -c _ ? 6 : + -p _ ? 7 : + -S _ ? 7 : defined($icon_map{$ext}) ? $icon_map{$ext} : 4; +local $user = !&supports_users() ? "root" : + defined(%uid_to_user) ? $uid_to_user{$st[4]} : getpwuid($st[4]); +$user = $st[4] if (!$user); +local $group = !&supports_users() ? "root" : + defined(%gid_to_group) ? $gid_to_group{$st[5]} :getgrgid($st[5]); +$group = $st[5] if (!$group); +local $rl = readlink($_[0]); +return join("\t", $dp, $type, + $user, $group, + $st[7] < 0 ? 2**32+$st[7] : $st[7], $st[2], + $st[9], $f ? "" : $islink && !$rl ? "???" : $rl); +} + +# switch_acl_uid() +sub switch_acl_uid +{ +if (!$module_info{'usermin'} && $access{'uid'}) { + local @u = $access{'uid'} < 0 ? getpwnam($remote_user) + : getpwuid($access{'uid'}); + @u || &error($text{'switch_euser'}); + $( = $u[3]; $) = "$u[3] ".join(" ", $u[3], &other_groups($u[0])); + ($>, $<) = ($u[2], $u[2]); + umask(oct($access{'umask'})); + } +} + +# switch_acl_uid_and_chroot() +# Combines the switch_acl_uid and go_chroot functions +sub switch_acl_uid_and_chroot +{ +if (!$module_info{'usermin'} && $access{'uid'}) { + local @u = $access{'uid'} < 0 ? getpwnam($remote_user) + : getpwuid($access{'uid'}); + @u || &error($text{'switch_euser'}); + local @other = &other_groups($u[0]); + &go_chroot(); + $( = $u[3]; $) = "$u[3] ".join(" ", $u[3], @other); + ($>, $<) = ($u[2], $u[2]); + umask(oct($access{'umask'})); + } +else { + &go_chroot(); + } +} + +# can_access(file) +# Returns 1 if some file can be edited/deleted +sub can_access +{ +return &under_root_dir($_[0], \@allowed_roots) && + ($_[0] eq "/" || !&under_root_dir($_[0], \@denied_roots)); +} + +# under_root_dir(file, &roots) +# Returns 1 if some file is under one of the given roots +sub under_root_dir +{ +local @f = grep { $_ ne '' } split(/\//, $_[0]); +local $r; +DIR: foreach $r (@{$_[1]}) { + return 1 if ($r eq '/' || $_[0] eq '/' || $_[0] eq $r); + local @a = grep { $_ ne '' } split(/\//, $r); + local $i; + for($i=0; $i<@a; $i++) { + next DIR if ($a[$i] ne $f[$i]); + } + return 1; + } +return 0; +} + +# can_list(dir) +# Returns 1 if some directory can be listed. Parent directories of allowed +# directories are included as well. +sub can_list +{ +return &under_root_dir_or_parent($_[0], \@allowed_roots) && + ($_[0] eq "/" || !&under_root_dir($_[0], \@denied_roots)); +} + +# under_root_dir_or_parent(file, &roots) +# Returns 1 if some file is under one of the given roots, or their parents +sub under_root_dir_or_parent +{ +local @f = grep { $_ ne '' } split(/\//, $_[0]); +DIR: foreach $r (@allowed_roots) { + return 1 if ($r eq '/' || $_[0] eq '/' || $_[0] eq $r); + local @a = grep { $_ ne '' } split(/\//, $r); + local $i; + for($i=0; $i<@a && $i<@f; $i++) { + next DIR if ($a[$i] ne $f[$i]); + } + return 1; + } +return 0; +} + +# accessible_subdir(dir) +# Returns the path to a dir under the given one that we can access +sub accessible_subdir +{ +local ($r, @rv); +foreach $r (@allowed_roots) { + if ($r =~ /^(\Q$_[0]\E\/[^\/]+)/) { + push(@rv, $1); + } + } +return @rv; +} + +sub open_trust_db +{ +local $trust = "$ENV{'WEBMIN_CONFIG'}/file/trust"; +eval "use SDBM_File"; +dbmopen(%trustdb, $trust, 0700); +eval { $trustdb{'1111111111'} = 'foo bar' }; +if ($@) { + dbmclose(%trustdb); + eval "use NDBM_File"; + dbmopen(%trustdb, $trust, 0700); + } +} + +# must_follow(path) +# For symlinks, returns 1 if a link should be follow, 0 if not +sub must_follow +{ +if ($follow == 1) { + return 1; + } +elsif ($follow == 0) { + return 0; + } +else { + local @s = stat($_[0]); + local @l = lstat($_[0]); + @st = ($s[4] == $l[4] ? @s : @l); + return $s[4] == $l[4]; + } +} + +# extract_archive(path, delete) +# Called by upload to extract some zip or tar.gz file. Returns undef if something +# was actually done, an error message otherwise. +sub extract_archive +{ +local $out; +$_[0] =~ /^(\S*\/)/ || return 0; +local $dir = $1; +local $qdir = quotemeta($dir); +local $qpath = quotemeta($_[0]); +if ($_[0] =~ /\.zip$/i) { + # Extract zip file + return &text('zip_ecmd', "unzip") if (!&has_command("unzip")); + $out = `(cd $qdir; unzip -o $qpath) 2>&1 &1 &1`; + if ($?) { + return &text('zip_euntar2', $out); + } + } +elsif ($_[0] =~ /\.gz$/i) { + # Uncompress gzipped file + return &text('zip_ecmd', "gunzip") if (!&has_command("gunzip")); + local $final = $_[0]; + $final =~ s/\.gz$//; + local $qfinal = quotemeta($final); + $out = `(cd $qdir; gunzip -c $qpath >$qfinal) 2>&1`; + if ($?) { + return &text('zip_euntar2', $out); + } + } +else { + return $text{'zip_ename'}; + } +if ($_[1]) { + unlink($_[0]); + } +return undef; +} + +# post_upload(path, dir, unzip) +sub post_upload +{ +local ($path, $dir, $zip) = @_; +if ($unarchive == 2) { + $zip = $path =~ /\.(zip|tgz|tar|tar\.gz)$/i ? 1 : 0; + } +elsif ($unarchive == 0) { + $zip = 0; + } +local $refresh = $path; +local $err; +if ($zip) { + $err = &extract_archive($path, $zip-1); + if (!$err) { + # Refresh whole dir + $refresh = $in{'dir'}; + } + } +$info = &file_info_line(&unmake_chroot($refresh), $refresh); +print "\n"; +} + +sub go_chroot +{ +if ($chroot ne "/" && $chroot ne "") { + # First build hash of users and groups, which will not be accessible + # after a chroot + local (@u, @g); + setpwent(); + while(@u = getpwent()) { + $uid_to_user{$u[2]} = $u[0] if (!defined($uid_to_user{$u[2]})); + $user_to_uid{$u[0]} = $u[2] if (!defined($user_to_uid{$u[0]})); + } + endpwent(); + setgrent(); + while(@g = getgrent()) { + $gid_to_group{$g[2]} = $g[0] if(!defined($gid_to_group{$g[2]})); + $group_to_gid{$g[0]} = $g[2] if(!defined($group_to_gid{$g[0]})); + } + endgrent(); + chroot($chroot) || die("chroot to $chroot failed"); + } +} + +# make_chroot(dir) +# Converts some real directory to the chroot form +sub make_chroot +{ +if ($chroot eq "/") { + return $_[0]; + } +elsif ($_[0] eq $chroot) { + return "/"; + } +else { + local $rv = $_[0]; + if ($rv =~ /^$chroot\//) { + $rv =~ s/^$chroot//; + return $rv; + } + else { + return undef; + } + } +} + +# unmake_chroot(dir) +# Converts some chroot'd directory to the real form +sub unmake_chroot +{ +if ($chroot eq "/") { + return $_[0]; + } +elsif ($_[0] eq "/") { + return $chroot; + } +else { + return $chroot.$_[0]; + } +} + +# print_content_type() +# Prints the content-type header, with a charset +sub print_content_type +{ +if ($userconfig{'nocharset'} || $config{'nocharset'}) { + # Never try to use charset + print "Content-type: text/plain\n\n"; + } +else { + $charset = &get_charset(); + print "Content-type: text/plain; charset=$charset\n\n"; + } +} + + +1; + diff --git a/file/filesystems.cgi b/file/filesystems.cgi new file mode 100755 index 000000000..cdf8cd056 --- /dev/null +++ b/file/filesystems.cgi @@ -0,0 +1,64 @@ +#!/usr/local/bin/perl +# filesystems.cgi +# List all filesystems and their types + +require './file-lib.pl'; +print "Content-type: text/plain\n\n"; +if (!&foreign_check("mount") || !$access{'filesystems'}) { + print "0\n"; + exit; + } +&foreign_require("mount", "mount-lib.pl"); +@mtab = &mount::list_mounted(); +%mtab = map { $_->[0], $_ } @mtab; +@fstab = &mount::list_mounts(); +%fstab = map { $_->[0], $_ } @fstab; +@mounts = ( @fstab, grep { !$fstab{$_->[0]} } @mtab ); + +print "1\n"; +foreach $m (sort { length($a->[0]) <=> length($b->[0]) } @mounts) { + next if ($m->[0] !~ /^\//); + local @supp = @{$support{$m->[2]}}; + if (!@supp) { + # Work out what this filesystem supports + @supp = ( eval $config{$m->[2]."_acl"} ? 1 : 0, + eval $config{$m->[2]."_attr"} ? 1 : 0, + eval $config{$m->[2]."_ext"} ? 1 : 0 ); + $support{$m->[2]} = \@supp; + } + + # Check if the filesystem really does support attrs and ACLs + local @supp2 = @supp; + if ($mtab{$m->[0]}) { + if ($supp2[0]) { + local $out = `$config{'getfacl'} '$m->[0]' 2>/dev/null`; + if ($?) { + $supp2[0] = 0; + } + else { + local $aclcount; + foreach $l (split(/\n/, $out)) { + $l =~ s/#.*$//; + $l =~ s/\s+$//; + $aclcount++ if ($l =~ /\S/); + } + $supp2[0] = 0 if (!$aclcount); + } + } + if ($supp2[1]) { + local $out = `attr -l '$m->[0]' 2>/dev/null`; + if ($?) { + $supp2[1] = 0; + } + } + } + + $m->[1] =~ s/\\/\//g; + $chrooted = &make_chroot($m->[0]); + if ($chrooted) { + print join(" ", $chrooted, @$m[1..3], @supp2, + $mtab{$m->[0]} ? 1 : 0, + $fstab{$m->[0]} ? 1 : 0),"\n"; + } + } + diff --git a/file/getattrs.cgi b/file/getattrs.cgi new file mode 100755 index 000000000..e926f802a --- /dev/null +++ b/file/getattrs.cgi @@ -0,0 +1,36 @@ +#!/usr/local/bin/perl +# getattrs.cgi +# Returns a list in URL-encode name=value format of attributes on some file + +require './file-lib.pl'; +&ReadParse(); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +if (!&can_access($in{'file'})) { + print $text{'facl_eaccess'},"\n"; + } +else { + $out = `attr -l '$in{'file'}' 2>&1`; + if ($?) { + print $out,"\n"; + } + else { + foreach $l (split(/[\r\n]+/, $out)) { + if ($l =~ /Attribute\s+"(.*)"/i) { + # Get the valid for this attribute + local $name = $1; + $got = `attr -g '$name' '$in{'file'}' 2>&1`; + if ($? || $got !~ /^(.*)\n([\0-\377]*)\n$/) { + print $got,"\n"; + exit; + } + push(@rv, [ $name, $2 ] ); + } + } + print "\n"; + foreach $r (@rv) { + print &urlize($r->[0]),"=",&urlize($r->[1]),"\n"; + } + } + } + diff --git a/file/getext.cgi b/file/getext.cgi new file mode 100755 index 000000000..ab13940a9 --- /dev/null +++ b/file/getext.cgi @@ -0,0 +1,25 @@ +#!/usr/local/bin/perl +# getext.cgi +# Returns a string of EXT attributes for some file + +require './file-lib.pl'; +&ReadParse(); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +if (!&can_access($in{'file'})) { + print $text{'facl_eaccess'},"\n"; + } +else { + $out = `lsattr -d '$in{'file'}' 2>&1`; + $out =~ s/^lsattr.*\n//; + if ($? || $out !~ /^(\S+)\s/) { + print $out,"\n"; + } + else { + print "\n"; + @a = split(//, $1); + print join("", grep { $_ ne '-' } @a),"\n"; + } + } + + diff --git a/file/getext.cgi.bak b/file/getext.cgi.bak new file mode 100755 index 000000000..b78b9f6f0 --- /dev/null +++ b/file/getext.cgi.bak @@ -0,0 +1,24 @@ +#!/usr/local/bin/perl +# getext.cgi +# Returns a string of EXT attributes for some file + +require './file-lib.pl'; +&ReadParse(); +&switch_acl_uid(); +print "Content-type: text/plain\n\n"; +if (!&can_access($in{'file'})) { + print $text{'facl_eaccess'},"\n"; + } +else { + $out = `lsattr -d '$in{'file'}' 2>&1`; + if ($? || $out !~ /^(\S+)\s/) { + print $out,"\n"; + } + else { + print "\n"; + @a = split(//, $1); + print join("", grep { $_ ne '-' } @a),"\n"; + } + } + + diff --git a/file/getfacl.cgi b/file/getfacl.cgi new file mode 100755 index 000000000..4adf7e533 --- /dev/null +++ b/file/getfacl.cgi @@ -0,0 +1,45 @@ +#!/usr/local/bin/perl +# getfacl.cgi +# Gets the ACLs for some file + +require './file-lib.pl'; +&ReadParse(); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +if (!&can_access($in{'file'})) { + print $text{'facl_eaccess'},"\n"; + } +else { + $getfacl = $config{'getfacl'}; + if ($getfacl =~ /^\.\//) { + $getfacl =~ s/^\./$module_root_directory/; + } + chdir("/"); + if ($in{'file'} eq '/') { + $in{'file'} = '.'; + } + else { + $in{'file'} =~ s/^\///; + } + $out = `$getfacl '$in{'file'}' 2>&1`; + if ($?) { + print $out,"\n"; + } + else { + foreach $l (split(/\n/, $out)) { + $l =~ s/#.*$//; + $l =~ s/\s+$//; + push(@rv, $l) if ($l =~ /\S/); + } + if (!@rv) { + print "Filesystem does not support ACLs\n"; + } + else { + print "\n"; + foreach $l (@rv) { + print $l,"\n"; + } + } + } + } + diff --git a/file/images/.xvpics/preview.gif b/file/images/.xvpics/preview.gif new file mode 100644 index 0000000000000000000000000000000000000000..ec6e9111261e03d0a87b24f82a7b5c99e3edf171 GIT binary patch literal 641 zcmWGAS1>j<;!^hXb@%jh^S3fGsW3882y%B)&@eGHQb?*SNiEjoQg-!oiT8JlclP)7 zb@dAg<^rk#AyZSX{|K;c8-k5sfkY=^$iUR1%D_ZHx)CzSq6isuQK(EV6B8pAI5C$Q z4R}og3FKmk|NRG&z!bmvM;$1RX%5H~H1Ww0F(h&C+dz)@|LtH2Zy*UZpOJx)SuNKy zR}~~N$rEM{BLjnqr)Mq@sWCG%00G!uAzc{(7NBA;pDd3&9YGx#2_4Rfxk54)5;8Ut zGO|9V0j7o!wxvvOu8fTg2uRAvSjb3#nIMt8Tp$xj1BGD#EZGMV2g?AtvOpHlOppLr eJ&1t-HXtUFIG7I-1DV>pZBi~acpDTw*Z=@=1Mltt literal 0 HcmV?d00001 diff --git a/file/images/Thumbs.db b/file/images/Thumbs.db new file mode 100755 index 0000000000000000000000000000000000000000..1bfc2c2c0c3b244d079d7a16d8030f20e6e5e586 GIT binary patch literal 38400 zcmeFZ1z23k+Nj$|Ai*IJAZYO5kl+?Vun-_XaJOK=-2(&-PJjdm1Pczq-QC^Y-Q7?1 z%;Z0_=j?y~vuE~mpXc6ts{8G)d#!JktorKfsA(0oVbY06qX0fE&OA;05plo&y8` z&j5k|ApkV47eERFL;#`yaR78Xl>e^=S%^7!*?_tbhL{0q1#twW{`27h>a>5=gx2@p3GfhDnBUjUpN*>!>byXJ+Ronz(DY$I1kf@;^YLfm zg0`hF=s_Sr?e_14zfyi^d;RcR`Jvf>eud^A>dSw&f2dD@*5}Xm4{ZZK+dtGVKz+c^ z_7B|$ZU0c80QCV-Ujp?3ziYPkiptaQU0qTp4@ z3KOI5hD6&J=AV4p8ew_Rh7YeDpI^P$w;W0>;$A8flYKU8;8m_AdQp2K{O|9;*(5mW5L7{;w z-`2?AyM@Ttj_`7yK8$QH|7wQM+Ypcjc?^dH*>RSU+TV$^&R%1lnAkc*9UzIDvktpz zOLI7VSw3QeXKHHa=(CRAW5LySqbFD8oT|3Tjly11$=hh-yUIzpw}=KpA) zKITVdG0ldcUz=mcBK%?~C;1v5UB{!d#|vUE5>(lY+b_98by$h5%IZ0n(C%KKzdZ1B zLvjcw!D`P!u9OW;rlCJlSv0<*~1w#B#w!Q}ANNW(Bwy++ZQt~k&F;vVxs|VWjR_qBHXl;FC!m6zDvyl=1`xvTGI(*_3w-D~|4up~-vCp1Ug_s-S)aU)0x8uMv|9ALlzuv%j zq4sMFKK@<%J-vXw&Tq=TxRKT4Hq-E;*sP-rBwE_8peCP+NLL2lLeRMT)n3(NYJFVz zM2x^~<74!?tl|)%|1z0+y2ag>$S`*zU^_jRXMwPW?W05y|6Nb6Jd|5VEt(Eqh|w)1 z{sUUsy0GOe#`1o)ihAPS3(Rf@gX=SEj3#I4t0Pj|)|Ygv?cdKn-a?RlX2cniZXq99 zJNea=ea&VmYbVBU^6cG50?rSNYRGOO4fCbp5{9+&EC;>O540ys+s#i(+_R=99*SC<3_FIT<4$iJ78r7Kx(@DY=wZgto2;G*O@`u&k z-CKx)^d%_5M!-&bE|sS5Yl;1r=!9QI1fPn%Ryo%-y6z9zH4tcy|D<@IsWF}MEEO?W zDw#Bff`-8*zvyPI^|UZyq4yIsE2-4F7`vIn|{)HN`r; z!a-Z9>@voWHmSzz3Go4?oaHdH)Q(5mpY&V+ai3Mta=S}wcm8K29 z&L4P`BrNJFaavfG`R3jIqTJS$MblpT?~o> zwv0;mLpUT#{U;{6vi0Ly{p5AjYNYIFZKn zRXxwbT0Ri3wBRsK255)BF6*O)ks{@s5)B!8lF}UaifmujvkJabA7>^2dC{jY?i^wZ%RQ zeJ8KwVi>?h+OrP@mB6n z%`$S*EBKjPjc1K}j!B+h z4SMO|_exEyb*yvCr%5!sx{PP|&_2`O3DEv0DDp33M$papQ~h7)7;p@F5D3uz+TRI( zrT_aFB-jD{vj73wSNuBxnm)A84DB!f+44ijJe$9jAKFj-JK?XCA384n0PXODFoDa} zz8+}6mSek*TYqw4GitJ+PNvC7^+}j$OMe!Q=lLoZA4}j$ac&LS8UL(Q%(ja}io|l$ zfM0TTVC9^Fq1r0-cb2$*W$@Q^rJd!l*jTu6@inM8#mzBbN~m%b31Nkcy1aGHL}1=M zkjT z!RMv;RT7V+B7QOlo3pe!r;_N0=4B4Aq87^|`Ssy8L|XK1LzjA?ujtimu96w+{F#h%U!PLsgy+~tbVgc{11x#x1V@jYEpQ>7n<~D9=Ntq9R9E#(Qh_WxFg1#(eB#zNF$Qk5>Aqt~Z z(U-#8+qsW?4B&|0QS4BOVQ6=mAWAPu5S7mxVZfHcGI2|8qn03_=RITKF{otVZE!Tg5Y@ z-ovw?iihyW=19MJ@qq$llC+QobsO8+k6+d!N`b_4q_Ur z{MqLufUk+<@v}}kEROr9BK@U-d1$Tl+{Z<#+b)ss+1u#5gq($m7tlX_(~tBg@V`tp zoUH$2w;Jji{#5u`|FgiKL0xJukpFJ~dv?D!*hPKsbOBz)ClPnj1=q2Jb1~rQG_ol{ z%{y3%wzo)4S&vCE1RvKfCJ>%g&hIweEk=FLRC306_|CEw+o)~ z1zqOoODXg%bGn{O4XNq!7M4*vH}$gV%H2?BiV0sUty@@nwieB1W9?Xa=mvP@uf1;} zcWaVwA@`WVu7j3IiXG1ZLkaK!mght2HD{8J-6n$O1=V73R$Z4Si|Xq zr3fksnzu0Wf}~htRso>8gl&GUu7@{W(CRvHYxgQOvyMBSPKdPwX&1(ufa=2et-4Gu zS)tX{eo2KkUEX62s>^hIx^kt*@z?4iXr4uPBb7*7Ke#Tfw~tK;7uS>QD;X?ZZXoY-f6Q4Wm))DGGM?tM^d?%ayf9o`#RgLdm(1!F!Ceb}nM(MA_pPhr z85s)L@onTf9jI;iaDOtS{*!v=J3weH%cMExM?Y@tLenlmF3+b!Px`oUU&Rz)% z0W1Ghd&IPH3pqpNxP@Q}TSdnN#l?j4xI7D!6CK+5Ug1N-_@uDgu?x#I0zOGa?b}p} zqn(KH;7iIwrBUY9<0OdoI0 zATMpYhx61`YQrR5$8(W~cQme^YMl8cWoid%hiH_@{ZI6YqM2tQk|TuU>l0TMuEUWl z?aJ9J6RYf$YZ52rE%1SLCqP4xoaJI6AT4(Hf=K%oQim^a zwk_9vdX4r2oDr0SE4z%9%Nt)M_dNvZ8y?}8B^s0xlisH2Lg5V;$~y6s#q#dt+X0B5 zTVyF`;Y+a=4IA%=N?_=#GGV1|H$=|-7p{Z<`umr!;mEBN9Y`Dk3m3g&BDZZjYf+6xoqBzWK5kpR)hwNCeaM;w z^Y|G`P`mn^>jGM;`T3Yv*v_`9e(hs5LOOKdyiAUPJT|V zqzrchwOdF(&tUEDFfbLuOwI98fg`D--OFQ>TSzNy^oecn_5Es|n`@O@$bQGaf63t= z{?~rCU+8rQX!}+A3;$oIA?$C%g@b9@L?)v`1NYDqkMkT3-x^UUEd+irEjPN`3%MXs z`6o&V8$lm96jf}C8#n9)m;H%6Qv_cg=E(HcfnocDy>Vc2QDJ!ljM7VGa zSANMVmcK}>TDq6c_eO4-k-?n4z9wETN;WW@-k~*$^B>N}zyAX|{(#;$fS$)cJN|hE zbZx+Sh6b)*#b5sXE8`ypklNO7=`;Uw$MG*G55~Q)FwlD>(0e+6w){Fk_viSJMh$Tx3RUxUk6>T9etc%R%?erCZ2a#()2VCZ(b{x>w?(eZ;O8h4v3Z%QFMm@Qo2o zK1PNa=^B(UpE}Fd`8XtrEM=FYvQkI>Ggc7-m{t-W3z|%(@9k(ARLN;|+VNr?Vg+Oc zToiQvq*pc|@f98NaLaU?? z$bYy0aB3Ul$blWem-t0Qk91G$X1Cb6qMJ81K$y6%E14C;fx_K>qI&vmyks+3h~ZnA zFL!yd1S+>R1^Nc1i3j#YiwZKDKE#WWOrIuxkLOEW2r<%^^S{R%Dp0vAB+2V6(M&wh zk%ookNa}7s6QI0n%AoH<_c2{N{Ou%`IH}yDMQ_B6C7a{a_>+MVC7rSgAABm)e2VZp zti+tJo#I8MRsP#UlCq@D4Qx}?h0^Iw-?m6|baB2;^l#_O4_qyIBA-@TSTVquIP`$M zP?tJ(g^=cT(^C9ci}fUa=HTS`v=Q#>4P*l4{D|&DG;A6jE9rN-T-$;DYL&CbA6J-s z^%LX^P(x3%E{k1vJqVk8Ld}r4nOpcR|L%Tar2=l-mG2?Bnp3wB6LJrt;{Hq8v|VwT zhjcp6lySfIe$DDN&eyZq?3N@^t1Z775ryS3Nj{O6o(WHSs?hYlfQcu8M=^d_r)_;S zCWgP<-TFE^7~XDFbSpEVn(~EVjz5f^hCRPs9$$LSW)817Bk?0^qeuLvMekW7Mmf#6 z=SGf4;whrhG0KZV6WAx7;frs^aS&OUIBiN}N%;DyO^8Xynv$ZV9QP0empzsDS5cOK zt=d-09WJg0!6VT$&Zm>0%|v#@U6mE5dk+VR+#$t4=Ws#my#@$wXeGEt@?fW$t)f-zzBW{*QM5i}L{=KkfhjjvxQ;`0@YG zW$8Xb4zh?ORH@*)pAV?3u}w<66F-7W#&b~ z@XjMxR^ejg&lD|YS~skyigh?w5&BRf=Zu7>Z3Gwcv-V+s-Sm!GJHfVl}~ zwx}XJ%3p0IU$7=)xQ#QZxmW+$ZNjFkf4~0;g9PmMm+QTt1Nzgi|0`(=cJf1w9fT); zKmGrjYxHOPzfK_Cq2K!dPyc@UFhA!+{@L_>K>Dh`rO);sNFN`>2c2X2XVVV_y6C^% z|Cu^-J5GxcGO}asYNCHReW_iZQ<;E1Q*W_8kXXsrCHjNW2kh>R9I! zjC?x#ZJ(8ZV(RyK)P=T}YGMN-A|rAK;oO7@W0xPx3GwKEB$^{m7q_rFPdei9{i+k~VnDRp1*{bykxG*&r`n zQg4>=C@g`Y?{JD)M{*^J^xC~V<9%GeqF$u6!i|aII-iM0$3_GN={v217qBL)7w4rn zxV?Vh+A-J7MC;W{_hEPaopavoi(5#q)MYJNoMLzFUX6<=xMbCPG9s`bcawF=WZ%AQ zFnZ%;KYeDiP-A)v@jhG-IFoWO$-jkQB^+yxJJ(3l@z)*>*6cQ>VJi-35bZzsvXJut zRaLy~zUoW@qR&q5&rw||=VvjE;%WP}hKpi7*oua|NJsz0VK}W0 ztMk%V)D=nU#{6Ve0e5}I7|8rx%BrRL#CN0*V9Rz1uO5Rd-KTFPazvXH!vrxV?|1-P z@C0}PJ^;J{(D`D%K>7jv0Re!IfIvVHAQ%t=fa-+-84id5d;&xQq5#o=&www07(gr_ z4gftS9>@g1H$WmF36Km(0i*)H1JVHLfDAw;APbNU$N}U6@&G>o`G5jIA)p9Q3@8DV z0?Gj8fC@k*pbAh8r~%Xh>HzhC20$aA3D68^0ki_z0MPt)0NDxX0(1j<0KI@dKtEsr z;0pZN5Rk)w5x^*53@{Fu089d=0MmdOz${=60F8eE$VI>sU>UFiSOq}$tpm9M*aU0= zwgEeUUBDh-A8-IT1RMdN$D9Cp3OECt111X@J_lm`pPyvNk#0&PfiD@39~!JVzRPOx3u*bgJd?}-rv zWP5Yyjs}i)aR>VnMF%q;-T5*>!$w_z70Q95jAYiDhoAS^mI#f9iBNqF`AN}hV`)7~ zQZw2D?CB7VC&I3LbLJpL591KqG>3o#B}xK=qA1FPMFPw5h_{C$Ohi;QI<++UZeRwR;Oi zUQZq#B)mFlZ(%N`XWMBKo3Pkwd$}Bepr$*+EokBI}xk?yr?9$a}U0;V8LfEgraH5I7>ZSsi6)u|k6}zuiR?UGV+E@? zEZBBL>WQjQ`J=RYa+Q?Q^$lUj^Sh+|G9{64wV$PTnH$}s@wCvay-InPZr&!F(jvMu zC(LO3+(Hj+m7%^cgWx<&r!3@AD*XH>ao!`t8c=%aR}tIFS07d@fZ8JC{<`ec+) zACdaob}9P-k+f)SQH1ah+^A?paiS#zTR+uDmxGK>iy@z^oSl`#Uddqv`Avq$-wY}K zNi+Oue{gWW+TY<{u)m!Bn9&yMW`ajC*GH8yfFgz3_!wzKc#TWx>+z%$Px$a<|txTBzZLluKhsMb_0TXEZP~&-SDi&GzmM zLGxSNZo5W#i6<3!wz%QUX983+2!n&jfd&~H*6#Cnsw(yxB8P3i(!Hipn`lfg3QgQx z-k!Hx3}oa!=96Z=L9Q5js?ECL)Di~z$yMwY8w?bfhY3vP$fblBWgCus;%e@7&b^p5 zrS_?*<00aOcXCb5Fv4@iA=I{9h@1;b!``nvb2)@z%jTqWa zZ7lJO^}|+YJ;FJBa<0jQlV~e&rzkzG_T$r{zFaoxBH@qDn#Gd$EQoN;EJR;B>y8FQ zNn;!JJGi;3b$N1{)(q0?|JYz(g}3c}=d>>;vEa(jgw~z?1zQ-kbV5($9qapY(h!ZY z*WpxzaBhk!w`S>*%&tBb7}7nz8T<|r-qIpJWw_h5Re6!aBv z&ZInO#^hq1y^dj|60pgEOCfyOh1wz)z4g*`LX-mK{$N^H#YtX{u~SLLTv<_8WOevb zHs@;sDxK!Tz^#^nyGIoJgDbNb4k4Pu=C%T`qNzQl(iRGYWLa1S^lEViX6&J&i4=>8 zno7-Bf=EJG-ob20ncNUg*qZ173QuewN@PM~oHsTQi#x6)*y8YyQC>da9HLEMgUliQ zm0L+a+fO;tuk9xTNG;&Iv3}>ju^?Lidj3luyhD*gt4RFWcr2Ic&QfvIeX8s1&$}KQ zJc>CE;b#tY%Dh*O`(RS;xtki?U<@sT<^q2@uONHud>$J6 zk0^z(8I9Trczu~st4tJ^?xNM%@BbMUn%ovXJ+(8vP4|J7U|eky=RwQ+R}u}K2KUz7U*x7m8UfvWN`;$IFHZT4_&tW zNE`znFUI|7aoAK7PG~{q$?8RVeqk+2T#L_d{xuA4m&KdcIts6s$S|{a-|S*zQY=Jb z@1Qe7a|8DQ)r{)53<9B2E*INJKAgv!@(Bym$HOII#L@H1(XzEejP#OKrGm2TzGhZu z8$u|SnlZcF1Y){H9F-Mr?saR<)y8EOn=d! z=2%zuN|z8KO&t%DgMR-?jF@29Hiuu5A=OpjmHKlkti_%?4Z3)9u#UWYsD=&+3(xju zvT}?Lj7;g)FLX9AnWKp<81Lh?LhiS(zBkOaT+HgW5CtP!!$PCS8Ahx#1eFqXlS#;B z=Xy-))z*Ut{|SwxG67_b_Cym6%#ovBwB95m?#R)x7#WAR5^a;q2=X_$@Mee*V#|U5 ztXja4%s!8NftM{rQzo3; z!Uc7AVG|+viWgz1%cqW6WKjw&2>fyV8tO?(XGyaQh(S+H;hLgicv)sYwgfMX>(8#D zj>8|-)#Wkv)4Rx+@58mkuzM^>ND|}iHZO`=zAM;0^x5)s($Z3lHjLt@DLwO8lq7hz zPx(Cr#eQKwxvWIl{=CsnkdK*}CdbsiarE%4Py@@+x<1=MJt^Fw!`meN3{P$KTepcx z4RLKkbIe{uXFRHI!!~wA%Nsg%(Yl6JJ_Hk0^}XY(8~V`?@oIY}#JGkj@vMm|8~g~k zTx(B+t=Kglf*w{837EvEHNAPl;Uue~HmN*SBqz!%P^ow>MxR23u4bDn(%C3$>}2P) za0}TYsCH}FeJLRkYr+#1V7Tgg3MR@uzVqor{bq1++qi?Vq_k9@i{`bLecssgy10?G zsex6$B;nr8w&pTvLFi{b%aMTNJnswQ)NfY;`9DU4kQ?;E#lD_?Ze)2RzGLC8^4E9L zweT_}@)u_t$Kxo_*{6(eU`+hDxhK2A0Tv<6id5+~T-@JOX~~$E*C}<9j88<(LZ6Fd z)OF~+J~H{2M+Q{R8|7AsCpr`$6A_QfmWRlByRY_cm)hI{T>Yo^fV4CW`Qp z^6OG5g*eJqT_}V|WP!EXX{Ge&QUJ%ncY(qCCT%`hoA4ohlzsSA7{!x9*k=%10>6&q z%@{g#p}p^=0)a<&q8m84Wyh|Q7@o`6^uFD%z`pJ%Bq~Qtx^%MiO+1rRO=xj~?VKn0 z`uLq&|AR!D3WGw2X(YF0<=`o=e%ETw#=fh^IlYT~F#3BzJ)cSh3_rg9r2b^Q%FJ89 zD!bK8aII!04trWrXumnZD|t_{);G24rlVRlOHz`8fWlv`;JrX?)cP7KhkW0arNP|V z)qV5%b#sA&JcW%xIdOz`GDZ4t=)21mPH>XLHUfmoXWRntlV?tf(2rc zoiuQl=VtNm`(+%W=TDM#Gffr-8#yK-j1LHcxOYajlOKc&&=-8u;-vNzHLD5xk12WE z*j;D_RNY_XJSJdxAo+Gg9c==6CE!^~H!((JuL8sXZ;3=@ZTqMe$AP-Va)VukKBhan zf~W|$8{0!XhW8O&d^V(qrH#M1e{$W8c27ERap+xUVH)oa+aV6<#Q@Uw`5yDQIbqDVAO3HzI zjEoRsuP)=GS`RR}rQt^*{+yZ`gb(ra@VYx3Sb^uQ{q{*+SsBC$ohALZ>rz!bbP2>o>@NgkH~rynruWYOIIRhUkL6JtOGb8~w7b`PZjCfQt-Z$`suvf?lYG z9(esx|@|9Ca`{ zAO~h(qyc@x!5{Syey67kbj(1m_5YA2G(JSA-n$n(hS-fTx?sd&2Fhdv%J%#Cpn1Cs z)%z`7sGh|i(uAI+d;g$g3-bT_SfHu>GDJFRPEJ~CgwgvYKl(sR|NqcK{#{H^Jv)#m zX#Rg6A2dbiSoLSF^ni}lKWISnjSAJ6utKNVtp_QZgH_~a|A!75ROh#{>4Tax`a{m4 zDWOAkHk2UroAogIU>*8DmJON`22|s>SfJG`)xm`7C<(td?rng9>X`k(PM(6@ zKgZwCfx$rSjups%`}*l`>wl|eW@YzXds{B6+1N}l=d+YP5oLmJ45a?Q|wE; z`s@*>&;3rl;zh%*MEh)m2-HY$c=4U#GF8ZD8oZZqWv-GfCPVi>O-N58kdE9T(=vCQM_J}hN2D3z zzHU0(pNK|S@hoyKv#R=5WE^hg+1x;l2q+t2tH#OJ(BStV2&oRd~X3msudB{ z`$^qMlYsFG74bvxM|cI67bV+IIhZL1o+rbyYcsMhLgrwf)l)Mh&{Pc6u&bXvM88M$ z;BK~#zv+abnU;8pw+Q^Z1~tK(d?-vd_F)OH07i?(Uke z##u|6JZ~Rkc++F(`n0c7M1%-KJA?zizvh`%8w8NI^6x7kl0bD+)w+mqtCn( z$#u8IZy~M<)(*20azR~g@B3xz7rW7{V5h0CkL3gxa~@cGmuvPUkObL8bFyw<>{qo3IR^n9O zLYzzKTlX^}MV~R#q){BSScO+4oG1lM4UW7P87Fi_eOa>Ke!3`f3vm=oDlXc^HR0CH z5^{b7cc!#bDM{u$*0B};%vCV;rm-+OGAPk~_r;_n&V~lY*)ZA5P-9X2MT&j(ndpUW zMe#ASMoIJQ`H9qEN%I%iOJ?RdqB0?0MF*>KcAVI&4RTcJOAa2l^}ytb^&d}4>P+i- zK9l0Y&rJ{;Ww13AYFf0n!ySfjW@pvnpkeWwr-SdT(Us&@Tog~$W?IZfxGGTAz**nvT?YN1x3KPFq z?6`R}bS!|mL1HrWP<+=+inRDu*u!hOPt45cDP0kreYQ{KMGGHv@Q!qCceGSjx2LD< zEv_eV=6>$Xc=d!Rj)X;KW3{x;&6cHrd0y}QyIEKsg{xtPPRS#CX{!D;E~=6(UR)MG ziS+hmuUiOx5<%Pz-yIcS3De5&JnrKfk~rKcrcE+T!@-L;IQgdYv9@3;mT_3fuGow& z$r^2k66xA|=X}uZM|v#zv6PBhK=1}9@qq`nCP&nkdvEGXdR+|*NgP>co%f#*$p4vl zO^3HPIPoIvftKM;a=SKky(q>AyHamit`|w(65T=`whtHKGvuPBrd~x$96r_cpgFqe z*HkooIP`EPmZ*!7z{;yWcT;G1VR#EmPk^0Yd(A}m#c=ZQyC~uLR+O~#rwTd73SV*V zEO#hRh+C51c_S;%_Fq3@yqt>q%<7bv`BAc6tZ+0Zg9alZBym5Lb?vy^?C=VTp_fHW@ z%~GrItqyhRahwpS;LDPlnAYz4@K#~NmCqZy{tG3eQ@nVVKRin}MLQOK0b!-bA;-{A zA~uWGHNxt0)v*>L0Mn@94J~yg>!Lq&T?i9h58Xs0CeZTCI{oyLp!$~#T ziye|hwMiGt0rF7C3e$}j(lb+Et_p>{fKTQlr_$V9lmz+0B!bOryFbq`K3qFpR3VjRHEz(2%6(ZL<4MiBKzjNw$&+& zn+sArx!RH{7^o$DHTQDAJ*unuAlsg`?s&)-U?r5fB#Xe1^N%oUEDpR-dq%C$QnPu$#}5pK?z zGz~=yxTy`oISTlpkHU=^vxDPBqum##PS`QHNU4$O%`3y^6jI6E;yHq0Sv!fwcYY5G6 z(rnu}e4@EC)_$@7=G_A3Bn@0fHx4H<7M2vEm5K5f83~p;qHg7+%$&LwM4>km=i)pL zGBeS5_)p)2O?46CEwm9Ql~=#qRT!R5EC|pqCN!4;g$_xz*uLvnRNB6Pc zlyYaO_sr)Ki*@P?aTu?f4;Y%ob4eVxp=v1RD9x_Nd?<X$Iec7B9nIIXP2)FhseqC(fGwh zf6!VVKULuHIeuIu`4;&{&T>S-Gbe81yH{D`xw_mu>ldF$EXOQ2Qr=ekD|T`bt>vzY z6qE*!A2V>(m^}8c+kEeM)ykHZ?Fbgh`K(02T&|%V6E!lO1!QF_2MLMCWAM9HMvVKC z1zadLDlW?OGpr(V399fDRbSeLpnPec^m?^-Jzh1SV}1I*5nM_^JUh*Ldc!h!wDWwT zp*Ohc2i}cHRm4K-q`Hgv0KF0kK5t}%}b zzjSn*Ss`CnUMbezwqbNKx=Hisvo3tNGZJ0@k*2TWMIbWYP|`4-zM`4x{!wnwJ#D`T zTAm}ER&Xu%{uX_ji7Wfij43DU&P0MQVZZDK2}&`KWkru(g~n!3&c&WP_ZM;%e>n=f)!v=Q9VLg#zc?s=v38_iVL zCwynIjqxPGLgD*}=GuLVlia55RsCCLs=Jb~V(vHy0XcKk=9dD>7*b6W(>EK>oUH5E zvh<{)c}=OWoO@g{__)@L=gy@^fL+YXPm0eUzT1xSn0RtV_~r(K3Zc4y`ubHD;vk#< zw~#{34R%)?DoWA(B^eF*{edws!h&B6TOu_#tGzbwDGTv`08?e6@03hQMl(|vvJZEd zQGB;Bo&M{n*Ae+GBuCiMY6lK=Y)+BBZjs`M69*Lsr-|Q6%R=;J>!?k_wyN+Oi-;Dh zKqqG}<%yCwTVyRv&kkQ2Y3Wq#Yn&jTVpGef!pWlTb=_7cc22noPVxG2O>mwv_OJp- z3&-0Ws;&=q24-e7xnIyC9cfP)Ovz{*C!IxgzBb%mxLk5lOd8uYahQ>?_m_f9u|yo@ z2}C~|KDy@A&|Du>X{-`KNj9RmK%z^-ShC5HF=QFYa&)mt%9<4>8-JzqNN>#UehaEX zZHeuVxQ6GQKenhxi-qihOTs_5DYJh~i9b^OG$TY2QQ6(~;c5z|+Yxn%wUal5gZ2KQ z1tQz3bz%FHqFR@P*g$Jx`GA=Ns>AIU-?GrZJPABO$Z9pWCvY6;r0!^p?0GWwQ0Yzs zCOym#-I6%k;k#w)N2UQpx7de95HF!7e7E#LjG%5~j@;3N;d}PpU?)D=DqZO=pM~ zgPC9tTpcON*0nNV7Edmb2}HX35XAg$S_qt5jr2);&Fc)EqhxnHADJAHEI zD!`I-!`GAcI;Tml+%H31(MJT2d@qlvk)jvAze?^=qsSsWNh;3Ag$VjmOcfDTv*~70 z>xpvBheZP#g4&omsrJ}1r~bUIPKtC3?aL-*?~>`?+G6!&L0IlVBJxocUOHq)DHn2WoB`k~bB#2QgPoNeAW8QKz zW@t}f;$4;GlMUMVSIpu}abEX=J3~~C%spofy_z3}RUnZ|u+A9omCaPSbJKYZ7n9Z? z3}nMBr@SS<4t2;A9t4Z*ggps^wzeN>z8kH8E5C!YJA225dXSfukx+M=K#wGV(OqrO zg-EAAHr8itfT;FmYd@G+Qc>|PY=t#LV7eC@+>hXBT-4mtA9yTZR&ssyYMPZhq)AVH z7td(Z_1h~e_|Thu@skY!+WsNfj|z62fC*FezYaug8C3+L*v2G1j|;8Vi#n>cfTYO6FSsW@-2g z)mQp;WG>Va$xIV8^ZR2)idaInHl5^zThEj{c7s1DW;(z%+|Uh}iJnY0m_|zVX}Y}M z4|e4qRZceI9#X_~t?e*;&Cw;LN5uSOeWWabU}M6qoGn(V4kc`dRjR$%Z>wf82WKtE z%)9ZEY~y>&ZW{)D0x=51Pi1&0qGaVFMGB!}IKO&LmQ5?ozHTvT(oBiizVIeCA3S*CZXZ-e!26E)$7N$Ttx$g ziH+XuLr-1ANW?S}Z?z`l6&zZ8NJnsEF%Fm;hI1@IrwSj!vx|ovWL?+8YPlWIeUMUB zdr1$!J=a-U)(g2|8@}Qxs2(aFC-n#zqZ(%%L$879`0mROdke2PoHs_^@#7%_BPB&f>Bs0ag7jMMoZAq|zN zNO0z<&r`I*B3`fk_-r$Fz-9jV2K*apOide}hN2Zb?-0P0+pus=dsXgxx&Pyuc6iFo zG~0iJCNG%b-Kr~d91I&=o>VEudmk+k>nhv3$1)JZ__!oFQS*J0GDiL)3-d}@89%cF@q!Tk5S7Su z(c9^BsJFp#;Tw7?A`wQ=ZaDRTaEt$#t>sgO1qx*h8FyH)iS^5UjgL8+e8rKS<}#ra z&tq%8YzjM(G!n_unc(~gd%nHyp~8*bo-)Ih-KM}Lwe-$X!+l|sy}wG8M;-BiN%{-+ z2R$d8Zk+W(e;f{xSPvpsy7XEO=EjN%jJXURU){-&m)%226`n*VBR4wR6hCh6gDo^7 z#42A9@B-tI^f-)`gikz5MAS+UVG{!maC}ILVZ$qYOtb2GU())Ny2QA}ANb2_62478 z`}kS{m0_v$3;Y(p;ONtsqAYVAl^NkD%mfg8ssQlVQH;$~I{IC`fqYAUB^H?Sx%)F! zxt;YIkttJZ(_PI%5bI;();_lf4$;jqo?SI&3EI>bml*{d;0cs>H(COg z%%4_PP9h8yI}b!#K}t%x?0L}Bv^54(3@s#d&d^gx0YTbw<- zcKWr|9j>a&^HiBIIE-&j9_>#R`|c)U(5xZQ6${_>5Pim?`s+`cG|aF7OME=2p!5DX zKON&xv-rkg(b))L`8hYsrrOla{o;xt3Zn&ahAF~ilvO^#?8#|Ho-?;ji;t9r22RXv zmTQJ7LoUoV87d}vMhx6@C`IlIbiFRZbN8xvc&5jMDSN)e%_FRnUIZ^rDfZ4{)}YK7 z7D{BEIZ>Anwommju?ig#HRBjhs5(!&24fa53ofy#514P;66nje>9yve?$FUSI^~q4 zVhK~kOJ2F)P{W5!$;j*OwM5*RozN=A6rVMKJIJ|jgs+||sQLU!z?Q)f)6N!uv%TfX zXCC?vyu30#VVu6E_b-wsDhN2i^DM|wM~OC78V0Ws7*?sxxUk>IrB5Mh(Fw=};(N~B zL9W9I%TcCN%e25$d{2|dw;$P^-CtaE65jP~-&^a+ajvK$v2@R%pxL**gOWRPo+GAg zQTw)Zba%EH8uQke4f80$x(;cL(c^ma~HmCi`2POh6p$mZqab&ASo8M0+L z)IWd0KfdAG?c@_X-^HqK45Q*=(24j+`n&UJN-N4JX0kfuLtv4yb%+l5^G(UjWc~&o z8YwS=4WXS#mw6AtmK_-QuUn3`Nd-(UdL`9x zn!PG%LT#OPBIzg#!FHkD8}(l@i7qvvTl`<`y$4hjNf-A$2$Cf!A~`FPa}ENM1VNCT zkqp8RBuN+qQG#Rz1py_fWRNiAAUO+28gdqpoYVN$xcYs&`|R$s;W=l|dC%LN-xM=- zyYBS#?dtC8s()b zY)<;5$(c+Fx5_djhQHdXL*4(LatX`9PHWHh1&y4FimN((%y+QPGDXs6<0j+vkV>P= z2?aS?xZN(CF7wZnsM+!V6n6w`WHYb|fa10AWktovdeHQFTkr+S$aW7APNz=!MLxz2<;+7D7aH>K2BitUzs z4q5@ERNnVZ5si$dD^1$Wo!<1&=X$)8PpFUQz}e2`dHjs3aQ8}PzE-ceMEZeCr@pNq zH=2IL? z(t@)7tpCrzRscLFL@hl3BmZ=utUv327uXhmdjyWspXUYd{{He~`{_Xuf7U;$p+Ee) z{~zuDSHbUr+9l*5{j1MUrv&mtXhe&LxL%nMnKXupJv7E7y8?B5-ZE`moj!_~wAqW- zFf!_3kIHWCfU$JUE=);ciCm(2o-a9oyzDta?RdmerQj3I+!>sO{lUKxt*-`_Wj>?R zh#7hRAW(ztbovR5^~I|`5*YI?`Jmyfx!rB_Q7Y&@ZIU)ENevyp_fR86w8=WY`JuXY zab!rcP>Ml8s0p!&IMkVAW^6>>X|#!%jvM7WKqkWIx*{s z8`izrKyKbo6>->QWAF!=q=~*$Dd=`W6{Xc?rh&KmXW|6IiPJ)u1qd^`(}SyLnndc0ahFa0@PkQ)m^48{oLzvisLJ785V z&r6gcyKGCLpk0+j$uzf0Uw3o{%cR;w$;gLnLo?phNbn)2N*{kju9v8wQX4|{!43vN z?fp=bB3<9{qZH7_E$%l0nvOgCc#?&zq1B)v4L58WJ`PTAE+%3~&(o|~*!+Sy`K-J9 z@h6jwcQus0lLrdS+qH|4h&&;rvDHtjky0Eu;yiqS?8o3Ov}G`8)9r{3tcq)441h>T z?&?0CS`X|RDCw~2LMyej(OE5O?I@l*qa1|^dq_~d+$e?RL*tm6XCQBLu82*h)*)Hm z=q(+Ip+DaVo!k1age-m>KkvZtggSnngY>T+Kl>pbC5_HGIsR!p2rOZ?Wx~vS&v{vXkxo5Cl=_p=ZSvcvT`bq0E zJhw5rIA@BXU<`|#<1^N)>|Urr2&1iDot#-20k6SFLTR1U2{?&-Uy*-kgAH!N0lcy=r0dN1 z=J3)uZCnw0_t;23mK+Yp0qDKLnJ&TQh4v#3@is~bw&&jZ@Mjl7*lUr+GX*7;TGf3m zVf>@niEN*Xx0&uj=x0Z3&0n`lARjKi#QiY1s=cpF!`||3&px<9GuC^1aya)3o%P+Yn8)yspZ53Iys^ng8RlNE?g&Vn zhE9CIbZ;$Z@%BAO+TArRPz&0qSHg{6Tis@U>2ZT&_zZ#IqOdT=_E5s2)keZ3P%_(X z&ihz&HKtoEY5~C(B zIRiikU;xenFacNqYyb`b7l0ZoiVxCr00ICZfCxYgAOV~QTmYc#E`pQ{a0x&Tpa4(; zP~34pS>4ALtA7Qj^iD}W8a4&VTA0=NL&0F*sSdw~zY4-fzd z0)zm<093vxNW}o+00{s}dq4_s4ImAW0muSSwsIhq2Pgm(0ZM=y092j|NN)mE0cwC- z0Cj){;5GndqXklJfDS+xpa;+g7yt|bMgU`g3BVM9TIUW(%>fnwO8{t=gIEJ>0JZ=- zfIZ+YzyaV0fC8KV&Hxtxs^7&u0BZgNcYp`L6W|575AX)~08sw?Kner+1Af$B55Cu5 z&VQ%=YJ1U#L&I{?MyjMa9^OKQznAaxB8e_~CbBbH^V!YeG3UA-yZ!$(N?EzmwMlz4 zS+q1NxgTA9(h2kM7#|;%;M0?Yf}!_=rzxr<`&HrV3+Bg_HEU}lO9^0Hh5{1)<;cCK zdJYQXqa7dL_i*n~>DAs@y$S8?<>!@lb(HD45V#g2MqE$rWH*tNnR}RU`H>>0L#tkD zly9HH9bv}2a|Zn-0=0bCKenCiD#zp3AgoaQqJZI6pIW$jZ#XhMpObH1+<+;Z8xpOD zTS&XXi7emE@ir1u{A4syXn1RKLm#~ zDjRh^Twh7iXM2;EP+`ZGoV<5_R$17L*&2sQh@93-5X;a{WPi4=d}-ZGlE3H?iMCUW ztaJ2!tf^beY>J=6@2(J9`);Y<&`{RPS~y^h=o)*u9vCQy?$He6^d2}>P)(Sbq3jT8 zBy$QtvutmFdq7#kcj!8izbtxhh>U1LubZy&ArT&@ww6@g_-0B+@{T60<52AY%)Fs? z?eHtamc|%X4PSRyk0^U5Ii3&8Lbg1Hjc+6S#H+qSyrC1Llhn?)d@I2e0a~Y#1YaSQ zi>K*cUdX-4YIu$4OlVackx0bMLf=3>cgCD<{b3zdfY*`MT)~4*4>G~HT(2N5hGxQU z$lUp!zI^6~1mZy;b@x zc*c#g6h%`r-Dz*VnyIchHty#i!S~Ryiy?TIW%T$Hi*UYU%}{Zdpe*$OB0VsRHQsC& zmw;{YsLog0KIaCf6=E!s{k^}0FtTb8eYwc!j=HPh;GCD`Q?#X)-Gu^Lt%MbluotCp z#tzUwTU9EbU-QT+!}&DV!C_Hxvt5@vo@paJ0B5m8?TwudEn;wR;$9?GMj(!h8m=N; zviI*81IY(}8G+;3%bhP0*J? z?j;)I;dT4KA#qeZlJ&Nzq$Va)ylW!mwV^8-{FCJ#}Mo%)WZMI{eQdf`78cO zf&VuE)FSXN_@@HCS-)?;;J@IX8TjA&?mzk@RiJ()Su(YBl}6SYqKH(dnA+{3RhKjD z*O#3+CoYQi$cNS>x>Bo4AYGEKzv0y->-yb8%93AYtLxFwe=HFgbX+4r*fPY)EPqs} zr8}BBpU}EV5R{o$TOl8K6Cz72= z7vJASf$BbzL4r|n$g-wXE@Dm0jP*t1vN??|T>&{{E<$+sMA|qEYG!XY`Z^f1S%^e; zcG+`a0>SX!+0AAN5ZH_)SqE z6$)Pd^7VgW!13$rE{T&E{(Rx-`!oaVLT5p@+z)3f760_*uS83Wto|E>Sj9Zl}Fu9=umkzhI((=<$kxg5Vya5<)hMDc~c+N0Sq zh#%(_iyuC~c<|Bzt6)Dh1c-kcz=mXj{-*$F%E~JRJpKx~W_JaQK>$)VMubTJPnrV) zH|1opj#g5RK1=PKeP;?jcLiV}{Y&s^SMp#huYjKO#Zcu+%_{%Kxd@kZcm8A_*kpM>G+L@OyVRR3D{P5$v>7t__6=r6J5$U(HFYSFGRSebeU$VSc^C(aOFu+w+XWiCn7pQbe$$Z$eHR+ zU~@NQXTu#di(pp%m`dDIw1*_2-GkN!NmgqX7;K78geEus_$_O=dKSNygN!uw!!ND@ zL7w}wM+1NGuGa`2EY6%cu|hHirsg54XUJchEgR0dR$tdb&37>5FhhuA=TXrJ7xkTQ zgfNMXrg3ho<9G;XC((nJ+j}{6mVL zOsw25E2CQ{Haba5=6SZ$q-;IK;J_$UF_FiKE!L<5V_AG+>C2-ra)6zv*tG`F4htaI zB%N#*nI$(-QCCZx9ti66GdwCSVzm}Cp4au0v)%R)EhvxdNYNg&R9Uni%O-5im4rUl zCgVADT}E_fzFhTwW_C#W`?bN3_*wWKKZAcGe)b=@bS1@Y72xa85GyT$B3iq zT?omS)(zo}=QNI0H+%3i;tA-boX2P}C zn<|Xb;i5@JzNxf=6ZTKm#K1mVRVNRfD#M19 zq;~j>d+d=JwJYfj# zArz$9!jM%|GtfRa&pqyEJl?)jYLIB(NI$Yl{`~#JHVqeV{8@peyKupwVA&!BACDzY zO#0j&d9!`rh@(S3(PQgkt2^!InU&hU@IC33LyoQpmB^PrX_q;SPGh{nxPTFXy^_GS zH>p>hCD3W5LDm^gPA)>r&E%wD*b6H?>RMILGv|$}v9M`vYdw6x7$CY3x>!SVfJylH z$Y?ygCd1V;{=8R97n&BqM`87`+1N?+zVh|QHE4m;$aoKPXr|!=bK`{b_BAcpVuA}E z!gKp|J9*yI>;9$(u#EBH(PbT>5NDy6J|9UzC$=E!ZV`zM36}p*H~JC(Bj3+|Z6N)t z{r{JJOg0ITMEN15dkJ0fFQ!LVG`m`&V=?NYI^WU?L*C5K`D;da-i?eDT`SBukqJE~ zrBzcLlEdgqUER=}0T=E@qnaXYuS^M%#2pk@vUK*H?lL}V(J2wuWvKK_t+@H>3mp;Z zp)j<*tllJLdGRr*ploW1b+n6y9CxMgOhzgV*oSht1LRrTF?H89DnrZKnx(%OR2?X9 za?+AF5xjt5INJ|~8Y?jbvl=#{Q65~>6qx2Zv9jxSmowH3%O-Y{*&5yBe{r26ZtO8RovS}g=wG=06MiXp+R zvw3V2eghX3&&UQyGhAk5j3~?ZI@Z*q!y&-I2!8$~LUg7EmJ@dBiyS#kO0VPODm-p} z&MW5-y+w|VG569;fyrWyz@FhN!~|9fv$o~N3;W`?`367Qz{2N|44TN5OX_XpBIpUN zwL_DuDI*A#Gc(7uRkndl+9R~|QU0n*%@rtNVR_&)WjwVs?`#oi`}Ndzbc4=jW9vP}qt40hy#{P<;%f6Pkb9i7&RqLpl33XC!gGsH zwnxSOat5&icn=b${WH3H*irA}$jy3PNL^E&U27Ya zbJU)9RM!WC}NoYPSq z2(Ku8dfNo{871%cgSh`4mt5~2`Z`U&dF?&@{J5p)1EShyZ?V#G(^ z1#Skk?tzJLR)kFKBaBoJE#O7+4se%E&ZX$DkgzxAm$E8g!Mln1B`ut9ecl_4qzR6e zd&b{u{R(O7=Xs)KB-MDoYX~tLf4fGH<4bR%!&sGag#~P8>3K6tUcBapR?{BbA+rPO zL-Vm+n?FR)z)y6#yt(&@$KTIP&28AIuvrtpYh8cFTpL1~>Ndmsx>{m*F<-!uHmG00 z`JJ(XPbSBSV($5T;%DcU)>{I-Xn#?(q^p>rv5E4T(T2!f@2J^Bot|A~L3g$k2iU=q=%X@I67b-S)s1??1kP_%|WRx(*D|&J#Z^2pL^5% zD}>%i3|R|q@OSJ!{UVQae0kzh!rti`#~XOKp=IEQOKWQ`_LT!wJOZo7V+J>&6lEP) z4|&GN=7v17J@43$?w6G&Ob9r~5n`KHmbazm413;b$K#LKy5#7H#+*U?rCW*4^gceJ zkJaDF2`#Rn?bEpKRv64HS`nRmi7N2$fp&bu(GA6jQXWhN9Syz)^e7lNYu^D(Nr`x{ znXYwtS>Dssg>d2Qe~FM<>JAaU(yb8OWw_Hy!^w=InF39c8mxI!Lf5u=K}b9l`tMcg)p zwq&@rI6y`R>|w8FL}>DY2{VAf_CKdinAw~zb6v$#aJX>>(iZWe&r|E z5j_9G^@k>?V>!U@j9PgA1^;Hi|JXOlho8Q~KYjgi?e%A`|Ng1JU$6g9{NJ^pW#CpN z$7!}8XNvVdmApk}W}>vDpBqu0F}i%;veQG*1E=Qd?KHv#Y!M6^X$&gjf0iw0eh^=0 zOt~4|YtC#;KH;QGF)oPNoRWz~cjIL} zqi>y$4bnls^5mt()P0~-+;h&; zK>m}Yc+YfpwiKVDk<1=3bfN5n{QIYr55}7Z*1JXW6U7Cl9Vl-dY)d`L%Q@+ycf%W& zt4)~2p=iJ5h~+`4Q!Bhsb9ZAXsMtYvwi8KFQMAn;^oh&tBGUc|ll@icGU_o0(8h$|jY&?2Ajpwzx!=}Vx zn$*xnUKS@ehRKUw2&A8*pG;Z5%71erFnx~j!^Q2<&)PBi^_?+3p%J40)?w~cJ zF_PDTSyaAVgPDkWsx|2E!dEGsv(!@U)NL1U*E+lJmVr{+Bq&ageMlA6;brZRvUbh{i->yi1)Sn;0@r1g5sskxENKyP4Kh6!|{zLuC zALGZtbH=9HEu9)_*qGW^h|=JHdmp-ki~3`W*dz;ayUC?(Z?A532Rlc6ST8Zf37n6q zXShg~6O3~P2U9y6iFLgSii9MmTekAV8jYC;_^b7DbLCzHGZbu_SvmSPM9#}u!ahLr zj%+6nz|+kWm-n^PLPNg%>nB(+q==r$&)Z~ED^hS*$nFoOxC+dCU<#dT6o1BwJ)HY7 zwx`p3==QYHopt^GHLEJ!>(Pdn9>-)zQ<7GYcpXOGU-n_kFt7>QD zL*9Bu&Pe&+OVXcQy~y_!VsjV`wHPnGVAdX`Ku2@V3)UEZUUieU5e8WjEvZGYTO)h7 z87A5)@3J&Jql>sEPQfONyb#~eb3|6VR z1`m7NMkA3TaypwFPo0*tq4x9X+_F?R9^JzAuOd*re<%AOu3gwo3tqC-cZoiNS(fGO zHDjzR5@Ul5;fsXpg` z-$7;xZ*-JAit1u`ApVh)z2rH{TNN^Ud(9SDXVXj@Bwtdn6>S)W4?IfprXC~2D;aUa z7meh=gmJ@IznqYnyP3T;Zt+0>uQlk zkJj5*Td5WLOZFM5|1GqBo&O`$Vuwy{-0M=$jfjQbBSj+-KUR|{1hX}Y&g}w?|0F(5 zd-L?s@w3;iM@shh+`TK+T`mD@e5*1*F}x(WFMW%cv8Q-@l#*~ewP<#8?&B-P9p!ts zln`(W0#&t>qMU;hFMbvh36k*(B<{H*=&`Y2*!ha26wOUsjL7S7IgF%i_iJ-NTB<{o zEq!C546*xkyZRm6<_!-i2^4EyyW2^sdI?dXMqnSFucs!42y+iLCsx0_;iq+X5&d`~ zDf{C61ZO9m#=g>5FXQks!B8bFReo3 zk)+nAYBeHXA@v~c%)or0A9B7zGWT1g4nU{*FRUg9S}D7d2a8}rTiVkgQml|1t4J-y zG%~U?ER2y|K9z!)ye;JtH>GFn$Oa)STTr_EWF!q3c6*iZbmJEv zhYoC15jD+>bEJjxOIif7zJhgJ$u+^N$2aEaLkOqIE-3P5VV%6c{~Knh)t46)`tvXI z8R|7LJv1$(O3A%{vpe#wv5Hk$QK%Aj{T&f0{hh=lTGguOUC!1QVu%A8UHpnQ_u{k% zi4Fw|a@5z@W%jRBtJzvQm=VU><2KREG;+CkfBLlnDNu0f)ib6mNYv;*SH(&m_K2=# z0_$~sPCk+D%}m=z6QuY}4MZkT^p8`6I>GFhKNUAXaUb284(5VC`0QkpXEj4isP+G}9w6C0iu9efTw69n}HcHPIQf?UE zy3>T_1eCgdQuVR~id;We^|}m)eMi)*E93zKs66|7nFP2{rBn rqFjjX3^eLc$NIf*$NT@Uc8Ic}L)m;U38l=3(hdCiw?}3FTg(3e+gZR9 literal 0 HcmV?d00001 diff --git a/file/images/acl.gif b/file/images/acl.gif new file mode 100644 index 0000000000000000000000000000000000000000..a224066274c95a96cb4c43a6c1810ec068402dd6 GIT binary patch literal 193 zcmV;y06zamNk%w1VHf}y0OJ4v|NsB;^77{9=GocV%*@QPva-Lwzow?9fPjEzW@a-p zGfYfO0000cCMI)pb6HtgEC2ui02lxm000Db5XecZy)}p}updMriUtvQlu%}bfldU0 z#V(z#}~Jc{E&IvxX_4i>Cc5PGX=AC)(hC&Uz7aUC?vz-Fc-&`9Z@DK TD@#(;yl47md995SX0QeTiEs+3@0 zU{0vmb?2YKshtc93?u$D)jMhQH9cZoV6a9fdfv(eUKZagOmBK}*T3JEaP|}Pw@r%fa8J6MY-#&+fu8;CWyqwOBryLGW8$*_%F=K GU=0A`p+l_z literal 0 HcmV?d00001 diff --git a/file/images/attr.gif b/file/images/attr.gif new file mode 100644 index 0000000000000000000000000000000000000000..858a2b4c4bd066a4bd4fcd719fe8a5679d91873e GIT binary patch literal 180 zcmZ?wbhEHblwgoxc+9}?|NsBv$B&1Gh87hSF)%Q!TD3}6R@Tzevahf2@#DupSu~&n zR0Py1!N9^&6gucJ_t^q3R&NP?g&Estu1YW1vg!s;gTX~N z`zDQxuMK=zJ%f&D&Qc3=O1G*MS|qjpjmz1T5$p{g^tVtK`LsnTve3ZD!e=J$G+O&F`r-mPfp{drsnFum%9$2O}W> literal 0 HcmV?d00001 diff --git a/file/images/cancel.gif b/file/images/cancel.gif new file mode 100644 index 0000000000000000000000000000000000000000..f53c1e2535129dcaea18044ab0fcb4f41b1ed68c GIT binary patch literal 107 zcmZ?wbhEHblwgoxXkcLY4+IPhia%Kx8Gt|sM1W)%n4DVrSDv2BDBF}6#F=4RwfSGh z{1pukO&7J@oU!Ke-XNJovCLv4x9Xbr*%Ql_-{J~)k_$CYHuSh+IF(yP_}Q7v?F~!} F)&N7dCL{m= literal 0 HcmV?d00001 diff --git a/file/images/config.gif b/file/images/config.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff95e3b9b13db21ddc4d9e16408a58399af34526 GIT binary patch literal 167 zcmV;Y09gM=Nk%w1VHf}y0OJ4v|NsB;^77{9=GocV%*@QPva-Lwzow?9fPjEzW@a-p zGfYfO0000cCMI)pb6HtgEC2ui02lxm000DB5XecZy*N`Qxu;7gjtjt06UdtOIZK_ literal 0 HcmV?d00001 diff --git a/file/images/copy.gif b/file/images/copy.gif new file mode 100644 index 0000000000000000000000000000000000000000..6cd331a314191ac2fffa35143f15f8a95a9ce925 GIT binary patch literal 113 zcmV-%0FM7hNk%v~VHf}y0HFW?|NsBY%*>gYnE(I)EC2ui02lxm0006?gpaAq-2tO? z2eLpxOrrarOh?BEh=dtlc`D#yR^02hNbKMmm+9%)vjHhS9#N|AGi%Zz;xE_@j zv#!f+caXZTq4At!Nu<**HKE8@9%{VS% literal 0 HcmV?d00001 diff --git a/file/images/delete.gif b/file/images/delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..18304a84bc440164f1e463fc1ee54fbb3180cb91 GIT binary patch literal 99 zcmZ?wbhEHblwgoxXkcLY4+IPhIt)Mn5@BF+YUy8jdM=}EQ(_QjhHcg6e;M;vG(0q2 z)OK^mn#+5GWD>Yu;y1EL(nyE8Iyg)I8bH<4j|n qTbYkpB;V<2DyYk-7BL>GG7C9*Eci^`m#q7n?^%6XW+chQU=0AI=N(}H literal 0 HcmV?d00001 diff --git a/file/images/dir.gif b/file/images/dir.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9ef302f09084b3654407a4a53405ad4b6ef788b GIT binary patch literal 88 zcmZ?wbhEHb6krfwSjfQe|Ns9pXU@!=IWsLSP4OoSBLfiVfC!L01CwS;f965mtd=># o+qz>H%;~?|8n4l$VmfcdO0LY;n_k_%wAuQ}uYJyT0SpY*08;TGz5oCK literal 0 HcmV?d00001 diff --git a/file/images/down.gif b/file/images/down.gif new file mode 100644 index 0000000000000000000000000000000000000000..bab413d62bbe7ad404e9c32d7e773c1c63f66a39 GIT binary patch literal 128 zcmZ?wbhEHblwgoxIK;s4|Nnmm28R0j`u+R&J2*H1xe%ZO6a}h~U|?YO<=A!SpY93G z1#_=B>8vh`c~I+PF{!I_+MUi-*|&}vJ)88wn4?C&g+)GpgF;K6jML!`8!g#0&z}73 cFk300EwFU%v0V{*YI~9F)2^7r>IC@ARe?v9U(OHED9 z$;rKRsRE0|hK7a?3=9+%70KoDuC6YrR7#`KluBh@4(Gf2h|xBpgco zpP%O!<6IN4O-FyJ4g2jUgdT>`>-9RFuKYa9(2E!bNOKZc*PkCB`$k<|T}w-gvX}Q* zdVcPSyrZK7f*=GTZftCrOeQ9ixx2e-u~^pD)(#F1TrO8w7?sQA?(grXq@;*MB9F&o zw>v5;D}_QKkH;er2x|3|+wJyxy=JpntyU9>h@YR|^73*?Nr}y73lER*_4Tc)s+yUZ zfnj)QX-T0_U@#a2K|(@8oK7bQf*Oscu&}VNug~;szPXxETao2;+a||k1Oom@9*IO! zsZ?Iif#v67y9zZAAs0*XtX8XS^@rs_)Yk|2svLCv*|WV+w>6xwH%fF)k(_Gu-gP{K z!B|;Yc{bj(-Ums_aCgdZe~l8|&#PXJMmeWY#}vt>Mlw<``T6-{-BxBCcos7dxolE8CS`+pOm!4|c#XR+XG?32nGpNuA$ zdXmo7wq@V~BG@-kNhww@pl5fc2~IRMW8-;XnQ?Xjq9m6Eb@m4F{i$zNzewZLZhd?F zRK45b#AKpCx{w~3J|>dTfVM~L8!P=ZB)O^C#mELc{F$>K0yQR5}3`EO~4U}(!Acovod(A&jz6hKSI5#HD3rqci zIxD7CAl>f(HIVWuF2C`;28wNSS!0M`3$Ub{ED`thj9cjC|OdP zUesCY1?!!jGb@absiJLsf3Ez+jwb4R{Bv=151;(>#0?P(j16cvW%%}s8aHAeDAL>F t21iWI@x#;PmIQ&01u-74UV#$FUu`WVs@z+PNz=@r+srw1j>`t#{SRAoYVH64 literal 0 HcmV?d00001 diff --git a/file/images/extract.gif b/file/images/extract.gif new file mode 100644 index 0000000000000000000000000000000000000000..6cbcfc5576aafb99aafb4b8c4cf9d53a2d6dc98e GIT binary patch literal 1165 zcmV;81akXFNk%w1VHf}y0OtSz000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^sIZa%Ew3Wn>_CX>@2HRA^-&M@dak03rDV0SW;B04x9i000;O7ytkW z{s8|897wRB!Gj1BDqP60p~5?D$Y`N*WnigIni68tBS+1cE?cr_X(LdSr%jk9O|mqp zpdUJH%!u*Q1q_;hw_2SV^{JDlOOzT3jP>u)9XM;ulqr*j%_(5JXt_c~3REXXYzAJs z^r+9AIB(E&SyD%oEnd5Bp$cSWN5M&kB0b6@MvD|AZ6c9!6>5$W9y1OmDs(6kBQ8>o zkon`N&=VmzS|CIu$&;l;hqN5w0v5@TAUt3oOyuYjs#c*KarsiF$rC3=biA0nNE0bl zu41iHv&D*(CPi|zxOVUmB1@o5;l8z|_wOM$T5Kz45E7wCokW#VMeEE&C`*D;%sA3a z8+C(`Dsc*RYL*x*Q=A|%qKDS8YT?o$)U=6|EH73(u>=~DoPx_S)O>?ZLZpcDiWO0K fkq07~sIrSP)_}v%e{uBT(1##~DB_3)1q1*)iDn{z literal 0 HcmV?d00001 diff --git a/file/images/file.gif b/file/images/file.gif new file mode 100644 index 0000000000000000000000000000000000000000..f865d6ff3a7cf7aa4751fe5f108d429b60d56bb7 GIT binary patch literal 1754 zcmV<01||7NNk%w1Vfz3t0OJ4v|NsA0RaF200II609UUFxcWHEJAV*0}PyiwM1OWg5001li0002{051Rl z1pW}n8HBw!=P`4bQiXwJX`bkySzo#eEh^7+ZQppVPsHnA1&JYZAY}-!gH zw4ylSu{pHwI+K)~Fd$Mui2+5KAcWEr8j7YH z*d?U~Ag2X{76I-AaI=6gW+5^h#8ES>xd~q1_?kf~K~S1bmlafdbOTfi*FYH(u$9!D zCt$TqjatG(0g+8CZbjj37>JuB25VUSa>LtO)>559D;XJ14{ucZ^$}1DmH_0)X#PP! zWn;Xsykt;GgH)`t0K~A)5$ZAk&GE#7xVs{+S#)n=b@se+uR#!pof`*0N;jIep!ozGPa3hOwmo33eSt0?cA}OUEH{fqG!qwo1QF^)11gi-tL3QqJiNbO# zG_u-sB1N;>T4vVJBYHq|pcAAX=C%nx;oZn&k{8%w06`^?6Ocs>DHOw_b$!z$IupYNDKc>4BsTVlL8!ReyFV15vlq*l9%R%>W{wdCoOwqssoyN~r}SmarOM+ij=k ztN&OtCKuKE<tTRA90=p z*p2)IA^`u(vBQ(%&=%LF; zZGk9X%b+gNUDo7Gx7*QnLeN|+5lwh#!1#{F8s|KmVg6vp5Niq8?aVFW?f47z32^E_ zvEBk?Ja-k1>N--+wj@d$IYK7OCA)MsOm&sdj;=EPvsJXr+CG$qt0s0Vbe+*bkHfk}a@z zesW-?ELcAZ8V_vP@*3~*_rTu8X(Bg(p#%kBkLfW-Y}Zm8#Y%U)RdQY*2kE2Dxw|vLP~Mi`73wUK|2V8=PH*0ID7sEpC-UZ zJ<5=kYtSQfoGYj-Q}+~AobsTvpreCmb&x?3VEqaXG&8V2sENg(O*q>%F~znEN7?esZfVn2{G{D5=2d^QY+Du w`pm*zCS9sjrz!fcB_aR-JMjA(`2YX_ literal 0 HcmV?d00001 diff --git a/file/images/find.gif b/file/images/find.gif new file mode 100644 index 0000000000000000000000000000000000000000..54712391366e5edcc5e6151b83f8ddea85332c1a GIT binary patch literal 94 zcmZ?wbhEHblwgoxXkY+=|Ns9h{$ycfU|?j>0r5dH3{0jy{VPwuWn9$5f0kS8$oJCE trolpb%9@tTr)Fimmdoxr`oQO~*}QbK*S|R>cgdeGy`s{7#+{MD8UPd0AX@+c literal 0 HcmV?d00001 diff --git a/file/images/goto.gif b/file/images/goto.gif new file mode 100644 index 0000000000000000000000000000000000000000..99535c8b4894316bd7a60f693813f7c3ac080e57 GIT binary patch literal 93 zcmZ?wbhEHblwgoxXkY+=|Ns9h{$ycfU|?j>0r5dH3`{0H{VQibIJc-Wz=-S3(yE8+ sY7~_EgwyBwuL{e|JhXUEqM6ja?Mp6K@-v;w(TPt#YLzl+854sw02fmrM*si- literal 0 HcmV?d00001 diff --git a/file/images/html.gif b/file/images/html.gif new file mode 100755 index 0000000000000000000000000000000000000000..831835e1f0c79809110a704d4e4e6ddaa512cb63 GIT binary patch literal 1372 zcmV-i1*7^$Nk%w1VHf}y0O$Vz00b}t1Tg{zD*y>N1r0n45lsabL>Lk?3m#7;7(4(b zSTh?X7a&{{Csqn8UH~v+Hylw0GiD7tZaXDwxBvhmICL*Jd_grA^^f72qjvGlsOx@B_e)7Gp{oV!Ym2^ zawvqw_JymhJ0ViU`SVqr?_NhhgT!e5x9+;Je=b_wEj09u&4-*g$5iE`t29ou&^-gzZhpu$k3#O8D^ z&W8=*dmh__0#~HJpO135fP&+K2ept(&W#_Gmx#ZQN?@qU=ZXMdtHxKa$Xu(_&W}Qj zpr7o7G3bXeX0N`>n;qthGGDUO=8QUDw$Q?)D{HdVhp5rUq&u&ANBr;XvP3H6~4_@e-E!PU^MO|q@5 ze!tv%#M8pBjQ6ex%eGn4vR`+~*welx^tJ)`v;*+AAc4%@%(#E*tZ(tY0EWxqzPPut zxz*aeTDrWs&bXq%yt?|p3f#JZwZPkw(c;F%!tBOZ`^YBx!$zOg=lRGx`^huk$c6pX z0O-E7qTJ`j&Eogj9r4GI{naJ=-T>3j!Tixo($LQL)=~Q72>9m!{pA3&;OFboqWs}I z@zAyU=PmBo#Q5WG-{Ic#+{OF-E$ijl{qkz)=j7?=@b2j6>+S0C^Y8fd_4@Vg_W1Ss z{Q3X=`~Cm?A^sIZa%Ew3Wn>_CX>@2HRA^-&M@dak04x9i000;O7ytkW{s8|894PP} zG*+xYL9<7&p~G%=s!TeT?$e|nIg&XXxR0McJ32_=!WAu@HC&?NNa=IWpTlp=cC?s8 zs+Fi{+@e{0b7q$?b^QkV(`QMI5IL17IijQUQ>SBIZg^UE?b$qm{^mX5#OYEYKU{M8 zDpf1ju}B;oxG^Uz8^3@4+~M)Vr*4`aeHvjhWvW!CLxQ|y3O21C++u|a@xj9fP?SM` z?nH`&B}Sk?X3o$8C+?pZkxKsM#0s4xkO$`)FrtH}R$4UeR3L4OmwGP{b-i)NW~)(hV@CV=XaU=hX%kRV|6F@*yJ3{ZhGvw(vQG5p*^L>P-Pfy5PU%;g6l ziwH0P0Tz@KOfc`n;txMvJW@vj!Q8$>$73`($Z3p}uH egw;R%)FaI;#4bb5J^J{%(U|`9`)u3sj(r!a_mK%7Pe`au_i3HX z(d$7KVc92$;q7TWdKa((=xBH5DWmS)3f(+a`X z9+vio#Mr`k=QE0~zJIKQbbbHNI+S*v8$SgOZ6t{2E~-@>1hvq^M^ z$NXiJBUbL5FoS;|Z->cozTVdU1MAMWF`Ra|d?@C~{y7I{*W90X@21?6C3n_#FMlO+ JGLVzO8UV*Ha`ylL literal 0 HcmV?d00001 diff --git a/file/images/image.gif b/file/images/image.gif new file mode 100644 index 0000000000000000000000000000000000000000..6b90209f17aabd105815e203b6bbb7d78af33710 GIT binary patch literal 124 zcmZ?wbhEHb6krfwIK;s4|Ns9pXU_Zw(hNWVq(KxADE?$&1kpMm0;HCK*^y(_#dq13 zjz=XFo5J<`{2eOiADO5c9H}zVGxl}UVw=Mn3-9~v`z$?s-G^7PbuCPSC4V%hPh$MU Qnd-ChsBgw<4+aKn01Boo%m4rY literal 0 HcmV?d00001 diff --git a/file/images/makelink.gif b/file/images/makelink.gif new file mode 100644 index 0000000000000000000000000000000000000000..feede9385e75468aaeb6e2f78a7f861ad4f8839a GIT binary patch literal 127 zcmV-_0D%8TNk%v~VHf}y0HFW?|NsBY%*>gYnPz5YEC2ui02lxm00075gpa8k?H^WZ z62xko5P)xfNlz6ro#&kvR*LNTso;yPWTy@r-cHKkyTt@RM9=sOx{`-ub5S%nrIP5> h_A6c?kimd*h}I0=M0p(cs?})3n%&OEq4RM806XKRIZ*%r literal 0 HcmV?d00001 diff --git a/file/images/mdir.gif b/file/images/mdir.gif new file mode 100644 index 0000000000000000000000000000000000000000..bfe0d5155ffc1d6703fa971388f49bfb2dc47f31 GIT binary patch literal 169 zcmZ?wbhEHb6krfwc+9|X=FFLyGiRoyrFC?4FfcGEDJcmG3c9$sgocKemzV#?0E$0Z z7#SG&8FYY(fhGtrFtCJuIO(~X#e!YC`M>=1-X&}`hZy*ns;XQV#aey~wn_19;g#p$ zXA1nx5y$A{B&NaB)%aLR&m*e2@Hvv|dd1i$syEq}PP HFjxZsLrFoX literal 0 HcmV?d00001 diff --git a/file/images/mkdir.gif b/file/images/mkdir.gif new file mode 100644 index 0000000000000000000000000000000000000000..f8c1594f951450dda794e6deda28677d550724f7 GIT binary patch literal 106 zcmZ?wbh9u|lwgoxSjfQe|Ns9pXU@!=IWsLSO@{#pK;jHc&Mo~bPrtq2G{=Co@$-u3 zX?qGUdrX_0P;viMRwnoQg;Ix$WAE?y`)=*K$zPk~6$DLexO&{xE=uy~vR_&Cwd!fc K_B-y34AuZj)GoIG literal 0 HcmV?d00001 diff --git a/file/images/mount.gif b/file/images/mount.gif new file mode 100644 index 0000000000000000000000000000000000000000..eb824e7aa730fd0afeff21eceab46e9b3789c714 GIT binary patch literal 221 zcmZ?wbhEHblwgoxc+9}?|NsA+H*ap*v}xwdnGFpMJv}|e#l>l9Y0H)^J9FmD{{8!( zJ$nXJ0|z<`KmgLqz%ohTgy-t5jy#8U3QRW@an79OCg64JrP$GpOiYfuR_w`geJ5A~F*mtO8c0k5DSH~%<|7_~w(l7ce*--duq(s_x}e5*LGL2b%*jk) R#thuEvc1-C6%}N#1^|w>WOo1n literal 0 HcmV?d00001 diff --git a/file/images/new.gif b/file/images/new.gif new file mode 100644 index 0000000000000000000000000000000000000000..94c4b2f8ed84e9efb4c1b06afc33f4889e09435b GIT binary patch literal 85 zcmZ?wbh9u|lwgoxXkcLY|NsA)GiP)dfB+=Iz+}?Wzw-23u|;$EkBMr9-aI?6;YNF< p%Ja;Z%8TA`P0zo4%IEDpt-Y@|%b)((cJRXUij^AEPcboA0|1eICN2N~ literal 0 HcmV?d00001 diff --git a/file/images/open.gif b/file/images/open.gif new file mode 100644 index 0000000000000000000000000000000000000000..06b68f6bf57b1269cb2f30592821130648e14992 GIT binary patch literal 114 zcmV-&0FD1gNk%v~VHf}y0HFW?|NsBY%*>gYnPz5YEC2ui02lxm0006@gpaAqtpTH3 zLD(y1s@Q5YgyKk+gJGs-#I|lEgj`40@i5!^o$qxB==nM);qX#C+LB5dvx#{^EvMiV UV=yYS*Nfq%3V+7r^0)v1JD9mMS^xk5 literal 0 HcmV?d00001 diff --git a/file/images/paste.gif b/file/images/paste.gif new file mode 100644 index 0000000000000000000000000000000000000000..62c79dcb2ef4f8734c686fb0e1f7fa4369331521 GIT binary patch literal 152 zcmZ?wbh9u|lwgoxIK;s4|Ns9pXU?Rhr7cLAG|M^BtsPlo2)jPHy&zm7e*vrE2r_V!m78pU%&L=JTwb7Nw#1^{Z} BA~yg4 literal 0 HcmV?d00001 diff --git a/file/images/preview.gif b/file/images/preview.gif new file mode 100644 index 0000000000000000000000000000000000000000..d7c2cf4d7289477356db5ec9b11a1ab4656468fc GIT binary patch literal 412 zcmZ?wbhEHblwgoxSjxcg|NsBht5?_8*E29Q0C^4$`x_b>{{MIQ|9}7f{SH8;g9DKD zpMk-Ffq_9sXLWdZxT9mEg9A|UelamIM@L7FqIQmt>>L}}IgHpH8-ZMRjv{vc$9()L zd<+c@R{d5wt96X$8jD>OWBAViG!$qf6@d=WSwNpiFfgzkbZ98>U}0f8x+JI~MQQq} zv_LLXyXjY6Zp~6n+j)3df`i`d^Dlr-&)9vx!0F(Jxa05NF*n`Y_V_&~J8NEDeH%+_ z1y@@q3pY<5H^YQ{?v|WV zQqnTwvNCen@&{zaPn=LtJguZGt8!dLSv>oM$_48Hu^)X v$BPX1SxEwsOd7Z6s`#AE+xxEf9rHsMvqu>_7Oae#u5dZC$7^{96N5DXR)r>5 literal 0 HcmV?d00001 diff --git a/file/images/rename.gif b/file/images/rename.gif new file mode 100644 index 0000000000000000000000000000000000000000..5a53743672a701c6ea28da97e9a1dfdb0c1fa64d GIT binary patch literal 144 zcmZ?wbh9u|lwgoxIK;s4|NsBAw6vKsXP!B8h5-rafY=~449u|{yYBomIQ6n=uSNF4 zE#D70csAdN5nRahRFWZo)fOKc!Ob^s3Y~j3leO*P;Es+3@0 zU{0vmb?2YKshtc93?u$D)jMhQH9cZoV6a9fdfrM00cP9FOmBK}*S|NNt^0%dTa@dA zT(>V%lvX`{U{c`}awuw{zyZ%id)K~}UJ_XqHbKNUu7BaX@22~_q#u7{%hZ4LOnP(L*Qi(ayn2yMi?cjalg}Zg zNzd|}Rz|HC2|TLwwv17{r@ZG(#)*u>YQ1Kgk0*SLUiI|cMCFX>T}LNP3$k@_^KEi* Z@Mv?fbn0?3GBI;e(bbK@O(0HNeierZE1cs hEs)EVZSCnd-=tk%9(pXkt>);;t4p_92QV;L0|0I=GSL74 literal 0 HcmV?d00001 diff --git a/file/images/save.gif b/file/images/save.gif new file mode 100644 index 0000000000000000000000000000000000000000..eda222b44ca8d5dcdf9816b7791cf796a3a88fc0 GIT binary patch literal 92 zcmZ?wbhEHblwgoxXkcLY|NlS3e+I>$EQ}05paUX6G7L<{E&VG`zpZB~ar8@DzpCna rUWojO#=y+3XO>y7w6<|r?VrMXB>2qf2>)h=U>k`(5tX$LtPIuwEX*GA literal 0 HcmV?d00001 diff --git a/file/images/sdir.gif b/file/images/sdir.gif new file mode 100644 index 0000000000000000000000000000000000000000..ee9e5d7d330ae8e20f00e156bc5c5532aaececf7 GIT binary patch literal 180 zcmZ?wbhEHb6krfwc+9|X=FFLyGiP>mbfl%F2?`1t8yhn)FqD^WCf0FuoC*VjH2|22F!=xg literal 0 HcmV?d00001 diff --git a/file/images/share.gif b/file/images/share.gif new file mode 100644 index 0000000000000000000000000000000000000000..c10f92765d9e9bbd2a68700164526de620ca0467 GIT binary patch literal 132 zcmV-~0DJ#ONk%w1VHf}y0HFW?|NsA)nVHPY%w}e0A^r|cVPs_>cWHEJAV*0}Pyj3d z0000O02lxO0!xICsmt9Vq6{v{88WQ^-XB#_22Kv2bL{cHfz?bhK7d!|Nnpf{Q2h1n`h6S z-Mo1-SRshe0TCd*3@qgWCp}lMZO$ySK6^W@;+nvmjDiUfUF+VY?8?%)ytP-u{k=RB zr(>|h5sRsb9?mZqba-SgG5wGg3B0u>=x^duKaC%s)<~?`tGjfKaUw(S;61D~ntvSq&BKHz%*f(BtS5T;$ z#NK+ui{bMD7JYul!e9k1=Kch63yGZN2NpCayqLhQQ6}*9!!j4SZw)7|?rY3rSY0Z5 X@<2x7)K{g{~sFqzpwBAs#X6XBLDyEFaQBa4Fj_-$F4j73{H8j u-fQvtY^p$lMw_#XNXDvVO*{8xaL@gqWq*GKck1*12No1~=;R48SOWlaz$^>^ literal 0 HcmV?d00001 diff --git a/file/images/sudir.gif b/file/images/sudir.gif new file mode 100644 index 0000000000000000000000000000000000000000..5f164a249c1f432d4186b9e2ed1b9a8358b3ae10 GIT binary patch literal 186 zcmZ?wbhEHb6krfwc+9|X=FFLyGiRoyrInYL8yg#khK6=@bmZmbO_(r2NlB@`zTU^j zM^I2OHa7M@7%2W^VPs(7XV75)0+1ODEa@Lkdah=%VApQ`FF(C^30s4P)*NO>k$HtR z9UG)t1UWnx=y04**eG9Asa)tWUAx6Kf^EYo{?&A$C!j11NQ$Jrk^ literal 0 HcmV?d00001 diff --git a/file/images/text.gif b/file/images/text.gif new file mode 100644 index 0000000000000000000000000000000000000000..c878641f6fa35ee5ee421675482fdd3dc68fd486 GIT binary patch literal 91 zcmZ?wbhEHb6krfwSjfQe|Ns9pXU@!=Ig^2bLGdRGBamXy0TCd11}2>r*_Bntd6{As sUAr-D&P=9mO9Az!=>kg0$L3AfTK8d3-j|H!rrNJ9?_JE`VP&ue05mKg!Te23iU#3eSkJv`)CxZ+^I z{rOBv4?R_K=7k3sa!atCXfP7H@w3R`l|kbHwL-IHjt{3c*|sx(?f#^3qA@JUYsKyN L<$eDI85yhrSeHw~ literal 0 HcmV?d00001 diff --git a/file/images/unknown.gif b/file/images/unknown.gif new file mode 100644 index 0000000000000000000000000000000000000000..d3664bf9cb13e5bdcbf466958d54e7440315e2d8 GIT binary patch literal 79 zcmZ?wbhEHb6krfwXkcLY|NsA)GiMZkvM@3LfewfO$uKafwaBilI?l@!W3Wy2`O;fg fx$8VM(iUe_u9!LP$?;90J=?zRNt_YLz+epk+T0vo literal 0 HcmV?d00001 diff --git a/file/images/upload.gif b/file/images/upload.gif new file mode 100644 index 0000000000000000000000000000000000000000..d97a9106e128e62ba06cd7812bef12ad9b87d411 GIT binary patch literal 154 zcmV;L0A>G2Nk%v~VHf}y0KxzO|NsBY%*+4)0A^-p`V&CR%>S90nE(I)EC2ui02lxm z000AL2)Y~oFtX`{z1W7yYW^FicpnyuWT}Z`pqea@s^>J!Wz7utd+7__z^4%!kC9~H z$mA&@&0}l|5I!X$=hZ;~Dh9IcW9lfF&u9lZfNmGm)c9KL9T@`mJbr(VK@5O_fpBt# Ih71V+JN*1WcK`qY literal 0 HcmV?d00001 diff --git a/file/images/view.gif b/file/images/view.gif new file mode 100644 index 0000000000000000000000000000000000000000..6f3bcb149e83ae35b85cb55ac9021d25d5ba2945 GIT binary patch literal 138 zcmZ?wbh9u|lwgoxIK;s49|%As!"; + $returnhtml = &text('index_index', + "$gconfig{'webprefix'}/")."

"; + } + } + +if ($gconfig{'referers_none'}) { + # Because java applet HTTP requests don't always include a referer: + # header, we need to use a DBM of trust keys to identify trusted applets + if (defined(&seed_random)) { &seed_random(); } + else { srand(time() ^ $$); } + $trust = int(rand(1000000000)); + local $now = time(); + &open_trust_db(); + foreach $k (keys %trustdb) { + if ($now - $trustdb{$k} > 30*24*60*60) { + delete($trustdb{$k}); + } + } + $trustdb{$trust} = $now; + dbmclose(%trustdb); + } + +$sharing = $access{'uid'} ? 0 : 1; +$mounting = !$access{'uid'} && &foreign_check("mount") ? 1 : 0; +if ($in{'open'}) { + $open = ""; + } +if ($session_id) { + $session = ""; + } +if (!$access{'noconfig'}) { + $config = ""; + } +$iconsize = int($config{'iconsize'}); +$root = join(" ", @allowed_roots); +$noroot = join(" ", @denied_roots); + +foreach $d (@disallowed_buttons) { + $disallowed .= "\n"; + } + +# Create parameters for custom colours +foreach $k (keys %tconfig) { + if ($k =~ /^applet_(.*)/) { + $colours .= "\n"; + } + } + +# Extract classes from jar, if we can +if ($config{'extract'} && + &has_command("unzip") && !-r "$module_root_directory/FileManager.class") { + system("unzip file.jar >/dev/null 2>&1"); + } + +print < +function upload(dir) +{ +open("upform.cgi?dir="+escape(dir)+"&trust=$trust", "upload", "toolbar=no,menubar=no,scrollbar=no,width=450,height=200"); +} +function htmledit(file, dir) +{ +open("edit_html.cgi?file="+escape(file)+"&dir="+escape(dir)+"&trust=$trust", "html", "toolbar=no,menubar=no,scrollbar=no,width=800,height=600"); +} + + + + + + + + + + + + + + + + + + + + + +$config +$session +$open +$return +$disallowed +$colours +$text{'index_nojava'}

+$returnhtml +

+EOF +&footer(); + + diff --git a/file/index.cgi.bak b/file/index.cgi.bak new file mode 100755 index 000000000..012d8f71b --- /dev/null +++ b/file/index.cgi.bak @@ -0,0 +1,79 @@ +#!/usr/local/bin/perl +# index.cgi +# Output HTML for the file manager applet + +require './file-lib.pl'; +&ReadParse(); +$theme_no_table = 1; +if ($access{'uid'} < 0 && !defined(getpwnam($remote_user))) { + &error(&text('index_eremote', $remote_user)); + } + +# Display header, depending on how many modules the user has +&read_acl(undef, \%acl); +$mc = @{$acl{$base_remote_user}} == 1; +$nolo = $ENV{'ANONYMOUS_USER'} || + $ENV{'SSL_USER'} || $ENV{'LOCAL_USER'} || + $ENV{'HTTP_USER_AGENT'} =~ /webmin/i; +if ($gconfig{'gotoone'} && $mc == 1 && !$nolo) { + &header($text{'index_title'}, "", undef, 0, 1); + $w = 100; + $h = 80; + } +else { + &header($text{'index_title'}); + $w = 100; + $h = 100; + } + +if ($gconfig{'referers_none'}) { + # Because java applet HTTP requests don't always include a referer: + # header, we need to use a DBM of trust keys to identify trusted applets + if (defined(&seed_random)) { &seed_random(); } + else { srand(time() ^ $$); } + $trust = int(rand(1000000000)); + local $now = time(); + &open_trust_db(); + foreach $k (keys %trustdb) { + if ($now - $trustdb{$k} > 30*24*60*60) { + delete($trustdb{$k}); + } + } + $trustdb{$trust} = $now; + dbmclose(%trustdb); + } + + +$sharing = $access{'uid'} ? 0 : 1; +&read_acl(undef, \%acl); +$mc = @{$acl{$base_remote_user}}; +if (!$gconfig{'gotoone'} || $mc > 1) { + %minfo = &get_module_info(); + $return = ""; + } +if ($in{'open'}) { + $open = "\n"; + } +print < +function upload(dir) +{ +open("upform.cgi?dir="+dir+"&trust=$trust", "upload", "toolbar=no,menubar=no,scrollbar=no,width=450,height=200"); +} + + + + + + + + + +$open +$return +$text{'index_nojava'}

+

+EOF +&footer(); + + diff --git a/file/irix-getfacl.pl b/file/irix-getfacl.pl new file mode 100755 index 000000000..58823367b --- /dev/null +++ b/file/irix-getfacl.pl @@ -0,0 +1,53 @@ +#!/usr/local/bin/perl +# irix-getfacl.pl +# Wrapper for the ls -D command + +$esc = quotemeta($ARGV[0]); +$out = `ls -dDL $esc 2>&1`; +if ($?) { + print STDERR $out; + exit 1; + } +if ($out !~ /\[([^\]]*)\]/) { + print STDERR "Failed to parse ls -D output : $out\n"; + exit 1; + } +if ($1) { + # Convert to normal ACL form + ($acl, $dacl) = split(/\//, $1); + foreach (split(/,/, $acl)) { + s/^u:/user:/; + s/^g:/group:/; + s/^o:/other:/; + s/^m:/mask:/; + print $_,"\n"; + } + foreach (split(/,/, $dacl)) { + s/^u:/user:/; + s/^g:/group:/; + s/^o:/other:/; + s/^m:/mask:/; + print "default:",$_,"\n"; + } + } +else { + # Make up ACL from perms + local @st = stat($ARGV[0]); + local $other = $st[2] & 7; + local $group = ($st[2] >> 3) & 7; + local $user = ($st[2] >> 6) & 7; + print "user::",&octal_to_perms($user),"\n"; + print "group::",&octal_to_perms($group),"\n"; + print "other::",&octal_to_perms($other),"\n"; + print "mask::",&octal_to_perms($user | $group),"\n"; + } + +sub octal_to_perms +{ +local $rv; +$rv .= ($_[0] & 4 ? "r" : "-"); +$rv .= ($_[0] & 2 ? "w" : "-"); +$rv .= ($_[0] & 1 ? "x" : "-"); +return $rv; +} + diff --git a/file/irix-setfacl.pl b/file/irix-setfacl.pl new file mode 100755 index 000000000..43d92befc --- /dev/null +++ b/file/irix-setfacl.pl @@ -0,0 +1,40 @@ +#!/usr/local/bin/perl +# irix-setfacl.pl +# Wrapper for the chacl command + +while() { + s/\r|\n//g; + $default = ($_ =~ s/^default://); + s/^(other|mask):([rwx\-]{3})$/\1::\2/g; + if ($default) { + push(@dacl, $_); + } + else { + push(@acl, $_); + } + } +$esc = quotemeta($ARGV[0]); +$acl = join(",", @acl); +$dacl = join(",", @dacl); +if ($acl && $dacl) { + $out = `chacl -b $acl $dacl $esc 2>&1`; + } +elsif ($acl) { + if (-d $ARGV[0]) { + $out = `chacl $acl $esc 2>&1 && chacl -D $esc 2>&1`; + } + else { + $out = `chacl $acl $esc 2>&1`; + } + } +elsif ($dacl) { + $out = `chacl -d $dacl $esc 2>&1 && chacl -R $esc 2>&1`; + } +else { + $out = `chacl -B $esc 2>&1`; + } +if ($?) { + print STDERR $out; + exit 1; + } + diff --git a/file/lang.cgi b/file/lang.cgi new file mode 100755 index 000000000..132777488 --- /dev/null +++ b/file/lang.cgi @@ -0,0 +1,21 @@ +#!/usr/local/bin/perl +# lang.cgi +# Return language translation values + +require './file-lib.pl'; + +print "Content-type: text/plain\n\n"; + +if (&get_charset() eq $default_charset) { + # Convert any HTML entities to their 'real' single-byte forms, + # as we are using the iso-8859-1 character set. + foreach $k (keys %text) { + print $k,"=",&entities_to_ascii($text{$k}),"\n"; + } + } +else { + # Don't do HTML entity conversion for other character sets + foreach $k (keys %text) { + print $k,"=",$text{$k},"\n"; + } + } diff --git a/file/lang/bg b/file/lang/bg new file mode 100644 index 000000000..243e87d4d --- /dev/null +++ b/file/lang/bg @@ -0,0 +1,322 @@ +index_title=File Manager +index_nojava=Òîçè ìîäóë èçïîëçâà java, íî Âàøèÿò áðàóçúð íÿìà java ïîääðúæêà +index_eremote=Íÿìà Unix ïîòðåáèòåë êîéòî äà ñúâïàäà ñ Webmin ïîòðåáèòåëñêîòî èìå $1. +switch_euser=Unix ïîòðåáèòåëÿ íå ñúùåñòâóâà! + +top_ret=Index +top_down=Çàïèñ +top_edit=Ðåäàêòèðàíå +top_refresh=Îïðåñíè +top_info=Èíôîðìàöèÿ +top_eacl=ACL +top_attr=Àòòð. +top_ext=EXT +top_delete=Èçòðèé +top_new=Íîâ +top_upload=Upload +top_rename=Ïðåèìåíóâàé +top_copy=Êîïèðàé +top_cut=Îòðåæè +top_paste=Ïîñòàâè +top_share=Sharing +top_mount=Mount +top_search=Òúðñè +top_config=Êîíôèãóðàöèÿ + +right_name=Èìå +right_size=Ðàçìåð +right_user=Ïîòðåáèòåë +right_group=Ãðóïà +right_date=Äàòà + +edit_enormal=Ñàìî îáèêíîâåíèòå ôàéëîâå ìîãàò äà áúäà ðåäàêòèðàíè +edit_title=Ðåäàêòèðàíå íà $1 +edit_title2=Ñúçäàâàíå íà ôàéë +edit_filename=Ôàéë: +edit_goto=Âúðâè +edit_find=Òúðñè +edit_gotoline=Âúðâè íà ðåä +edit_replace=Çàìåíè +edit_all=Çàìåíè âñè÷êè +edit_searchfor=Òúðñè çà +edit_replaceby=Çàìåíè ñúñ +edit_eover=$1 íå ìîæå äà áúäå ïðåçàïèñàí +edit_esave=Ãðåøêà ïðè çàïèñ íà ôàéë : $1 +edit_eaccess=Íÿìàòå ïðàâà äà çàïèøåòå '$1' +edit_notfound=Òåêñòúò $1 íå å íàìåðåí +edit_saveclose=Çàïèøè & Çàòâîðè + +info_file=Ôàéë +info_path=Ïúò: +info_type=Òèï: +info_size=Ðàçìåð: +info_mod=Ìîäèôèöèðàí íà: +info_link=Âðúçêà êúì: +info_perms=Ïðàâà +info_user=Ïîòðåáèòåëñêè: +info_group=Ãðóïîâè: +info_other=Âñè÷êè äðóãè: +info_octal=Îñìè÷íè: +info_sticky=Sticky: +info_sticky2=Ñàìî ñîáñâåíèöèòå ìîãàò äà èçòðèâàò ôàéëîâå +info_own=Ñîáñòâåíèê +info_setuid=Setuid: +info_setuid2=Èçïúëíÿâàé êàòî ïîòðåáèòåë +info_setgid=Setgid: +info_setgid2=Ôàéëîâåòå íàñëåäÿâàò ãðóïà +info_setgid3=Èçïúëíÿâàé êàòî ãðóïà +info_apply=Ïðèëîæè ïðîìåíèòå íà +info_apply1=Ñàìî òàçè äèðåêòîðèÿ +info_apply2=Òàçè äèðåêòîðèÿ è ôàéëîâåòå â íåÿ +info_apply3=Òàçè äèðåêòîðèÿ è âñè÷êè íåéíè ïîääèðåêòîðèè +info_efailed=Ãðåøêà ïðè îáíîâÿâàíå íà $1 : $2 +info_read=×åòåíå +info_write=Çàïèñ +info_list=Ïðåãëåä +info_exec=Èçïúëíÿâàíå + +eacl_eacls=Ãðåøêà ïðè ÷åòåíå íà ACL : $1 +eacl_acltype=ACL Òèï +eacl_aclname=Ïðèëîæè íà +eacl_aclperms=Ïðàâà +eacl_add=Äîáàâè ACL îò òèïà : +eacl_remove=Ïðåìàõíè ACL +eacl_efs=Ôàéëîâàòà ñèñòåìà $1 íå ïîääúðæà ACL +eacl_create=Ñúçäàé ACL +eacl_edit=Ðåäàêòèðàé ACL +eacl_user=Ñîáñòâåíèê íà ôàéë $1 +eacl_group=Ãðóïà çà ôàéë $1 +eacl_eowner=Ëèïñâàù ïîòðåáèòåë èëè ãðóïà çà ïðèëàãàíå +eacl_efailed=Ãðåøêà ïðè çàäàâàíå íà ACL çà $1 : $2 +eacl_emask=Ìîæå äà ñúùåñòâóâà ñàìî åäèí mask ACL +eacl_edefmask=Ìîæå äà ñúùåñòâóâà íàé-ìíîãî åäíî ïîäðàçáèðàùî ñå mask ACL +eacl_title=ACL çà $1 +eacl_owner=Ñîáñòâåíèê íà ôàéë +eacl_edefaults=Àêî íà ôàéë å çàäåäàí ïîäðàçáèðàù ñå ACL, òîé òðÿáâà äà èìà ïîäðàçáèðàù ñå ïîòðåáèòåëñêè, ãðóïîâ è äðóã ACL. + +acltype_user=Ïîòðåáèòåë +acltype_group=Ãðóïà +acltype_other=Äðóãè +acltype_mask=Ìàñêà +acltype_default_user=Ïîäðàçáèðàù ñå ïîòðåáèòåë +acltype_default_group=Ïîäðàçáèðàùà ñå ãðóïà +acltype_default_other=Ïîäðàçáèðàùè ñå äðóãè +acltype_default_mask=Ïîäðàçáèðàùà ñå ìàñêà + +delete_mtitle=Èçòðèé íÿêîëêî ôàéëà +delete_dtitle=Èçòðîé äèðåêòîðèÿ +delete_ftitle=Èçòðèé ôàéë +delete_ddesc=Ñèãóðíè ëè ñòå, ÷å èñêàòå äà èçòðèåòå äèðåêòîðèÿ $1 è âñè÷êî â íåÿ? +delete_fdesc=Ñèãóðíè ëè ñòå, ÷å èñêàòå äà èçòðèåòå ôàéë $1 ? +delete_mdesc=Ñèãóðíè ëè ñòå, ÷å èñêàòå äà èçòðèå òåçè ôàéëîâå è äèðåêòîðèè? : +delete_efailed=Ãðåøêà ïðè èçòðèâàíå íà $1 : $2 + +mkdir_title=Ñúçäàâàíå íà äèðåêòîðèÿ +mkdir_dir=Íîâà äèðåêòîðèÿ: +mkdir_eexists=$1 âå÷å ñúùåñòâóâà +mkdir_efailed=Ãðåøêà ïðè ñúçäàâàíå íà äèðåêòîðèÿ : $1 +mkdir_eaccess=Íÿìàòå ïðàâà çà ñúçäàâàíå íà '$1' + +link_title=Ñúçäàâàíå íà ïðåïðàòêà +link_from=Ïðåïðàòêà çà: +link_to=Ïðåïðàòêà êúì: +link_eexists=$1 âå÷å ñúùåñòâóâà +link_efailed=Ãðåøêà : $1 +link_efrom=Íÿìàòå ïðàâà çà ñúçäàâàòå ïðåïðàòêà íà '$1' +link_efollow=Íÿìàòå ïðàâà çà ñúçäàâàíå íà ïðåïðàòêè + +rename_title=Ïðåèìåíóâàíå íà $1 +rename_old=Ñòàðî èìà: +rename_new=Íîâî èìå: +rename_ok=Ïðåèìåíóâàé +rename_eexists=Ôàéë ñ èìå $1 âå÷å ñúùåñòâóâà +rename_efailed=Ãðåøêà ïðè ïðåèìåíóâàíå : $1 +rename_eold=Íÿìàòå ïðàâà çà ïðåèìåíóâàíå íà '$1' +rename_enew=Íåâúçìîæíî ïðåèìåíóâàíå â '$1' + +file_type0=Äèðåêòîðèÿ +file_type1=Òåêñòîâ ôàéë +file_type2=Ãðàôè÷åí ôàéë +file_type3=Áèíàðåí ôàéë +file_type4=Ôàéë +file_type5=Ïðåïðàòêà +file_type6=Óñòðîéñòâî +file_type7=Pipe + +view_enormal=Ñàìî îáèêíîâåííè ôàéëîâå ìîãàò äà áúäàò ðàçãëåæäàíè +view_enormal2=Ñàìî îáèêíîâåííè ôàéëîâå ìîãàò äà áúäàò download-âàíè +view_eaccess=Íÿìàòå ïðàâà çà äîñòúï äî $1 +view_eopen=Ãðåøêà ïðè îòâàðÿíå íà $1 : $2 + +paste_ecopy=Òðÿáâà äà ñòå êîïèðàëè èëè îòðÿçàëè íåùî ïðåäè äà èçïúëÿâàòå "ïîñòàâè" +paste_egone=Êîïèðàíèÿò ôàéë $1 âå÷å íå ñúùåñòâóâà +paste_eover=$1 íå ìîæå äà áúäå ïðåçàïèñàí +paste_eself=Íå ìîæåòå äà èçïúëíèòå "ïîñòàâè" âúðõó ñúùèÿò ôàéë +paste_emfailed=Ãðåøêà ïðè ïðåìåñòâàíå íà : $1 +paste_ecfailed=Ãðåøêà ïðè êîïèðàíå íà : $1 + +over_title=Ôàéëúò ñúùåñòâóâà âå÷å +over_msg=Ôàéëúò $1 ñúùåñòâóâà âå÷å. Èçïîëçâàéòå ïîëåòî çà äà âúâåäåòå íîâî èìå íà ôàéëà. +over_new=Íîâî èìå: +over_ok=Îê + +upload_efailed=Ãðåøêà ïðè îòâàðÿíå íà upload : $1 +upload_title=Upload íà ôàéë +upload_file=Ôàéë çà upload +upload_dir=Upload â äèðåêòîðèÿ +upload_ok=Upload +upload_conv=Êîâåðòèðàé â DOS ôîðìàò íîâèòå ðåäîâå? +upload_efile=Íå å ïîñî÷åí ôàéë çà upload. +upload_edir=Upload äèðåêòîðèÿòà íå ñúùåñòâóâà. +upload_eperm=Íÿìàòå ïðàâà çà ñúçäàâàíå íà $1 +upload_ewrite=Ãðåøêà ïðè çàïèñ íà $1 : $2. +upload_already=Ôàéëúò $1 âå÷å ñúùåñòâóâà. Ñèãóðíè ëè ñòå, ÷å èñêàòå äà ãî ïðåçàïèøåòå? + +find_eaccess=Íÿìàòå ïðàâà çà äîñòúï äî $1 +find_eexist=$1 íå ñúùåñòâóâà â $2 +find_edir=$1 íå å äèðåêòîðèÿ â $2 + +cancel=Îòêàæè +close=Çàòâîðè + +chmod_eaccess=Íÿìàòå ïðàâà çà äîñòúï äî '$1' +chmod_euser=$1 : íåñúùåñòâóâàù ïîòðåáèòåë +chmod_egroup=$1 : íåñúùåñòâóâàùà ãðóïà +chmod_elink=Ãðåøêà ïðè ñúçäàâàíå íà ïðåïðàòêà : $1 +chmod_echown=Ãðåøêà ïðè ïðîìÿíà íà ñîáñòâåíèêà : $1 +chmod_echmod=Ãðåøêà ïðè ïðîìÿíà íà ïðàâàòà : $1 +chmod_efollow=Íÿìàòå ïðàâà çà ïðîìÿíà íà ïðåïðàòêè + +copy_efrom=Íÿìàòå ïðàâà äà êîïèðàòå îò '$1' +copy_eto=Íÿìàòå ïðàâà äà êîïèðàòå íà '$1' +copy_elink=ãðåøêà ïðè ñúçäàâàíå íà ïðåïðàòêà : $1 + +delete_eaccess=Íÿìàòå ïðàâà äà èçòðèåòå '$1' + +list_eaccess=Íÿìàòå ïðàâà çà äîñòúï äî òàçè äèðåêòîðèÿ +list_edir=Ãðåøêà ïðè ïîêàçâàíå íå $1 : $2 + +move_eto=Íÿìàòå ïðàâà äà ïðåìåñâàòå â '$1' +move_afrom=Íÿìàòå ïðàâà äà ïðåìåñòèòå '$1' + +acl_user=Äîñòúï äî ôàéëîâåòå íà ñúðâúðà êàòî ïîòðåáèòåë +acl_user_def=Ñúùèÿò êàòî Webmin login +acl_umask=Umask çà íîâèòå ôàéëîâå +acl_follow=Âèíàãè ñëåäâàé ïðåïðàòêèòå? +acl_ro=Ðåæèì ñàìî çà ÷åòåíå? +acl_dirs=Ðàçðåøè äîñòúï ñàìî äî äèðåêòîðèèòå +acl_home=Âêëþ÷è home äèðåêòîðèÿòà íà Webmin ïîòðåáèòåëÿ +acl_log=Çàïèñâàé â æóðíàëà âñè÷êè ïðîìåíè íà ôàéëîâå? +acl_goto=Ïîêàçâàé ïúðâàòà ðàçðåøåíà äèðåêòîðèÿ? + +share_title=Sharing +share_samba=Windows +share_nfs=NFS +share_son=Windows ñïîäåëÿíå íà ôàéëîâå ðàçðåøåíî +share_soff=Windows ñïîäåëÿíå íà ôàéëîâå çàáðàíåíî +share_writable=Ïðàâà çà çàïèñ? +share_available=Ðàçðåøåì â ìîìåíòà? +share_sheader=Sharing íàñòðîéêèòå +share_only=Ñàìî +share_guest=Àíîíèìåí äîñòúï? +share_comment=Êîìåíòàð +share_nheader=Íàñòðîéêè íà NFS åñïîðò +share_non=NFS ñïîäåëÿíå íà ôàéëîâå ðàçðåøåíî +share_noff=NFS ñïîäåëÿíå íà ôàéëîâå çàáðàíåíî +share_desc=Îïèñàíèå +share_ro=Õîñòîâå ñ ïðàâà ñàìî çà ÷åòåíå +share_rw=Õîñòîâå ñ ïðàâà çà ÷åòåíå è çàïèñ +share_root=Õîñòîâå ñ àäìèíñòðàòîðñêè ïðàâà +share_none=Íèùî +share_all=Âñè÷êî +share_listed=Èçáðàíèòå.. +share_host=Õîñòîâå +share_opts=Íàñòðîéêè +share_s0=Íå ñå äîâåðÿâàé íà íèêîé +share_s1=Äîâåðè íå íå àäìèíñòðàòîðèòå +share_s2=Äîâåðè ñå íà âñè÷êè +share_lro=Ñàìî çà ÷åòåíå +share_lrw=×åòåíå è çàïèñ + +log_create_export=Ñúçäàäåí NFS åêñïîðò $1 +log_modify_export=Ìîäèôèöèðàí NFS åêñïîðò $1 +log_delete_export=Èçòðèò NFS åêñïîðò $1 +log_create_share=Ñúçäàäåíî Samba ñïîäåëÿíå $1 +log_modify_share=Ìîäîôèöèðàíî Samba ñïîäåëÿíå $1 +log_delete_share=Èçòðèòî Samba ñïîäåëÿíå $1 +log_save=Çàïèñàí å ôàéë $1 +log_chmod=Ïðîìåíåíè ïðàâàòà íà ôàéë $1 +log_mkdir=Ñúçäàäåíà äèðåêòîðèÿ $1 +log_upload=Upload-íàò ôàéë $1 +log_link=Ñúçäàäåíå ïðåïðàòêà îò $1 êúì $2 +log_relink=Ìîäèôèöèðàíå ïðåïðàòêà îò $1 êúì $2 +log_copy=Êîïèðàí å ôàéë îò $1 íà $2 +log_move=Ïðåìåñòåí å ôàéë îò $1 íà $2 +log_delete=Èçòðè ôàéë $1 +log_attr=Çàäàäåíè àòðèáóòè íà ôàéë $1 +log_acl=Çàäàäåí ACL íà ôàéë $1 + +search_eaccess=Íÿìàòå ïðàâà çà òúðñåíå â òàçè äèðåêòîðèÿ +search_title=Òúðñè ôàéë +search_ok=Òúðñè +search_dir=Òúðñè äèðåêòîðèÿ +search_match=Ôàéëîâå, êîèòî +search_user=Ñîáñòâåíîñò íà ïîòðåáèòåë +search_group=Ñîáñòâåíîñò íà ãðóïà +search_any=Âñè÷êè +search_type=Âèä ôàéë +search_types_=Âñè÷êè +search_types_f=Ôàéë +search_types_d=Äèðåêòîðèÿ +search_types_l=Ïðàïðàòêà +search_types_p=Named pipe +search_size=Ðàçìåð íà ôàéë +search_more=Ïîâå÷å îò +search_less=Ïî-ìàëêî îò +search_xdev=Òúðñè â ìîíòèðàíèòå ó-âà? +search_edir=Ëèïñâàùà èëè íåâàëèäíà äèòðåêòîðèÿ çà òúðñåíå +search_ematch=Ëèïñâàù ðåãóëÿðåí èçðàç çà òúðñåíå +search_euser=Ëèïñâàùî èìå íà ïîòðåáèòåë +search_egroup=Ëèïñâàùî èìå íà ãðóïà +search_esize=Ðàçìåðà íà ôàéëà òðÿáâà äà å öÿëî ÷èñëî +search_crit=Êðèòåðèè çà òúðñåíå +search_list=Ðåçóëòàòè îò òúðñåíå + +facl_eaccess=Íÿìàòå ïðàâà çà çàäàâàíå íà ACL ìà òîçè ôàéë + +attr_eattrs=Ãðåøêà ïðè ðàç÷èòàíå íà àòðèáóòèòå : $1 +attr_efs=Ôàéëîâàòà ñèñòåìà $1 íå ïîääúðæà àòðèáóòè +attr_add=Äîáàâè àòðèáóò +attr_name=Èìå íà àòðèáóò +attr_value=Ñòîéíîñò íà àòðèáóò +attr_efailed=Ãðåøêà ïðè ðàç÷èòàíå íà àòðèáóòèòå $1 : $2 +attr_title=Ôàéëîâè àòðèáóòè íà $1 +attr_create=Äîáàâè àòðèáóò +attr_edit=Ïðîìÿíà íà àòðèáóò +attr_ename=Ëèïñâà èìå íà àòðèáóò + +ext_eattrs=Ãðåøêà ïðè ðàç÷èòàíå íà EXT àòðèáóòèòå : $1 +ext_efs=Ôàéëîâàòà ñèñòåìà $1 íå ïîääúðæà EXT àòðèáóòè +ext_title=EXT àòðèáóòè íà $1 +ext_header=EXT ôàéëîâè àòðèáóòè +ext_efailed=Ãåðøêà ïðè çàäàâàíå àòðèáóòèòå íà $1 : $2 + +eattr_A=Íå îáíîâÿâàé ïîñëåäíèÿò ìîìåíò íà äîñòúï +eattr_a=Ìîæå ñàìî äà áúäå äîáàâÿíî êúì ôàéëà +eattr_c=Êîìïðåñèðàé äàííèòå íà äèñê +eattr_d=Íå ïðàâè backup ñúñ dump +eattr_i=Çàáðàâè ìîäèôèêàöèè +eattr_s=Çàïúëíè ñ íóëè ïðè èçòðèâàíå +eattr_S=Âèíàãè ïðàâè sync ñëåä îïåðàöèÿ çà çàïèñ +eattr_u=Çàïèñè ñúäúðæàíèåòî çà äà èìà âúçìîæíîñò çà âðúùàíå íà èçòðèò ôàéë + +mount_eaccess=Íÿìàòå ïðàâà çà ìîíòèðàíå íà ôàéëîâè ñèñòåìè +mount_efstab=Íÿìà íàìåðåíà ôàéëîâà ñúñòåìà íà ïîñî÷åíèÿò mounth point +mount_epoint=$1 å íåâàëèäåí mount point +mount_rusure1=Ñèãóðíè ëè ñòå, ÷å èñêàòå äà ìîíòèðàòå $1 îò $2 ? +mount_rusure2=Ñèãóðíè ëè ñòå, ÷å èñêàòå äà ðàçìîíòèðàíå $1 îò $2 ? +mount_err1=Ãðåøêà ïðè ìîíòèðàíå $1 : $2 +mount_err2=Ãðåøêà ïðè ðàçìîíòèðàíå $1 : $2 +mount_title1=Ìîíòèðàíà å ôàéëîâà ñèñòåìà +mount_title2=Ðàçìîíòèðàíå å ôàéëîâà ñèñòåìà + diff --git a/file/lang/ca b/file/lang/ca new file mode 100644 index 000000000..5700de166 --- /dev/null +++ b/file/lang/ca @@ -0,0 +1,424 @@ +index_title=Administrador de Fitxers +index_nojava=Aquest mòdul requereix java per funcionar, però el teu navegador no suporta java +index_eremote=No hi ha cap usuari Unix que coincideixi amb l'entrada $1 de Webmin. +index_index=Torna a l'Índex de Webmin. +switch_euser=L'usuari Unix no existeix! + +top_ret=Índex +top_down=Desa +top_preview=Previsualitza +top_edit=Edita +top_html=HTML +top_refresh=Refresca +top_info=Info +top_eacl=ACL +top_attr=Atributs +top_ext=EXT +top_delete=Suprimeix +top_new=Nou +top_upload=Puja +top_extract=Extreu +top_rename=Renomena +top_copy=Copia +top_cut=Retalla +top_paste=Enganxa +top_share=Xarxa +top_mount=Munta +top_search=Busca +top_config=Configura +top_efile=No has seleccionat cap fitxer + +right_name=Nom +right_size=Mida +right_user=Usuari +right_group=Grup +right_date=Data + +edit_enormal=Només es poden editar els fitxers normals +edit_title=Editant $1 +edit_title2=Creant el fitxer +edit_filename=Nom del fitxer: +edit_goto=Ves +edit_find=Busca +edit_gotoline=Ves a la línia +edit_replace=Reemplaça +edit_all=Reemplaça-ho tot +edit_searchfor=Busca +edit_replaceby=Reemplaça amb +edit_eover=$1 no es pot reescriure +edit_esave=No he pogut desar el fitxer: $1 +edit_eaccess=No tens permís per desar '$1' +edit_efollow=No tens permís per gravar l'enllaç simbòlic '$1' +edit_notfound=El text $1 no s'ha trobat +edit_saveclose=Desa & Tanca +edit_elength=S'ha escapçat el fitxer! + +info_file=Fitxer +info_path=Camí: +info_type=Tipus: +info_size=Mida: +info_mod=Modificat: +info_link=Enllaç a: +info_perms=Permisos +info_user=Usuari: +info_group=Grup: +info_other=Altres: +info_octal=Octal: +info_sticky=Sticky: +info_sticky2=Només els propietaris poden esborrar fitxers +info_own=Propietat +info_setuid=Setuid: +info_setuid2=Executa com a usuari +info_setgid=Setgid: +info_setgid2=Els fitxers hereten el grup +info_setgid3=Executa com a grup +info_apply=Aplica els canvis a +info_apply1=Aquest directori nomes +info_apply2=Aquest directori i els seus fitxers +info_apply3=Aquest directori i tots els seus subdirectoris +info_efailed=No he pogut actualitzar $1: $2 +info_read=Llegir +info_write=Escriure +info_list=Llistar +info_exec=Executar +info_sizeheader=Mida del directori +info_bytes=Total bytes: +info_files=Total fitxers: +info_dirs=Total directoris: +info_getsize=Obtingues la Mida +info_esize=No he pogut obtenir les mides: $1 + +eacl_eacls=No he pogut llegir les ACLs: $1 +eacl_acltype=Tipus d'ACL +eacl_aclname=Aplica a +eacl_aclperms=Permisos +eacl_add=Afegeix ACL del tipus: +eacl_remove=Esborra ACL +eacl_efs=El sistema de fitxers $1 no suporta ACLs +eacl_create=Crea ACL +eacl_edit=Edita ACL +eacl_user=Propietari del fitxer $1 +eacl_group=Grup del fitxer $1 +eacl_eowner=Hi falta l'usuari o el grup per aplicar +eacl_efailed=No he pogut establir l'ACL per a $1: $2 +eacl_emask=Hi pot haver com a molt una entrada de màscara ACL +eacl_edefmask=Hi pot haver com a molt una entrada per defecte de màscara ACL +eacl_title=ACL de $1 +eacl_owner=Propietari del fitxer +eacl_edefaults=Si un fitxer té alguna ACL per defecte, ha de tenir usuari i grup per defecte. + +acltype_user=Usuari +acltype_group=Grup +acltype_other=Altres +acltype_mask=Màscara +acltype_default_user=Usuari per defecte +acltype_default_group=Grup per defecte +acltype_default_other=Altres per defecte +acltype_default_mask=Màscara per defecte + +delete_mtitle=Suprimeix fitxers múltiples +delete_dtitle=Supressió de directori +delete_ftitle=Supressió de fitxer +delete_ddesc=Segur que vols esborrar de forma definitiva el directori $1 i tot el seu contingut? +delete_fdesc=Segur que vols esborrar de forma definitiva el fitxer $1? +delete_efailed=No he pogut esborrar $1: $2 +delete_mdesc=Segur que vols suprimir de forma permanent aquests fitxers i directoris? + +mkdir_title=Nou Directori +mkdir_dir=Nou directori: +mkdir_eexists=$1 ja existeix +mkdir_efailed=La creació del director ha fallat: $1 +mkdir_eaccess=No tens permís per crear '$1' + +link_title=Creació d'enllaç +link_from=Enllaça: +link_to=A: +link_eexists=$1 ja existeix +link_efrom=L'origen de l'enllaç ha de ser un camí absolut +link_efailed=L'enllaç ha fallat: $1 +link_efrom2=No tens permís per enllaçar '$1' +link_efollow=No tens permís per crear enllaços simbòlics + +rename_title=Renomenament de $1 +rename_old=Nom vell: +rename_new=Nom nou: +rename_ok=Renomena +rename_eexists=Ja existeix un fitxer anomenat $1 +rename_eslash=El nom de fitxer nou $1 conté una / +rename_efailed=El renomenament ha fallat: $1 +iename_eold=No tens permís per renomenar '$1' +rename_enew=No tens permís per renomenar a '$1' + +file_type0=Directori +file_type1=Fitxer de text +file_type2=Fitxer d'imatge +file_type3=Fitxer binari +file_type4=Fitxer +file_type5=Enllaç simbòlic +file_type6=Fitxer de dispositiu +file_type7=Pipe + +view_enormal=Només es poden mostrar els fitxers normals +view_enormal2=Només es poden descarregar fitxers normals +view_eaccess=No tens permís per accedir a $1 +view_eopen=No he pogut obrir $1: $2 +view_edir=Un arxiu només es pot crear per a un directori +view_ecmd=L'ordre $1 necessària per a crear un arxiu no està instal·lada +view_ecomp=No he pogut crear l'arxiu: $1 +view_earchive=No tens permís per descarregar arxius +view_earchmax=El directori seleccionat és més gran que el màxim permès per arxivar ($1 bytes) + +paste_ecopy=Has de copiar o retallar abans d'enganxar +paste_egone=El fitxer copiat $1 ja no existeix +paste_eover=$1 no es pot reescriure +paste_eself=No pots enganxar un fitxer sobre ell mateix +paste_emfailed=El desplaçament ha fallat: $1 +paste_ecfailed=La copia ha fallat: $1 + +over_title=Fitxer Existent +over_msg=El fitxer $1 ja existeix. Utilitza el camp inferior per introduir un nom de fitxer nou per al fitxer enganxat. +over_new=Nom de fitxer nou: +over_ok=Bé + +upload_efailed=No he pogut obrir el fitxer per pujar: $1 +upload_title=Puja de Fitxer +upload_file=Fitxer per pujar +upload_dir=Puja'l al directori +upload_ok=Puja +upload_conv=Converteix salts de línia DOS +upload_efile=No s'ha seleccionat cap fitxer per pujar. +upload_edir=El directori de destinació no existeix. +upload_eperm=No tens permís per crear $1 +upload_ewrite=No he pogut escriure a $1: $2. +upload_already=El fitxer $1 ja existeix. Segur que el vols reescriure? +upload_elink=No puc fer la puja sobre un enllaç simbòlic +upload_zip=Descomprimeixo el fitxer ZIP o TAR? +upload_yes=Sí, llavors suprimeix-lo + +find_eaccess=No tens permís per accedir $1 +find_eexist=$1 no existeix a $2 +find_edir=$1 no és un directori de $2 + +cancel=Cancel·la +close=Tanca +eopen=La descàrrega ha fallat: $1 + +chmod_eaccess=No tens permís per accedir '$1' +chmod_euser=$1: no existeix l'usuari +chmod_egroup=$1: no existeix el grup +chmod_elink=enllaç simbòlic fallit: $1 +chmod_echown=chown fallit: $1 +chmod_echmod=chmod fallit: $1 +chmod_efollow=No tens permís per editar els enllaços simbòlics + +copy_efrom=No tens permís per copiar de '$1' +copy_eto=No tens permís per copiar a '$1' +copy_elink=enllaç simbòlic fallit: $1 + +delete_eaccess=No tens permís per esborrar '$1' + +list_eaccess=No tens permís per accedir a aquest directori +list_edir=No he pogut llistar $1: $2 + +move_eto=No tens permís per desplaçar a '$1' +move_afrom=No tens permís per desplaçar '$1' + +acl_user=Accedeix els fitxers del servidor com a usuari +acl_user_def=Igual que l'usuari Webmin +acl_umask=Umask per a fitxers nous +acl_follow=Segueix sempre els enllaços simbòlics +acl_fyes=Si el propietari coincideix +acl_ro=Mode només lectura +acl_dirs=Permet l'accés nomes als directoris +acl_nodirs=Denega l'accés als directoris +acl_home=Inclou el directori arrel de l'usuari Webmin +acl_log=Enregistra totes les modificacions de fitxers +acl_goto=Obre el primer directori permès +acl_max=Mida màxima de pujada +acl_unlim=Il·limitada +acl_b=bytes +acl_archive=Pot descarregar arxius de directoris +acl_archmax=Sí, si són més petits de +acl_buttons=Botons disponibles a la barra d'eines +acl_button_save=Desa (descarrega el fitxer) +acl_button_preview=Previsualitza (visualitza imatge escalada) +acl_button_edit=Edita (edita el fitxer de text) +acl_button_info=Info (edita els permisos i propietat del fitxer) +acl_button_acl=ACL (edita l'ACL Posix) +acl_button_attr=Atr (edita els atributs XFS) +acl_button_ext=EXT (edita els atributs EXT) +acl_button_search=Busca (busca fitxers) +acl_button_delete=Suprimeix (suprimeix fitxers) +acl_button_new=Nou (crea fitxer de text) +acl_button_upload=Puja (puja un fitxer des del client) +acl_button_mkdir=Nou (crea un directori) +acl_button_makelink=Nou (crea un enllaç simbòlic) +acl_button_rename=Renomena (renomena el fitxer) +acl_button_sharing=Comparteix (configura els fitxers compartits Samba i NFS) +acl_button_mount=Munta (munta o desmunta el sistema de fitxers) +acl_button_copy=Copia, Retalla i Enganxa +acl_unarchive=Pot extreure fitxers d'un arxiu pujat +acl_unarchive2=Intenta-ho sempre +acl_unarchive1=$yes +acl_unarchive0=$no +acl_dostounix=Pot convertir els salts de línia DOS +acl_chroot=Directori chroot del gestor de fitxers complet +acl_relto=(relatiu a qualsevol directori chroot) +acl_noperms=Pot canviar els permisos dels fitxers +acl_nousers=Pot canviar el propietari dels fitxers +acl_filesystems=Pot veure els punts de muntatge dels sistemes de fitxers +acl_contents=Permet la recerca de continguts de fitxers + +share_title=Xarxa +share_samba=Windows +share_nfs=NFS +share_son=Compartició de fitxers Windows activada +share_soff=Compartició de fitxers Windows desactivada +share_writable=Gravable +share_available=Actualment actiu +share_sheader=Opcions del recurs +share_only=Nomes +share_guest=Accés hoste +share_comment=Comentari +share_nheader=Opcions d'exportació NFS +share_non=Compartició de fitxers NFS activada +share_noff=Compartició de fitxers NFS desactivada +share_desc=Descripció +share_ro=Hosts nomes lectura +share_rw=Hosts lectura/escriptura +share_root=Hosts amb accés root +share_none=Cap +share_all=Tot +share_listed=Llistats... +share_host=Hosts +share_opts=Opcions +share_s0=No et refiïs de ningú +share_s1=Refia't de no-root +share_s2=Refia't de tothom +share_lro=Només lectura +share_lrw=Lectura-escriptura + +log_create_export=He creat l'exportació NFS $1 +log_modify_export=He modificat l'exportació NFS $1 +log_delete_export=He suprimit l'exportació NFS $1 +log_create_share=He creat el recurs Samba $1 +log_modify_share=He modificat el recurs Samba $1 +log_delete_share=He suprimit el recurs Samba $1 +log_save=He desat el fitxer $1 +log_chmod=He canviat els permisos del fitxer $1 +log_mkdir=He creat el directori $1 +log_upload=He pujat el fitxer $1 +log_link=He creat l'enllaç simbòlic $1 a $2 +log_relink=He modificat l'enllaç simbòlic $1 a $2 +log_copy=He copiat el fitxer $1 a $2 +log_move=He desplaçat el fitxer $1 a $2 +log_delete=He esborrat el fitxer $1 +log_attr=Estableix atributs sobre el fitxer $1 +log_acl=Estableix ACL sobre el fitxer $1 + +search_eaccess=No tens permís per buscar en aquest directori +search_title=Busca Fitxers +search_ok=Busca ara +search_dir=Busca al directori +search_match=els fitxers que coincideixin amb +search_cont=que continguin el text +search_user=Usuari propietari +search_group=Grup propietari +search_any=Qualsevol +search_type=Tipus de fitxer +search_types_=Qualsevol +search_types_f=Fitxer +search_types_d=Directori +search_types_l=Enllaç simbòlic +search_types_p=Pipe +search_size=Mida del fitxer +search_more=Més de +search_less=Menys de +search_xdev=Busca muntatges anteriors +search_edir=Hi falta el directori de recerca o bé no és correcte +search_ematch=Hi falta una expressió regular +search_euser=Hi falta un nom d'usuari +search_egroup=Hi falta un nom de grup +search_esize=La mida del fitxer ha de ser un enter +search_crit=Criteris de Recerca +search_list=Resultats de la Recerca +search_down=Descarrega +search_edown=No has seleccionat cap fitxer de resultats de recerca per descarregar + +facl_eaccess=No tens permís per establir ACLs per a aquest fitxer + +attr_eattrs=No he trobat els atributs: $1 +attr_efs=El sistema de fitxers $1 no suporta atributs +attr_add=Afegeix Atribut +attr_name=Nom de l'Atribut +attr_value=Valor de l'Atribut +attr_efailed=No he pogut establir els atributs de $1: $2 +attr_title=Atributs de Fitxer de $1 +attr_create=Crea Atribut +attr_edit=Edita Atribut +attr_ename=Hi falta el nom de l'atribut + +ext_eattrs=No he pogut obtenir els atributs EXT: $1 +ext_efs=El sistema de fitxers $1 no suporta atributs EXT +ext_title=Atributs EXT de $1 +ext_header=Atributs EXT de fitxer +ext_efailed=No he pogut establir els atributs de $1: $2 + +eattr_A=No actualitzis els temps d'accés +eattr_a=Només pot afegir al fitxer +eattr_c=Comprimeix les dades del disc +eattr_d=No en facis còpia amb dump +eattr_i=No en permetis la modificació +eattr_s=Posa els blocs a zero en suprimir +eattr_S=Fes sempre un sync després de gravar +eattr_u=Desa el contingut per a desfer + +mount_eaccess=No tens permís per muntar sistemes de fitxers +mount_efstab=No hi ha cap sistema de fitxers en aquest punt de muntatge +mount_epoint=$1 no és un punt de muntatge +mount_rusure1=Segur que vols muntar $1 de $2 ? +mount_rusure2=Segur que vols desmuntar $1 de $2 ? +mount_err1=No he pogut muntar $1: $2 +mount_err2=No he pogut desmuntar $1: $2 +mount_title1=Munta el sistema de fitxers +mount_title2=Desmunta el sistema de fitxers + +zip_err=No puc extreure el fitxer: $1 +zip_ecmd=Hi falta l'ordre $1 +zip_eunzip=La descompressió ZIP ha fallat: $1 +zip_ename=No sembla que sigui cap fitxer zip, tar ni tar.gz +zip_euntar=El desarxivat TAR ha fallat: $1 +zip_euntar2=La descompressió i desarxivat TAR ha fallat: $1 + +ddir_title=Descàrrega de Directori +ddir_rusure=Per descarregar el contingut de $1 com un fitxer d'arxiu, fes clic sobre una dels botons de tipus d'arxiu de sota. +ddir_zip=ZIP +ddir_tgz=TAR.GZ +ddir_tar=TAR + +ebutton=Aquesta característica no està disponible + +preview_etype=No he pogut determinar el tipus de fitxer per a $1 +preview_etype2=$1 no és cap format d'imatge suportat +preview_ecmd=L'ordre $1 necessària per escalar la imatge no està instal·lada +preview_eimage=Només es poden previsualitzar imatges +preview_title=Vista Prèvia de $1 +preview_bad=No he pogut carregar la imatge a previsualitzar +preview_egd=No he pogut carregar la imatge amb GD + +html_efailed=No he pogut obrir l'editor HTML: $1 +html_title=Edició de Fitxer HTML +html_title2=Creació de Fitxer HTML +html_save=Desa i Tanca +html_err=No he pogut desar el fitxer HTML + +history_title=Historial de Camins +history_ok=Vés A +history_button=Historial + +extract_etype=Només es poden exterure fitxers +extract_title=Extracció de Fitxer Comprimit +extract_rusure=Segur que vols extreure el fitxer comprimit: +extract_rusure2=Els fitxers existents al mateix directori es reescriuran. +extract_err=No he pogut extreure el fitxer: $1 +extract_yes=Sí, després suprimeix-lo diff --git a/file/lang/de b/file/lang/de new file mode 100644 index 000000000..456396176 --- /dev/null +++ b/file/lang/de @@ -0,0 +1,345 @@ +acl_archive=Darf Archive von Verzeichnissen herunterladen? +acl_archmax=Ja, wenn sie kleiner sind als +acl_b=bytes +acl_button_acl=ACL (bearbeite Posix ACL) +acl_button_attr=ATTR (bearbeite XFS-Attribute) +acl_button_copy=Kopieren, Ausschneiden und Einfügen +acl_button_delete=Löschen (Dateien löschen) +acl_button_edit=Bearbeiten (Textdatei bearbeiten) +acl_button_ext=EXT (bearbeite EXT-Attribute) +acl_button_info=Info (bearbeite Dateirechte und -inhaberschaft) +acl_button_makelink=Neu (Erzeuge symbolischen Link) +acl_button_mkdir=Neu (Erzeuge Verzeichnis) +acl_button_mount=Einbinden (Einbinden oder Aushängen von Dateisystemen) +acl_button_new=Neu (Erzeuge Textdatei) +acl_button_rename=Umbenennen (Datei umbenennen) +acl_button_save=Speichern (heruntergeladene Datei) +acl_button_search=Finde (Dateien finden) +acl_button_sharing=Gemeinsamer Dateizugriff (richte Samba- und NFS Dateizugriff ein) +acl_button_upload=Hochladen (lade Dateien eines Clients hoch) +acl_buttons=Verfügbare Knöpfe in der Toolbar +acl_chroot=ChangeRoot-Verzeichnis für den gesamten Dateimanager +acl_dirs=Erlaube nur Zugriff auf Verzeichnisse +acl_dostounix=Darf DOS-"Neue Zeile"-Zeichen konvertieren? +acl_follow=Folge immer symbolischen Links? +acl_fyes=Wenn Benutzer übereinstimmt +acl_goto=Öffne erstes erlaubtes Verzeichnis? +acl_home=Das Heimatverzeichnis des Webmin-Benutzers einbinden? +acl_log=Alle Dateiänderungen protokollieren? +acl_max=Maximale Hochladegröße +acl_nodirs=Verweigere Zugriff auf Verzeichnisse +acl_relto=(relativ zu jedem ChangeRoot-Verzeichnis) +acl_ro=Nur-Lesen-Modus? +acl_umask=Umask für neue Dateien +acl_unarchive=Darf hochgeladene Archivdateien auspacken? +acl_unarchive0=$nein +acl_unarchive1=$ja +acl_unarchive2=Versuche immer +acl_unlim=Unbegrenzt +acl_user=Greife als Benutzer auf Dateien auf dem Server zu +acl_user_def=Wie Webmin-Benutzer +acltype_default_group=Standard-Gruppe +acltype_default_mask=Standard-Maske +acltype_default_other=Andere Standards +acltype_default_user=Standard-Benutzer +acltype_group=Gruppe +acltype_mask=Maske +acltype_other=Andere +acltype_user=Benutzer +attr_add=Attribut hinzufügen +attr_create=Attribut hinzufügen +attr_eattrs=Konnte Attribute nicht lesen: $1 +attr_edit=Attribut bearbeiten +attr_efailed=Konnte Attribute für $1 nicht setzen: $2 +attr_efs=Dateisystem $1 unterstützt keine Attribute +attr_ename=Fehlender Attributname +attr_name=Attributname +attr_title=Dateiattribute für $1 +attr_value=Attribut Wert +cancel=Abbrechen +chmod_eaccess=Sie haben keine Berechtigung zum Zugriff auf '$1' +chmod_echmod=chmod schlug fehl : $1 +chmod_echown=chown schlug fehl : $1 +chmod_efollow=Sie dürfen keine symbolischen Links bearbeiten +chmod_egroup=$1 : Gruppe nicht gefunden +chmod_elink=Symbolischer Link schlug fehl : $1 +chmod_euser=$1 : Benutzer nicht gefunden +close=Schließen +copy_efrom=Sie haben keine Berechtigung aus '$1' zu kopieren +copy_elink=Symbolischer Link schlug fehl : $1 +copy_eto=Sie haben keine Berechtigung in '$1' zu kopieren +ddir_rusure=Um den Inhalt von $1 als Archivdatei herunterzuladen, klicken Sie bitte auf den Archivbutton. +ddir_tar=TAR +ddir_tgz=TAR.GZ +ddir_title=Download-Verzeichnis +ddir_zip=ZIP +delete_ddesc=Sind Sie sicher, daß Sie das Verzeichnis $1 und alle Unterverzeichnisse unwiderruflich löschen wollen? +delete_dtitle=Lösche Verzeichnis +delete_eaccess=Sie haben keine Berechtigung '$1' zu löschen +delete_efailed=Fehler beim Löschen von $1 : $2 +delete_fdesc=Sind Sie sicher, dass Sie die Datei $1 unwiderruflich löschen wollen? +delete_ftitle=Lösche Datei +delete_mdesc=Sind Sie sicher, dass Sie diese Dateien und Verzeichnisse permanent löschen wollen? : +delete_mtitle=Mehrere Dateien löschen +eacl_aclname=Anwenden auf +eacl_aclperms=Berechtigungen +eacl_acltype=ACL-Typ +eacl_add=ACL des Typs hinzufügen : +eacl_create=ACL einrichten +eacl_eacls=Konnte ACLs nicht einlesen: $1 +eacl_edefaults=Wenn eine Datei eine Standard-ACL hat, dann muß ein Standard-Benutzer, eine -Gruppe und andere ACLs eingerichtet sein. +eacl_edefmask=Es kann nur einen Standard-ACL-Eintrag geben +eacl_edit=ACL bearbeiten +eacl_efailed=Konnte ACL für $1 nicht setzen : $2 +eacl_efs=Dateisystem $1 unterstützt keine ACLs +eacl_emask=Es kann nur einen ACL-Eintrag geben +eacl_eowner=Benutzer oder Gruppe nicht angegeben +eacl_group=Datei-Gruppe $1 +eacl_owner=Datei-Besitzer +eacl_remove=ACL entfernen +eacl_title=ACL für $1 +eacl_user=Datei-Besitzer $1 +eattr_A=Zugriffszeit nicht ändern +eattr_S=Nach Schreiben immer synchronisieren +eattr_a=Kann nur an Datei anhängen +eattr_c=Datei auf Festplatte komprimieren +eattr_d=Nicht mit dump sichern +eattr_i=Keine Änderungen zulassen +eattr_s=Beim Löschen mit Null-Blöcken überschreiben +eattr_u=Inhalte für Wiederherstellung sichern +ebutton=Diese Funktion ist nicht verfügbar +edit_all=Alles ersetzen +edit_eaccess=Sie haben keine Berechtigung die Datei '$1' zu speichern +edit_efollow=Sie dürfen nicht auf den symbolischen Link '$1' schreiben +edit_elength=Datei wurde abgeschnitten! +edit_enormal=Nur normale Dateien können bearbeitet werden +edit_eover=$1 kann nicht überschrieben werden +edit_esave=Fehler beim Speichern der Datei : $1 +edit_filename=Dateiname: +edit_find=Finde +edit_goto=Gehe zu +edit_gotoline=Gehe zu Zeile +edit_notfound=Der Text $1 wurde nicht gefunden +edit_replace=Ersetzen +edit_replaceby=Ersetzen mit +edit_saveclose=Speichern & Schliessen +edit_searchfor=Suchen nach +edit_title=Bearbeite $1 +edit_title2=Erstelle Datei +eopen=Download gescheitert: $1 +ext_eattrs=Konnte EXT-Attribute nicht lesen : $1 +ext_efailed=Konnte EXT-Attribute für $1 nicht lesen : $2 +ext_efs=Dateisystem $1 unterstützt keine EXT-Attribute +ext_header=EXT-Datei-Attribute +ext_title=EXT-Datei-Attribute für $1 +facl_eaccess=Sie dürfen keine ACLs für diese Datei setzen +file_type0=Verzeichnis +file_type1=Textdatei +file_type2=Bilddatei +file_type3=Binäre Datei +file_type4=Datei +file_type5=Symbolischer Link +file_type6=Gerätedatei +file_type7=Pipe +find_eaccess=Sie haben keine Berechtigung um auf $1 zuzugreifen +find_edir=$1 ist kein Verzeichnis in $2 +find_eexist=$1 existiert nicht in $2 +index_eremote=Für diesen Unix-Benutzer gibt es keine Webmin-Anmeldung $1. +index_nojava=Dieses Modul benötigt Java. Entweder unterstützt Ihr Browser kein Java oder Java ist nicht richtig installiert. +index_title=Datei-Manager +info_apply=Änderungen anwenden auf +info_apply1=Nur dieses Verzeichnis +info_apply2=Dieses Verzeichnisse und seine Dateien +info_apply3=Dieses Verzeichnis und alle Unterverzeichnisse +info_efailed=Fehler beim Update von $1 : $2 +info_exec=Ausführen +info_file=Datei +info_group=Gruppe: +info_link=Link nach: +info_list=Liste +info_mod=Verändert: +info_octal=Oktal: +info_other=Andere: +info_own=Besitzer +info_path=Pfad: +info_perms=Rechte +info_read=Lesen +info_setgid=SetGID: +info_setgid2=Dateien erben Gruppen +info_setgid3=Führe aus als Gruppe +info_setuid=SetUID: +info_setuid2=Führe aus als Benutzer +info_size=Größe: +info_sticky=Sticky: +info_sticky2=Nur Besitzer darf Dateien löschen +info_type=Typ: +info_user=Benutzer: +info_write=Schreiben +link_eexists=$1 existiert bereits +link_efailed=Link schlug fehl : $1 +link_efollow=Sie haben keine Berechtigung symbolische Links anzulegen +link_efrom=Sie haben keine Berechtigung von '$1' zu verknüpfen +link_efrom2=Sie dürfen nicht von '$1' linken +link_from=Link von: +link_title=Erstelle Link +link_to=Link zu: +list_eaccess=Sie haben keine Berechtigung zum Zugriff auf dieses Verzeichnis +list_edir=Konnte $1 nicht auflisten : $2 +log_acl=ACL für Datei $1 gesetzt +log_attr=Attribute für Datei $1 gesetzt +log_chmod=Berechtigungen für Datei $1 geändert +log_copy=Datei von $1 nach $2 kopiert +log_create_export=NFS-Export $1 erzeugt +log_create_share=Samba-Freigabe $1 erzeugt +log_delete=Datei $1 gelöscht +log_delete_export=NFS-Export $1 gelöscht +log_delete_share=Samba-Freigabe $1 gelöscht +log_link=Symbolischer Link von $1 nach $2 erzeugt +log_mkdir=Verzeichnis angelegt $1 +log_modify_export=NFS-Export $1 geändert +log_modify_share=Samba-Freigabe $1 geändert +log_move=Datei von $1 nach $2 verschoben +log_relink=Symbolischer Link von $1 nach $2 geändert +log_save=Datei $1 gespeichert +log_upload=Datei $1 hochgeladen +mkdir_dir=Neues Verzeichnis: +mkdir_eaccess=Sie haben keine Berechtigung, '$1' anzulegen +mkdir_eexists=$1 existiert bereits +mkdir_efailed=Erstellen des Verzeichnisses schlug fehl : $1 +mkdir_title=Neues Verzeichnis +mount_eaccess=Sie dürfen keine Dateisysteme einbinden +mount_efstab=Es existiert kein Dateisystem an diesem Einhängepunkt +mount_epoint=$1 ist kein Einhängepunkt +mount_err1=Konnte $1 nicht einhängen : $2 +mount_err2=Konnte $1 nicht aushängen : $2 +mount_rusure1=Sind Sie sicher, dass Sie $1 in $2 einhängen wollen ? +mount_rusure2=Sind Sie sicher, dass Sie $1 von $2 aushängen wollen ? +mount_title1=Dateisystem einhängen +mount_title2=Dateisystem aushängen +move_afrom=Sie haben keine Berechtigung '$1' zu verschieben +move_eto=Sie haben keine Berechtigung, Dateien nach '$1' zu verschieben +over_msg=Die Datei $1 existiert bereits. Benutzen Sie das Feld unten um einen anderen Namen für die neue Datei anzugeben. +over_new=Neuer Dateiname: +over_ok=Ok +over_title=Datei existiert +paste_ecfailed=Kopieren schlug fehl : $1 +paste_ecopy=Vor dem Einfügen mußen Sie kopieren oder ausschneiden +paste_egone=Kopierte Datei $1 existiert nicht mehr +paste_emfailed=Verschieben schlug fehl : $1 +paste_eover=$1 kann nicht überschrieben werden +paste_eself=Sie können keine Datei auf sich selber einfügen +rename_eexists=Es existiert bereits eine Datei mit dem Namen $1 +rename_efailed=Umbennenen schlug fehl : $1 +rename_enew=Sie haben keine Berechtigung zu '$1' umzubennenen +rename_eold=Sie haben keine Berechtigung, '$1' umzubennenen +rename_new=Neuer Name: +rename_ok=Umbenennen +rename_old=Alter Name: +rename_title=Umbennenen von $1 +right_date=Datum +right_group=Gruppe +right_name=Name +right_size=Größe +right_user=Benutzer +search_any=Alle +search_crit=Suchkriterien +search_dir=Suche in Verzeichnis +search_eaccess=Sie haben keine Berechtigung, dieses Verzeichnis zu durchsuchen +search_edir=Fehlendes oder ungültiges Verzeichnis +search_egroup=Fehlender Gruppen-Name +search_ematch=Fehlender anwendbarer regulärer Ausdruck +search_esize=Dateigröße muß eine Ganzzahl sein +search_euser=Fehlender Benutzername +search_group=Im Besitz der Gruppe +search_less=Weniger als +search_list=Suchergebnisse +search_match=auf Dateien passend +search_more=Mehr als +search_ok=Jetzt suchen +search_size=Dateigrösse +search_title=Dateien suchen +search_type=Datei-Typ +search_types_=Alle +search_types_d=Verzeichnis +search_types_f=Datei +search_types_l=Symbolischer Link +search_types_p=Benannte Pipe +search_user=Im Besitz des Benutzers +search_xdev=Hinter Einhängepunkten suchen? +share_all=Alle +share_available=Momentan aktiv? +share_comment=Kommentar +share_desc=Beschreibung +share_guest=Gast-Zugriff +share_host=Hosts +share_listed=Aufgelistet.. +share_lro=Nur-Lesen +share_lrw=Lesen-Schreiben +share_nfs=NFS +share_nheader=NFS-Exporteinstellungen +share_noff=NFS-Dateifreigabe deaktiviert +share_non=NFS-Dateifreigabe aktiviert +share_none=Keine +share_only=Nur +share_opts=Einstellungen +share_ro=Nur-Lesen Hosts +share_root=Root-Zugriff Hosts +share_rw=Lesen-Schreiben Hosts +share_s0=Niemandem trauen +share_s1=Nicht-Root trauen +share_s2=Jedem trauen +share_samba=Windows +share_sheader=Windows-Freigabeeinstellungen +share_soff=Windows-Datei-Freigabe deaktiviert +share_son=Windows-Datei-Freigabe aktiviert +share_title=Freigabe +share_writable=Beschreibbar? +switch_euser=Dieser Unix-Benutzer existiert nicht! +top_attr=Attribute +top_config=Konfig. +top_copy=Kopieren +top_cut=Ausschneiden +top_delete=Löschen +top_down=Speichern +top_eacl=ACL +top_edit=Bearbeiten +top_ext=EXT +top_info=Info +top_mount=Mount +top_new=Neu +top_paste=Einfügen +top_refresh=Neu laden +top_rename=Umbenennen +top_ret=Webmin +top_search=Suchen +top_share=Freigabe +top_upload=Hochladen +upload_already=Die Datei $1 existiert bereits. Möchten Sie diese überschreiben? +upload_conv=Konvertiere DOS Zeilenvorschübe? +upload_dir=Hochladen zu Verzeichnis +upload_edir=Hochlade-Verzeichnis existiert nicht. +upload_efailed=Fehler beim Öffnen der hochzuladenden Datei : $1 +upload_efile=Keine Datei zum Hochladen ausgewählt. +upload_elink=Kann auf einen symbolischen Link nicht hochladen +upload_eperm=Sie haben keine Berechtigung $1 zu erstellen +upload_ewrite=Fehler beim Schreiben von $1 : $2. +upload_file=Datei zum Hochladen +upload_ok=Hochladen +upload_title=Datei hochladen +upload_yes=Ja, dann löschen +upload_zip=ZIP- oder TAR-Dateien dekomprimieren? +view_eaccess=Sie haben keine Berechtigung zum Zugriff auf $1 +view_earchive=Sie dürfen keine Archive herunterladen +view_earchmax=Das ausgewählte Verzeichnis ist größer als die maximal erlaubte Größe für Archive ($1 bytes) +view_ecmd=Der Befehl $1, der zum Erzeugen von Archiven benötigt wird, ist nicht installiert. +view_ecomp=Konnte Archiv nicht erzeugen: $1 +view_edir=Ein Archiv kann nur für ein Verzeichnis angelegt werden +view_enormal=Nur normale Dateien können betrachtet werden +view_enormal2=Nur normale Dateien können lokal gespeichert werden. +view_eopen=Fehler beim Öffnen von $1 : $2 +zip_ecmd=Fehlendes $1 Kommando +zip_ename=Scheint keine ZIP-, TAR- oder TAR.GZ-Datei zu sein. +zip_err=Konnte Datei nicht auspacken: $1 +zip_euntar=Un-TAR gescheitert: $1 +zip_euntar2=Dekomprimierung und Un-TAR gescheitert: $1 +zip_eunzip=Un-ZIP gescheitert: $1 diff --git a/file/lang/en b/file/lang/en new file mode 100644 index 000000000..cbd870062 --- /dev/null +++ b/file/lang/en @@ -0,0 +1,424 @@ +index_title=File Manager +index_nojava=This module requires java to function, but your browser does not support java +index_eremote=There is no Unix user matching the Webmin login $1. +index_index=Return to Webmin index. +switch_euser=Unix user does not exist! + +top_ret=Index +top_down=Save +top_preview=Preview +top_edit=Edit +top_html=HTML +top_refresh=Refresh +top_info=Info +top_eacl=ACL +top_attr=Attrs +top_ext=EXT +top_delete=Delete +top_new=New +top_upload=Upload +top_extract=Extract +top_rename=Rename +top_copy=Copy +top_cut=Cut +top_paste=Paste +top_share=Sharing +top_mount=Mount +top_search=Find +top_config=Config +top_efile=No file selected + +right_name=Name +right_size=Size +right_user=User +right_group=Group +right_date=Date + +edit_enormal=Only normal files can be edited +edit_title=Editing $1 +edit_title2=Creating file +edit_filename=Filename: +edit_goto=Goto +edit_find=Find +edit_gotoline=Go to line +edit_replace=Replace +edit_all=Replace all +edit_searchfor=Search for +edit_replaceby=Replace by +edit_eover=$1 cannot be overwritten +edit_esave=Failed to save file : $1 +edit_eaccess=You are not allowed to save '$1' +edit_efollow=You are not allowed to write to the symbolic link '$1' +edit_notfound=The text $1 was not found +edit_saveclose=Save & Close +edit_elength=File was truncated! + +info_file=File +info_path=Path: +info_type=Type: +info_size=Size: +info_mod=Modified: +info_link=Link to: +info_perms=Permissions +info_user=User: +info_group=Group: +info_other=Other: +info_octal=Octal: +info_sticky=Sticky: +info_sticky2=Only owners can delete files +info_own=Ownership +info_setuid=Setuid: +info_setuid2=Execute as user +info_setgid=Setgid: +info_setgid2=Files inherit group +info_setgid3=Execute as group +info_apply=Apply changes to +info_apply1=This directory only +info_apply2=This directory and its files +info_apply3=This directory and all subdirectories +info_efailed=Failed to update $1 : $2 +info_read=Read +info_write=Write +info_list=List +info_exec=Exec +info_sizeheader=Directory size +info_bytes=Total bytes: +info_files=Total files: +info_dirs=Total directories: +info_getsize=Get Size +info_esize=Failed to get sizes : $1 + +eacl_eacls=Failed to read ACLs : $1 +eacl_acltype=ACL Type +eacl_aclname=Apply to +eacl_aclperms=Permissions +eacl_add=Add ACL of type : +eacl_remove=Remove ACL +eacl_efs=The filesystem $1 does not support ACLs +eacl_create=Create ACL +eacl_edit=Edit ACL +eacl_user=File owner $1 +eacl_group=File group $1 +eacl_eowner=Missing user or group to apply to +eacl_efailed=Failed to set ACL for $1 : $2 +eacl_emask=There can be at most one mask ACL entry +eacl_edefmask=There can be at most one default mask ACL entry +eacl_title=ACL for $1 +eacl_owner=File owner +eacl_edefaults=If a file has any default ACL, it must have default user, group and other ACLs. + +acltype_user=User +acltype_group=Group +acltype_other=Others +acltype_mask=Mask +acltype_default_user=Default User +acltype_default_group=Default Group +acltype_default_other=Default Others +acltype_default_mask=Default Mask + +delete_mtitle=Delete multiple files +delete_dtitle=Delete directory +delete_ftitle=Delete file +delete_ddesc=Are you sure you want to permanently delete the directory $1 and all its contents? +delete_fdesc=Are you sure you want to permanently delete the file $1 ? +delete_mdesc=Are you sure you want to permanently delete these files and directories? : +delete_efailed=Failed to delete $1 : $2 + +mkdir_title=New Directory +mkdir_dir=New directory: +mkdir_eexists=$1 already exists +mkdir_efailed=Create directory failed : $1 +mkdir_eaccess=You are not allowed to create '$1' + +link_title=Create Link +link_from=Link from: +link_to=Link to: +link_eexists=$1 already exists +link_efrom=Link source must be an absolute path +link_efailed=Link failed : $1 +link_efrom2=You are not allowed to link from '$1' +link_efollow=You are not allowed to create symlinks + +rename_title=Rename $1 +rename_old=Old name: +rename_new=New name: +rename_ok=Rename +rename_eexists=A file called $1 already exists +rename_eslash=The new file name $1 contains a / +rename_efailed=Rename failed : $1 +rename_eold=You are not allowed to rename '$1' +rename_enew=You are not allowed to rename to '$1' + +file_type0=Directory +file_type1=Text file +file_type2=Image file +file_type3=Binary file +file_type4=File +file_type5=Symbolic link +file_type6=Device file +file_type7=Pipe + +view_enormal=Only normal files can be viewed +view_enormal2=Only normal files can be downloaded +view_eaccess=You are not allowed to access $1 +view_eopen=Failed to open $1 : $2 +view_edir=An archive can only be created for a directory +view_ecmd=The command $1 needed to create an archive is not installed +view_ecomp=Failed to create archive : $1 +view_earchive=You are not allowed to download archives +view_earchmax=The selected directory is larger than the maximum allowed for archiving ($1 bytes) + +paste_ecopy=You must cut or copy before pasting +paste_egone=Copied file $1 no longer exists +paste_eover=$1 cannot be overwritten +paste_eself=You cannot paste a file over itself +paste_emfailed=Move failed : $1 +paste_ecfailed=Copy failed : $1 + +over_title=File Exists +over_msg=The file $1 already exists. Use the field below to enter a new filename for the pasted file. +over_new=New filename: +over_ok=Ok + +upload_efailed=Failed to open upload : $1 +upload_title=Upload File +upload_file=File to upload +upload_dir=Upload to directory +upload_ok=Upload +upload_conv=Convert DOS newlines? +upload_efile=No file selected to upload. +upload_edir=Upload directory does not exist. +upload_eperm=You are not allowed to create $1 +upload_ewrite=Failed to write to $1 : $2. +upload_already=The file $1 already exists. Are you sure that you want to overwrite it? +upload_elink=Cannot upload to a symbolic link +upload_zip=Uncompress ZIP or TAR file? +upload_yes=Yes, then delete + +find_eaccess=You are not allowed to access $1 +find_eexist=$1 does not exist in $2 +find_edir=$1 is not a directory in $2 + +cancel=Cancel +close=Close +eopen=Download failed : $1 + +chmod_eaccess=You are not allowed to access '$1' +chmod_euser=$1 : no such user +chmod_egroup=$1 : no such group +chmod_elink=symlink failed : $1 +chmod_echown=chown failed : $1 +chmod_echmod=chmod failed : $1 +chmod_efollow=You are not allowed to edit symbolic links + +copy_efrom=You are not allowed to copy from '$1' +copy_eto=You are not allowed to copy to '$1' +copy_elink=symlink failed : $1 + +delete_eaccess=You are not allowed to delete '$1' + +list_eaccess=You are not allowed to access this directory +list_edir=Failed to list $1 : $2 + +move_eto=You are not allowed to move to '$1' +move_afrom=You are not allowed to move '$1' + +acl_user=Access files on server as user +acl_user_def=Same as Webmin login +acl_umask=Umask for new files +acl_follow=Always follow symlinks? +acl_fyes=If owners match +acl_ro=Read-only mode? +acl_dirs=Only allow access to directories +acl_nodirs=Deny access to directories +acl_home=Include home directory of Webmin user +acl_log=Log all file modifications? +acl_goto=Open first allowed directory? +acl_max=Maximum upload size +acl_unlim=Unlimited +acl_b=bytes +acl_archive=Can download archives of directories? +acl_archmax=Yes, if smaller than +acl_buttons=Available buttons on toolbar +acl_button_save=Save (download file) +acl_button_preview=Preview (view scaled-down image) +acl_button_edit=Edit (edit text file) +acl_button_info=Info (edit file permissions and ownership) +acl_button_acl=ACL (edit Posix ACL) +acl_button_attr=Attr (edit XFS attributes) +acl_button_ext=EXT (edit EXT attributes) +acl_button_search=Find (find files) +acl_button_delete=Delete (delete files) +acl_button_new=New (create text file) +acl_button_upload=Upload (upload file from client) +acl_button_mkdir=New (create directory) +acl_button_makelink=New (create symbolic link) +acl_button_rename=Rename (rename file) +acl_button_sharing=Sharing (setup Samba and NFS file sharing) +acl_button_mount=Mount (mount or un-mount filesystem) +acl_button_copy=Copy, Cut and Paste +acl_unarchive=Can extract uploaded archive files? +acl_unarchive2=Always attempt to +acl_unarchive1=$yes +acl_unarchive0=$no +acl_dostounix=Can have DOS newlines converted? +acl_chroot=Chroot directory for entire file manager +acl_relto=(relative to any chroot directory) +acl_noperms=Can change file permissions? +acl_nousers=Can change file ownership? +acl_filesystems=Can see filesystem mount points? +acl_contents=Allow searching of file contents? + +share_title=Sharing +share_samba=Windows +share_nfs=NFS +share_son=Windows file sharing enabled +share_soff=Windows file sharing disabled +share_writable=Writable? +share_available=Currently active? +share_sheader=Sharing options +share_only=Only +share_guest=Guest access? +share_comment=Comment +share_nheader=NFS export options +share_non=NFS file sharing enabled +share_noff=NFS file sharing disabled +share_desc=Description +share_ro=Read-only hosts +share_rw=Read-write hosts +share_root=Root access hosts +share_none=None +share_all=All +share_listed=Listed.. +share_host=Hosts +share_opts=Options +share_s0=Trust nobody +share_s1=Trust non-root +share_s2=Trust everybody +share_lro=Read-only +share_lrw=Read-write + +log_create_export=Created NFS export $1 +log_modify_export=Modified NFS export $1 +log_delete_export=Deleted NFS export $1 +log_create_share=Created Samba share $1 +log_modify_share=Modified Samba share $1 +log_delete_share=Deleted Samba share $1 +log_save=Saved file $1 +log_chmod=Changed permissions on file $1 +log_mkdir=Created directory $1 +log_upload=Uploaded file $1 +log_link=Created symbolic link $1 to $2 +log_relink=Modified symbolic link $1 to $2 +log_copy=Copied file $1 to $2 +log_move=Moved file $1 to $2 +log_delete=Deleted file $1 +log_attr=Set attributes on file $1 +log_acl=Set ACL on file $1 + +search_eaccess=You are not allowed to search this directory +search_title=Find files +search_ok=Search Now +search_dir=Search directory +search_match=For files matching +search_cont=Containing text +search_user=Owned by user +search_group=Owned by group +search_any=Any +search_type=File type +search_types_=Any +search_types_f=File +search_types_d=Directory +search_types_l=Symbolic link +search_types_p=Named pipe +search_size=File size +search_more=More than +search_less=Less than +search_xdev=Search past mounts? +search_edir=Missing or invalid search directory +search_ematch=Missing matching regexp +search_euser=Missing username +search_egroup=Missing group name +search_esize=File size must be an integer +search_crit=Search criteria +search_list=Search results +search_down=Download +search_edown=No search result file to download selected + +facl_eaccess=You are not allowed to set ACLs for this file + +attr_eattrs=Failed to get attributes : $1 +attr_efs=The filesystem $1 does not support attributes +attr_add=Add Attribute +attr_name=Attribute Name +attr_value=Attribute Value +attr_efailed=Failed to set attributes for $1 : $2 +attr_title=File Attributes for $1 +attr_create=Add Attribute +attr_edit=Edit Attribute +attr_ename=Missing attribute name + +ext_eattrs=Failed to get EXT attributes : $1 +ext_efs=The filesystem $1 does not support EXT attributes +ext_title=EXT attributes for $1 +ext_header=EXT file attributes +ext_efailed=Failed to set attributes for $1 : $2 + +eattr_A=Do not update access times +eattr_a=Can only append to file +eattr_c=Compress data on disk +eattr_d=Do not backup with dump +eattr_i=Do not allow modification +eattr_s=Zero blocks when deleting +eattr_S=Always sync after writing +eattr_u=Save contents for undeletion + +mount_eaccess=You are not allowed to mount filesystems +mount_efstab=No filesystem exists at this mount point +mount_epoint=$1 is not a mount point +mount_rusure1=Are you sure you want to mount $1 from $2 ? +mount_rusure2=Are you sure you want to un-mount $1 from $2 ? +mount_err1=Failed to mount $1 : $2 +mount_err2=Failed to un-mount $1 : $2 +mount_title1=Mount filesystem +mount_title2=Un-mount filesystem + +zip_err=Could not extract file : $1 +zip_ecmd=Missing $1 command +zip_eunzip=Unzip failed : $1 +zip_ename=Does not appear to be a zip, tar or tar.gz file +zip_euntar=Un-tar failed : $1 +zip_euntar2=Un-compress and un-tar failed : $1 + +ddir_title=Download Directory +ddir_rusure=To download the contents of $1 as an archive file, click on one of the archive type buttons below. +ddir_zip=ZIP +ddir_tgz=TAR.GZ +ddir_tar=TAR + +ebutton=This feature is not available + +preview_etype=Could not work out file type for $1 +preview_etype2=$1 is not in a supported image format +preview_ecmd=The command $1 needed to scale this image is not installed +preview_eimage=Only images can be previewed +preview_title=Preview of $1 +preview_bad=Could not load image to preview +preview_egd=Failed to load image with GD + +html_efailed=Failed to open HTML editor : $1 +html_title=Edit HTML File +html_title2=Create HTML File +html_save=Save and Close +html_err=Failed to save HTML file + +history_title=Path History +history_ok=Go To +history_button=History + +extract_etype=Only files can be extracted +extract_title=Extract Compressed File +extract_rusure=Are you sure you want to extract the compressed file : +extract_rusure2=Existing files in the same directory may be overwritten. +extract_err=Failed to extract file : $1 +extract_yes=Yes, then delete diff --git a/file/lang/es b/file/lang/es new file mode 100644 index 000000000..916e67a33 --- /dev/null +++ b/file/lang/es @@ -0,0 +1,345 @@ +acl_archive=¿Puede descargar archivos de directorios? +acl_archmax=Sí, si son menores que +acl_b=bytes +acl_button_acl=ACL (editar ACL Posix) +acl_button_attr=Attr (editar atributos XFS) +acl_button_copy=Copiar, Cortar y Pegar +acl_button_delete=Borrar (borrar archivos) +acl_button_edit=Editar (editar archivo texto) +acl_button_ext=EXT (editar atributos EXT) +acl_button_info=Info (editar permisos y propiedad de archivo) +acl_button_makelink=Nuevo (crear link simbólico) +acl_button_mkdir=Nuevo (crear directorio) +acl_button_mount=Montar (montar o desmontar sistema de archivos) +acl_button_new=Nuevo (crear archivo de texto) +acl_button_rename=Renombrar (renombrar archivo) +acl_button_save=Guardar (descargar archivo) +acl_button_search=Buscar (buscar archivos) +acl_button_sharing=Compartir (configurar compartición de archivo por Samba y NFS) +acl_button_upload=Subir (subir archivo desde cliente) +acl_buttons=Botones disponibles en la barra de herramientas +acl_chroot=Cambiar directorio raiz (chroot) para todo el explorador de archivos +acl_dirs=Permitir acceso solo a los directorios +acl_dostounix=¿Se le pueden convertir las nuevas líneas de DOS? +acl_follow=¿Seguir siempre los vínculos simbólicos? +acl_fyes=Si los propietarios coinciden +acl_goto=¿Abrir el primer directorio permitido? +acl_home=Incluir directorio de inicio del usuario Webmin +acl_log=¿Registrar todas las modificaciones de archivos? +acl_max=Máximo tamaño de subida +acl_nodirs=Denegar acceso a directorios +acl_relto=(relativo a cualquier directorio raiz) +acl_ro=¿Modo de solo lectura? +acl_umask=Máscara de Usuario para Nuevos archivos +acl_unarchive=¿Puede extraer archivos subidos? +acl_unarchive0=$no +acl_unarchive1=$sí +acl_unarchive2=Siempre intentar +acl_unlim=Ilimitado +acl_user=Acceder a archivos en el servidor como usuario +acl_user_def=Igual que el nombre de ingreso de Webmin +acltype_default_group=Grupo por defecto +acltype_default_mask=Máscara por defecto +acltype_default_other=Otros por defecto +acltype_default_user=Usuario por defecto +acltype_group=Grupo +acltype_mask=Máscara +acltype_other=Otros +acltype_user=Usuario +attr_add=Agregar Atributo +attr_create=Agregar atributo +attr_eattrs=Fallo al obtener atributos : $1 +attr_edit=Editar atributo +attr_efailed=Fallo al configurar atributo para $1 : $2 +attr_efs=El sistema de archivos $1 no soporta atributos +attr_ename=Nombre de atributo no ingresado +attr_name=Nombre del atributo +attr_title=Atributos de archivo para $1 +attr_value=Valor del atributo +cancel=Cancelar +chmod_eaccess=No está autorizado a acceder a '$1' +chmod_echmod=fallo al cambiar modo : $1 +chmod_echown=fallo al cambiar dueño : $1 +chmod_efollow=No está autorizado a editar vínculos simbólicos +chmod_egroup=$1 : no existe dicho grupo +chmod_elink=fallo en vínculo simbólico : $1 +chmod_euser=$1 : no existe dicho usuario +close=Cerrar +copy_efrom=No está autorizado a copiar desde '$1' +copy_elink=fallo en vínculo simbólico : $1 +copy_eto=No está autorizado a copiar a '$1' +ddir_rusure=Para descargar los contenidos de $1 como un archivo de ficheros, elija abajo uno de los botones de tipo de archivo. +ddir_tar=TAR +ddir_tgz=TAR.GZ +ddir_title=Descargar Directorio +ddir_zip=ZIP +delete_ddesc=¿Está seguro que quiere borrar permanentemente el directorio $1 y todo su contenido? +delete_dtitle=Borrar directorio +delete_eaccess=No está autorizado a borrar '$1' +delete_efailed=Fallo al borrar $1 : $2 +delete_fdesc=¿Está seguro que quiere borrar permanentemente el archivo $1 ? +delete_ftitle=Borrar archivo +delete_mdesc=¿Está seguro que quiere borrar permanentemente estos archivos y directorios? : +delete_mtitle=Borrar múltiples archivos +eacl_aclname=Aplicar a +eacl_aclperms=Permisos +eacl_acltype=Tipo de ACL +eacl_add=Agregar ACL de tipo : +eacl_create=Crear ACL +eacl_eacls=Fallo al leer ACLs : $1 +eacl_edefaults=si un archivo tiene alguna ACL por defecto, debe tener usuario, grupo y otras ACL por defecto. +eacl_edefmask=Puede haber a lo sumo una entrada de máscara de ACL por defecto +eacl_edit=Editar ACL +eacl_efailed=Fallo al asignar ACL para $1 : $2 +eacl_efs=El sistema de archivos $1 no soporta ACLs +eacl_emask=Puede haber a lo sumo una entrada de máscara de ACL +eacl_eowner=Usuario o grupo a aplicar no ingresado +eacl_group=Grupo de archivo $1 +eacl_owner=Dueño del archivo +eacl_remove=Borrar ACL +eacl_title=ACL para $1 +eacl_user=Dueño de archivo $1 +eattr_A=No actualizar tiempos de acceso +eattr_S=Siempre sincronizar despues de escribir +eattr_a=Solo puede agregar a archivo +eattr_c=Comprimir datos en el disco +eattr_d=No respaldar con volcado +eattr_i=No permitir modificaciones +eattr_s=Poner a cero los bloques a borrar +eattr_u=Salvar contenido para recuperación después de borrado +ebutton=Esta opción no está disponible +edit_all=Reemplazar todo +edit_eaccess=No está autorizado a salvar '$1' +edit_efollow=No está autorizado a escribir en el vínculo simbólico '$1' +edit_elength=¡El archivo se truncó! +edit_enormal=Solo los archivos normales pueden ser editados +edit_eover=$1 no puede ser sobreescrito +edit_esave=Fallo al salvar archivo : $1 +edit_filename=Nombre de archivo: +edit_find=Buscar +edit_goto=Ir a +edit_gotoline=Ir a línea +edit_notfound=El texto $1 no fue encontrado +edit_replace=Reemplazar +edit_replaceby=Reemplazar por +edit_saveclose=Salvar y Cerrar +edit_searchfor=Buscar +edit_title=Editando $1 +edit_title2=Creando archivo +eopen=Descarga fallida: $1 +ext_eattrs=Fallo al obtener atributos EXT : $1 +ext_efailed=Fallo al configurar atributos para $1 : $2 +ext_efs=El sistema de archivos $1 no soporta atributos EXT +ext_header=Atributos EXT de archivo +ext_title=Atributos EXT para $1 +facl_eaccess=No está autorizado a configurar ACLs para este archivo +file_type0=Directorio +file_type1=Archivo de texto +file_type2=Archivo de imágen +file_type3=Archivo binario +file_type4=Archivo +file_type5=Vínculo simbólico +file_type6=Archivo de dispositivo +file_type7=Tubería +find_eaccess=No está autorizado a acceder a $1 +find_edir=$1 no es un directorio en $2 +find_eexist=$1 no existe en $2 +index_eremote=No hay ningún usuario Unix que coincida con el usuario de ingreso de Webmin $1. +index_nojava=Este módulo requiere java para funcionar, pero su navegador no soporta java +index_title=Administrador de Archivos +info_apply=Aplicar cambios a +info_apply1=Este directorio solamente +info_apply2=Este directorio y sus archivos +info_apply3=Este directorio y todos sus subdirectorios +info_efailed=Fallo al actualizar $1 : $2 +info_exec=Ejecutar +info_file=Archivo +info_group=Grupo: +info_link=Vínculo a: +info_list=Listar +info_mod=Modificado: +info_octal=Octal: +info_other=Otro: +info_own=Propiedad +info_path=Ruta: +info_perms=Permisos +info_read=Leer +info_setgid=Ingresar ID de grupo: +info_setgid2=Archivos heredan grupo +info_setgid3=Ejecutar como grupo +info_setuid=Ingresar ID de usuario: +info_setuid2=Ejecutar como usuario +info_size=Tamaño: +info_sticky=Restricción: +info_sticky2=Solo los dueños pueden borrar archivos +info_type=Tipo: +info_user=Usuario: +info_write=Escribir +link_eexists=$1 ya existe +link_efailed=Fallo vínculo : $1 +link_efollow=No está autorizado a crear vínculos simbólicos +link_efrom=No está autorizado a vincular desde '$1' +link_efrom2=No tiene permiso para linkar desde '$1' +link_from=Vincular desde: +link_title=Crear Vínculo +link_to=Vincular hacia: +list_eaccess=No está autorizado a acceder a este directorio +list_edir=Fallo al listar $1 : $2 +log_acl=Configurado ACL sobre archivo $1 +log_attr=Configurados atributos en archivo $1 +log_chmod=Permisos cambiados en el archivo $1 +log_copy=Copiado archivo $1 a $2 +log_create_export=Creada exportación NFS $1 +log_create_share=Creada compartición Samba $1 +log_delete=Borrado archivo $1 +log_delete_export=Borrada exportación NFS $1 +log_delete_share=Borrada compartición Samba $1 +log_link=Creado vínculo simbólico $1 a $2 +log_mkdir=Creado directorio $1 +log_modify_export=Modificada exportación NFS $1 +log_modify_share=Modificada compartición Samba $1 +log_move=Movido archivo $1 a $2 +log_relink=Modificado vínculo simbólico $1 a $2 +log_save=Salvado archivo $1 +log_upload=Cargado archivo $1 +mkdir_dir=Nuevo directorio: +mkdir_eaccess=No está autorizado a crear '$1' +mkdir_eexists=$1 ya existe +mkdir_efailed=Fallo al crear directorio : $1 +mkdir_title=Nuevo Directorio +mount_eaccess=No está autorizado a montar sistemas de archivos +mount_efstab=No existe sistema de archivo en este punto de montaje +mount_epoint=$1 no es un punto de montaje +mount_err1=Fallo al montar $1 : $2 +mount_err2=Fallo al desmontar $1 : F2 +mount_rusure1=¿Está seguro que desea montar $1 desde $2 ? +mount_rusure2=¿Está seguro que desea desmontar $1 desde $2 ? +mount_title1=Montar sistema de archivos +mount_title2=Desmontar sistema de archivos +move_afrom=No está autorizado a mover '$1' +move_eto=No está autorizado a mover a '$1' +over_msg=El archivo $1 ya existe. Use el campo de abajo para ingresar un nuevo nombre de archivo para el archivo pegado. +over_new=Nuevo nombre de archivo: +over_ok=Ok +over_title=Archivo existe +paste_ecfailed=Fallo al copiar : $1 +paste_ecopy=Debe cortar o copiar antes de pegar +paste_egone=El archivo copiado $1 ya no existe +paste_emfailed=Fallo al mover : $1 +paste_eover=$1 no puede ser sobreescrito +paste_eself=No puede pegar un archivo sobre si mismo +rename_eexists=Ya existe un archivo llamado $1 +rename_efailed=Fallo al renombrar : $1 +rename_enew=No está autorizado a renombrar a '$1' +rename_eold=No está autorizado a renombrar '$1' +rename_new=Nombre nuevo: +rename_ok=Renombrar +rename_old=Nombre anterior: +rename_title=Renombrar $1 +right_date=Fecha +right_group=Grupo +right_name=Nombre +right_size=Tamaño +right_user=Usuario +search_any=Cualquiera +search_crit=Criterio de búsqueda +search_dir=Buscar directorio +search_eaccess=No está autorizado a buscar este directorio +search_edir=Directorio de búsqueda no ingresado o no válido +search_egroup=Nombre de grupo no ingresado +search_ematch=Expresión de coincidencia no ingresada +search_esize=El tamaño del archivo debe ser un entero +search_euser=Nombre de usuario no ingresado +search_group=Perteneciente al grupo +search_less=Menos que +search_list=Resultados de la búsqueda +search_match=Para archivos que coincidan +search_more=Mas que +search_ok=Buscar Ahora +search_size=Tamaño de archivo +search_title=Buscar archivos +search_type=Tipo de archivo +search_types_=Cualquiera +search_types_d=Directorio +search_types_f=Archivo +search_types_l=Vínculo Simbólico +search_types_p=Tubería nombrada +search_user=Perteneciente al usuario +search_xdev=¿Buscar en montajes anteriores? +share_all=Todos +share_available=¿Actualmente activo? +share_comment=Comentario +share_desc=Descripción +share_guest=¿Acceso como invitado? +share_host=Máquinas +share_listed=Listado.. +share_lro=Solo lectura +share_lrw=Lectura-escritura +share_nfs=NFS +share_nheader=Opciones de exportación NFS +share_noff=Compartir archivos NFS deshabilitado +share_non=Compartir archivos NFS habilitado +share_none=Ninguno +share_only=Solo +share_opts=Opciones +share_ro=Máquina de solo lectura +share_root=Máquinas de acceso raíz +share_rw=Máquina de lectura-escritura +share_s0=No confiar en nadie +share_s1=Confiar en aquellos que no sean raíz +share_s2=Confiar en todos +share_samba=Windows +share_sheader=Opciones para compartir +share_soff=Deshabilitar compartir archivos de Windows +share_son=Habilitar compartir archivos de Windows +share_title=Compartir +share_writable=¿Editable? +switch_euser=¡El usuario Unix no existe! +top_attr=Atributos +top_config=Configurar +top_copy=Copiar +top_cut=Cortar +top_delete=Borrar +top_down=Salvar +top_eacl=ACL +top_edit=Editar +top_ext=EXT +top_info=Información +top_mount=Montar +top_new=Nuevo +top_paste=Pegar +top_refresh=Refrescar +top_rename=Renombrar +top_ret=Indice +top_search=Buscar +top_share=Compartir +top_upload=Cargar +upload_already=El archivo $1 ya existe. ¿Está seguro que desea sobreescribirlo? +upload_conv=¿Convertir nuevas líneas de DOS? +upload_dir=Cargar a directorio +upload_edir=El directorio para cargar no existe. +upload_efailed=Fallo al abrir carga : $1 +upload_efile=No se seleccionó ningún archivo para cargar. +upload_elink=No se puede cargar a un vínculo simbólico +upload_eperm=No está autorizado a crear $1 +upload_ewrite=Fallo al escribir a $1 : $2. +upload_file=Archivo para cargar +upload_ok=Cargar +upload_title=Cargar Archivos +upload_yes=Si, después borrar +upload_zip=¿Descomprimir archivo ZIP o TAR? +view_eaccess=No está autorizado a acceder a $1 +view_earchive=No tiene permiso para descargar archivos +view_earchmax=El directorio elegido es mayor que el máximo permitido para archivar ($1 bytes) +view_ecmd=El comando $1, necesario para crear un archivo no está instalado +view_ecomp=Falló la creación de archivo: $1 +view_edir=Un archivo sólo puede ser creado en un directorio +view_enormal=Solo los archivos normales pueden ser visualizados +view_enormal2=Solo los archivos normales pueden ser descargados +view_eopen=Fallo al abrir $1 : $2 +zip_ecmd=Comando $1 no introducido +zip_ename=No parece ser un archivo zip, tar o tar.gz válido +zip_err=No se pudo extraer archivo : $1 +zip_euntar=Extracción tar fallida : $1 +zip_euntar2=Descompresión y extracción tar fallida : $1 +zip_eunzip=Extracción zip fallida : $1 diff --git a/file/lang/fa b/file/lang/fa new file mode 100644 index 000000000..27e2f43b3 --- /dev/null +++ b/file/lang/fa @@ -0,0 +1,383 @@ + +index_title=مدير پرونده +index_nojava=اين پيمانه جهت اجرا شدن نياز به جاوا دارد اما مرورگر شمااز جاوا پشتيباني نمي‌کند. +index_eremote=کاربر يونيکسي Ú©Ù‡ با $1 جهت ورود به وب‌مين مطابقت کند وجود ندارد. + +switch_euser=کاربر يونيکس وجود ندارد! + +top_ret=شاخص +top_down=ذخيره +top_edit=ويرايش +top_refresh=بازآوري +top_info=اطلاعات +top_eacl=ACL +top_attr=Attrs +top_ext=EXT +top_delete=حذ٠+top_new=جديد +top_upload=بارگيري +top_rename=تغيير نام +top_copy=رونوشت +top_cut=بريدن +top_paste=چسباندن +top_share=اشتراک گذاري +top_mount=سوار کردن +top_search=ÙŠØ§ÙØªÙ† +top_config=پيکربندي + +right_name=نام +right_size=اندازه +right_user=کاربر +right_group=گروه +right_date=تاريخ + +edit_enormal=Ùقط پرونده‌هاي عادي قابل ويرايش مي‌باشند +edit_title=در حال ويرايش $1 +edit_title2=در حال ايجاد کردن پرونده +edit_filename=نام پرونده: +edit_goto=برو به +edit_find=ÙŠØ§ÙØªÙ† +edit_gotoline=برو به خط +edit_replace=جايگزين کردن +edit_all=جايگزين کردن همه +edit_searchfor=جستجو براي +edit_replaceby=جايگزين کردن با +edit_eover=$1 قادر به نوشتن مجدد نمي‌باشد +edit_esave=عدم موÙقيت در ذخيره کردن پرونده: $1 +edit_eaccess=شما اجازه ذخيره کردن نداريد '$1' +edit_efollow=شما اجازه نوشتن برروي اتصال نمادين '$1' را نداريد +edit_notfound=متن '$1' ÙŠØ§ÙØª نشد +edit_saveclose=ذخيره کردن Ùˆ بستن +edit_elength=پرونده کوتاه شده‌است + +info_file=پرونده +info_path=مسير: +info_type=نوع: +info_size=اندازه: +info_mod=تاريخ اصلاح: +info_link=اتصال به: +info_perms=مجوزها +info_user=کاربر: +info_group=گروه: +info_other=ديگران: +info_octal=مبناي هشت: +info_sticky=محکم: +info_sticky2=تنها مالک مي‌تواند پرونده‌ها را حذ٠کند +info_own=مالکيت +info_setUID=قراردادن UID: +info_setUID2=اجرا به‌عنوان کاربر +info_setgid=قراردادن GID: +info_setgid2=پرونده‌ها از گروه ارث برند +info_setgid3=اجرا به‌عنوان گروه +info_apply=به‌کاربستن تغييرات در +info_apply1=Ùقط اين Ùهرست راهنما +info_apply2=اين Ùهرست راهنما Ùˆ پرونده‌هايش +info_apply3=اين Ùهرست راهنما Ùˆ کليه زير Ùهرستها +info_efailed=عدم موÙقيت در به‌روزرساني $1 +info_read=خواندن +info_write=نوشتن +info_list=ليست +info_exec=اجرا + +eacl_eacls=عدم موÙقيت در خواندن ACLها: $1 +eacl_acltype=نوع ACL +eacl_aclname=به‌کاربستن در +eacl_aclperms=مجوزها +eacl_add=اضاÙÙ‡ کردن ACL نوع: +eacl_remove=حذ٠ACL +eacl_efs=سيستم پرونده $1 از ACLها پشتيباني نمي‌کند +eacl_create=ايجاد ACL +eacl_edit=ويرايش ACL +eacl_user=مالک پرونده $1 +eacl_group=گروه پرونده $1 +eacl_eowner=کاربر يا گروه جهت به‌کاربستن ÙŠØ§ÙØª نشد +eacl_efailed=عدم موÙقيت در قرار دادن ACL براي $1: $2 +eacl_emask=حداکثر مي‌توان ÙŠÚ© پوشش ورودي ACL داشت +eacl_edefmask=حداکثر مي‌توان ÙŠÚ© پوشش ورودي ACL پيش‌گزيده داشت +eacl_title=ACL براي $1 +eacl_owner=مالک پرونده +eacl_edefaults=اگر پرونده شامل تعدادي ACL پيش‌گزيده باشد بايد کاربر، گروه Ùˆ ACLهاي پيش‌گزيده ديگري داشته باشد + +acltype_user=کاربر +acltype_group=گروه +acltype_other=ديگران +acltype_mask=پوشش +acltype_default_user=کاربر پيش‌گزيده +acltype_default_group=گروه پيش‌گزيده +acltype_default_other=ديگران پيش‌گزيده +acltype_default_mask=پوشش پيش‌گزيده + +delete_mtitle=حذ٠چندين پرونده +delete_dtitle=حذ٠Ùهرست راهنما +delete_ftitle=حذ٠پرونده +delete_ddesc=آيا از حذ٠دائم Ùهرست راهنماي $1 Ùˆ همه محتويات آن مطمئن هستيد؟ +delete_fdesc=آيا از حذ٠پرونده $1 مطمئن هستيد؟ +delete_mdesc=آيا از حذ٠دائمي اين پرونده‌ها Ùˆ Ùهرست راهنماها مطمئن هستيد؟ +delete_efailed=عدم موÙقيت در حذ٠$1: $2 + +mkdir_title=Ùهرست راهنماي جديد +mkdir_dir=Ùهرست راهنماي جديد: +mkdir_eexists=$1 از قبل وجود دارد +mkdir_efailed=عدم موÙقيت در ايجاد Ùهرست راهنماي: $1 +mkdir_eaccess=شما اجازه ايجاد $1 را نداريد + +link_title=ايجاد اتصال +link_from=اتصال از: +link_to=اتصال به: +link_eexists=$1 از قبل وجود دارد +link_efrom=منبع اتصال بايد ÙŠÚ© مسير مطلق باشد +link_efailed=عدم موÙقيت در اتصال: $1 +link_efrom2=شما اجازه اتصال از '$1' را نداريد +link_efollow=شما اجازه ايجاد اتصال نمادين را نداريد + +rename_title=تغيير نام $1 +rename_old=نام قبلي: +rename_new=نام جديد: +rename_ok=تغيير نام +rename_eexists=پرونده‌اي با نام $1 از قبل وجود دارد +rename_efailed=عدم موÙقيت در تغيير نام: $1 +rename_eold=شما اجازه تغيير نام '$1' را نداريد +rename_enew=شما اجازه تغيير نام به '$1' را نداريد + +file_type0=Ùهرست راهنما +file_type1=پرونده متني +file_type2=پرونده تصويري +file_type3=پرونده دودويي +file_type4=پرونده +file_type5=اتصال نمادين +file_type6=پرونده دستگاه +file_type7=لوله + +view_enormal=Ùقط پرونده‌هاي متني را مي‌توان ديد +view_enormal2=Ùقط پرونده‌هاي معمولي را مي‌توان بار کرد +view_eaccess=شما اجازه دستيابي به $1 را نداريد +view_eopen=عدم موÙقيت در باز کردن $1:$2 +view_edir=ايجاد بايگاني تنها براي Ùهرست راهنماهاي امکان پذير مي‌باشد +view_ecmd=دستور $1 Ú©Ù‡ براي ايجاد بايگاني لازم است نصب نشده‌است +view_ecomp=عدم موÙقيت در ايجاد بايگاني: $1 +view_earchive=شما اجازه بارکردن بايگانيها را نداريد +view_earchmax=Ùهرست راهنماي انتخاب شده بزرگ‌تر از بيشترين مقداري است Ú©Ù‡ براي بايگاني در نظر Ú¯Ø±ÙØªÙ‡ شده‌است ($1 بايت) + +paste_ecopy=شما قبل از چسباندن بايد ببريد يا رونوشت نمائيد +paste_egone=پرونده رونوشت شده $1 وجود ندارد +paste_eover=$1 قابل باز نويسي نمي‌باشد +paste_eself=شما نمي‌توانيد ÙŠÚ© پرونده را برروي خودش بچسبانيد +paste_emfailed=عدم موÙقيت در انتقال: $1 +paste_ecfailed=عدم موÙقيت در رونوشت: $1 + +over_title=پرونده وجود دارد +over_msg=پرونده $1 از قبل وجود دارد از حوزه زير جهت وارد کردن نام جديد براي پرونده چسبانده Ø´Ø¯Ù‡â€ŒØ§Ø³ØªÙØ§Ø¯Ù‡ نمائيد +over_new=نام پرونده جديد: +over_ok=تاييد + +upload_efailed=عدم موÙقيت در باز کردن بارگيري شده: $1 +upload_title=بارگيري پرونده +upload_file=پرونده جهت بارگيري +upload_dir=بارگيري به Ùهرست راهنما +upload_ok=بارگيري +upload_conv=آيا خطوط جديد DOS تبديل شوند؟ +upload_efile=پرونده‌اي براي بارگيري انتخاب نشده +upload_edir=Ùهرست راهنماي مقصد بارگيري موجود نيست +upload_eperm=شما اجازه ايجاد $1 را نداريد +upload_ewrite=عدم موÙقيت در نوشتن درون $1:$2 +upload_already=پرونده $1 از قبل وجود دارد از باز نويسي روي آن مطمئن هستيد +upload_elink=نمي‌توان به ÙŠÚ© اتصال نمادين بارگيري نمود +upload_zip=آيا پرونده‌هاي tarيا zip از ÙØ´Ø±Ø¯Ú¯ÙŠ Ø®Ø§Ø±Ø¬ شوند؟ +upload_yes=بله Ùˆ سپس حذ٠شود + +find_eaccess=شما اجازه دستيابي به $1 را نداريد +find_eexist=$1 درون $2 وجود ندارد +find_edir=$1 ÙŠÚ© Ùهرست راهنما در $2 نيست + +cancel=لغو +close=بستن +eopen=عدم موÙقيت در بارگيري کردن: $1 + +chmod_eaccess=شما اجازه دستيابي به '$1' را نداريد +chmod_euser=$1: چنين کاربري وجود ندارد +chmod_egroup=$1: چنين گروهي وجود ندارد +chmod_elink=عدم موÙقيت در اتصال نمادين +chmod_echown=عدم موÙقيت در تغيير مالکيت: $1 +chmod_echmod=عدم موÙقيت در تغيير chmod: $1 +chmod_efollow=شما اجازه اجازه ويرايش اتصالهاي نمادين را نداريد + +copy_efrom=شما اجازه اجازه رونوشت برداشتن از $1 را نداريد +copy_eto=شما اجازه اجازه رونويسي در $1 را نداريد +copy_elink=عدم موÙقيت در اتصال نمادين: $1 + +delete_eaccess=شما اجازه اجازه حذ٠$1 را نداريد + +list_eaccess=شما اجازه اجازه دستيابي به اين Ùهرست راهنما را نداريد +list_edir=عدم موÙقيت در ليست کردن$1: $2 + +move_eto=شما اجازه اجازه منتقل کردن به $1 را نداريد +move_afrom=شما اجازه اجازه انتقال '$1' را نداريد + +acl_user=دستيابي به پرونده برروي کارساز به‌عنوان کاربر +acl_user_def=مانند وب‌مين +acl_umask=پوشش براي پرونده‌هاي جديد +acl_follow=آيا اتصالهاي نمادين دنبال شوند؟ +acl_fyes=اگر صاحبان آن يکسان باشند +acl_ro=آيا حالت Ùقط خواندني است؟ +acl_dirs=Ùقط اجازه دستيابي به اين Ùهرست (هاي) راهنما داه شود +acl_nodirs=دستيابي به Ùهرست (هاي) راهنما ممنوع شود +acl_home=به اضاÙÙ‡ Ùهرست شخصي کاربر وب‌مين +acl_log=آيا کليه اصلاحات پرونده‌ها ثبت شود؟ +acl_goto=اولين Ùهرست راهنماي اجازه داده شده باز شود؟ +acl_max=بيشينه اندازه بار گذاري +acl_unlim=نامحدود +acl_b=بايت +acl_archive=آيا مي‌توان بايگانيهاي Ùهرستهاي راهنما را بار کرد؟ +acl_archmax=بله، اگر کوچک‌تر است از: +acl_buttons=دگمه‌هاي قابل دستيابي در نوار ابزار +acl_button_save=ذخيره(بار کردن پرونده) +acl_button_edit=ويرايش(ويرايش پرونده‌هاي متني) +acl_button_info=اطلاعات (ويرايش مجوزها Ùˆ مالکيت ) +acl_button_acl=ACL (ويرايش ACL) +acl_button_attr=Attr (ويرايش خصيصه‌هاي XFS) +acl_button_ext=EXT (ويرايش خصيصه‌هاي EXT ) +acl_button_search=ÙŠØ§ÙØªÙ† (ÙŠØ§ÙØªÙ† پرونده‌ها) +acl_button_delete=حذÙ(حذ٠پرونده‌ها) +acl_button_new=جديد(ايجاد پرونده متني) +acl_button_upload=بارگيري(بارگيري پرونده‌ها توسط کارخواه) +acl_button_mkdir=جديد (ايجاد Ùهرست راهنما) +acl_button_makelink=جديد (ايجاد اتصال نمادين) +acl_button_rename=تغيير نام (تغيير نام پرونده) +acl_button_sharing=اشتراک گذاري(تنظيم کردن سامبا Ùˆ اشتراک گذاري پرونده NFS) +acl_button_mount=سوار (سوار يا پياده کردن سيستم پرونده ) +acl_button_copy=رونوشت٬ برش Ùˆ چسباندن +acl_unarchive=آيا مي‌توان پرونده‌هاي بايگاني بارگيري شده را استخراج نمود؟ +acl_unarchive2=هميشه سعي شود +acl_unarchive1=$Yes +acl_unarchive0=$No +acl_dostounix=آيا مي‌توان خطوط جديد تبديل شده Dos داشت؟ +acl_chroot=تغيير Ùهرست راهنماي مدير سيستم براي مدير پرونده وارد شده: +acl_relto=(وابسته به Ùهرست راهنماي هر مدير سيستم chroot) + +share_title=اشتراک گذاري +share_samba=ويندوز +share_nfs=NFS +share_son=اشتراک گذاري پرونده ويندوز ÙØ¹Ø§Ù„ شود +share_soff=اشتراک گذاري پرونده ويندوز ØºÙŠØ±ÙØ¹Ø§Ù„ شود +share_writable=آيا قابل نوشتن است؟ +share_available=آيا در حال حاضر ÙØ¹Ø§Ù„ است؟ +share_sheader=گزينه‌هاي اشتراک گذاري +share_only=Ùقط +share_guest=آيا براي مهمان قابل دستيابي است؟ +share_comment=شرح +share_nheader=گزينه‌هاي برون‌برد NFS +share_non=اشتراک گذاري پرونده NFS ÙØ¹Ø§Ù„ شود +share_noff=اشتراک گذاري پرونده NFS ØºÙŠØ±ÙØ¹Ø§Ù„ شود +share_desc=شرح +share_ro=ميزبانهاي Ùقط خواندني +share_rw=ميزبانهاي خواندني Ùˆ نوشتني +share_root=ميزبانهاي دستيابي به ريشه +share_none=هيچ +share_all=همه +share_listed=ليست شده.. +share_host=ميزبانها +share_opts=گزينه‌ها +share_s0=هيچ کس مطمئن نيست +share_s1=هيچ کس غير از root مطمئن نيست +share_s2=همه مطمئن هستند +share_lro=Ùقط خواندني +share_lrw=خواندني Ùˆ نوشتني + +log_create_export=برون‌برد $1 NFS ايجاد شد. +log_modify_export=برون‌برد $1 NFS تغيير کرد. +log_delete_export=برون‌برد $1 NFS حذ٠شد. +log_create_share=اشتراک $1 سامبا ايجاد شد +log_modify_share=اشتراک $1 سامبا تغيير کرد +log_delete_share=اشتراک $1 سامبا حذ٠شد +log_save=پرونده $1 ذخيره شد +log_chmod=مجوزهاي پرونده $1 تغيير داده شد +log_mkdir=Ùهرست راهنماي $1ايجاد شد +log_upload=پرونده $1 بار گذاري شد +log_link=اتصال نمادين از $1 به $2 ايجاد شد +log_relink=اتصال نمادين از $1 به $2 تغيير کرد +log_copy=از پرونده $1 در $2 رونويسي شد +log_move=پرونده $1 به $2 حرکت داده شد +log_delete=پرونده $1حذ٠شد +log_attr=خصيصه‌هاي پرونده $1 قرار داده شد +log_acl=ACL پرونده $1قرار داده شد + +search_eaccess=شما اجازه جستجو در اين Ùهرست راهنما را نداريد +search_title=ÙŠØ§ÙØªÙ† پرونده‌ها +search_ok=جستجو +search_dir=جستجو در Ùهرست راهنما +search_match=براي تطبق دادن پرونده‌ها +search_user=کاربر مالک +search_group=گروه مالک +search_any=همه +search_type=نوع پرونده +search_types_=همه +search_types_f=پرونده +search_types_d=Ùهرست راهنما +search_types_l=اتصال نمادين +search_types_p=لوله نامدار +search_size=اندازه پرونده +search_more=بيش از +search_less=کمتر از +search_xdev=آيا سوار شده‌هاي قبلي نيز جستجو شود؟ +search_edir=Ùهرست راهنماي جستجو نامعتبر است Ùˆ يا ÙŠØ§ÙØª نشد +search_ematch=عبارت با قاعده تطبيق ÙŠØ§ÙØª نشد +search_euser=اسم‌کاربر ÙŠØ§ÙØª نشد +search_egroup=نام گروه ÙŠØ§ÙØª نشد +search_esize=اندازه پرونده بايد ÙŠÚ© عدد صحيح باشد +search_crit=معيارهاي جستجو +search_list=نتايج جستجو + +facl_eaccess=شما اجازه قرار دادن ACLها براي اين پرونده را نداريد + +attr_eattrs=عدم موÙقيت در Ø¯Ø±ÙŠØ§ÙØª خصيصه‌ها: $1 +attr_efs=سيستم پرونده $1 از خصيصه‌ها پشتيباني نمي‌کند +attr_add=Ø§ÙØ²ÙˆØ¯Ù† خصيصه +attr_name=نام خصيصه +attr_value=مقدار خصيصه +attr_efailed=عدم موÙقيت در قرار دادن خصيصه‌ها براي $1: $2 +attr_title=خصيصه پرونده براي $1 +attr_create=Ø§ÙØ²ÙˆØ¯Ù† خصيصه +attr_edit=ويرايش خصيصه +attr_ename=نام خصيصه ÙŠØ§ÙØª نشد + +ext_eattrs=عدم موÙقيت در Ø¯Ø±ÙŠØ§ÙØª خصيصه‌هايEXT: $1 +ext_efs=سيستم پرونده $1از خصيصه‌هاي EXT پشتيباني نمي‌کند +ext_title=خصيصه‌هايEXTبراي $1 +ext_header=خصيصه‌هاي پروندهEXT +ext_efailed=عدم موÙقيت در قرار دادن خصيصه‌ها براي $1: $2 + +eattr_A=زمانهاي دستيابي به‌روزرساني نشود +eattr_a=تنها مي‌توان به پرونده‌ها اضاÙÙ‡ کرد +eattr_c=داده‌ها برروي ديسک ÙØ´Ø±Ø¯Ù‡ سازي شوند +eattr_d=با زباله پشتيبان تهيه نشود +eattr_i=اجازه اصلاحات داده نشود +eattr_s=به هنگام حذ٠کردن بلاکها ØµÙØ± شوند +eattr_S=هميشه پس از نوشتن همزمان شوند +eattr_u=محتويات براي غيرحذÙيها Ø­ÙØ¸ شوند + +mount_eaccess=شما اجازه سوار کردن سيستم پرونده را نداريد +mount_efstab=هيچ سيستم پرونده‌اي در اين نقطه از سوار وجود دارد +mount_epoint=$1 ÙŠÚ© نقطه سوار نيست +mount_rusure1=آيا شما مطمئن هستيد Ú©Ù‡ مي‌خواهيد $1 از $2را سوار نمائيد ? +mount_rusure2=آيا شما مطمئن هستيد Ú©Ù‡ مي‌خواهيد $1 از $2را پياده نمائيد؟ +mount_err1=عدم موÙقيت در سوار کردن $1: $2 +mount_err2=عدم موÙقيت در پياده کردن $1: $2 +mount_title1=سوار کردن سيستم پرونده +mount_title2=پياده کردن سيستم پرونده + +zip_err=نمي توان پرونده : $1را استخراج نمود +zip_ecmd=دستور $1ÙŠØ§ÙØª نشد +zip_eunzip=عدم موÙقيت در Unzipکردن: $1 +zip_ename=به نظر مي‌رسد ÙŠÚ© پرونده zip, tar يا tar.gz نيست +zip_euntar=عدم موÙقيت درUn-tarکردن: $1 +zip_euntar2=عدم موÙقيت در خارج کردن از ÙØ´Ø±Ø¯Ù‡ سازي Ùˆ un-tar کردن: $1 + +ddir_title=Ùهرست راهنماي بار کردن +ddir_rusure=براي بار کردن محتويات $1 به‌صورت ÙŠÚ© پرونده بايگاني ÙŠÚ©ÙŠ از دگمه‌هاي نوع بايگاني زير را ÙØ´Ø§Ø± دهيد. +ddir_zip=ZIP +ddir_tgz=TAR.GZ +ddir_tar=TAR + +ebutton=اين خصوصيت قابل دستيابي نيست + + diff --git a/file/lang/fr b/file/lang/fr new file mode 100644 index 000000000..d1d5b1978 --- /dev/null +++ b/file/lang/fr @@ -0,0 +1,229 @@ +index_title=Gestionnaire de Fichier +index_nojava=Ce module nécessite que java soit en fonction, mais votre fureteur ne le supporte pas +switch_euser=L'utilisateur Unix n'existe pas ! + +top_open=Ouvrir +top_view=Voir +top_edit=Éditer +top_refresh=Rafraîchir +top_info=Information +top_delete=Supprimer +top_new=Nouveau +top_upload=Envoyer +top_rename=Renommer +top_copy=Copier +top_cut=Couper +top_paste=Coller +top_share=Partage +top_search=Trouver + +right_name=Nom +right_size=Taille +right_user=Usager +right_group=Groupe +right_date=Date + +edit_enormal=Seulement les fichiers normaux peuvent être éditer +edit_title=Éditer '$1' +edit_title2=Créer un fichier +edit_filename=Nom de fichier: +edit_eover='$1' ne peut être écrit par-dessus +edit_esave=Impossible d'ouvrir le fichier '$1' +edit_eaccess=Vous n'êtes pas autorisé à sauver '$1' + +info_file=Fichier +info_path=Chemin: +info_type=Type: +info_size=Taille: +info_mod=Modifié: +info_link=Liens vers: +info_perms=Permissions +info_user=Usager: +info_group=Groupe: +info_other=Autre: +info_sticky=Collant: +info_sticky2=Seulement son propriétaire peut effacer un fichier +info_own=Propriétaire +info_setuid=SUID: +info_setuid2=Exécuter comme usager +info_setgid=SGID: +info_setgid2=Les fichiers hérite du groupe +info_setgid3=Exécuter comme groupe +info_apply=Appliquer les changements à +info_apply1=Ce répertoire seulement +info_apply2=Ce répertoire et à ses fichiers +info_apply3=Ce répertoire et tout ses sous-répertoires +info_efailed=Impossible de mettre à jour '$1' : $2 +info_read=Lire +info_write=Écrire +info_list=Lister +info_exec=Exécuter + +delete_dtitle=Supprimer un répertoire +delete_ftitle=Supprimer un fichier +delete_ddesc=Vous êtes sur que vous voulez supprimer définitivement le répertoire '$1' et tout son contenu? +delete_fdesc=Vous êtes sur que vous voulez supprimer définitivement le fichier $1? +delete_efailed=Impossible de supprimer '$1' : $2 + +mkdir_title=Nouveau Répertoire +mkdir_dir=Nouveau répertoire: +mkdir_eexists='$1' existe déjà +mkdir_efailed=Impossible de créer le répertoire : $1 +mkdir_eaccess=Vous n'êtes pas autorisé à créer '$1' + +link_title=Créer un Lien Symbolique +link_from=Lien de: +link_to=Lien vers: +link_eexists='$1' Existe déjà +link_efailed=Impossible de faire le lien symbolique '$1' +link_efrom=Vous n'êtes pas autorisé à créer aucun lien symbolique de '$1' +link_efollow=Vous n'êtes pas autorisé à créer aucun lien symbolique + +rename_title=Renommer '$1' +rename_old=Ancien nom: +rename_new=Nouveau nom: +rename_ok=Renommer +rename_eexists=Un fichier appelé '$1' existe déjà +rename_efailed=Impossible de renommer '$1' +rename_eold=Vous n'êtes pas autorisé à renommer '$1' +rename_enew=Vous n'êtes pas autorisé à renommer pour '$1' + +file_type0=Répertoire +file_type1=Fichier texte +file_type2=Fichier image +file_type3=Fichier binaire +file_type4=Fichier +file_type5=Lien symbolique +file_type6=Fichier de périphérique +file_type7=Tuyau + +view_enormal=Seulement un fichier normal peut être visionné +view_eaccess=Vous n'êtes pas autorisé d'accéder à '$1' +view_eopen=Impossible d'ouvrir '$1' : $2 + +paste_ecopy=Vous devez copier ou couper avant de coller +paste_egone=Le fichier copié '$1' n'existe plus +paste_eover='$1' ne peut être écrasé +paste_eself=Vous ne pouvez coller un fichier par-dessus lui-même +paste_emfailed=Impossible de déplacer '$1' +paste_ecfailed=Impossible de copier '$1' + +over_title=Le fichier existe +over_msg=Le fichier $1 existe déjà. Utiliser le champ ci-dessous pour entrer un nouveau fichier pour le fichier collé. +over_new=Nouveau nom de fichier:: +over_ok=Ok + +upload_efailed=Impossible d'ouvrir l'envoie '$1' +upload_title=Envoie de Fichier +upload_file=Fichier à envoyer +upload_dir=Envoyer dans un répertoire +upload_ok=Envoie +upload_conv=Convertir les retours de chariot en format DOS? +upload_efile=Aucun fichier n'ont été sélectionné pour envoyer. +upload_edir=Le répertoire d'envoi n'existe pas. +upload_eperm=Vous n'êtes pas autorisé à créer '$1' +upload_ewrite=Impossible d'écrire dans '$1' : $2 + +find_eaccess=Vous n'êtes pas autorisé d'accéder à '$1' +find_eexist='$1' n'existe pas dans '$2' +find_edir='$1' n'est pas un répertoire dans '$2' + +cancel=Annuler + +chmod_eaccess=Vous n'êtes pas autorisé d'accéder à '$1' +chmod_euser=$1 : usager inexistant +chmod_egroup=$1 : groupe inexistant +chmod_elink=lien symbolique impossible : $1 +chmod_echown=Impossible de changer de propriétaire : $1 +chmod_echmod=Impossible de changer de permission : $1 + +copy_efrom=Vous n'êtes pas autorisé à copier de '$1' +copy_eto=Vous n'êtes pas autorisé à copier vers '$1' +copy_elink=lien symbolique impossible : $1 + +delete_eaccess=Vous n'êtes pas autorisé à supprimer '$1' + +list_eaccess=Vous n'êtes pas autorisé d'accéder ce répertoire +list_edir=Echec du listage de $1 : $2 + +move_eto=Vous n'êtes pas autorisé à déplacer vers '$1' +move_afrom=Vous n'êtes pas autorisé à déplacer '$1' + +acl_user=Accéder au système de fichier en étant un usager +acl_user_def=Pareil que le login Webmin +acl_umask=Démasquer tout nouveau fichier +acl_follow=Toujours suivre les liens symboliques? +acl_dirs=Seulement accès aux répertoires +acl_home=Inclure le répertoire personnel de l'utilisateur Webmin + +share_title=Partage +share_samba=Windows +share_nfs=NFS +share_son=Partage de fichiers Windows activé +share_soff=Partage de fichiers Windows désactivé +share_writable=En écriture ? +share_available=Actuellement disponible ? +share_sheader=Options de partage +share_only=Seulement +share_guest=Accès Invité ? +share_comment=Commentaire +share_nheader=Options d'export NFS +share_non=Partage de fichiers NFS activé +share_noff=Partage de fichiers NFS désactivé +share_desc=Description +share_ro=Machines en lecture seule +share_rw=Machines en lecture/écriture +share_root=Machines avec accès root +share_none=Aucune +share_all=Toutes +share_listed=Listées ... +share_host=Machines +share_opts=Options +share_s0=Ne faire confiance à personne +share_s1=Faire confiance aux non-root +share_s2=Faire confiance à tout le monde +share_lro=Lecture seule +share_lrw=Lecture-écriture + +log_create_export=Export NFS $1 créé +log_modify_export=Export NFS $1 modifié +log_delete_export=Export NFS $1 supprimé +log_create_share=Ressource partagée Samba $1 créée +log_modify_share=Ressource partagée Samba $1 modifiée +log_delete_share=Ressource partagée Samba $1 supprimée +log_save=Fichier $1 sauvé +log_chmod=Permissions modifiées sur le fichier $1 +log_mkdir=Répertoire $1 créé +log_upload=Fichier $1 téléchargé +log_link=Lien symbolique de $1 vers $2 créé +log_relink=Lien symbolique de $1 vers $2 modifié +log_copy=Lien symbolique de $1 vers $2 copié +log_move=Fichier renommé de $1 en $2 +log_delete=Fichier $1 supprimé + +search_eaccess=Vous n'avez pas le droit de chercher dans ce répertoire +search_title=Trouver des fichiers +search_ok=Chercher maintenant +search_dir=Répertoire de recherche +search_match=Pour les fichiers correspondant à +search_user=Possédé par utilisateur +search_group=Possédé par groupe +search_any=N'importe +search_type=Type de fichier +search_types_=N'importe +search_types_f=Fichier +search_types_d=Répertoire +search_types_l=Lien symbolique +search_types_p=Tube nommé +search_size=Taille de fichier +search_more=Plus de +search_less=Moins de +search_xdev=Chercher au-delà des points de montage ? +search_edir=Répertoire de recherche manquant ou invalide +search_ematch=Expression rationnelle manquante +search_euser=Nom d'utilisateur manquant +search_egroup=Nom de groupe manquant +search_esize=La taille de fichier doit être un entier +search_crit=Critères de recherche +search_list=Résultats de la recherche + diff --git a/file/lang/it b/file/lang/it new file mode 100644 index 000000000..a95c3e71d --- /dev/null +++ b/file/lang/it @@ -0,0 +1,321 @@ +index_title=File Manager +index_nojava=Questo modulo richiede java per funzionare, il tuo browser non supporta java +index_eremote=Non esiste un utente Unix corrispondente il login Webmin $1. +switch_euser=L'utente Unix non esiste! + +top_ret=Indice +top_down=Salva +top_edit=Modifica +top_refresh=Ricarica +top_info=Informazioni +top_eacl=ACL +top_attr=Attributi +top_ext=EXT +top_delete=Cancella +top_new=Nuovo +top_upload=Upload +top_rename=Rinomina +top_copy=Copia +top_cut=Taglia +top_paste=Incolla +top_share=Condivisione +top_mount=Mount +top_search=Cerca +top_config=Configura + +right_name=Nome +right_size=Dimensione +right_user=Utente +right_group=Gruppo +right_date=Data + +edit_enormal=Puoi modificare solo file normali +edit_title=Modifica di $1 +edit_title2=Creazione file +edit_filename=Nome file: +edit_goto=Vai a +edit_find=Cerca +edit_gotoline=Vai alla riga +edit_replace=Sostituisci +edit_all=Sostituisci tutto +edit_searchfor=Cerca +edit_replaceby=Sostituisci con +edit_eover=$1 non può�essere sovrascritto +edit_esave=Salvataggio file fallito : $1 +edit_eaccess=Non sei autorizzato a salvare '$1' +edit_notfound=Il testo $1 non è�stato trovato +edit_saveclose=Salva & Esci + +info_file=File +info_path=Percorso: +info_type=Tipo: +info_size=Dimensione: +info_mod=Modificato: +info_link=Link a: +info_perms=Permessi +info_user=Utente: +info_group=Gruppo: +info_other=Altri: +info_octal=Ottale: +info_sticky=Sticky: +info_sticky2=Solo i proprietari possono cancellare file +info_own=Possesso +info_setuid=Setuid: +info_setuid2=Esegui come utente +info_setgid=Setgid: +info_setgid2=I file ereditano il gruppo +info_setgid3=Esegui come gruppo +info_apply=Applica modifiche a +info_apply1=Solo questa directory +info_apply2=Questa directory e i suoi file +info_apply3=Questa directory e tutte le subdirectory +info_efailed=Aggiornamento $1 fallito : $2 +info_read=Lettura +info_write=Scrittura +info_list=Elenco +info_exec=Esecuzione + +eacl_eacls=Lettura ACL fallito : $1 +eacl_acltype=Tipo ACL +eacl_aclname=Applica a +eacl_aclperms=Permessi +eacl_add=Aggiungi ACL di tipo : +eacl_remove=Rimuovi ACL +eacl_efs=Il filesystem $1 non supporta ACL +eacl_create=Crea ACL +eacl_edit=Modifica ACL +eacl_user=Proprietario file $1 +eacl_group=Gruppo file $1 +eacl_eowner=Utente o gruppo da applicare mancante +eacl_efailed=Settaggio ACL fallito per $1 : $2 +eacl_emask=Pu�esserci al massimo una maschera ACL +eacl_edefmask=Pu�esserci al massimo una maschera ACL di default +eacl_title=ACL per $1 +eacl_owner=Proprietario File +eacl_edefaults=Se il file ha ACL di default, deve avere utente, gruppo e altre ACL di default + +acltype_user=Utente +acltype_group=Gruppo +acltype_other=Altri +acltype_mask=Maschera +acltype_default_user=Utente di default +acltype_default_group=Gruppo di default +acltype_default_other=Altri di default +acltype_default_mask=Maschera di default + +delete_mtitle=Cancellazione multipla di file +delete_dtitle=Cancellazione directory +delete_ftitle=Cancellazione file +delete_ddesc=Sei sicuro di voler cancellare definitivamente la directory $1 e tutto il suo contenuto? +delete_fdesc=Sei sicuro di voler cancellare definitivamente il file $1 ? +delete_mdesc=Sei sicuro di voler cancellare definitivamente questi file e directory? : +delete_efailed=Cancellazione $1 fallita : $2 + +mkdir_title=Nuova Directory +mkdir_dir=Nuova directory: +mkdir_eexists=$1 gi�esistente +mkdir_efailed=Creazione directory fallita : $1 +mkdir_eaccess=Non sei autorizzato a creare '$1' + +link_title=Creazione Link +link_from=Link da: +link_to=Link a: +link_eexists=$1 gi�esistente +link_efailed=Link fallito : $1 +link_efrom=Non sei autorizzato a fare un link da '$1' +link_efollow=Non sei autorizzato a creare link simbolici + +rename_title=Rinomina $1 +rename_old=Vecchio nome: +rename_new=Nuovo nome: +rename_ok=Rinomina +rename_eexists=Esiste gi�un file di nome $1 +rename_efailed=Rinominazione fallita : $1 +rename_eold=Non sei autorizzato a rinominare '$1' +rename_enew=Non sei autorizzato a rinominare a '$1' + +file_type0=Directory +file_type1=File di testo +file_type2=File immagine +file_type3=File binario +file_type4=File +file_type5=Link simbolico +file_type6=File Device +file_type7=Pipe + +view_enormal=Possono essere visualizzati solo file normali +view_enormal2=Possono essere scaricati solo file normali +view_eaccess=Non sei autorizzato ad accedere $1 +view_eopen=Apertura $1 fallita : $2 + +paste_ecopy=Devi tagliare o copiare prima di incollare +paste_egone=Il file copiato $1 non esite pi +paste_eover=$1 non pu�essere sovrascritto +paste_eself=Non puoi incollare un file sopra se stesso +paste_emfailed=Spostamento fallito : $1 +paste_ecfailed=Copia fallita : $1 + +over_title=Il File Esiste Gi�over_msg=Il file $1 esiste gi� Usa il campo qui sotto per inserire un nuovo nome per il file incollato. +over_new=Nuovo nome: +over_ok=Vai + +upload_efailed=Inizio trasferimento fallito : $1 +upload_title=Trasferisci file (upload) +upload_file=File da trasferire +upload_dir=Trasferisci alla directory +upload_ok=Trasferimento +upload_conv=Convertire nuovariga DOS? +upload_efile=Nessun file selezionato per il trasferimento. +upload_edir=La directory di destinazine non esiste. +upload_eperm=Non sei autorizzato a creare $1 +upload_ewrite=Scrittura $1 fallita : $2. +upload_already=Il file $1 esiste gi� Sei sicuro di volerlo sovrascrivere? + +find_eaccess=Non sei autorizzato ad accedere $1 +find_eexist=$1 non esiste in $2 +find_edir=$1 non �una directory in $2 + +cancel=Cancella +close=Chiudi + +chmod_eaccess=Non sei autorizzato ad accedere '$1' +chmod_euser=$1 : utente non esistente +chmod_egroup=$1 : gruppo non esistente +chmod_elink=Link simbolico fallito : $1 +chmod_echown=chown fallito : $1 +chmod_echmod=chmod fallito : $1 +chmod_efollow=Non sei autorizzato a modificare link simbolici + +copy_efrom=Non sei autorizzato a copiare da '$1' +copy_eto=Non sei autorizzato a copiare in '$1' +copy_elink=Link simbolico fallito : $1 + +delete_eaccess=Non sei autorizzato a cancellare '$1' + +list_eaccess=Non sei autorizzato ad accedere questa directory +list_edir=Elenco $1 fallito : $2 + +move_eto=Non sei autorizzato a muovere in '$1' +move_afrom=Non sei autorizzato a muovere '$1' + +acl_user=Accesso file sul server come utente +acl_user_def=Uguale al login Webmin +acl_umask=Umask per i nuovi file +acl_follow=Seguire sempre i link simbolici? +acl_ro=Modalit�sola lettura? +acl_dirs=Autorizza accesso alle sole directory +acl_home=Includi la home directory dell'utente Webmin +acl_log=Eseguo log di tutte le modifiche ai file? +acl_goto=Aprire la prima directory autorizzata? + +share_title=Sharing +share_samba=Windows +share_nfs=NFS +share_son=File sharing windows abilitato +share_soff=File sharing windows disabilitato +share_writable=Scrivibile? +share_available=Attualmente attivo? +share_sheader=Opzioni di sharing +share_only=Solamente +share_guest=Accesso guest? +share_comment=Commento +share_nheader=Opzioni export NFS +share_non=File sharing NFS abilitato +share_noff=File sharing NFS disabilitato +share_desc=Descrizione +share_ro=Host sola lettura +share_rw=Host lettura e scrittura +share_root=Host con accesso root access +share_none=Nessuno +share_all=Tutti +share_listed=Elencati.. +share_host=Host +share_opts=Opzioni +share_s0=Non fidarti di nessuno +share_s1=Fidati degli utenti non-root +share_s2=Fidati di tutti +share_lro=Sola lettura +share_lrw=Lettura scrittura + +log_create_export=Creato export NFS $1 +log_modify_export=Modificato export NFS $1 +log_delete_export=Cancellato export NFS $1 +log_create_share=Creato share Samba $1 +log_modify_share=Modificato share Samba $1 +log_delete_share=Cancellato share Samba $1 +log_save=File $1 salvato +log_chmod=Cambiati permessi del file $1 +log_mkdir=Creata directory $1 +log_upload=Trasferito file $1 +log_link=Creato link simbolico $1 a $2 +log_relink=Modificato link simbolico $1 a $2 +log_copy=Copiato file $1 a $2 +log_move=Spostato file $1 a $2 +log_delete=Cancellato file $1 +log_attr=Settati attributi del file $1 +log_acl=Settati ACL al file $1 + +search_eaccess=Non sei autorizzato a cercare questa directory +search_title=Cerca file +search_ok=Esegui Ricerca +search_dir=Cerca directory +search_match=File corrispondenti +search_user=Utente proprietario +search_group=Gruppo proprietario +search_any=Qualsiasi +search_type=Tipo file +search_types_=Qualsiasi +search_types_f=File +search_types_d=Directory +search_types_l=Link simbolico +search_types_p=Named pipe +search_size=Dimensione File +search_more=Pi di +search_less=Meno di +search_xdev=Cerco sotto i mount? +search_edir=Directory di ricerca mancante o invalido +search_ematch=regexp di corrispondenza mancante o invalida +search_euser=Nome utente mancante o invalido +search_egroup=Nome gruppo mancante +search_esize=La dimensione del file deve essere un intero +search_crit=Criterio di ricerca +search_list=Risultati ricerca + +facl_eaccess=Non sei autorizzato a settare ACL per questo file + +attr_eattrs=Lettura attributi fallito : $1 +attr_efs=Il filesystem $1 non supporta attributi +attr_add=Aggiungi Attributo +attr_name=Nome Attributo +attr_value=Valore Attributo +attr_efailed=Settaggio attributo fallito per $1 : $2 +attr_title=Attributi per $1 +attr_create=Aggiungi Attributo +attr_edit=Modifica Attributo +attr_ename=Nome attributo mancante + +ext_eattrs=Lettura attributi EXT fallito : $1 +ext_efs=Il filesystem $1 non supporta attributi EXT +ext_title=Attributi EXT per $1 +ext_header=Attributi EXT +ext_efailed=Settaggio attributi fallito per $1 : $2 + +eattr_A=Non aggiornare il tempo di accesso +eattr_a=Puoi solo appendere al file +eattr_c=Dati compressi sul disco +eattr_d=Non fare backup con dump +eattr_i=Non permettere modifiche +eattr_s=Azzera blocchi in cancellazione +eattr_S=Sync dopo la scrittura +eattr_u=Salva il contenuto per de-cancellazione + +mount_eaccess=Non sei autorizzato a montare filesystem +mount_efstab=Non esiste filesystem in questo mount point +mount_epoint=$1 non �un mount point +mount_rusure1=Sei sicuro di voler montare $1 in $2 ? +mount_rusure2=Sei sicuro di voler smontare $1 da $2 ? +mount_err1=Mount di $1 fallito : $2 +mount_err2=Un-mount di $1 fallito : $2 +mount_title1=Mount filesystem +mount_title2=Un-mount filesystem + diff --git a/file/lang/ja_JP.UTF-8 b/file/lang/ja_JP.UTF-8 new file mode 100644 index 000000000..30f5a4479 --- /dev/null +++ b/file/lang/ja_JP.UTF-8 @@ -0,0 +1,226 @@ +index_title=ファイル マãƒãƒ¼ã‚¸ãƒ£ +index_nojava=ã“ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¯å‹•作ã™ã‚‹ã®ã« Java ã‚’å¿…è¦ã¨ã—ã¾ã™ãŒã€ã”使用ã®ãƒ–ラウザ㯠Java をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“ + +top_open=é–‹ã +top_view=表示 +top_edit=編集 +top_refresh=æ›´æ–° +top_info=情報 +top_delete=削除 +top_new=æ–°è¦ +top_upload=アップロード +top_rename=å称変更 +top_copy=コピー +top_cut=カット +top_paste=ペースト +top_share=共有 +top_search=検索 + +right_name=ファイルå +right_size=サイズ +right_user=ユーザ +right_group=グループ +right_date=日時 + +edit_enormal=標準ファイルã®ã¿ç·¨é›†ã§ãã¾ã™ +edit_title=$1 を編集中 +edit_title2=ファイルを作æˆä¸­ +edit_filename=ファイルå: +edit_eover=$1 ã¯ä¸Šæ›¸ãã§ãã¾ã›ã‚“ +edit_esave=ファイルをä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: $1 +edit_eaccess='$1' ã‚’ä¿å­˜ã§ãã¾ã›ã‚“ + +info_file=ファイル +info_path=パス: +info_type=種類: +info_size=サイズ: +info_mod=変更: +info_link=リンク先: +info_perms=è¨±å¯ +info_user=ユーザ: +info_group=グループ: +info_other=ãã®ä»–: +info_sticky=スティッキー: +info_sticky2=所有者ã®ã¿ãŒãƒ•ァイルを削除ã§ãã¾ã™ +info_own=所有権 +info_setuid=setuid (ユーザ ID を設定): +info_setuid2=次ã®ãƒ¦ãƒ¼ã‚¶ã¨ã—ã¦å®Ÿè¡Œ +info_setgid=setgid (グループ ID を設定): +info_setgid2=ファイルã®ç¶™æ‰¿ã‚°ãƒ«ãƒ¼ãƒ— +info_setgid3=次ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¨ã—ã¦å®Ÿè¡Œ +info_apply=変更をé©ç”¨ +info_apply1=ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ã¿ +info_apply2=ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨ãã“ã«å«ã¾ã‚Œã¦ã„るファイル +info_apply3=ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨ã™ã¹ã¦ã®ã‚µãƒ–ディレクトリ +info_efailed=$1 ã‚’æ›´æ–°ã§ãã¾ã›ã‚“ã§ã—ãŸ: $2 +info_read=読å–り +info_write=書込㿠+info_list=リスト +info_exec=実行 + +delete_dtitle=ディレクトリã®å‰Šé™¤ +delete_ftitle=ファイルã®å‰Šé™¤ +delete_ddesc=ディレクトリ $1 ã¨ãã®å†…容を永久ã«å‰Šé™¤ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ +delete_fdesc=ユーザ $1を永久ã«å‰Šé™¤ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ +delete_efailed=$1 を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: $2 + +mkdir_title=æ–°è¦ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª +mkdir_dir=æ–°è¦ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª: +mkdir_eexists=$1 ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ +mkdir_efailed=ディレクトリを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: $1 +mkdir_eaccess='$1' を作æˆã§ãã¾ã›ã‚“ + +link_title=リンクã®ä½œæˆ +link_from=リンク元: +link_to=リンク先: +link_eexists=$1 ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ +link_efailed=リンクã§ãã¾ã›ã‚“ã§ã—ãŸ: $1 +link_efrom='$1' ã‹ã‚‰ãƒªãƒ³ã‚¯ã§ãã¾ã›ã‚“ +link_efollow=シンボリック リンクを作æˆã§ãã¾ã›ã‚“ + +rename_title=$1 ã®å称変更 +rename_old=å¤ã„åå‰: +rename_new=æ–°ã—ã„åå‰: +rename_ok=å称変更 +rename_eexists=$1 ã¨ã„ã†ãƒ•ァイルã¯ã™ã§ã«å­˜åœ¨ã—ã¦ã„ã¾ã™ +rename_efailed=åå‰ã‚’変更ã§ãã¾ã›ã‚“ã§ã—ãŸ: $1 +rename_eold='$1' ã®åå‰ã‚’変更ã§ãã¾ã›ã‚“ +rename_enew='$1' ã®åå‰ã‚’変更ã§ãã¾ã›ã‚“ + +file_type0=ディレクトリ +file_type1=テキスト ファイル +file_type2=ç”»åƒãƒ•ァイル +file_type3=ãƒã‚¤ãƒŠãƒª ファイル +file_type4=ファイル +file_type5=シンボリック リンク +file_type6=デãƒã‚¤ã‚¹ ファイル +file_type7=パイプ + +view_enormal=標準ファイルã®ã¿è¡¨ç¤ºã§ãã¾ã™ +view_eaccess=$1 ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ +view_eopen=$1 ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: $2 + +paste_ecopy=ペーストã™ã‚‹å‰ã«ã‚«ãƒƒãƒˆã¾ãŸã¯ã‚³ãƒ”ーã—ã¦ãã ã•ã„ +paste_egone=コピーã—ãŸãƒ•ァイル $1 ã¯ã‚‚ã†å­˜åœ¨ã—ã¾ã›ã‚“ +paste_eover=$1 ã¯ä¸Šæ›¸ãã§ãã¾ã›ã‚“ +paste_eself=ファイルをãã®ãƒ•ァイル自身ã«ãƒšãƒ¼ã‚¹ãƒˆã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ +paste_emfailed=移動ã§ãã¾ã›ã‚“ã§ã—ãŸ: $1 +paste_ecfailed=コピーã§ãã¾ã›ã‚“ã§ã—ãŸ: $1 + +over_title=既存ã®ãƒ•ァイル +over_msg=ファイル $1 ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚ペーストã•れãŸãƒ•ã‚¡ã‚¤ãƒ«ã®æ–°è¦ãƒ•ァイルåを下ã®ãƒ•ィールドã«å…¥åŠ›ã—ã¦ãã ã•ã„。 +over_new=æ–°è¦ã®ãƒ•ァイルå: +over_ok=OK + +upload_efailed=アップロードを開ã‘ã¾ã›ã‚“ã§ã—ãŸ: $1 +upload_title=ファイルã®ã‚¢ãƒƒãƒ—ロード +upload_file=アップロードã™ã‚‹ãƒ•ァイル +upload_dir=アップロード ディレクトリ +upload_ok=アップロード +upload_conv=DOS 改行ã«å¤‰æ›ã—ã¾ã™ã‹ï¼Ÿ +upload_efile=アップロードã™ã‚‹ãƒ•ァイルãŒé¸æŠžã•れã¦ã„ã¾ã›ã‚“。 +upload_edir=アップロードã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒå­˜åœ¨ã—ã¾ã›ã‚“。 +upload_eperm=$1 を作æˆã§ãã¾ã›ã‚“ +upload_ewrite=$1 ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: $2. + +find_eaccess=$1 ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ +find_eexist=$1 㯠$2 ã«ã¯å­˜åœ¨ã—ã¾ã›ã‚“ +find_edir=$1 㯠$2 内ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“ + +cancel=キャンセル + +chmod_eaccess='$1' ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ +chmod_euser=$1 : ãã®ãƒ¦ãƒ¼ã‚¶ã¯å­˜åœ¨ã—ã¾ã›ã‚“ +chmod_egroup=$1 : ãã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯å­˜åœ¨ã—ã¾ã›ã‚“ +chmod_elink=symlink ãŒå¤±æ•—ã—ã¾ã—ãŸ: $1 +chmod_echown=chown ãŒå¤±æ•—ã—ã¾ã—ãŸ: $1 +chmod_echmod=chmod ãŒå¤±æ•—ã—ã¾ã—ãŸ: $1 + +copy_efrom='$1' ã‹ã‚‰ã¯ã‚³ãƒ”ーã§ãã¾ã›ã‚“ +copy_eto='$1' ã¸ã¯ã‚³ãƒ”ーã§ãã¾ã›ã‚“ +copy_elink=symlink ãŒå¤±æ•—ã—ã¾ã—ãŸ: $1 + +delete_eaccess='$1' を削除ã§ãã¾ã›ã‚“ + +list_eaccess=ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ +list_edir=$1 をリストã§ãã¾ã›ã‚“ã§ã—ãŸ: $2 + +move_eto='$1' ã¸ã¯ç§»å‹•ã§ãã¾ã›ã‚“ +move_afrom='$1' ã¯ç§»å‹•ã§ãã¾ã›ã‚“ + +acl_user=サーãƒã®ãƒ•ã‚¡ã‚¤ãƒ«ã«æ¬¡ã®ãƒ¦ãƒ¼ã‚¶ã¨ã—ã¦ã‚¢ã‚¯ã‚»ã‚¹ +acl_umask=æ–°è¦ãƒ•ァイル㮠Umask +acl_follow=symlink を常ã«ãŸã©ã‚Šã¾ã™ã‹ï¼Ÿ +acl_dirs=次ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã®ã¿ã‚’è¨±å¯ + +share_title=共有 +share_samba=Windows +share_nfs=NFS +share_son=Windows ファイルã®å…±æœ‰ã‚’有効 +share_soff=Windows ファイルã®å…±æœ‰ã‚’無効 +share_writable=書込ã¿ã§ãã¾ã™ã‹ï¼Ÿ +share_available=ç¾åœ¨ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã§ã™ã‹ï¼Ÿ +share_sheader=共有オプション +share_only=次ã®ã¿ +share_guest=ゲストã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’å¯èƒ½ã«ã—ã¾ã™ã‹ï¼Ÿ +share_comment=コメント +share_nheader=NFS エクスãƒãƒ¼ãƒˆ オプション +share_non=NFS ファイルã®å…±æœ‰ã‚’有効 +share_noff=NFS ファイルã®å…±æœ‰ã‚’無効 +share_desc=説明 +share_ro=読å–り専用ã®ãƒ›ã‚¹ãƒˆ +share_rw=読å–り-書込ã¿å¯èƒ½ã®ãƒ›ã‚¹ãƒˆ +share_root=root アクセスã®ãƒ›ã‚¹ãƒˆ +share_none=ãªã— +share_all=ã™ã¹ã¦ +share_listed=リスト.. +share_host=ホスト +share_opts=オプション +share_s0=ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ã‚’ä¿¡é ¼ã—ãªã„ +share_s1=root 以外を信頼 +share_s2=ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ã‚’ä¿¡é ¼ +share_lro=読å–り専用 +share_lrw=読å–り-書込㿠+ +log_create_export=NFS エクスãƒãƒ¼ãƒˆ $1 を作æˆã—ã¾ã—㟠+log_modify_export=NFS エクスãƒãƒ¼ãƒˆ $1 を変更ã—ã¾ã—㟠+log_delete_export=NFS エクスãƒãƒ¼ãƒˆ$1 を削除ã—ã¾ã—㟠+log_create_share=Samba ã®å…±æœ‰ $1 を作æˆã—ã¾ã—㟠+log_modify_share=Samba ã®å…±æœ‰ $1 を変更ã—ã¾ã—㟠+log_delete_share=Samba ã®å…±æœ‰ $1 を削除ã—ã¾ã—㟠+log_save=ファイル $1 ã‚’ä¿å­˜ã—ã¾ã—㟠+log_chmod=ファイル $1 ã®è¨±å¯ã‚’変更ã—ã¾ã—㟠+log_mkdir=ディレクトリ $1 を作æˆã—ã¾ã—㟠+log_upload=ファイル $1 をアップロードã—ã¾ã—㟠+log_link=$2ã¸ã®ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ リンク $1 を作æˆã—ã¾ã—㟠+log_relink=$2 ã¸ã®ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ リンク $1 を変更ã—ã¾ã—㟠+log_copy=ファイル $1 ã‚’ $2 ã«ã‚³ãƒ”ーã—ã¾ã—㟠+log_move=ファイル $1 ã‚’ $2 ã«ç§»å‹•ã—ã¾ã—㟠+log_delete=ファイル $1 を削除ã—ã¾ã—㟠+ +search_eaccess=ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’検索ã§ãã¾ã›ã‚“ +search_title=ãƒ•ã‚¡ã‚¤ãƒ«ã®æ¤œç´¢ +search_ok=ã™ãã«æ¤œç´¢ +search_dir=検索ディレクトリ +search_match=一致ã—ãŸãƒ•ァイル +search_user=所有ユーザ +search_group=所有グループ +search_any=ä»»æ„ +search_type=ファイルã®ç¨®é¡ž +search_types_=ä»»æ„ +search_types_f=ファイル +search_types_d=ディレクトリ +search_types_l=シンボリック リンク +search_types_p=åå‰ä»˜ãパイプ +search_size=ファイル サイズ +search_more=次より大ãã„ +search_less=次よりå°ã•ã„ +search_xdev=éŽåŽ»ã®ãƒžã‚¦ãƒ³ãƒˆã‚’検索ã—ã¾ã™ã‹ï¼Ÿ +search_edir=検索ディレクトリãŒãªã„ã‹ç„¡åйã§ã™ +search_ematch=一致ã—ãŸæ­£è¦è¡¨ç¾ãŒã‚りã¾ã›ã‚“ +search_euser=ユーザåãŒã‚りã¾ã›ã‚“ +search_egroup=グループåãŒã‚りã¾ã›ã‚“ +search_esize=ファイル ã‚µã‚¤ã‚ºã¯æ•´æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“ +search_crit=検索æ¡ä»¶ +search_list=æ¤œç´¢çµæžœ + diff --git a/file/lang/ja_JP.euc b/file/lang/ja_JP.euc new file mode 100644 index 000000000..49a6bcd01 --- /dev/null +++ b/file/lang/ja_JP.euc @@ -0,0 +1,226 @@ +index_title=¥Õ¥¡¥¤¥ë ¥Þ¥Í¡¼¥¸¥ã +index_nojava=¤³¤Î¥â¥¸¥å¡¼¥ë¤Ïưºî¤¹¤ë¤Î¤Ë Java ¤òɬÍפȤ·¤Þ¤¹¤¬¡¢¤´»ÈÍѤΥ֥饦¥¶¤Ï Java ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó + +top_open=³«¤¯ +top_view=ɽ¼¨ +top_edit=ÊÔ½¸ +top_refresh=¹¹¿· +top_info=¾ðÊó +top_delete=ºï½ü +top_new=¿·µ¬ +top_upload=¥¢¥Ã¥×¥í¡¼¥É +top_rename=̾¾ÎÊѹ¹ +top_copy=¥³¥Ô¡¼ +top_cut=¥«¥Ã¥È +top_paste=¥Ú¡¼¥¹¥È +top_share=¶¦Í­ +top_search=¸¡º÷ + +right_name=¥Õ¥¡¥¤¥ë̾ +right_size=¥µ¥¤¥º +right_user=¥æ¡¼¥¶ +right_group=¥°¥ë¡¼¥× +right_date=Æü»þ + +edit_enormal=ɸ½à¥Õ¥¡¥¤¥ë¤Î¤ßÊÔ½¸¤Ç¤­¤Þ¤¹ +edit_title=$1 ¤òÊÔ½¸Ãæ +edit_title2=¥Õ¥¡¥¤¥ë¤òºîÀ®Ãæ +edit_filename=¥Õ¥¡¥¤¥ë̾: +edit_eover=$1 ¤Ï¾å½ñ¤­¤Ç¤­¤Þ¤»¤ó +edit_esave=¥Õ¥¡¥¤¥ë¤òÊݸ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: $1 +edit_eaccess='$1' ¤òÊݸ¤Ç¤­¤Þ¤»¤ó + +info_file=¥Õ¥¡¥¤¥ë +info_path=¥Ñ¥¹: +info_type=¼ïÎà: +info_size=¥µ¥¤¥º: +info_mod=Êѹ¹: +info_link=¥ê¥ó¥¯Àè: +info_perms=µö²Ä +info_user=¥æ¡¼¥¶: +info_group=¥°¥ë¡¼¥×: +info_other=¤½¤Î¾: +info_sticky=¥¹¥Æ¥£¥Ã¥­¡¼: +info_sticky2=½êÍ­¼Ô¤Î¤ß¤¬¥Õ¥¡¥¤¥ë¤òºï½ü¤Ç¤­¤Þ¤¹ +info_own=½êÍ­¸¢ +info_setuid=setuid (¥æ¡¼¥¶ ID ¤òÀßÄê): +info_setuid2=¼¡¤Î¥æ¡¼¥¶¤È¤·¤Æ¼Â¹Ô +info_setgid=setgid (¥°¥ë¡¼¥× ID ¤òÀßÄê): +info_setgid2=¥Õ¥¡¥¤¥ë¤Î·Ñ¾µ¥°¥ë¡¼¥× +info_setgid3=¼¡¤Î¥°¥ë¡¼¥×¤È¤·¤Æ¼Â¹Ô +info_apply=Êѹ¹¤òŬÍÑ +info_apply1=¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î¤ß +info_apply2=¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê¤È¤½¤³¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë +info_apply3=¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê¤È¤¹¤Ù¤Æ¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê +info_efailed=$1 ¤ò¹¹¿·¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: $2 +info_read=ÆÉ¼è¤ê +info_write=½ñ¹þ¤ß +info_list=¥ê¥¹¥È +info_exec=¼Â¹Ô + +delete_dtitle=¥Ç¥£¥ì¥¯¥È¥ê¤Îºï½ü +delete_ftitle=¥Õ¥¡¥¤¥ë¤Îºï½ü +delete_ddesc=¥Ç¥£¥ì¥¯¥È¥ê $1 ¤È¤½¤ÎÆâÍÆ¤ò±Êµ×¤Ëºï½ü¤·¤Æ¤â¤è¤í¤·¤¤¤Ç¤¹¤«¡© +delete_fdesc=¥æ¡¼¥¶ $1¤ò±Êµ×¤Ëºï½ü¤·¤Æ¤â¤è¤í¤·¤¤¤Ç¤¹¤«¡© +delete_efailed=$1 ¤òºï½ü¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: $2 + +mkdir_title=¿·µ¬¤Î¥Ç¥£¥ì¥¯¥È¥ê +mkdir_dir=¿·µ¬¤Î¥Ç¥£¥ì¥¯¥È¥ê: +mkdir_eexists=$1 ¤Ï¤¹¤Ç¤Ë¸ºß¤·¤Þ¤¹ +mkdir_efailed=¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: $1 +mkdir_eaccess='$1' ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó + +link_title=¥ê¥ó¥¯¤ÎºîÀ® +link_from=¥ê¥ó¥¯¸µ: +link_to=¥ê¥ó¥¯Àè: +link_eexists=$1 ¤Ï¤¹¤Ç¤Ë¸ºß¤·¤Þ¤¹ +link_efailed=¥ê¥ó¥¯¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: $1 +link_efrom='$1' ¤«¤é¥ê¥ó¥¯¤Ç¤­¤Þ¤»¤ó +link_efollow=¥·¥ó¥Ü¥ê¥Ã¥¯ ¥ê¥ó¥¯¤òºîÀ®¤Ç¤­¤Þ¤»¤ó + +rename_title=$1 ¤Î̾¾ÎÊѹ¹ +rename_old=¸Å¤¤Ì¾Á°: +rename_new=¿·¤·¤¤Ì¾Á°: +rename_ok=̾¾ÎÊѹ¹ +rename_eexists=$1 ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤Ï¤¹¤Ç¤Ë¸ºß¤·¤Æ¤¤¤Þ¤¹ +rename_efailed=̾Á°¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: $1 +rename_eold='$1' ¤Î̾Á°¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó +rename_enew='$1' ¤Î̾Á°¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó + +file_type0=¥Ç¥£¥ì¥¯¥È¥ê +file_type1=¥Æ¥­¥¹¥È ¥Õ¥¡¥¤¥ë +file_type2=²èÁü¥Õ¥¡¥¤¥ë +file_type3=¥Ð¥¤¥Ê¥ê ¥Õ¥¡¥¤¥ë +file_type4=¥Õ¥¡¥¤¥ë +file_type5=¥·¥ó¥Ü¥ê¥Ã¥¯ ¥ê¥ó¥¯ +file_type6=¥Ç¥Ð¥¤¥¹ ¥Õ¥¡¥¤¥ë +file_type7=¥Ñ¥¤¥× + +view_enormal=ɸ½à¥Õ¥¡¥¤¥ë¤Î¤ßɽ¼¨¤Ç¤­¤Þ¤¹ +view_eaccess=$1 ¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤»¤ó +view_eopen=$1 ¤ò³«¤±¤Þ¤»¤ó¤Ç¤·¤¿: $2 + +paste_ecopy=¥Ú¡¼¥¹¥È¤¹¤ëÁ°¤Ë¥«¥Ã¥È¤Þ¤¿¤Ï¥³¥Ô¡¼¤·¤Æ¤¯¤À¤µ¤¤ +paste_egone=¥³¥Ô¡¼¤·¤¿¥Õ¥¡¥¤¥ë $1 ¤Ï¤â¤¦Â¸ºß¤·¤Þ¤»¤ó +paste_eover=$1 ¤Ï¾å½ñ¤­¤Ç¤­¤Þ¤»¤ó +paste_eself=¥Õ¥¡¥¤¥ë¤ò¤½¤Î¥Õ¥¡¥¤¥ë¼«¿È¤Ë¥Ú¡¼¥¹¥È¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó +paste_emfailed=°Üư¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: $1 +paste_ecfailed=¥³¥Ô¡¼¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: $1 + +over_title=´û¸¤Î¥Õ¥¡¥¤¥ë +over_msg=¥Õ¥¡¥¤¥ë $1 ¤Ï¤¹¤Ç¤Ë¸ºß¤·¤Þ¤¹¡£¥Ú¡¼¥¹¥È¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Î¿·µ¬¥Õ¥¡¥¤¥ë̾¤ò²¼¤Î¥Õ¥£¡¼¥ë¥É¤ËÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£ +over_new=¿·µ¬¤Î¥Õ¥¡¥¤¥ë̾: +over_ok=OK + +upload_efailed=¥¢¥Ã¥×¥í¡¼¥É¤ò³«¤±¤Þ¤»¤ó¤Ç¤·¤¿: $1 +upload_title=¥Õ¥¡¥¤¥ë¤Î¥¢¥Ã¥×¥í¡¼¥É +upload_file=¥¢¥Ã¥×¥í¡¼¥É¤¹¤ë¥Õ¥¡¥¤¥ë +upload_dir=¥¢¥Ã¥×¥í¡¼¥É ¥Ç¥£¥ì¥¯¥È¥ê +upload_ok=¥¢¥Ã¥×¥í¡¼¥É +upload_conv=DOS ²þ¹Ô¤ËÊÑ´¹¤·¤Þ¤¹¤«¡© +upload_efile=¥¢¥Ã¥×¥í¡¼¥É¤¹¤ë¥Õ¥¡¥¤¥ë¤¬ÁªÂò¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ +upload_edir=¥¢¥Ã¥×¥í¡¼¥É¤Î¥Ç¥£¥ì¥¯¥È¥ê¤¬Â¸ºß¤·¤Þ¤»¤ó¡£ +upload_eperm=$1 ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó +upload_ewrite=$1 ¤Ë½ñ¤­¹þ¤á¤Þ¤»¤ó¤Ç¤·¤¿: $2. + +find_eaccess=$1 ¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤»¤ó +find_eexist=$1 ¤Ï $2 ¤Ë¤Ï¸ºß¤·¤Þ¤»¤ó +find_edir=$1 ¤Ï $2 Æâ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó + +cancel=¥­¥ã¥ó¥»¥ë + +chmod_eaccess='$1' ¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤»¤ó +chmod_euser=$1 : ¤½¤Î¥æ¡¼¥¶¤Ï¸ºß¤·¤Þ¤»¤ó +chmod_egroup=$1 : ¤½¤Î¥°¥ë¡¼¥×¤Ï¸ºß¤·¤Þ¤»¤ó +chmod_elink=symlink ¤¬¼ºÇÔ¤·¤Þ¤·¤¿: $1 +chmod_echown=chown ¤¬¼ºÇÔ¤·¤Þ¤·¤¿: $1 +chmod_echmod=chmod ¤¬¼ºÇÔ¤·¤Þ¤·¤¿: $1 + +copy_efrom='$1' ¤«¤é¤Ï¥³¥Ô¡¼¤Ç¤­¤Þ¤»¤ó +copy_eto='$1' ¤Ø¤Ï¥³¥Ô¡¼¤Ç¤­¤Þ¤»¤ó +copy_elink=symlink ¤¬¼ºÇÔ¤·¤Þ¤·¤¿: $1 + +delete_eaccess='$1' ¤òºï½ü¤Ç¤­¤Þ¤»¤ó + +list_eaccess=¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤»¤ó +list_edir=$1 ¤ò¥ê¥¹¥È¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: $2 + +move_eto='$1' ¤Ø¤Ï°Üư¤Ç¤­¤Þ¤»¤ó +move_afrom='$1' ¤Ï°Üư¤Ç¤­¤Þ¤»¤ó + +acl_user=¥µ¡¼¥Ð¤Î¥Õ¥¡¥¤¥ë¤Ë¼¡¤Î¥æ¡¼¥¶¤È¤·¤Æ¥¢¥¯¥»¥¹ +acl_umask=¿·µ¬¥Õ¥¡¥¤¥ë¤Î Umask +acl_follow=symlink ¤ò¾ï¤Ë¤¿¤É¤ê¤Þ¤¹¤«¡© +acl_dirs=¼¡¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¥¢¥¯¥»¥¹¤Î¤ß¤òµö²Ä + +share_title=¶¦Í­ +share_samba=Windows +share_nfs=NFS +share_son=Windows ¥Õ¥¡¥¤¥ë¤Î¶¦Í­¤òÍ­¸ú +share_soff=Windows ¥Õ¥¡¥¤¥ë¤Î¶¦Í­¤ò̵¸ú +share_writable=½ñ¹þ¤ß¤Ç¤­¤Þ¤¹¤«¡© +share_available=¸½ºß¥¢¥¯¥Æ¥£¥Ö¤Ç¤¹¤«¡© +share_sheader=¶¦Í­¥ª¥×¥·¥ç¥ó +share_only=¼¡¤Î¤ß +share_guest=¥²¥¹¥È¤Î¥¢¥¯¥»¥¹¤ò²Äǽ¤Ë¤·¤Þ¤¹¤«¡© +share_comment=¥³¥á¥ó¥È +share_nheader=NFS ¥¨¥¯¥¹¥Ý¡¼¥È ¥ª¥×¥·¥ç¥ó +share_non=NFS ¥Õ¥¡¥¤¥ë¤Î¶¦Í­¤òÍ­¸ú +share_noff=NFS ¥Õ¥¡¥¤¥ë¤Î¶¦Í­¤ò̵¸ú +share_desc=ÀâÌÀ +share_ro=ÆÉ¼è¤êÀìÍѤΥۥ¹¥È +share_rw=ÆÉ¼è¤ê-½ñ¹þ¤ß²Äǽ¤Î¥Û¥¹¥È +share_root=root ¥¢¥¯¥»¥¹¤Î¥Û¥¹¥È +share_none=¤Ê¤· +share_all=¤¹¤Ù¤Æ +share_listed=¥ê¥¹¥È.. +share_host=¥Û¥¹¥È +share_opts=¥ª¥×¥·¥ç¥ó +share_s0=¤¹¤Ù¤Æ¤Î¥æ¡¼¥¶¤ò¿®Íꤷ¤Ê¤¤ +share_s1=root °Ê³°¤ò¿®Íê +share_s2=¤¹¤Ù¤Æ¤Î¥æ¡¼¥¶¤ò¿®Íê +share_lro=ÆÉ¼è¤êÀìÍÑ +share_lrw=ÆÉ¼è¤ê-½ñ¹þ¤ß + +log_create_export=NFS ¥¨¥¯¥¹¥Ý¡¼¥È $1 ¤òºîÀ®¤·¤Þ¤·¤¿ +log_modify_export=NFS ¥¨¥¯¥¹¥Ý¡¼¥È $1 ¤òÊѹ¹¤·¤Þ¤·¤¿ +log_delete_export=NFS ¥¨¥¯¥¹¥Ý¡¼¥È$1 ¤òºï½ü¤·¤Þ¤·¤¿ +log_create_share=Samba ¤Î¶¦Í­ $1 ¤òºîÀ®¤·¤Þ¤·¤¿ +log_modify_share=Samba ¤Î¶¦Í­ $1 ¤òÊѹ¹¤·¤Þ¤·¤¿ +log_delete_share=Samba ¤Î¶¦Í­ $1 ¤òºï½ü¤·¤Þ¤·¤¿ +log_save=¥Õ¥¡¥¤¥ë $1 ¤òÊݸ¤·¤Þ¤·¤¿ +log_chmod=¥Õ¥¡¥¤¥ë $1 ¤Îµö²Ä¤òÊѹ¹¤·¤Þ¤·¤¿ +log_mkdir=¥Ç¥£¥ì¥¯¥È¥ê $1 ¤òºîÀ®¤·¤Þ¤·¤¿ +log_upload=¥Õ¥¡¥¤¥ë $1 ¤ò¥¢¥Ã¥×¥í¡¼¥É¤·¤Þ¤·¤¿ +log_link=$2¤Ø¤Î¥·¥ó¥Ü¥ê¥Ã¥¯ ¥ê¥ó¥¯ $1 ¤òºîÀ®¤·¤Þ¤·¤¿ +log_relink=$2 ¤Ø¤Î¥·¥ó¥Ü¥ê¥Ã¥¯ ¥ê¥ó¥¯ $1 ¤òÊѹ¹¤·¤Þ¤·¤¿ +log_copy=¥Õ¥¡¥¤¥ë $1 ¤ò $2 ¤Ë¥³¥Ô¡¼¤·¤Þ¤·¤¿ +log_move=¥Õ¥¡¥¤¥ë $1 ¤ò $2 ¤Ë°Üư¤·¤Þ¤·¤¿ +log_delete=¥Õ¥¡¥¤¥ë $1 ¤òºï½ü¤·¤Þ¤·¤¿ + +search_eaccess=¤³¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò¸¡º÷¤Ç¤­¤Þ¤»¤ó +search_title=¥Õ¥¡¥¤¥ë¤Î¸¡º÷ +search_ok=¤¹¤°¤Ë¸¡º÷ +search_dir=¸¡º÷¥Ç¥£¥ì¥¯¥È¥ê +search_match=°ìÃפ·¤¿¥Õ¥¡¥¤¥ë +search_user=½êÍ­¥æ¡¼¥¶ +search_group=½êÍ­¥°¥ë¡¼¥× +search_any=Ǥ°Õ +search_type=¥Õ¥¡¥¤¥ë¤Î¼ïÎà +search_types_=Ǥ°Õ +search_types_f=¥Õ¥¡¥¤¥ë +search_types_d=¥Ç¥£¥ì¥¯¥È¥ê +search_types_l=¥·¥ó¥Ü¥ê¥Ã¥¯ ¥ê¥ó¥¯ +search_types_p=̾Á°ÉÕ¤­¥Ñ¥¤¥× +search_size=¥Õ¥¡¥¤¥ë ¥µ¥¤¥º +search_more=¼¡¤è¤êÂ礭¤¤ +search_less=¼¡¤è¤ê¾®¤µ¤¤ +search_xdev=²áµî¤Î¥Þ¥¦¥ó¥È¤ò¸¡º÷¤·¤Þ¤¹¤«¡© +search_edir=¸¡º÷¥Ç¥£¥ì¥¯¥È¥ê¤¬¤Ê¤¤¤«Ìµ¸ú¤Ç¤¹ +search_ematch=°ìÃפ·¤¿Àµµ¬É½¸½¤¬¤¢¤ê¤Þ¤»¤ó +search_euser=¥æ¡¼¥¶Ì¾¤¬¤¢¤ê¤Þ¤»¤ó +search_egroup=¥°¥ë¡¼¥×̾¤¬¤¢¤ê¤Þ¤»¤ó +search_esize=¥Õ¥¡¥¤¥ë ¥µ¥¤¥º¤ÏÀ°¿ô¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó +search_crit=¸¡º÷¾ò·ï +search_list=¸¡º÷·ë²Ì + diff --git a/file/lang/ko_KR.UTF-8 b/file/lang/ko_KR.UTF-8 new file mode 100644 index 000000000..ae53eb27a --- /dev/null +++ b/file/lang/ko_KR.UTF-8 @@ -0,0 +1,226 @@ +index_title=ç£æž 淫軒切 +index_nojava=戚 乞汲精 Java人 敗臆 ç´«é‚背醤 馬走幻 è–„ä»™ 崎虞酔煽拭辞 Javaç ” èµ°æ®é¦¬èµ° çœæŸ”艦陥 + +top_open=伸奄 +top_view=左奄 +top_edit=畷増 +top_refresh=歯稽 壱徴 +top_info=舛左 +top_delete=肢薦 +top_new=歯稽 幻級奄 +top_upload=ç©£ç¨½çƒ +top_rename=戚硯 郊è·å¥„ +top_copy=差紫 +top_cut=設虞鎧奄 +top_paste=細食隔奄 +top_share=因政 +top_search=é”奄 + +right_name=戚硯 +right_size=滴奄 +right_user=ç´«é‚切 +right_group=益血 +right_date=劾促 + +edit_enormal=æžé‹¼ ç£æžå¹» ç•·å¢—æ‹ å‘ª 赤柔艦陥 +edit_title=$1 畷増 +edit_title2=ç£æž 拙失 +edit_filename=ç£æž 戚硯: +edit_eover=$1ç²¾(æ¾—) 気嬢承 呪 蒸柔艦陥 +edit_esave=ç£æžè– 煽舌馬走 公梅柔艦陥: $1 +edit_eaccess='$1'è–(ç ”) ç…½èˆŒæ‹ å‘ª 蒸柔艦陥 + +info_file=ç£æž +info_path=井稽: +info_type=政莫: +info_size=滴奄: +info_mod=呪舛廃 劾促: +info_link=元滴 ä¼é›Œ: +info_perms=ç´«é‚ æ˜ å»ƒ +info_user=ç´«é‚切: +info_group=益血: +info_other=益 é ˆ: +info_sticky=壱舛: +info_sticky2=社政切幻 ç£æžè– è‚¢è–¦æ‹ å‘ª 赤柔艦陥 +info_own=社政映 +info_setuid=Setuid: +info_setuid2=ç´«é‚切稽辞 唿¥³ +info_setgid=Setgid: +info_setgid2=ç£æžæˆš 益血 雌紗 +info_setgid3=益血生稽辞 唿¥³ +info_apply=痕井 éŽ§é‚ æ—‹é‚ ä¼é›Œ +info_apply1=è–„ä»™ 巨刑塘軒幻 +info_apply2=è–„ä»™ 巨刑塘軒人 èƒŒé› ç£æž +info_apply3=è–„ä»™ 巨刑塘軒人 乞窮 馬是 巨刑塘軒 +info_efailed=$1è–(ç ”) 穣汽戚闘馬走 公梅柔艦陥: $2 +info_read=石奄 +info_write=床奄 +info_list=蟹伸 +info_exec=唿¥³ + +delete_dtitle=巨刑塘軒 肢薦 +delete_ftitle=ç£æž 肢薦 +delete_ddesc=巨刑塘軒 $1引(人) 益 照税 乞窮 ç£æžè– 慎姥旋生稽 肢薦馬ç£ç•柔艦猿? +delete_fdesc=ç£æž $1è–(ç ”) 慎姥旋生稽 肢薦馬ç£ç•柔艦猿? +delete_efailed=$1è–(ç ”) 肢薦馬走 公梅柔艦陥: $2 + +mkdir_title=æ­¯ 巨刑塘軒 +mkdir_dir=æ­¯ 巨刑塘軒: +mkdir_eexists=$1戚(亜) 戚耕 赤柔艦陥 +mkdir_efailed=巨刑塘軒研 拙失馬走 公梅柔艦陥: $1 +mkdir_eaccess='$1'è–(ç ”) æ‹™å¤±æ‹ å‘ª 蒸柔艦陥 + +link_title=元滴 拙失 +link_from=元滴 社什: +link_to=元滴 ä¼é›Œ: +link_eexists=$1戚(亜) 戚耕 赤柔艦陥 +link_efailed=元滴 å”é³¶: $1 +link_efrom='$1'拭辞 å…ƒæ»´æ‹ å‘ª 蒸柔艦陥 +link_efollow=å®¿ç‘³é£ å…ƒæ»´ç ” æ‹™å¤±æ‹ å‘ª 蒸柔艦陥 + +rename_title=$1 戚硯 郊è·å¥„ +rename_old=奄糎 戚硯: +rename_new=æ­¯ 戚硯: +rename_ok=戚硯 郊è·å¥„ +rename_eexists=ç£æž $1戚(亜) 戚耕 赤柔艦陥 +rename_efailed=æˆšç¡¯è– éƒŠè·èµ° 公梅柔艦陥: $1 +rename_eold='$1'税 æˆšç¡¯è– éƒŠè¦ å‘ª 蒸柔艦陥 +rename_enew='$1'(生)稽 æˆšç¡¯è– éƒŠè¦ å‘ª 蒸柔艦陥 + +file_type0=巨刑塘軒 +file_type1=努什闘 ç£æž +file_type2=戚耕走 ç£æž +file_type3=æˆšé­ ç£æž +file_type4=ç£æž +file_type5=å®¿ç‘³é£ å…ƒæ»´ +file_type6=舌帖 ç£æž +file_type7=ç£æˆšè¦— + +view_enormal=æžé‹¼ ç£æžå¹» 瑳 呪 赤柔艦陥 +view_eaccess=$1æ‹­ ç¾¨æ‚¦æ‹ å‘ª 蒸柔艦陥 +view_eopen=$1è–(ç ”) 伸走 公梅柔艦陥: $2 + +paste_ecopy=細食隔奄 ç©¿æ‹­ 設虞鎧暗蟹 差紫背醤 æ¯è‰¦é™¥ +paste_egone=差紫廃 ç£æž $1(戚)亜 希 戚雌 糎仙馬走 çœæŸ”艦陥 +paste_eover=$1ç²¾(æ¾—) 気嬢承 呪 蒸柔艦陥 +paste_eself=æ—­ç²¾ ç£æžæ‹­æ¾— ç´°é£Ÿéš”è– å‘ª 蒸柔艦陥 +paste_emfailed=戚疑馬走 公梅柔艦陥: $1 +paste_ecfailed=差紫馬走 公梅柔艦陥: $1 + +over_title=ç£æž 糎仙 +over_msg=ç£æž $1戚(亜) 戚耕 赤柔艦陥. 細食隔精 ç£æžç¨Ž æ­¯ æˆšç¡¯è– ç„¼æŽ˜ç¨Ž ç¶çƒæ‹­ 脊径馬淑ç£ç¥ž. +over_new=æ­¯ ç£æž 戚硯: +over_ok=溌昔 + +upload_efailed=ç©£ç¨½çƒæ‹ ç£æžè– 伸走 公梅柔艦陥: $1 +upload_title=ç£æž ç©£ç¨½çƒ +upload_file=ç©£ç¨½çƒæ‹ ç£æž +upload_dir=巨刑塘軒拭 ç©£ç¨½çƒ +upload_ok=ç©£ç¨½çƒ +upload_conv=DOS åŒéƒŠå˜©è– 痕発æ¯è‰¦çŒ¿? +upload_efile=ç©£ç¨½çƒæ‹ ç£æžè– 識澱馬走 çœç´¹æŸ”艦陥. +upload_edir=ç©£ç¨½çƒ å·¨åˆ‘å¡˜è»’äºœ 糎仙馬走 çœæŸ”艦陥. +upload_eperm=$1è–(ç ”) æ‹™å¤±æ‹ å‘ª 蒸柔艦陥 +upload_ewrite=$1æ‹­ 床走 公梅柔艦陥: $2 + +find_eaccess=$1æ‹­ è¡å®¤ä»€æ‹ 呪 蒸柔艦陥 +find_eexist=$2æ‹­ $1戚(亜) 糎仙馬走 çœæŸ”艦陥 +find_edir=$1ç²¾(æ¾—) $2税 巨刑塘軒亜 焼鑑艦陥 + +cancel=昼社 + +chmod_eaccess='$1'æ‹­ ç¾¨æ‚¦æ‹ å‘ª 蒸柔艦陥 +chmod_euser=$1: èƒŒé› ç´«é‚切 蒸製 +chmod_egroup=$1: èƒŒé› ç›Šè¡€ 蒸製 +chmod_elink=å®¿ç‘³é£ å…ƒæ»´ å”é³¶: $1 +chmod_echown=chown å”é³¶: $1 +chmod_echmod=chmod å”é³¶: $1 + +copy_efrom='$1'拭辞 å·®ç´«æ‹ å‘ª 蒸柔艦陥 +copy_eto='$1'æ‹­ å·®ç´«æ‹ å‘ª 蒸柔艦陥 +copy_elink=å®¿ç‘³é£ å…ƒæ»´ å”é³¶: $1 + +delete_eaccess='$1'è–(ç ”) è‚¢è–¦æ‹ å‘ª 蒸柔艦陥 + +list_eaccess=戚 巨刑塘軒拭 ç¾¨æ‚¦æ‹ å‘ª 蒸柔艦陥 +list_edir=$1è–(ç ”) 蟹伸馬走 公梅柔艦陥: $2 + +move_eto='$1'(生)稽 æˆšç–‘æ‹ å‘ª 蒸柔艦陥 +move_afrom='$1'è–(ç ”) æˆšç–‘æ‹ å‘ª 蒸柔艦陥 + +acl_user=ç´«é‚切稽辞 è¾žç„ ç£æžæ‹­ 羨悦 +acl_umask=æ­¯ ç£æžç¨Ž Umask +acl_follow=牌雌 å®¿ç‘³é£ å…ƒæ»´ç ” 魚絹艦猿? +acl_dirs=巨刑塘軒拭 ä¼å»ƒ è¡å®¤ä»€å¹» è²·é‚ + +share_title=因政 +share_samba=制亀酔 +share_nfs=NFS +share_son=制亀酔 ç£æž 因政 亜管 +share_soff=制亀酔 ç£æž 因政 ç½ç®¡ +share_writable=床奄 亜管æ¯è‰¦çŒ¿? +share_available=è–„ä»™ 醗失 雌殿脊艦猿? +share_sheader=因政 è¾›èŠ +share_only=ç©¿é‚ +share_guest=惟什闘 ç¾¨æ‚¦è– è²·é‚æ¯è‰¦çŒ¿? +share_comment=çˆ½æ± +share_nheader=NFS 鎧左鎧奄 è¾›èŠ +share_non=NFS ç£æž 因政 亜管 +share_noff=NFS ç£æž 因政 ç½ç®¡ +share_desc=竺誤 +share_ro=石奄 ç©¿é‚ ç¡²ä»€é—˜ +share_rw=石奄/床奄 硲什闘 +share_root=root è¡å®¤ä»€ 硲什闘 +share_none=蒸製 +share_all=乞砧 +share_listed=蟹伸.. +share_host=硲什闘 +share_opts=è¾›èŠ +share_s0=焼巷亀 é‡è»½é¦¬èµ° çœè£½ +share_s1=rooté ˆ ç´«é‚切 é‡è»½ +share_s2=乞窮 ç´«é‚切 é‡è»½ +share_lro=石奄 ç©¿é‚ +share_lrw=石奄/床奄 + +log_create_export=NFS 鎧左鎧奄 $1 拙失喫 +log_modify_export=NFS 鎧左鎧奄 $1 呪舛喫 +log_delete_export=NFS 鎧左鎧奄 $1 肢薦喫 +log_create_share=誌郊 因政 $1 拙失喫 +log_modify_share=誌郊 因政 $1 呪舛喫 +log_delete_share=誌郊 因政 $1 肢薦喫 +log_save=ç£æž $1 煽舌喫 +log_chmod=ç£æž $1税 ç´«é‚ æ˜ å»ƒ 痕井喫 +log_mkdir=巨刑塘軒 $1 拙失喫 +log_upload=ç£æž $1 穣稽çƒå–« +log_link=$2æ‹­ ä¼å»ƒ å®¿ç‘³é£ å…ƒæ»´ $1 拙失喫 +log_relink=$2æ‹­ ä¼å»ƒ å®¿ç‘³é£ å…ƒæ»´ $1 呪舛喫 +log_copy=$2(生)稽 ç£æž $1 差紫喫 +log_move=$2(生)稽 ç£æž $1 戚疑喫 +log_delete=ç£æž $1 肢薦喫 + +search_eaccess=戚 巨刑塘軒研 ä¼Šäº‹æ‹ å‘ª 蒸柔艦陥 +search_title=ç£æž é”奄 +search_ok=走榎 伊事 +search_dir=巨刑塘軒 伊事 +search_match=ç£æž 伊事 鳶渡 +search_user=ç´«é‚切 社政 +search_group=益血 社政 +search_any=績税 +search_type=ç£æž 政莫 +search_types_=績税 +search_types_f=ç£æž +search_types_d=巨刑塘軒 +search_types_l=å®¿ç‘³é£ å…ƒæ»´ +search_types_p=èª¤èª¤å‰ ç£æˆšè¦— +search_size=ç£æž 滴奄 +search_more=左陥 é‘ +search_less=左陥 拙製 +search_xdev=走蟹娃 原錘闘研 伊事æ¯è‰¦çŒ¿? +search_edir=蒸暗蟹 è¨­å…¬å‰ ä¼Šäº‹ 巨刑塘軒 +search_ematch=æžå¸–馬澗 舛鋭 縦戚 蒸柔艦陥 +search_euser=蒸澗 ç´«é‚切 戚硯 +search_egroup=蒸澗 益血 戚硯 +search_esize=ç£æž 滴奄澗 舛呪食醤 æ¯è‰¦é™¥ +search_crit=伊事 奄層 +search_list=伊事 衣引 + diff --git a/file/lang/ko_KR.euc b/file/lang/ko_KR.euc new file mode 100644 index 000000000..abb58f9ba --- /dev/null +++ b/file/lang/ko_KR.euc @@ -0,0 +1,226 @@ +index_title=ÆÄÀÏ °ü¸®ÀÚ +index_nojava=ÀÌ ¸ðµâÀº Java¿Í ÇÔ²² »ç¿ëÇØ¾ß ÇÏÁö¸¸ ÇöÀç ºê¶ó¿ìÀú¿¡¼­ Java¸¦ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù + +top_open=¿­±â +top_view=º¸±â +top_edit=ÆíÁý +top_refresh=»õ·Î °íħ +top_info=Á¤º¸ +top_delete=»èÁ¦ +top_new=»õ·Î ¸¸µé±â +top_upload=¾÷·Îµå +top_rename=À̸§ ¹Ù²Ù±â +top_copy=º¹»ç +top_cut=Àß¶ó³»±â +top_paste=ºÙ¿©³Ö±â +top_share=°øÀ¯ +top_search=ã±â + +right_name=À̸§ +right_size=Å©±â +right_user=»ç¿ëÀÚ +right_group=±×·ì +right_date=³¯Â¥ + +edit_enormal=ÀÏ¹Ý ÆÄÀϸ¸ ÆíÁýÇÒ ¼ö ÀÖ½À´Ï´Ù +edit_title=$1 ÆíÁý +edit_title2=ÆÄÀÏ ÀÛ¼º +edit_filename=ÆÄÀÏ À̸§: +edit_eover=$1Àº(´Â) µ¤¾î¾µ ¼ö ¾ø½À´Ï´Ù +edit_esave=ÆÄÀÏÀ» ÀúÀåÇÏÁö ¸øÇß½À´Ï´Ù: $1 +edit_eaccess='$1'À»(¸¦) ÀúÀåÇÒ ¼ö ¾ø½À´Ï´Ù + +info_file=ÆÄÀÏ +info_path=°æ·Î: +info_type=À¯Çü: +info_size=Å©±â: +info_mod=¼öÁ¤ÇÑ ³¯Â¥: +info_link=¸µÅ© ´ë»ó: +info_perms=»ç¿ë ±ÇÇÑ +info_user=»ç¿ëÀÚ: +info_group=±×·ì: +info_other=±× ¿Ü: +info_sticky=°íÁ¤: +info_sticky2=¼ÒÀ¯ÀÚ¸¸ ÆÄÀÏÀ» »èÁ¦ÇÒ ¼ö ÀÖ½À´Ï´Ù +info_own=¼ÒÀ¯±Ç +info_setuid=Setuid: +info_setuid2=»ç¿ëÀڷμ­ ½ÇÇà +info_setgid=Setgid: +info_setgid2=ÆÄÀÏÀÌ ±×·ì »ó¼Ó +info_setgid3=±×·ìÀ¸·Î¼­ ½ÇÇà +info_apply=º¯°æ ³»¿ë Àû¿ë ´ë»ó +info_apply1=ÇöÀç µð·ºÅ丮¸¸ +info_apply2=ÇöÀç µð·ºÅ丮¿Í ÇØ´ç ÆÄÀÏ +info_apply3=ÇöÀç µð·ºÅ丮¿Í ¸ðµç ÇÏÀ§ µð·ºÅ丮 +info_efailed=$1À»(¸¦) ¾÷µ¥ÀÌÆ®ÇÏÁö ¸øÇß½À´Ï´Ù: $2 +info_read=Àбâ +info_write=¾²±â +info_list=³ª¿­ +info_exec=½ÇÇà + +delete_dtitle=µð·ºÅ丮 »èÁ¦ +delete_ftitle=ÆÄÀÏ »èÁ¦ +delete_ddesc=µð·ºÅ丮 $1°ú(¿Í) ±× ¾ÈÀÇ ¸ðµç ÆÄÀÏÀ» ¿µ±¸ÀûÀ¸·Î »èÁ¦ÇϽðڽÀ´Ï±î? +delete_fdesc=ÆÄÀÏ $1À»(¸¦) ¿µ±¸ÀûÀ¸·Î »èÁ¦ÇϽðڽÀ´Ï±î? +delete_efailed=$1À»(¸¦) »èÁ¦ÇÏÁö ¸øÇß½À´Ï´Ù: $2 + +mkdir_title=»õ µð·ºÅ丮 +mkdir_dir=»õ µð·ºÅ丮: +mkdir_eexists=$1ÀÌ(°¡) ÀÌ¹Ì ÀÖ½À´Ï´Ù +mkdir_efailed=µð·ºÅ丮¸¦ ÀÛ¼ºÇÏÁö ¸øÇß½À´Ï´Ù: $1 +mkdir_eaccess='$1'À»(¸¦) ÀÛ¼ºÇÒ ¼ö ¾ø½À´Ï´Ù + +link_title=¸µÅ© ÀÛ¼º +link_from=¸µÅ© ¼Ò½º: +link_to=¸µÅ© ´ë»ó: +link_eexists=$1ÀÌ(°¡) ÀÌ¹Ì ÀÖ½À´Ï´Ù +link_efailed=¸µÅ© ½ÇÆÐ: $1 +link_efrom='$1'¿¡¼­ ¸µÅ©ÇÒ ¼ö ¾ø½À´Ï´Ù +link_efollow=½Éº¼¸¯ ¸µÅ©¸¦ ÀÛ¼ºÇÒ ¼ö ¾ø½À´Ï´Ù + +rename_title=$1 À̸§ ¹Ù²Ù±â +rename_old=±âÁ¸ À̸§: +rename_new=»õ À̸§: +rename_ok=À̸§ ¹Ù²Ù±â +rename_eexists=ÆÄÀÏ $1ÀÌ(°¡) ÀÌ¹Ì ÀÖ½À´Ï´Ù +rename_efailed=À̸§À» ¹Ù²ÙÁö ¸øÇß½À´Ï´Ù: $1 +rename_eold='$1'ÀÇ À̸§À» ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù +rename_enew='$1'(À¸)·Î À̸§À» ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù + +file_type0=µð·ºÅ丮 +file_type1=ÅØ½ºÆ® ÆÄÀÏ +file_type2=À̹ÌÁö ÆÄÀÏ +file_type3=ÀÌÁø ÆÄÀÏ +file_type4=ÆÄÀÏ +file_type5=½Éº¼¸¯ ¸µÅ© +file_type6=ÀåÄ¡ ÆÄÀÏ +file_type7=ÆÄÀÌÇÁ + +view_enormal=ÀÏ¹Ý ÆÄÀϸ¸ º¼ ¼ö ÀÖ½À´Ï´Ù +view_eaccess=$1¿¡ Á¢±ÙÇÒ ¼ö ¾ø½À´Ï´Ù +view_eopen=$1À»(¸¦) ¿­Áö ¸øÇß½À´Ï´Ù: $2 + +paste_ecopy=ºÙ¿©³Ö±â Àü¿¡ À߶󳻰ųª º¹»çÇØ¾ß ÇÕ´Ï´Ù +paste_egone=º¹»çÇÑ ÆÄÀÏ $1(ÀÌ)°¡ ´õ ÀÌ»ó Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù +paste_eover=$1Àº(´Â) µ¤¾î¾µ ¼ö ¾ø½À´Ï´Ù +paste_eself=°°Àº ÆÄÀÏ¿¡´Â ºÙ¿©³ÖÀ» ¼ö ¾ø½À´Ï´Ù +paste_emfailed=À̵¿ÇÏÁö ¸øÇß½À´Ï´Ù: $1 +paste_ecfailed=º¹»çÇÏÁö ¸øÇß½À´Ï´Ù: $1 + +over_title=ÆÄÀÏ Á¸Àç +over_msg=ÆÄÀÏ $1ÀÌ(°¡) ÀÌ¹Ì ÀÖ½À´Ï´Ù. ºÙ¿©³ÖÀº ÆÄÀÏÀÇ »õ À̸§À» ¾Æ·¡ÀÇ Çʵ忡 ÀÔ·ÂÇϽʽÿÀ. +over_new=»õ ÆÄÀÏ À̸§: +over_ok=È®ÀÎ + +upload_efailed=¾÷·ÎµåÇÒ ÆÄÀÏÀ» ¿­Áö ¸øÇß½À´Ï´Ù: $1 +upload_title=ÆÄÀÏ ¾÷·Îµå +upload_file=¾÷·ÎµåÇÒ ÆÄÀÏ +upload_dir=µð·ºÅ丮¿¡ ¾÷·Îµå +upload_ok=¾÷·Îµå +upload_conv=DOS ÁٹٲÞÀ» º¯È¯Çմϱî? +upload_efile=¾÷·ÎµåÇÒ ÆÄÀÏÀ» ¼±ÅÃÇÏÁö ¾Ê¾Ò½À´Ï´Ù. +upload_edir=¾÷·Îµå µð·ºÅ丮°¡ Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù. +upload_eperm=$1À»(¸¦) ÀÛ¼ºÇÒ ¼ö ¾ø½À´Ï´Ù +upload_ewrite=$1¿¡ ¾²Áö ¸øÇß½À´Ï´Ù: $2 + +find_eaccess=$1¿¡ ¾×¼¼½ºÇÒ ¼ö ¾ø½À´Ï´Ù +find_eexist=$2¿¡ $1ÀÌ(°¡) Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù +find_edir=$1Àº(´Â) $2ÀÇ µð·ºÅ丮°¡ ¾Æ´Õ´Ï´Ù + +cancel=Ãë¼Ò + +chmod_eaccess='$1'¿¡ Á¢±ÙÇÒ ¼ö ¾ø½À´Ï´Ù +chmod_euser=$1: ÇØ´ç »ç¿ëÀÚ ¾øÀ½ +chmod_egroup=$1: ÇØ´ç ±×·ì ¾øÀ½ +chmod_elink=½Éº¼¸¯ ¸µÅ© ½ÇÆÐ: $1 +chmod_echown=chown ½ÇÆÐ: $1 +chmod_echmod=chmod ½ÇÆÐ: $1 + +copy_efrom='$1'¿¡¼­ º¹»çÇÒ ¼ö ¾ø½À´Ï´Ù +copy_eto='$1'¿¡ º¹»çÇÒ ¼ö ¾ø½À´Ï´Ù +copy_elink=½Éº¼¸¯ ¸µÅ© ½ÇÆÐ: $1 + +delete_eaccess='$1'À»(¸¦) »èÁ¦ÇÒ ¼ö ¾ø½À´Ï´Ù + +list_eaccess=ÀÌ µð·ºÅ丮¿¡ Á¢±ÙÇÒ ¼ö ¾ø½À´Ï´Ù +list_edir=$1À»(¸¦) ³ª¿­ÇÏÁö ¸øÇß½À´Ï´Ù: $2 + +move_eto='$1'(À¸)·Î À̵¿ÇÒ ¼ö ¾ø½À´Ï´Ù +move_afrom='$1'À»(¸¦) À̵¿ÇÒ ¼ö ¾ø½À´Ï´Ù + +acl_user=»ç¿ëÀڷμ­ ¼­¹ö ÆÄÀÏ¿¡ Á¢±Ù +acl_umask=»õ ÆÄÀÏÀÇ Umask +acl_follow=Ç×»ó ½Éº¼¸¯ ¸µÅ©¸¦ µû¸¨´Ï±î? +acl_dirs=µð·ºÅ丮¿¡ ´ëÇÑ ¾×¼¼½º¸¸ Çã¿ë + +share_title=°øÀ¯ +share_samba=À©µµ¿ì +share_nfs=NFS +share_son=À©µµ¿ì ÆÄÀÏ °øÀ¯ °¡´É +share_soff=À©µµ¿ì ÆÄÀÏ °øÀ¯ ºÒ´É +share_writable=¾²±â °¡´ÉÇմϱî? +share_available=ÇöÀç Ȱ¼º »óÅÂÀԴϱî? +share_sheader=°øÀ¯ ¿É¼Ç +share_only=Àü¿ë +share_guest=°Ô½ºÆ® Á¢±ÙÀ» Çã¿ëÇմϱî? +share_comment=ÁÖ¼® +share_nheader=NFS ³»º¸³»±â ¿É¼Ç +share_non=NFS ÆÄÀÏ °øÀ¯ °¡´É +share_noff=NFS ÆÄÀÏ °øÀ¯ ºÒ´É +share_desc=¼³¸í +share_ro=Àбâ Àü¿ë È£½ºÆ® +share_rw=Àбâ/¾²±â È£½ºÆ® +share_root=root ¾×¼¼½º È£½ºÆ® +share_none=¾øÀ½ +share_all=¸ðµÎ +share_listed=³ª¿­.. +share_host=È£½ºÆ® +share_opts=¿É¼Ç +share_s0=¾Æ¹«µµ ½Å·ÚÇÏÁö ¾ÊÀ½ +share_s1=root¿Ü »ç¿ëÀÚ ½Å·Ú +share_s2=¸ðµç »ç¿ëÀÚ ½Å·Ú +share_lro=Àбâ Àü¿ë +share_lrw=Àбâ/¾²±â + +log_create_export=NFS ³»º¸³»±â $1 ÀÛ¼ºµÊ +log_modify_export=NFS ³»º¸³»±â $1 ¼öÁ¤µÊ +log_delete_export=NFS ³»º¸³»±â $1 »èÁ¦µÊ +log_create_share=»ï¹Ù °øÀ¯ $1 ÀÛ¼ºµÊ +log_modify_share=»ï¹Ù °øÀ¯ $1 ¼öÁ¤µÊ +log_delete_share=»ï¹Ù °øÀ¯ $1 »èÁ¦µÊ +log_save=ÆÄÀÏ $1 ÀúÀåµÊ +log_chmod=ÆÄÀÏ $1ÀÇ »ç¿ë ±ÇÇÑ º¯°æµÊ +log_mkdir=µð·ºÅ丮 $1 ÀÛ¼ºµÊ +log_upload=ÆÄÀÏ $1 ¾÷·ÎµåµÊ +log_link=$2¿¡ ´ëÇÑ ½Éº¼¸¯ ¸µÅ© $1 ÀÛ¼ºµÊ +log_relink=$2¿¡ ´ëÇÑ ½Éº¼¸¯ ¸µÅ© $1 ¼öÁ¤µÊ +log_copy=$2(À¸)·Î ÆÄÀÏ $1 º¹»çµÊ +log_move=$2(À¸)·Î ÆÄÀÏ $1 À̵¿µÊ +log_delete=ÆÄÀÏ $1 »èÁ¦µÊ + +search_eaccess=ÀÌ µð·ºÅ丮¸¦ °Ë»öÇÒ ¼ö ¾ø½À´Ï´Ù +search_title=ÆÄÀÏ Ã£±â +search_ok=Áö±Ý °Ë»ö +search_dir=µð·ºÅ丮 °Ë»ö +search_match=ÆÄÀÏ °Ë»ö ÆÐÅÏ +search_user=»ç¿ëÀÚ ¼ÒÀ¯ +search_group=±×·ì ¼ÒÀ¯ +search_any=ÀÓÀÇ +search_type=ÆÄÀÏ À¯Çü +search_types_=ÀÓÀÇ +search_types_f=ÆÄÀÏ +search_types_d=µð·ºÅ丮 +search_types_l=½Éº¼¸¯ ¸µÅ© +search_types_p=¸í¸íµÈ ÆÄÀÌÇÁ +search_size=ÆÄÀÏ Å©±â +search_more=º¸´Ù Å­ +search_less=º¸´Ù ÀÛÀ½ +search_xdev=Áö³ª°£ ¸¶¿îÆ®¸¦ °Ë»öÇմϱî? +search_edir=¾ø°Å³ª À߸øµÈ °Ë»ö µð·ºÅ丮 +search_ematch=ÀÏÄ¡ÇÏ´Â Á¤±Ô ½ÄÀÌ ¾ø½À´Ï´Ù +search_euser=¾ø´Â »ç¿ëÀÚ À̸§ +search_egroup=¾ø´Â ±×·ì À̸§ +search_esize=ÆÄÀÏ Å©±â´Â Á¤¼ö¿©¾ß ÇÕ´Ï´Ù +search_crit=°Ë»ö ±âÁØ +search_list=°Ë»ö °á°ú + diff --git a/file/lang/pl b/file/lang/pl new file mode 100644 index 000000000..13e6c7664 --- /dev/null +++ b/file/lang/pl @@ -0,0 +1,326 @@ +index_title=Zarz±dca plików +index_nojava=Ten modu³ wymaga do swojego dzia³ania javy, natomiast Twoja przegl±darka javy nie obs³uguje +# switch_euser=U¿ytkownik Uniksa nie istnieje! +switch_euser=Uzytkownik Uniksa nie istnieje! + +# top_open=Otwórz +top_open=Otworz +top_view=Obejrzyj +top_edit=Modyfikuj +# top_refresh=Od¶wie¿ +top_refresh=Odswiez +top_info=Informacje +# top_delete=Usuñ +top_delete=Usun +top_new=Nowy +# top_upload=Prze¶lij +top_upload=Przeslij +# top_rename=Zmieñ nazwê +top_rename=Zmien nazwe +top_copy=Kopiuj +top_cut=Wytnij +top_paste=Wklej +# top_share=Udostêpnianie +top_share=Udostepnianie +top_search=Szukaj + +right_name=Nazwa +right_size=Rozmiar +# right_user=W³a¶ciciel +right_user=Wlasciciel +right_group=Grupa +right_date=Data + +# edit_enormal=Modyfikowaæ mo¿na tylko zwyk³e pliki +edit_enormal=Modyfikowac mozna tylko zwykle pliki +edit_title=Modyfikacja $1 +edit_title2=Tworzenie pliku +edit_filename=Nazwa pliku: +# edit_eover=$1 nie mo¿e byæ nadpisany +edit_eover=$1 nie moze byc nadpisany +# edit_esave=Nie uda³o siê zachowaæ pliku : $1 +edit_esave=Nie udalo sie zachowac pliku : $1 +# edit_eaccess=Nie masz uprawnieñ do zachowania '$1' +edit_eaccess=Nie masz uprawnien do zachowania '$1' + +info_file=Plik +# info_path=¦cie¿ka: +info_path=Sciezka: +info_type=Typ: +info_size=Rozmiar: +info_mod=Zmieniony: +# info_link=Dowi±zanie do: +info_link=Dowiazanie do: +info_perms=Uprawnienia +# info_user=W³a¶ciciel: +info_user=Wlasciciel: +info_group=Grupa: +info_other=Inni: +info_sticky=Sticky: +# info_sticky2=Tylko w³a¶ciciele mog± usuwaæ pliki +info_sticky2=Tylko wlasciciele moga usuwac pliki +# info_own=Prawa w³asno¶ci +info_own=Prawa wlasnosci +info_setuid=Setuid: +# info_setuid2=Uruchom jako u¿ytkownik +info_setuid2=Uruchom jako uzytkownik +info_setgid=Setgid: +# info_setgid2=Pliki dziedzicz± grupê +info_setgid2=Pliki dziedzicza grupe +info_setgid3=Uruchom jako grupa +info_apply=Zastosuj zmiany do +info_apply1=tylko katalogu +# info_apply2=katalogu i zawartych w nim plików +info_apply2=katalogu i zawartych w nim plikow +info_apply3=katalogu wraz z podkatalogami +# info_efailed=Nie uda³o sie zaktualizowaæ $1 : $2 +info_efailed=Nie udalo sie zaktualizowac $1 : $2 +info_read=Odczyt +info_write=Zapis +# info_list=Przegl±danie +info_list=Przegladanie +info_exec=Uruchamianie + +delete_dtitle=Usuñ katalog +delete_ftitle=Usuñ plik +# delete_ddesc=Czy jeste¶ pewien, ¿e chcesz nieodwracalnie usun±æ katalog $1 wraz z ca³± zawarto¶ci±? +delete_ddesc=Czy jestes pewien, ze chcesz nieodwracalnie usunac katalog $1 wraz z cala zawartoscia? +# delete_fdesc=Czy jeste¶ pewien, ¿e chcesz nieodwracalnie usun±æ plik $1 ? +delete_fdesc=Czy jestes pewien, ze chcesz nieodwracalnie usunac plik $1 ? +# delete_efailed=Nie uda³o siê usun±æ $1 : $2 +delete_efailed=Nie udalo sie usunac $1 : $2 + +mkdir_title=Nowy katalog +mkdir_dir=Nowy katalog: +# mkdir_eexists=$1 ju¿ istnieje +mkdir_eexists=$1 juz istnieje +# mkdir_efailed=Nie uda³o sie utworzyæ katalogu : $1 +mkdir_efailed=Nie udalo sie utworzyc katalogu : $1 +# mkdir_eaccess=Nie masz uprawnieñ do utworzenia '$1' +mkdir_eaccess=Nie masz uprawnien do utworzenia '$1' + +link_title=Utwórz dowi±zanie +link_from=Nazwa dowi±zania: +link_to=Dowi±zanie do: +# link_eexists=$1 ju¿ istnieje +link_eexists=$1 juz istnieje +# link_efailed=Nie uda³o siê utworzyæ dowi±zania : $1 +link_efailed=Nie udalo sie utworzyc dowiazania : $1 +# link_efrom=Nie masz uprawnieñ do utworzenia dowi±zania '$1' +link_efrom=Nie masz uprawnien do utworzenia dowiazania '$1' +# link_efollow=Nie masz uprawnieñ do tworzenia dowi±zañ symbolicznych +link_efollow=Nie masz uprawnien do tworzenia dowiazan symbolicznych + +rename_title=Zmieñ nazwê $1 +rename_old=Stara nazwa: +rename_new=Nowa nazwa: +# rename_ok=Zmieñ nazwê +rename_ok=Zmien nazwe +# rename_eexists=Plik o nazwie $1 ju¿ istnieje +rename_eexists=Plik o nazwie $1 juz istnieje +# rename_efailed=Nie uda³o siê zmieniæ nazwy : $1 +rename_efailed=Nie udalo sie zmienic nazwy : $1 +# rename_eold=Nie masz uprawnieñ do zmiany nazwy '$1' +rename_eold=Nie masz uprawnien do zmiany nazwy '$1' +# rename_enew=Nie masz uprawnieñ do zmiany nazwy na '$1' +rename_enew=Nie masz uprawnien do zmiany nazwy na '$1' + +file_type0=Katalog +file_type1=Plik tekstowy +file_type2=Plik Image +file_type3=Plik binarny +file_type4=Plik +# file_type5=Dowi±zanie symboliczne +file_type5=Dowiazanie symboliczne +# file_type6=Plik urz±dzenia +file_type6=Plik urzadzenia +file_type7=plik FIFO + +# view_enormal=Mo¿na ogl±daæ tylko zwyk³e pliki +view_enormal=Mozna ogladac tylko zwykle pliki +# view_eaccess=Nie masz prawa dostêpu do $1 +view_eaccess=Nie masz prawa dostepu do $1 +# view_eopen=Nie uda³o siê otworzyæ $1 : $2 +view_eopen=Nie udalo sie otworzyc $1 : $2 + +# paste_ecopy=Aby wkleiæ musisz wcze¶niej co¶ skopiowaæ lub wyci±æ +paste_ecopy=Aby wkleic musisz wczesniej cos skopiowac lub wyciac +# paste_egone=Kopiowany plik $1 ju¿ nie istnieje +paste_egone=Kopiowany plik $1 juz nie istnieje +# paste_eover=Nie mo¿na nadpisaæ $1 +paste_eover=Nie mozna nadpisac $1 +# paste_eself=Nie mo¿esz wkleiæ pliku w miejsce jego samego +paste_eself=Nie mozesz wkleic pliku w miejsce jego samego +# paste_emfailed=Nie uda³o siê przesun±æ : $1 +paste_emfailed=Nie udalo sie przesunac : $1 +# paste_ecfailed=Nie uda³o siê skopiowaæ : $1 +paste_ecfailed=Nie udalo sie skopiowac : $1 + +over_title=Plik istnieje +# over_msg=Plik $1 ju¿ istnieje. Podaj now± nazwê dla tworzonego pliku korzystaj±c z pola poni¿ej. +over_msg=Plik $1 juz istnieje. Podaj nowa nazwe dla tworzonego pliku korzystajac z pola ponizej. +over_new=Nowa nazwa pliku: +over_ok=OK + +# upload_efailed=Nie uda³o siê otworzyæ przesy³ania : $1 +upload_efailed=Nie udalo sie otworzyc przesylania : $1 +# upload_title=Prze¶lij plik +upload_title=Przeslij plik +# upload_file=Plik do przes³ania +upload_file=Plik do przeslania +# upload_dir=Prze¶lij do katalogu +upload_dir=Przeslij do katalogu +# upload_ok=Prze¶lij +upload_ok=Przeslij +# upload_conv=Przekszta³ciæ DOS-owe koñce linii? +upload_conv=Przekszta³cic DOS-owe konce linii? +# upload_efile=Nie podano pliku do przes³ania. +upload_efile=Nie podano pliku do przeslania. +# upload_edir=Katalog, do którego ma nast±piæ przes³anie nie istnieje. +upload_edir=Katalog, do ktorego ma nastapic przeslanie nie istnieje. +# upload_eperm=Nie masz uprawnieñ do utworzenia $1 +upload_eperm=Nie masz uprawnien do utworzenia $1 +# upload_ewrite=Nie uda³o siê zapisaæ w $1 : $2. +upload_ewrite=Nie udalo sie zapisac w $1 : $2. + +# find_eaccess=Nie masz prawa dostêpu do $1 +find_eaccess=Nie masz prawa dostepu do $1 +find_eexist=$1 nie istnieje w $2 +find_edir=$1 nie jest podkatalogiem $2 + +cancel=Rezygnuj + +# chmod_eaccess=Nie masz prawa dostêpu do '$1' +chmod_eaccess=Nie masz prawa dostepu do '$1' +# chmod_euser=$1 : nie ma takiego u¿ytkownika +chmod_euser=$1 : nie ma takiego uzytkownika +chmod_egroup=$1 : nie ma takiej grupy +# chmod_elink=nie uda³o siê utworzyæ dowi±zania symbolicznego : $1 +chmod_elink=nie udalo sie utworzyc dowiazania symbolicznego : $1 +# chmod_echown=nie uda³o siê zmieniæ w³a¶ciciela : $1 +chmod_echown=nie udalo sie zmienic w³asciciela : $1 +# chmod_echmod=nie uda³o siê zmieniæ uprawnieñ : $1 +chmod_echmod=nie udalo sie zmienic uprawnien : $1 + +# copy_efrom=Nie masz uprawnieñ do kopiowania '$1' +copy_efrom=Nie masz uprawnien do kopiowania '$1' +# copy_eto=Nie masz uprawnieñ do kopiowania do '$1' +copy_eto=Nie masz uprawnien do kopiowania do '$1' +# copy_elink=nie uda³o siê utworzyæ dowi±zania symbolicznego : $1 +copy_elink=nie udalo sie utworzyc dowiazania symbolicznego : $1 + +# delete_eaccess=Nie masz uprawnieñ do usuniêcia '$1' +delete_eaccess=Nie masz uprawnien do usuniecia '$1' + +# list_eaccess=Nie masz prawa dostêpu do tego katalogu +list_eaccess=Nie masz prawa dostepu do tego katalogu +# list_edir=Nie uda³o siê przejrzeæ $1 : $2 +list_edir=Nie udalo sie przejrzec $1 : $2 + +# move_eto=Nie masz uprawnieñ do przenoszenia do '$1' +move_eto=Nie masz uprawnien do przenoszenia do '$1' +# move_afrom=Nie masz uprawnieñ do przeniesienia '$1' +move_afrom=Nie masz uprawnien do przeniesienia '$1' + +acl_user=Dostêp do plików na serwerze z prawami u¿ytkownika +acl_user_def=Taki sam jak zalogowany do Webmina +acl_umask=Umaska dla nowych plików +acl_follow=Zawsze ¶ledziæ dowi±zania symboliczne? +acl_dirs=Pozwoliæ jedynie na dostêp do katalogów +# acl_home=Do³±cz katalog domowy u¿ytkownika Webmina +acl_home=Dolacz katalog domowy uzytkownika Webmina + +share_title=Udostêpnianie +share_samba=Windows +share_nfs=NFS +# share_son=Udostêpnianie plików dla Windows w³±czone +share_son=Udostepnianie plikow dla Windows wlaczone +# share_soff=Udostêpnianie plików dla Windows wy³±czone +share_soff=Udostepnianie plikow dla Windows wylaczone +share_writable=Prawa zapisu? +share_available=Aktualnie czynne? +# share_sheader=Opcje wspó³dzielenia +share_sheader=Opcje wspoldzielenia +# share_only=Wy³±cznie +share_only=Wylacznie +# share_guest=Dostêp go¶cinny? +share_guest=Dostep goscinny? +share_comment=Uwagi +# share_nheader=Opcje udostêpniania NFS +share_nheader=Opcje udostepniania NFS +# share_non=Udostêpnianie NFS w³±czone +share_non=Udostepnianie NFS wlaczone +# share_noff=Udostêpnianie NFS wy³±czone +share_noff=Udostepnianie NFS wylaczone +share_desc=Opis +# share_ro=Hosty z dostêpem tylko do odczytu +share_ro=Hosty z dostepem tylko do odczytu +# share_rw=Hosty z dostêpem do zapisu +share_rw=Hosty z dostepem do zapisu +# share_root=Hosty z dostêpem roota +share_root=Hosty z dostepem roota +share_none=Brak +share_all=Wszystkie +share_listed=Wymienione.. +share_host=Hosty +share_opts=Opcje +share_s0=Nie ufaj nikomu +# share_s1=Ufaj wszystkim prócz roota +share_s1=Ufaj wszystkim procz roota +share_s2=Ufaj wszystkim +share_lro=Tylko do odczytu +share_lrw=Odczyt i zapis + +log_create_export=Utworzono udostêpnianie NFS $1 +log_modify_export=Zmieniono udostêpnianie NFS $1 +log_delete_export=Usuniêto udostêpnianie NFS $1 +log_create_share=Utworzono zasób Samby $1 +log_modify_share=Zmieniono zasób Samby $1 +log_delete_share=Usuniêto zasób Samby $1 +log_save=Zachowano plik $1 +log_chmod=Zmieniono uprawnienia dla pliku $1 +log_mkdir=Utworzono katalog $1 +log_upload=Przes³ano plik $1 +log_link=Utworzono dowi±zanie symboliczne $1 do $2 +log_relink=Zmieniono dowi±zanie symboliczne $1 do $2 +log_copy=Skopiowano plik $1 jako $2 +log_move=Przeniesiono plik $1 do $2 +log_delete=Usuniêto plik $1 + +# search_eaccess=Nie masz uprawnieñ do przeszukiwania tego katalogu +search_eaccess=Nie masz uprawnien do przeszukiwania tego katalogu +search_title=Szukaj plików +search_ok=Szukaj teraz +search_dir=Szukaj w katalogu +# search_match=Plików wg wzorca +search_match=Plikow wg wzorca +# search_user=Nale¿±cych do u¿ytkownika +search_user=Nalezacych do uzytkownika +# search_group=Nale¿±cych do grupy +search_group=Nalezacych do grupy +search_any=Dowolny +search_type=Rodzaj pliku +search_types_=Dowolny +# search_types_f=Zwyk³y plik +search_types_f=Zwykly plik +search_types_d=Katalog +# search_types_l=Dowi±zanie symboliczne +search_types_l=Dowiazanie symboliczne +search_types_p=Nazwane FIFO +search_size=Rozmiar pliku +# search_more=Wiêkszy ni¿ +search_more=Wiekszy niz +# search_less=Mniejszy ni¿ +search_less=Mniejszy niz +# search_xdev=Przeszukiwaæ inne systemy plików? +search_xdev=Przeszukiwac inne systemy plikow? +search_edir=Nie podany lub niepoprawny katalog przeszukiwania +# search_ematch=Brak wyra¿enia regularnego do dopasowania +search_ematch=Brak wyrazenia regularnego do dopasowania +# search_euser=Nie podano nazwy u¿ytkownika +search_euser=Nie podano nazwy uzytkownika +search_egroup=Nie podano nazwy grupy +# search_esize=Rozmiar pliku musi byæ liczb± ca³kowit± +search_esize=Rozmiar pliku musi byc liczba calkowita +search_crit=Kryteria szukania +search_list=Wyniki szukania diff --git a/file/lang/pt b/file/lang/pt new file mode 100644 index 000000000..8f39838b6 --- /dev/null +++ b/file/lang/pt @@ -0,0 +1,146 @@ +index_title=Administrador de Ficheiros +index_nojava=Este módulo requer java para funcionar, mas o seu navegador não suporta java + +top_open=Abrir +top_view=Ver +top_edit=Editar +top_refresh=Refrescar +top_info=Informações +top_delete=Apagar +top_new=Novo +top_upload=Carregar +top_rename=Renomear +top_copy=Copiar +top_cut=Cortar +top_paste=Colar + +right_name=Nome +right_size=Tamanho +right_user=Utilizador +right_group=Grupo +right_date=Data + +edit_enormal=Apenas ficheiros normais podem ser editados +edit_title=A editar $1 +edit_title2=A criar ficheiro +edit_filename=Nome do ficheiro: +edit_eover=$1 não pode ser sobrescrito +edit_esave=Erro ao guardar ficheiro : $1 +edit_eaccess=Você não está autorizado para guardar '$1' + +info_file=Ficheiro +info_path=Caminho: +info_type=Tipo: +info_size=Tamanho: +info_mod=Modificado: +info_link=Enlace com: +info_perms=Permissões +info_user=Utilizador: +info_group=Grupo: +info_other=Outro: +info_sticky=Restrição: +info_sticky2=Apenas os proprietários podem apagar ficheiros +info_own=Propriedade +info_setuid=Colocar UID: +info_setuid2=Executar como utilizador +info_setgid=Colocar GID: +info_setgid2=Ficheiros herdados do grupo +info_setgid3=Executar como grupo +info_apply=Aplicar alterações a +info_apply1=Este directório apenas +info_apply2=Este directório e os seus ficheiros +info_apply3=Este directório e todos os subdirectórios +info_efailed=Erro ao actualizar $1 : $2 +info_read=Leitura +info_write=Escrita +info_list=Lista +info_exec=Execução + +delete_dtitle=Apagar directório +delete_ftitle=Apagar ficheiro +delete_ddesc=Tem a certeza que quer permanentemente apagar o directório $1 e todo o seu conteúdo? +delete_fdesc=Tem a certeza que quer apagar permanentemente o ficheiro $1 ? +delete_efailed=Erro ao apagar $1 : $2 + +mkdir_title=Novo Directório +mkdir_dir=Novo directório: +mkdir_eexists=$1 já existe +mkdir_efailed=Erro na criação de directório : $1 +mkdir_eaccess=Você não está autorizado para criar '$1' + +link_title=Criar Enlace +link_from=Enlace de: +link_to=Enlace com: +link_eexists=$1 já existe +link_efailed=Erro no enlace : $1 +link_efrom=Você não está autorizado para criar enlaces de '$1' +link_efollow=Você não está autorizado para criar enlaces simbólicos + +rename_title=Renomear $1 +rename_old=Nome antigo: +rename_new=Nome novo: +rename_ok=Renomear +rename_eexists=Já existe um ficheiro denominado $1 +rename_efailed=Erro na renomeação : $1 +rename_eold=Você não está autorizado para renomear '$1' +rename_enew=Você não está autorizado para renomear para '$1' + +file_type0=Directório +file_type1=Ficheiro de texto +file_type2=Ficheiro de imagem +file_type3=Ficheiro binário +file_type4=Ficheiro +file_type5=Enlace simbólico +file_type6=Ficheiro de dispositivo +file_type7=Tubo + +view_enormal=Apenas ficheiros normais podem ser vistos +view_eaccess=Você não está autorizado para aceder a $1 +view_eopen=Erro ao abrir $1 : $2 + +paste_ecopy=Tem de cortar ou copiar primeiro antes de colar +paste_egone=O ficheiro cpoiado $1 já não existe +paste_eover=$1 não pode ser sobrescrito +paste_eself=Não pode colar um ficheiro sobre si mesmo +paste_emfailed=Erro ao mover : $1 +paste_ecfailed=Erro ao copiar : $1 + +upload_efailed=Erro ao abrir ficheiro carregado : $1 +upload_title=Carregar Ficheiro +upload_file=Ficheiro paa carregar +upload_dir=Carregar para o directório +upload_ok=Carregar +upload_conv=Converter linhas de DOS? +upload_efile=Não foram seleccionados ficheiros para carregar. +upload_edir=Directório de carga não existe. +upload_eperm=Você não está autorizado para criar $1 +upload_ewrite=Erro ao escrever para $1 : $2. + +find_eaccess=Você não está autorizado para aceder a $1 +find_eexist=$1 não existe em $2 +find_edir=$1 não é um directório de $2 + +cancel=Cancelar + +chmod_eaccess=Você não está autorizado para aceder a '$1' +chmod_euser=$1 : não existe tal utilizador +chmod_egroup=$1 : não existe tal grupo +chmod_elink=erro no enlace simbólico : $1 +chmod_echown=erro na alteração de proprietário : $1 +chmod_echmod=erro na alteração de permissões : $1 + +copy_efrom=Você não está autorizado para copiar de '$1' +copy_eto=Você não está autorizado para copiar para '$1' +copy_elink=erro no enlace simbólico : $1 + +delete_eaccess=Você não está autorizado para apagar '$1' + +list_eaccess=Você não está autorizado para aceder a este directório + +move_eto=Você não está autorizado para mover para '$1' +move_afrom=Você não está autorizado para mover '$1' + +acl_user=Aceder a ficheiros no servidor como utilizador +acl_umask=Máscara de utilizador para novos ficheiros +acl_follow=Seguir sempre enlaces simbólicos? +acl_dirs=Apenas permitir acesso a directórios diff --git a/file/lang/pt_BR b/file/lang/pt_BR new file mode 100644 index 000000000..678c69418 --- /dev/null +++ b/file/lang/pt_BR @@ -0,0 +1,282 @@ +acl_b=bytes +acl_button_copy=Copiar, Cortar e Colar +acl_button_delete=Deletar (deletar arquivos) +acl_button_edit=Editar (editar arquivo texto) +acl_button_ext=EXT (editar atributos EXT) +acl_button_info=Informações (editar permissões e posse) +acl_button_makelink=Novo (criar link simbólico) +acl_button_mkdir=Novo (criar diretório) +acl_button_mount=Montar (montar ou demosntar dados) +acl_button_new=Novo (criar arqiovo texto) +acl_button_rename=Renomear (renomear arquivo) +acl_button_save=Salvar (baixar arquivo) +acl_button_search=Procurar (procurar arquivo) +acl_button_upload=Upload (enviar arquivo do cliente) +acl_dirs=Permite acesso somente aos diretórios +acl_follow=Seguir links simbólicos sempre? +acl_goto=Abrir primeiro o diretório permitido? +acl_home=Incluir diretório home do usuário Webmin +acl_log=Logar todas as modificações nos arquivos? +acl_ro=Modo somente leitura? +acl_umask=Umask para novos arquivos +acl_user=Acessar arquivos no servidor como usuário +acl_user_def=O mesmo que no login do Webmin +acltype_default_group=Grupo Padrão +acltype_default_mask=Máscara Padrão +acltype_default_other=Outros Padrão +acltype_default_user=Usuário Padrão +acltype_group=Grupo +acltype_mask=Máscara +acltype_other=Outros +acltype_user=Usuário +attr_add=Adicionar atributo +attr_create=Adicionar atributo +attr_eattrs=Falha ao receber atributos de : $1 +attr_edit=Editar atributo +attr_efailed=Falha ao setar atributos para $1 : $2 +attr_efs=O sistema de arquivos $1 não suporta atributos +attr_ename=Faltando o nome do atributo +attr_name=Nome do atributo +attr_title=Atributos do arquivo para $1 +attr_value=Valor do atributo +cancel=Cancelar +chmod_eaccess=Você não está autorizado a acessar '$1' +chmod_echmod=falha no chmod : $1 +chmod_echown=falha no chown : $1 +chmod_efollow=Você não está autorizado a editar links simbólicos +chmod_egroup=$1 : grupo inválido +chmod_elink=falha no link simbólico : $1 +chmod_euser=$1 : usuário inválido +copy_efrom=Você não está autorizado a copiar de '$1' +copy_elink=falha no link simbólico : $1 +copy_eto=Você não esta autorizado a copiar para '$1' +delete_ddesc=Você tem certeza que deseja apagar permanentemente o diretório $1 e todo o seu conteúdo? +delete_dtitle=Apagar diretório +delete_eaccess=Você não esta autorizado a apagar '$1' +delete_efailed=Falha ao apagar $1 : $2 +delete_fdesc=Você tem certeza que deseja apagar permanentemente o arquivo $1 ? +delete_ftitle=Apagar arquivo +delete_mdesc=Você tem certeza que deseja apagar permanentemente estes arquivos e diretórios? : +delete_mtitle=Apagar múltiplos arquivos +eacl_aclname=Aplicar a +eacl_aclperms=Permissões +eacl_acltype=Tipo de ACL +eacl_add=Adicionar ACL do tipo : +eacl_create=Criar ACL +eacl_eacls=Falha ao ler ACLs : $1 +eacl_edefaults=Se o arquivo contém qualquer ACL padrão, ele precisa ter usuário, grupo e outras ACLs padrão. +eacl_edefmask=Pode existir uma entrada a mais padrão para a máscara ACL +eacl_edit=Editar ACL +eacl_efailed=Falha ao setar ACL para $1 : $2 +eacl_efs=O sistema de arquivos $1 não suporta ACLs +eacl_emask=Pode existir uma entrada a mais para a máscara ACL +eacl_eowner=Faltando o usuário ou grupo para aplicar a +eacl_group=Grupo do arquivo $1 +eacl_owner=Dono do arquivo +eacl_remove=Remover ACL +eacl_title=ACL para $1 +eacl_user=Dono do arquivo $1 +eattr_A=Nâo atualize os tempos de acesso +eattr_S=Sempre sincronizar após escrever +eattr_a=Pode somente adicionar ao fim do arquivo +eattr_c=Comprimir dados no disco +eattr_d=Não fazer backup com o dump +eattr_i=Não permitir modificação +eattr_s=Zerar blocos quando apagar +eattr_u=Salvar conteúdo para recuperar +edit_eaccess=Você não está autorizado a salvar '$1' +edit_enormal=Somente arquivos comuns podem ser editados +edit_eover=$1 não pode ser sobrescrito +edit_esave=Falha ao salvar o arquivo : $1 +edit_filename=Nome do arquivo: +edit_title=Editando $1 +edit_title2=Criando o arquivo +ext_eattrs=Falha ao receber atributos EXT : $1 +ext_efailed=Falha ao fixar atributos para $1 : $2 +ext_efs=O sistema de arquivos $1 não suporta atributos EXT +ext_header=Atributos EXT do arquivo +ext_title=Atributos EXT para $1 +facl_eaccess=Você não tem permissão para alterar ACLs para este arquivo +file_type0=Directório +file_type1=Arquivo texto +file_type2=Arquivo de Imagem +file_type3=Arquivo Binário +file_type4=Arquivo +file_type5=Link simbólico +file_type6=Arquivo de dispositivo +file_type7=Pipe +find_eaccess=Você não tem permissão para acessar $1 +find_edir=$1 não é um diretório em $2 +find_eexist=$1 não existe em $2 +index_eremote=Não há nenhum usuário Unix que corresponda ao login $1 do Webmin. +index_nojava=Este módulo requer java para funcionar, porém o seu navegador não suporta java +index_title=Gerenciador de Arquivos +info_apply=Aplicar mudanças a +info_apply1=Somente a este diretório +info_apply2=Este diretório e seus arquivos +info_apply3=Este diretório e todos os seus subdiretórios +info_efailed=Falha ao atualizar $1 : $2 +info_exec=Executar +info_file=Arquivo +info_group=Grupo: +info_link=Link para: +info_list=Listar +info_mod=Modificado: +info_octal=Octal: +info_other=Outros: +info_own=Dono +info_path=Caminho: +info_perms=Permissões +info_read=Ler +info_setgid=Setar gid: +info_setgid2=Grupo inerente dos arquivos +info_setgid3=Executar como grupo +info_setuid=Setar uid: +info_setuid2=Executar como usuário +info_size=Tamanho: +info_sticky=Sticky: +info_sticky2=Somente os donos podem apagar os arquivos +info_type=Tipo: +info_user=Usuário: +info_write=Escrever +link_eexists=$1 já existe +link_efailed=Falha ao criar link : $1 +link_efollow=Você não está autorizado a criar links simbólicos +link_efrom=Você não está autorizado a linkar de '$1' +link_from=Link de: +link_title=Criar Link +link_to=Link para: +list_eaccess=Você não esta autorizado a acessar este diretorio +list_edir=Falha ao listar $1 : $2 +log_acl=Setar ACL no arquivo $1 +log_attr=Foram setados os atributos no arquivo $1 +log_chmod=Permissões alteradas no arquivo $1 +log_copy=Copiado o arquivo $1 para $2 +log_create_export=Criada exportação NFS $1 +log_create_share=Criado compartilhamento Samba $1 +log_delete=Deletado o arquivo $1 +log_delete_export=Deletada exportação NFS $1 +log_delete_share=Deletado compartilhamento Samba $1 +log_link=Criado o link simbólico $1 para $2 +log_mkdir=Criado o diretório $1 +log_modify_export=Modificada exportação NFS $1 +log_modify_share=Modificado compartilhamento Samba $1 +log_move=Movido o arquivo $1 para $2 +log_relink=Modificado o link simbólico $1 para $2 +log_save=Foi salvo o arquivo $1 +log_upload=Foi enviado o arquivo $1 +mkdir_dir=Novo diretório: +mkdir_eaccess=Você não está autorizado a criar '$1' +mkdir_eexists=$1 já existe +mkdir_efailed=Falha ao criar diretório : $1 +mkdir_title=Novo Diretório +move_afrom=Você não está autorizado a mover '$1' +move_eto=Você não está autorizado a mover para '$1' +over_msg=O arquivo $1 já existe. Use o campo abaixo para digitar o nome do arquivo a ser colado. +over_new=Novo nome do arquivo: +over_ok=Ok +over_title=Arquivo já existe +paste_ecfailed=Falha ao copiar : $1 +paste_ecopy=Você precisa recortar ou copiar antes de colar +paste_egone=Arquivo copiado $1 não existe mais +paste_emfailed=Falha ao mover : $1 +paste_eover=$1 não pode ser sobrescrito +paste_eself=Você não pode colar um arquivo sobre ele mesmo +rename_eexists=Um arquivo chamado $1 já existe +rename_efailed=Falha ao renomear : $1 +rename_enew=Você não está autorizado a renomear para '$1' +rename_eold=Você não está autorizado a renomear '$1' +rename_new=Nome novo: +rename_ok=Renomear +rename_old=Nome antigo: +rename_title=Renomear $1 +right_date=Data +right_group=Grupo +right_name=Nome +right_size=Tamanho +right_user=Usuário +search_any=Qualquer +search_crit=Critério de pesquisa +search_dir=Procurar no diretório +search_eaccess=Você não tem autorização para procurar neste diretório +search_edir=Diretório de procura inválido ou faltando +search_egroup=Faltando nome do grupo +search_ematch=Falatando coincidir regexp +search_esize=O tamanho do arquivo precisa ser um inteiro +search_euser=Faltando nome de usuário +search_group=Pertençam ao grupo +search_less=Menos do que +search_list=Resultados da pesquisa +search_match=Por arquivos que coincidam com +search_more=Mais do que +search_ok=Procurar agora +search_size=Tamanho do arquivo +search_title=Procurar arquivos +search_type=Tipo de arquivo +search_types_=Qualquer +search_types_d=Diretório +search_types_f=Arquivo +search_types_l=Link simbólico +search_types_p=Pipe nomeado +search_user=Pertençam ao usuário +search_xdev=Procurar montagens anteriores? +share_all=Todos +share_available=Ativo atualmente? +share_comment=Comentário +share_desc=Descriçao +share_guest=Acesso a convidados? +share_host=Hosts +share_listed=Listados.. +share_lro=Somente leitura +share_lrw=Leitura e escrita +share_nfs=NFS +share_nheader=Opções de exportação NFS +share_noff=Compartilhamento de arquivos NFS desabilitado +share_non=Compartilhamento de arquivos NFS abilitado +share_none=Nenhum +share_only=Somente +share_opts=Opções +share_ro=Hosts somente leitura +share_root=Hosts com acesso root +share_rw=Hosts leitura e escrita +share_s0=Não confiar em ninguém +share_s1=Confiar em não root +share_s2=Confiar em todos +share_samba=Windows +share_sheader=Opções de compartilhamento +share_soff=Compartilhamento de arquivos Windows desabilitado +share_son=Compartilhamento de arquivos Windows abilitado +share_title=Compartilhamento +share_writable=Permitir escrita? +switch_euser=O usuário Unix não existe! +top_attr=Atributos +top_copy=Copiar +top_cut=Recortar +top_delete=Apagar +top_down=Salvar +top_eacl=ACL +top_edit=Editar +top_ext=EXT +top_info=Info +top_new=Novo +top_paste=Colar +top_refresh=Atualizar +top_rename=Renomear +top_ret=Índice +top_search=Procurar +top_share=Compartilhar +top_upload=Upload +upload_conv=Converter novas linhas do DOS? +upload_dir=Upload para qual diretório +upload_edir=Diretório de upload não existe. +upload_efailed=Falha ao abrir upload : $1 +upload_efile=Não foi selecionado nenhum arquivo para upload. +upload_eperm=Você não está autorizado a criar $1 +upload_ewrite=Falha a escrever para $1 : $2. +upload_file=Arquivo para upload +upload_ok=Upload +upload_title=Arquivo para upload +view_eaccess=Você não está autorizado a acessar $1 +view_enormal=Somente arquivos comuns podem ser vizualizados +view_enormal2=Somente pode ser feito download de arquivos comuns +view_eopen=Falha ao abrir $1 : $2 diff --git a/file/lang/ru_RU b/file/lang/ru_RU new file mode 100644 index 000000000..949c3fb93 --- /dev/null +++ b/file/lang/ru_RU @@ -0,0 +1,268 @@ +top_delete=Óäàëèòü +info_apply=Ïðèìåíèòü èçìåíåíèÿ +info_perms=Ïðàâà +info_file=Ôàéë +view_enormal=Ìîæíî ïðîñìàòðèâàòü òîëüêî îáû÷íûå ôàéëû +top_upload=Çàãðóçèòü +edit_esave=Íå óäàëîñü ñîõðàíèòü ôàéë : $1 +upload_ewrite=Íå óäàëîñü çàïèñàòü â $1 : $2. +chmod_elink=Îøèáêà ïðè âûçîâå symlink : $1 +upload_ok=Çàãðóçèòü +view_eaccess=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ äîñòóïà ê $1 +info_group=Ãðóïïû: +edit_title2=Ñîçäàíèå ôàéëà +top_info=Ñâîéñòâà +move_afrom=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ïåðåìåùåíèÿ '$1' +link_efailed=Ñîçäàòü ññûëêó íå óäàëîñü : $1 +info_setuid2=Âûïîëíÿòü îò èìåíè ïîëüçîâàòåëÿ +chmod_euser=$1 : íåò òàêîãî ïîëüçîâàòåëÿ +link_efrom=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ñîçäàíèÿ ññûëêè '$1' +info_mod=Èçìåíåí: +right_date=Äàòà +copy_efrom=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ êîïèðîâàíèÿ èç '$1' +info_sticky2=Òîëüêî âëàäåëüöû ìîãóò óäàëÿòü ôàéëû +rename_old=Ñòàðîå èìÿ: +find_eaccess=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ äîñòóïà ê $1 +mkdir_eexists=$1 óæå ñóùåñòâóåò +upload_dir=Çàãðóæàòü â êàòàëîã +rename_enew=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ïåðåèìåíîâàíèÿ â '$1' +find_edir=$1 íå ÿâëÿåòñÿ êàòàëîãîì â $2 +upload_efile=Íå âûáðàí ôàéë äëÿ çàãðóçêè. +info_type=Òèï: +info_setuid=Áèò setuid: +right_group=Ãðóïïà +upload_efailed=Íå óäàëîñü íà÷àòü çàãðóçêó : $1 +top_cut=Âûðåçàòü +info_read=×òåíèå +acl_user=Îáðàùàòüñÿ ê ôàéëàì íà ñåðâåðå ïîä èìåíåì ïîëüçîâàòåëÿ +paste_ecopy=Ïåðåä âñòàâêîé íåîáõîäèìî âûðåçàòü èëè êîïèðîâàòü +info_exec=Âûïîëíåíèå +delete_ddesc=Íàâñåãäà óäàëèòü êàòàëîã $1 ñî âñåì åãî ñîäåðæèìûì? +info_link=Ññûëêà íà: +link_to=Ìåñòî íàçíà÷åíèÿ: +info_size=Ðàçìåð: +info_path=Ïóòü: +copy_eto=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ êîïèðîâàíèÿ â '$1' +rename_ok=Ïåðåèìåíîâàòü +chmod_egroup=$1 : íåò òàêîé ãðóïïû +info_own=Ïðèíàäëåæíîñòü +upload_conv=Ïðåîáðàçîâàòü ïåðåâîäû ñòðîê DOS? +cancel=Îòìåíà +info_list=Ïðîñìîòð +index_nojava=Äëÿ ôóíêöèîíèðîâàíèÿ ýòîãî ìîäóëÿ òðåáóåòñÿ java, îäíàêî âàø áðàóçåð java íå ïîääåðæèâàåò +paste_eover=$1 íå ìîæåò áûòü ïåðåçàïèñàí +info_user=Ïîëüçîâàòåëÿ: +delete_fdesc=Íàâñåãäà óäàëèòü ôàéë $1 ? +edit_title=Ðåäàêòèðîâàíèå $1 +paste_egone=Êîïèðóåìûé ôàéë $1 áîëüøå íå ñóùåñòâóåò +top_paste=Âñòàâèòü +chmod_echmod=Îøèáêà ïðè âûçîâå chmod : $1 +edit_filename=Èìÿ ôàéëà: +link_eexists=$1 óæå ñóùåñòâóåò +edit_enormal=Ìîæíî ðåäàêòèðîâàòü òîëüêî îáû÷íûå ôàéëû +info_setgid2=Ôàéëû íàñëåäóþò ãðóïïó +info_setgid3=Âûïîëíÿòü îò èìåíè ãðóïïû +top_copy=Êîïèðîâàòü +edit_eaccess=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ñîõðàíåíèÿ '$1' +right_name=Èìÿ +rename_efailed=Ïåðåèìåíîâàòü íå óäàëîñü : $1 +upload_edir=Êàòàëîã äëÿ çàãðóçêè íå ñóùåñòâóåò. +rename_new=Íîâîå èìÿ: +delete_dtitle=Óäàëåíèå êàòàëîãà +link_from=Èñòî÷íèê: +index_title=Ìåíåäæåð ôàéëîâ +file_type0=Êàòàëîã +file_type1=Òåêñòîâûé ôàéë +file_type2=Ôàéë èçîáðàæåíèÿ +file_type3=Áèíàðíûé ôàéë +file_type4=Ôàéë +file_type5=Ñèìâîëüíàÿ ññûëêà +file_type6=Ôàéë óñòðîéñòâà +file_type7=Êàíàë +info_sticky=Áèò sticky: +upload_title=Çàãðóçêà ôàéëà +top_edit=Èçìåíèòü +upload_eperm=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ñîçäàíèÿ $1 +move_eto=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ïåðåìåùåíèÿ â '$1' +paste_eself=Íåëüçÿ ïåðåïèñàòü ôàéë ñàìèì ñîáîé +copy_elink=Îøèáêà ïðè âûçîâå symlink : $1 +chmod_echown=Îøèáêà ïðè âûçîâå chown : $1 +acl_umask=Umask äëÿ íîâûõ ôàéëîâ +mkdir_dir=Íîâûé êàòàëîã: +info_other=Ïðî÷èõ: +mkdir_title=Íîâûé êàòàëîã +delete_ftitle=Óäàëåíèå ôàéëà +find_eexist=$1 íå ñóùåñòâóåò â $2 +right_size=Ðàçìåð +edit_eover=$1 íå ìîæåò áûòü ïåðåçàïèñàí +paste_emfailed=Íå óäàëîñü ïåðåìåñòèòü : $1 +link_title=Ñîçäàíèå ññûëêè +info_apply1=Òîëüêî ê ýòîìó êàòàëîãó +info_apply2=Ê ýòîìó êàòàëîãó è åãî ôàéëàì +info_apply3=Ê Ýòîìó êàòàëîãó è âñåì åãî ïîäêàòàëîãàì +info_efailed=Íå óäàëîñü îáíîâèòü $1 : $2 +acl_follow=Âñåãäà ïåðåõîäèòü ïî ñèìâîëüíûì ññûëêàì? +upload_file=Ôàéë äëÿ çàãðóçêè +info_setgid=Áèò setgid: +paste_ecfailed=Íå óäàëîñü ñêîïèðîâàòü : $1 +mkdir_eaccess=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ñîçäàíèÿ '$1' +right_user=Ïîëüçîâàòåëü +rename_eold=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ïåðåèìåíîâàíèÿ '$1' +link_efollow=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ñîçäàíèÿ ññûëîê +rename_title=Ïåðåèìåíîâàíèå $1 +top_new=Ññûëêà +mkdir_efailed=Íå óäàëîñü ñîçäàòü êàòàëîã : $1 +info_write=Çàïèñü +rename_eexists=Ôàéë ñ èìåíåì $1 óæå ñóùåñòâóåò +acl_dirs=Ïîçâîëÿòü äîñòóï òîëüêî ê êàòàëîãàì +chmod_eaccess=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ äîñòóïà ê '$1' +top_refresh=Îáíîâèòü +delete_eaccess=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ óäàëåíèÿ '$1' +view_eopen=Íå óäàëîñü îòêðûòü $1 : $2 +top_rename=Ïåðåèìåíîâàòü +list_eaccess=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ äîñòóïà ê ýòîìó êàòàëîãó +delete_efailed=Íå óäàëîñü óäàëèòü $1 : $2 +log_chmod=Èçìåíåíû ïðàâà íà ôàéë $1 +eacl_edefmask=There can be at most one default mask ACL entry +acl_log=Âåñòè æóðíàë âñåõ èçìåíåíèé ôàéëîâ? +eacl_eacls=Íå óäàëîñü ñ÷èòàòü ACL : $1 +search_eaccess=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ ïîèñêà â ýòîì êàòàëîãå +over_msg=Ôàéë $1 óæå ñóùåñòâóåò. Óêàæèòå äëÿ âñòàâëÿåìîãî ôàéëà íîâîå èìÿ. +share_nfs=NFS +log_copy=Ñêîïèðîâàí ôàéë $1 â $2 +acltype_default_group=Ãðóïïà ïî óìîë÷àíèþ +eacl_aclname=Ïðèìåíèòü ê +search_size=Ðàçìåð ôàéëà +log_upload=Çàãðóæåí ôàéë $1 +attr_create=Äîáàâèòü àòðèáóò +search_types_d=Êàòàëîã +ext_eattrs=Íå óäàëîñü ïîëó÷èòü àòðèáóòû EXT : $1 +search_group=Ïðèíàäëåæàùèå ãðóïïå +search_types_f=Ôàéë +index_eremote=Íåò ïîëüçîâàòåëÿ Unix ñîîòâåòñòâóþùåãî ïîëüçîâàòåëþ Webmin $1. +search_types_l=Ñèìâîëüíàÿ ññûëêà +search_types_p=Èìåíîâàííûé êàíàë +search_dir=Èñêàòü â êàòàëîãå +acltype_user=Ïîëüçîâàòåëü +acl_user_def=Ïîëüçîâàòåëÿ Webmin +top_share=Ñåòü +switch_euser=Ïîëüçîâàòåëü Unix íå ñóùåñòâóåò! +acl_home=Âêëþ÷àÿ äîìàøíèé êàòàëîã ïîëüçîâàòåëÿ Webmin +search_match=Ôàéëû ñîâïàäàþùèå ñ +share_writable=Çàïèñü ðàçðåøåíà? +delete_mtitle=Óäàëåíèå íåñêîëüêèõ ôàéëîâ +search_less=Ìåíåå +top_attr=Àòðèáóòû +log_link=Ñîçäàíà ñèìâîëüíàÿ ññûëêà $1 íà $2 +log_create_export=Ñîçäàí ðåñóðñ NFS $1 +eacl_acltype=Òèï ACL +share_s0=Äîâåðÿòü nobody +share_s1=Äîâåðÿòü íå-root +share_s2=Äîâåðÿòü âñåì +ext_header=Àòðèáóòû EXT ôàéëà +search_title=Ïîèñê ôàéëîâ +search_types_=Ëþáîé +log_move=Ïåðåìåùåí ôàéë $1 â $2 +acl_goto=Îòêðûâàòü ïåðâûé äîñòóïíûé êàòàëîã? +top_search=Íàéòè +share_none=Íåò +log_delete=Óäàëåí ôàéë $1 +share_opts=Íàñòðîéêà +share_ro=Óçëû, èìåþùèå äîñòóï òîëüêî äëÿ ÷òåíèÿ +share_rw=Óçëû, èìåþùèå äîñòóï äëÿ ÷òåíèÿ è çàïèñè +share_guest=Äîñòóï áåç àóòåíòèôèêàöèè (Guest)? +share_nheader=Íàñòðîéêà äîñòóïà ïî ïðîòîêîëó NFS +over_title=Ôàéë ñóùåñòâóåò +over_new=Íîâîå èìÿ ôàéëà: +share_host=Óçëû +search_esize=Ðàçìåð ôàéëà äîëæåí áûòü öåëûì ÷èñëîì +acltype_other=Ïðî÷èå +ext_efailed=Íå óäàëîñü óñòàíîâèòü àòðèáóòû EXT $1 : $2 +share_title=Äîñòóï ïî ñåòè +share_only=Òîëüêî +attr_edit=Èçìåíèòü àòðèáóò +eacl_eowner=Íå óêàçàí ïîëüçîâàòåëü èëè ãðóïïà äëÿ êîòîðîé âíîñÿòñÿ èçìåíåíèÿ +view_enormal2=Ìîæíî çàãðóæàòü òîëüêî îáû÷íûå ôàéëû +search_user=Ïðèíàäëåæàùèå ïîëüçîâàòåëþ +log_mkdir=Ñîçäàí êàòàëîã $1 +attr_ename=Íå óêàçàíî íàçâàíèå àòðèáóòà +search_more=Áîëåå +eacl_user=Âëàäåëåö ôàéëà $1 +ext_efs=Ôàéëîâàÿ ñèñòåìà $1 íå ïîääåðæèâàåò àòðèáóòû EXT +acltype_default_user=Ïîëüçîâàòåëü ïî óìîë÷àíèþ +top_ext=EXT +eacl_efs=Ýòà ôàéëîâàÿ ñèñòåìà $1 íå ïîääåðæèâàåò ACL +search_egroup=Èìÿ ãðóïïû íå óêàçàíî èëè óêàçàíî íåâåðíî +share_lro=Òîëüêî ÷òåíèå +acl_ro=Ðåæèì òîëüêî äëÿ ÷òåíèÿ? +eacl_edefaults=If a file has any default ACL, it must have default user, group and other ACLs. +list_edir=Íå óäàëîñü ïðîñìîòðåòü $1 : $2 +eacl_owner=Âëàäåëåö ôàéëà +share_lrw=×òåíèå/çàïèñü +attr_name=Íàçâàíèå àòðèáóòà +eacl_aclperms=Ïðàâà +acltype_default_other=Ïðî÷èå ïî óìîë÷àíèþ +acltype_mask=Ìàñêà +attr_eattrs=Íå óäàëîñü ñ÷èòàòü àòðèáóòû : $1 +search_ematch=Ðåãóëÿðíîå âûðàæåíèå äëÿ ïîèñêà íå óêàçàíî èëè óêàçàíî íåâåðíî +eacl_add=Äîáàâèòü ACL : +log_attr=Èçìåíåíû àòðèáóòû ôàéëà $1 +log_modify_export=Èçìåíåí ðåñóðñ NFS $1 +attr_efs=Ôàéëîâàÿ ñèñòåìà $1 íå ïîääåðæèâàåò àòðèáóòû +top_down=Ñîõðàíèòü +eattr_A=Íå îáíîâëÿòü âðåìÿ äîñòóïà +search_crit=Êðèòåðèé ïîèñêà +attr_add=Äîáàâèòü àòðèáóò +chmod_efollow=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ èçìåíåíèÿ ñèìâîëüíûõ ññûëîê +ext_title=Àòðèáóòû EXT äëÿ $1 +share_son=Äîñòóï èç ñåòè Windows ðàçðåøåí +log_create_share=Ñîçäàí ðåñóðñ Samba $1 +search_ok=Èñêàòü +attr_title=Àòðèáóòû ôàéëà äëÿ $1 +eattr_S=Âñåãäà ñèíõðîíèçèðîâàòü ïîñëå çàïèñè +search_edir=Êàòàëîã äëÿ ïîèñêà íå óêàçàí èëè óêàçàí íåâåðíî +share_non=Äîñòóï ïî NFS ðàçðåøåí +eattr_a=Âîçìîæíî òîëüêî äîáàâëåíèå ê ôàéëó +share_samba=Windows +eattr_c=Ñæèìàòü äàííûå íà äèñêå +eattr_d=Íå ïðîèçâîäèòü ðåçåðâíîå êîïèðîâàíèå ñ ïîìîùüþ dump +search_xdev=Èñêàòü â ïîäìîíòèðîâàííûõ ôàéëîâûõ ñèñòåìàõ? +eacl_edit=Èçìåíèòü ACL +eattr_i=Çàïðåòèòü èçìåíåíèå +share_soff=Äîñòóï èç ñåòè Windows çàïðåùåí +search_euser=Èìÿ ïîëüçîâàòåëÿ íå óêàçàíî èëè óêàçàíî íåâåðíî +eattr_s=Îáíóëÿòü áëîêè ïðè óäàëåíèè +eattr_u=Ñîõðàíÿòü ñîäåðæèìîå ôàéëà äëÿ âîññòàíîâëåíèÿ +top_ret=Ìåíþ +log_delete_share=Óäàëåí ðåñóðñ Samba $1 +eacl_emask=There can be at most one mask ACL entry +log_delete_export=Óäàëåí ðåñóðñ NFS $1 +eacl_group=Ãðóïïà ôàéëà $1 +share_noff=Äîñòóï ïî NFS çàïðåùåí +share_available=Äîñòóïåí â äàííûé ìîìåíò? +info_octal=Âîñüìåðè÷íûé âèä: +attr_efailed=Íå óäàëîñü óñòàíîâèòü àòðèáóòû äëÿ $1 : $2 +acltype_default_mask=Ìàñêà ïî óìîë÷àíèþ +log_modify_share=Èçìåíåí ðåñóðñ Samba $1 +log_save=Ñîõðàíåí ôàéë $1 +share_comment=Êîììåíòàðèé +share_desc=Îïèñàíèå +eacl_remove=Óäàëèòü ACL +attr_value=Çíà÷åíèå àòðèáóòà +search_any=Ëþáîé +search_type=Òèï ôàéëà +eacl_title=ACL äëÿ $1 +top_eacl=ACL +facl_eaccess=Ó âàñ íåäîñòàòî÷íî ïðàâ äëÿ èçìåíåíèÿ ACL äëÿ ýòîãî ôàéëà +share_root=Óçëû, äëÿ êîòîðûõ ðàçðåøåí äîñòóï ñ ïðàâàìè root +eacl_efailed=Íå óäàëîñü óñòàíîâèòü ACL äëÿ $1 : $2 +share_all=Âñå +delete_mdesc=Íàâñåãäà óäàëèòü óêàçàííûå ôàéëû è êàòàëîãè? : +acltype_group=Ãðóïïà +log_acl=Äëÿ ôàéëà $1 íàçíà÷åí ACL +share_listed=Óêàçàííûå.. +share_sheader=Íàñòðîéêà äîñòóïà +search_list=Ðåçóëüòàòû ïîèñêà +eacl_create=Ñîçäàòü ACL +log_relink=Èçìåíåíà ñèìâîëüíàÿ ññûëêà $1 íà $2 +over_ok=ÎÊ diff --git a/file/lang/ru_SU b/file/lang/ru_SU new file mode 100644 index 000000000..99e68fac7 --- /dev/null +++ b/file/lang/ru_SU @@ -0,0 +1,299 @@ +index_title=íÅÎÅÄÖÅÒ ÆÁÊÌÏ× +index_nojava=äÌÑ ÆÕÎËÃÉÏÎÉÒÏ×ÁÎÉÑ ÜÔÏÇÏ ÍÏÄÕÌÑ ÔÒÅÂÕÅÔÓÑ java, ÏÄÎÁËÏ ×ÁÛ ÂÒÁÕÚÅÒ java ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ +index_eremote=îÅÔ ÐÏÌØÚÏ×ÁÔÅÌÑ Unix ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÅÇÏ ÐÏÌØÚÏ×ÁÔÅÌÀ Webmin $1. +switch_euser=ðÏÌØÚÏ×ÁÔÅÌØ Unix ÎÅ ÓÕÝÅÓÔ×ÕÅÔ! + +top_ret=íÅÎÀ +top_down=óÏÈÒÁÎÉÔØ +top_edit=éÚÍÅÎÉÔØ +top_refresh=ïÂÎÏ×ÉÔØ +top_info=ó×ÏÊÓÔ×Á +top_eacl=ACL +top_attr=áÔÒÉÂÕÔÙ +top_ext=EXT +top_delete=õÄÁÌÉÔØ +top_new=óÓÙÌËÁ +top_upload=úÁÇÒÕÚÉÔØ +top_rename=ðÅÒÅÉÍÅÎÏ×ÁÔØ +top_copy=ëÏÐÉÒÏ×ÁÔØ +top_cut=÷ÙÒÅÚÁÔØ +top_paste=÷ÓÔÁ×ÉÔØ +top_share=óÅÔØ +top_search=îÁÊÔÉ + +right_name=éÍÑ +right_size=òÁÚÍÅÒ +right_user=ðÏÌØÚÏ×ÁÔÅÌØ +right_group=çÒÕÐÐÁ +right_date=äÁÔÁ + +edit_enormal=íÏÖÎÏ ÒÅÄÁËÔÉÒÏ×ÁÔØ ÔÏÌØËÏ ÏÂÙÞÎÙÅ ÆÁÊÌÙ +edit_title=òÅÄÁËÔÉÒÏ×ÁÎÉÅ $1 +edit_title2=óÏÚÄÁÎÉÅ ÆÁÊÌÁ +edit_filename=éÍÑ ÆÁÊÌÁ: +edit_eover=$1 ÎÅ ÍÏÖÅÔ ÂÙÔØ ÐÅÒÅÚÁÐÉÓÁÎ +edit_esave=îÅ ÕÄÁÌÏÓØ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ : $1 +edit_eaccess=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÓÏÈÒÁÎÅÎÉÑ '$1' + +info_file=æÁÊÌ +info_path=ðÕÔØ: +info_type=ôÉÐ: +info_size=òÁÚÍÅÒ: +info_mod=éÚÍÅÎÅÎ: +info_link=óÓÙÌËÁ ÎÁ: +info_perms=ðÒÁ×Á +info_user=ðÏÌØÚÏ×ÁÔÅÌÑ: +info_group=çÒÕÐÐÙ: +info_other=ðÒÏÞÉÈ: +info_octal=÷ÏÓØÍÅÒÉÞÎÙÊ ×ÉÄ: +info_sticky=âÉÔ sticky: +info_sticky2=ôÏÌØËÏ ×ÌÁÄÅÌØÃÙ ÍÏÇÕÔ ÕÄÁÌÑÔØ ÆÁÊÌÙ +info_own=ðÒÉÎÁÄÌÅÖÎÏÓÔØ +info_setuid=âÉÔ setuid: +info_setuid2=÷ÙÐÏÌÎÑÔØ ÏÔ ÉÍÅÎÉ ÐÏÌØÚÏ×ÁÔÅÌÑ +info_setgid=âÉÔ setgid: +info_setgid2=æÁÊÌÙ ÎÁÓÌÅÄÕÀÔ ÇÒÕÐÐÕ +info_setgid3=÷ÙÐÏÌÎÑÔØ ÏÔ ÉÍÅÎÉ ÇÒÕÐÐÙ +info_apply=ðÒÉÍÅÎÉÔØ ÉÚÍÅÎÅÎÉÑ +info_apply1=ôÏÌØËÏ Ë ÜÔÏÍÕ ËÁÔÁÌÏÇÕ +info_apply2=ë ÜÔÏÍÕ ËÁÔÁÌÏÇÕ É ÅÇÏ ÆÁÊÌÁÍ +info_apply3=ë üÔÏÍÕ ËÁÔÁÌÏÇÕ É ×ÓÅÍ ÅÇÏ ÐÏÄËÁÔÁÌÏÇÁÍ +info_efailed=îÅ ÕÄÁÌÏÓØ ÏÂÎÏ×ÉÔØ $1 : $2 +info_read=þÔÅÎÉÅ +info_write=úÁÐÉÓØ +info_list=ðÒÏÓÍÏÔÒ +info_exec=÷ÙÐÏÌÎÅÎÉÅ + +eacl_eacls=îÅ ÕÄÁÌÏÓØ ÓÞÉÔÁÔØ ACL : $1 +eacl_acltype=ôÉÐ ACL +eacl_aclname=ðÒÉÍÅÎÉÔØ Ë +eacl_aclperms=ðÒÁ×Á +eacl_add=äÏÂÁ×ÉÔØ ACL : +eacl_remove=õÄÁÌÉÔØ ACL +eacl_efs=üÔÁ ÆÁÊÌÏ×ÁÑ ÓÉÓÔÅÍÁ $1 ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ACL +eacl_create=óÏÚÄÁÔØ ACL +eacl_edit=éÚÍÅÎÉÔØ ACL +eacl_user=÷ÌÁÄÅÌÅà ÆÁÊÌÁ $1 +eacl_group=çÒÕÐÐÁ ÆÁÊÌÁ $1 +eacl_eowner=îÅ ÕËÁÚÁÎ ÐÏÌØÚÏ×ÁÔÅÌØ ÉÌÉ ÇÒÕÐÐÁ ÄÌÑ ËÏÔÏÒÏÊ ×ÎÏÓÑÔÓÑ ÉÚÍÅÎÅÎÉÑ +eacl_efailed=îÅ ÕÄÁÌÏÓØ ÕÓÔÁÎÏ×ÉÔØ ACL ÄÌÑ $1 : $2 +eacl_emask=There can be at most one mask ACL entry +eacl_edefmask=There can be at most one default mask ACL entry +eacl_title=ACL ÄÌÑ $1 +eacl_owner=÷ÌÁÄÅÌÅà ÆÁÊÌÁ +eacl_edefaults=If a file has any default ACL, it must have default user, group and other ACLs. + +acltype_user=ðÏÌØÚÏ×ÁÔÅÌØ +acltype_group=çÒÕÐÐÁ +acltype_other=ðÒÏÞÉÅ +acltype_mask=íÁÓËÁ +acltype_default_user=ðÏÌØÚÏ×ÁÔÅÌØ ÐÏ ÕÍÏÌÞÁÎÉÀ +acltype_default_group=çÒÕÐÐÁ ÐÏ ÕÍÏÌÞÁÎÉÀ +acltype_default_other=ðÒÏÞÉÅ ÐÏ ÕÍÏÌÞÁÎÉÀ +acltype_default_mask=íÁÓËÁ ÐÏ ÕÍÏÌÞÁÎÉÀ + +delete_mtitle=õÄÁÌÅÎÉÅ ÎÅÓËÏÌØËÉÈ ÆÁÊÌÏ× +delete_dtitle=õÄÁÌÅÎÉÅ ËÁÔÁÌÏÇÁ +delete_ftitle=õÄÁÌÅÎÉÅ ÆÁÊÌÁ +delete_ddesc=îÁ×ÓÅÇÄÁ ÕÄÁÌÉÔØ ËÁÔÁÌÏÇ $1 ÓÏ ×ÓÅÍ ÅÇÏ ÓÏÄÅÒÖÉÍÙÍ? +delete_fdesc=îÁ×ÓÅÇÄÁ ÕÄÁÌÉÔØ ÆÁÊÌ $1 ? +delete_mdesc=îÁ×ÓÅÇÄÁ ÕÄÁÌÉÔØ ÕËÁÚÁÎÎÙÅ ÆÁÊÌÙ É ËÁÔÁÌÏÇÉ? : +delete_efailed=îÅ ÕÄÁÌÏÓØ ÕÄÁÌÉÔØ $1 : $2 + +mkdir_title=îÏ×ÙÊ ËÁÔÁÌÏÇ +mkdir_dir=îÏ×ÙÊ ËÁÔÁÌÏÇ: +mkdir_eexists=$1 ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ +mkdir_efailed=îÅ ÕÄÁÌÏÓØ ÓÏÚÄÁÔØ ËÁÔÁÌÏÇ : $1 +mkdir_eaccess=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÓÏÚÄÁÎÉÑ '$1' + +link_title=óÏÚÄÁÎÉÅ ÓÓÙÌËÉ +link_from=éÓÔÏÞÎÉË: +link_to=íÅÓÔÏ ÎÁÚÎÁÞÅÎÉÑ: +link_eexists=$1 ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ +link_efailed=óÏÚÄÁÔØ ÓÓÙÌËÕ ÎÅ ÕÄÁÌÏÓØ : $1 +link_efrom=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÓÏÚÄÁÎÉÑ ÓÓÙÌËÉ '$1' +link_efollow=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÓÏÚÄÁÎÉÑ ÓÓÙÌÏË + +rename_title=ðÅÒÅÉÍÅÎÏ×ÁÎÉÅ $1 +rename_old=óÔÁÒÏÅ ÉÍÑ: +rename_new=îÏ×ÏÅ ÉÍÑ: +rename_ok=ðÅÒÅÉÍÅÎÏ×ÁÔØ +rename_eexists=æÁÊÌ Ó ÉÍÅÎÅÍ $1 ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ +rename_efailed=ðÅÒÅÉÍÅÎÏ×ÁÔØ ÎÅ ÕÄÁÌÏÓØ : $1 +rename_eold=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÐÅÒÅÉÍÅÎÏ×ÁÎÉÑ '$1' +rename_enew=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÐÅÒÅÉÍÅÎÏ×ÁÎÉÑ × '$1' + +file_type0=ëÁÔÁÌÏÇ +file_type1=ôÅËÓÔÏ×ÙÊ ÆÁÊÌ +file_type2=æÁÊÌ ÉÚÏÂÒÁÖÅÎÉÑ +file_type3=âÉÎÁÒÎÙÊ ÆÁÊÌ +file_type4=æÁÊÌ +file_type5=óÉÍ×ÏÌØÎÁÑ ÓÓÙÌËÁ +file_type6=æÁÊÌ ÕÓÔÒÏÊÓÔ×Á +file_type7=ëÁÎÁÌ + +view_enormal=íÏÖÎÏ ÐÒÏÓÍÁÔÒÉ×ÁÔØ ÔÏÌØËÏ ÏÂÙÞÎÙÅ ÆÁÊÌÙ +view_enormal2=íÏÖÎÏ ÚÁÇÒÕÖÁÔØ ÔÏÌØËÏ ÏÂÙÞÎÙÅ ÆÁÊÌÙ +view_eaccess=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÄÏÓÔÕÐÁ Ë $1 +view_eopen=îÅ ÕÄÁÌÏÓØ ÏÔËÒÙÔØ $1 : $2 + +paste_ecopy=ðÅÒÅÄ ×ÓÔÁ×ËÏÊ ÎÅÏÂÈÏÄÉÍÏ ×ÙÒÅÚÁÔØ ÉÌÉ ËÏÐÉÒÏ×ÁÔØ +paste_egone=ëÏÐÉÒÕÅÍÙÊ ÆÁÊÌ $1 ÂÏÌØÛÅ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ +paste_eover=$1 ÎÅ ÍÏÖÅÔ ÂÙÔØ ÐÅÒÅÚÁÐÉÓÁÎ +paste_eself=îÅÌØÚÑ ÐÅÒÅÐÉÓÁÔØ ÆÁÊÌ ÓÁÍÉÍ ÓÏÂÏÊ +paste_emfailed=îÅ ÕÄÁÌÏÓØ ÐÅÒÅÍÅÓÔÉÔØ : $1 +paste_ecfailed=îÅ ÕÄÁÌÏÓØ ÓËÏÐÉÒÏ×ÁÔØ : $1 + +over_title=æÁÊÌ ÓÕÝÅÓÔ×ÕÅÔ +over_msg=æÁÊÌ $1 ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ. õËÁÖÉÔÅ ÄÌÑ ×ÓÔÁ×ÌÑÅÍÏÇÏ ÆÁÊÌÁ ÎÏ×ÏÅ ÉÍÑ. +over_new=îÏ×ÏÅ ÉÍÑ ÆÁÊÌÁ: +over_ok=ïë + +upload_efailed=îÅ ÕÄÁÌÏÓØ ÎÁÞÁÔØ ÚÁÇÒÕÚËÕ : $1 +upload_title=úÁÇÒÕÚËÁ ÆÁÊÌÁ +upload_file=æÁÊÌ ÄÌÑ ÚÁÇÒÕÚËÉ +upload_dir=úÁÇÒÕÖÁÔØ × ËÁÔÁÌÏÇ +upload_ok=úÁÇÒÕÚÉÔØ +upload_conv=ðÒÅÏÂÒÁÚÏ×ÁÔØ ÐÅÒÅ×ÏÄÙ ÓÔÒÏË DOS? +upload_efile=îÅ ×ÙÂÒÁÎ ÆÁÊÌ ÄÌÑ ÚÁÇÒÕÚËÉ. +upload_edir=ëÁÔÁÌÏÇ ÄÌÑ ÚÁÇÒÕÚËÉ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ. +upload_eperm=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÓÏÚÄÁÎÉÑ $1 +upload_ewrite=îÅ ÕÄÁÌÏÓØ ÚÁÐÉÓÁÔØ × $1 : $2. + +find_eaccess=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÄÏÓÔÕÐÁ Ë $1 +find_eexist=$1 ÎÅ ÓÕÝÅÓÔ×ÕÅÔ × $2 +find_edir=$1 ÎÅ Ñ×ÌÑÅÔÓÑ ËÁÔÁÌÏÇÏÍ × $2 + +cancel=ïÔÍÅÎÁ + +chmod_eaccess=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÄÏÓÔÕÐÁ Ë '$1' +chmod_euser=$1 : ÎÅÔ ÔÁËÏÇÏ ÐÏÌØÚÏ×ÁÔÅÌÑ +chmod_egroup=$1 : ÎÅÔ ÔÁËÏÊ ÇÒÕÐÐÙ +chmod_elink=ïÛÉÂËÁ ÐÒÉ ×ÙÚÏ×Å symlink : $1 +chmod_echown=ïÛÉÂËÁ ÐÒÉ ×ÙÚÏ×Å chown : $1 +chmod_echmod=ïÛÉÂËÁ ÐÒÉ ×ÙÚÏ×Å chmod : $1 +chmod_efollow=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÉÚÍÅÎÅÎÉÑ ÓÉÍ×ÏÌØÎÙÈ ÓÓÙÌÏË + +copy_efrom=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ËÏÐÉÒÏ×ÁÎÉÑ ÉÚ '$1' +copy_eto=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ËÏÐÉÒÏ×ÁÎÉÑ × '$1' +copy_elink=ïÛÉÂËÁ ÐÒÉ ×ÙÚÏ×Å symlink : $1 + +delete_eaccess=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÕÄÁÌÅÎÉÑ '$1' + +list_eaccess=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÄÏÓÔÕÐÁ Ë ÜÔÏÍÕ ËÁÔÁÌÏÇÕ +list_edir=îÅ ÕÄÁÌÏÓØ ÐÒÏÓÍÏÔÒÅÔØ $1 : $2 + +move_eto=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÐÅÒÅÍÅÝÅÎÉÑ × '$1' +move_afrom=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÐÅÒÅÍÅÝÅÎÉÑ '$1' + +acl_user=ïÂÒÁÝÁÔØÓÑ Ë ÆÁÊÌÁÍ ÎÁ ÓÅÒ×ÅÒÅ ÐÏÄ ÉÍÅÎÅÍ ÐÏÌØÚÏ×ÁÔÅÌÑ +acl_user_def=ðÏÌØÚÏ×ÁÔÅÌÑ Webmin +acl_umask=Umask ÄÌÑ ÎÏ×ÙÈ ÆÁÊÌÏ× +acl_follow=÷ÓÅÇÄÁ ÐÅÒÅÈÏÄÉÔØ ÐÏ ÓÉÍ×ÏÌØÎÙÍ ÓÓÙÌËÁÍ? +acl_ro=òÅÖÉÍ ÔÏÌØËÏ ÄÌÑ ÞÔÅÎÉÑ? +acl_dirs=ðÏÚ×ÏÌÑÔØ ÄÏÓÔÕÐ ÔÏÌØËÏ Ë ËÁÔÁÌÏÇÁÍ +acl_home=÷ËÌÀÞÁÑ ÄÏÍÁÛÎÉÊ ËÁÔÁÌÏÇ ÐÏÌØÚÏ×ÁÔÅÌÑ Webmin +acl_log=÷ÅÓÔÉ ÖÕÒÎÁÌ ×ÓÅÈ ÉÚÍÅÎÅÎÉÊ ÆÁÊÌÏ×? +acl_goto=ïÔËÒÙ×ÁÔØ ÐÅÒ×ÙÊ ÄÏÓÔÕÐÎÙÊ ËÁÔÁÌÏÇ? + +share_title=äÏÓÔÕÐ ÐÏ ÓÅÔÉ +share_samba=Windows +share_nfs=NFS +share_son=äÏÓÔÕÐ ÉÚ ÓÅÔÉ Windows ÒÁÚÒÅÛÅÎ +share_soff=äÏÓÔÕÐ ÉÚ ÓÅÔÉ Windows ÚÁÐÒÅÝÅÎ +share_writable=úÁÐÉÓØ ÒÁÚÒÅÛÅÎÁ? +share_available=äÏÓÔÕÐÅÎ × ÄÁÎÎÙÊ ÍÏÍÅÎÔ? +share_sheader=îÁÓÔÒÏÊËÁ ÄÏÓÔÕÐÁ +share_only=ôÏÌØËÏ +share_guest=äÏÓÔÕÐ ÂÅÚ ÁÕÔÅÎÔÉÆÉËÁÃÉÉ (Guest)? +share_comment=ëÏÍÍÅÎÔÁÒÉÊ +share_nheader=îÁÓÔÒÏÊËÁ ÄÏÓÔÕÐÁ ÐÏ ÐÒÏÔÏËÏÌÕ NFS +share_non=äÏÓÔÕÐ ÐÏ NFS ÒÁÚÒÅÛÅÎ +share_noff=äÏÓÔÕÐ ÐÏ NFS ÚÁÐÒÅÝÅÎ +share_desc=ïÐÉÓÁÎÉÅ +share_ro=õÚÌÙ, ÉÍÅÀÝÉÅ ÄÏÓÔÕÐ ÔÏÌØËÏ ÄÌÑ ÞÔÅÎÉÑ +share_rw=õÚÌÙ, ÉÍÅÀÝÉÅ ÄÏÓÔÕÐ ÄÌÑ ÞÔÅÎÉÑ É ÚÁÐÉÓÉ +share_root=õÚÌÙ, ÄÌÑ ËÏÔÏÒÙÈ ÒÁÚÒÅÛÅÎ ÄÏÓÔÕÐ Ó ÐÒÁ×ÁÍÉ root +share_none=îÅÔ +share_all=÷ÓÅ +share_listed=õËÁÚÁÎÎÙÅ.. +share_host=õÚÌÙ +share_opts=îÁÓÔÒÏÊËÁ +share_s0=äÏ×ÅÒÑÔØ nobody +share_s1=äÏ×ÅÒÑÔØ ÎÅ-root +share_s2=äÏ×ÅÒÑÔØ ×ÓÅÍ +share_lro=ôÏÌØËÏ ÞÔÅÎÉÅ +share_lrw=þÔÅÎÉÅ/ÚÁÐÉÓØ + +log_create_export=óÏÚÄÁÎ ÒÅÓÕÒÓ NFS $1 +log_modify_export=éÚÍÅÎÅÎ ÒÅÓÕÒÓ NFS $1 +log_delete_export=õÄÁÌÅÎ ÒÅÓÕÒÓ NFS $1 +log_create_share=óÏÚÄÁÎ ÒÅÓÕÒÓ Samba $1 +log_modify_share=éÚÍÅÎÅÎ ÒÅÓÕÒÓ Samba $1 +log_delete_share=õÄÁÌÅÎ ÒÅÓÕÒÓ Samba $1 +log_save=óÏÈÒÁÎÅÎ ÆÁÊÌ $1 +log_chmod=éÚÍÅÎÅÎÙ ÐÒÁ×Á ÎÁ ÆÁÊÌ $1 +log_mkdir=óÏÚÄÁÎ ËÁÔÁÌÏÇ $1 +log_upload=úÁÇÒÕÖÅÎ ÆÁÊÌ $1 +log_link=óÏÚÄÁÎÁ ÓÉÍ×ÏÌØÎÁÑ ÓÓÙÌËÁ $1 ÎÁ $2 +log_relink=éÚÍÅÎÅÎÁ ÓÉÍ×ÏÌØÎÁÑ ÓÓÙÌËÁ $1 ÎÁ $2 +log_copy=óËÏÐÉÒÏ×ÁÎ ÆÁÊÌ $1 × $2 +log_move=ðÅÒÅÍÅÝÅÎ ÆÁÊÌ $1 × $2 +log_delete=õÄÁÌÅÎ ÆÁÊÌ $1 +log_attr=éÚÍÅÎÅÎÙ ÁÔÒÉÂÕÔÙ ÆÁÊÌÁ $1 +log_acl=äÌÑ ÆÁÊÌÁ $1 ÎÁÚÎÁÞÅÎ ACL + +search_eaccess=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÐÏÉÓËÁ × ÜÔÏÍ ËÁÔÁÌÏÇÅ +search_title=ðÏÉÓË ÆÁÊÌÏ× +search_ok=éÓËÁÔØ +search_dir=éÓËÁÔØ × ËÁÔÁÌÏÇÅ +search_match=æÁÊÌÙ ÓÏ×ÐÁÄÁÀÝÉÅ Ó +search_user=ðÒÉÎÁÄÌÅÖÁÝÉÅ ÐÏÌØÚÏ×ÁÔÅÌÀ +search_group=ðÒÉÎÁÄÌÅÖÁÝÉÅ ÇÒÕÐÐÅ +search_any=ìÀÂÏÊ +search_type=ôÉÐ ÆÁÊÌÁ +search_types_=ìÀÂÏÊ +search_types_f=æÁÊÌ +search_types_d=ëÁÔÁÌÏÇ +search_types_l=óÉÍ×ÏÌØÎÁÑ ÓÓÙÌËÁ +search_types_p=éÍÅÎÏ×ÁÎÎÙÊ ËÁÎÁÌ +search_size=òÁÚÍÅÒ ÆÁÊÌÁ +search_more=âÏÌÅÅ +search_less=íÅÎÅÅ +search_xdev=éÓËÁÔØ × ÐÏÄÍÏÎÔÉÒÏ×ÁÎÎÙÈ ÆÁÊÌÏ×ÙÈ ÓÉÓÔÅÍÁÈ? +search_edir=ëÁÔÁÌÏÇ ÄÌÑ ÐÏÉÓËÁ ÎÅ ÕËÁÚÁÎ ÉÌÉ ÕËÁÚÁÎ ÎÅ×ÅÒÎÏ +search_ematch=òÅÇÕÌÑÒÎÏÅ ×ÙÒÁÖÅÎÉÅ ÄÌÑ ÐÏÉÓËÁ ÎÅ ÕËÁÚÁÎÏ ÉÌÉ ÕËÁÚÁÎÏ ÎÅ×ÅÒÎÏ +search_euser=éÍÑ ÐÏÌØÚÏ×ÁÔÅÌÑ ÎÅ ÕËÁÚÁÎÏ ÉÌÉ ÕËÁÚÁÎÏ ÎÅ×ÅÒÎÏ +search_egroup=éÍÑ ÇÒÕÐÐÙ ÎÅ ÕËÁÚÁÎÏ ÉÌÉ ÕËÁÚÁÎÏ ÎÅ×ÅÒÎÏ +search_esize=òÁÚÍÅÒ ÆÁÊÌÁ ÄÏÌÖÅÎ ÂÙÔØ ÃÅÌÙÍ ÞÉÓÌÏÍ +search_crit=ëÒÉÔÅÒÉÊ ÐÏÉÓËÁ +search_list=òÅÚÕÌØÔÁÔÙ ÐÏÉÓËÁ + +facl_eaccess=õ ×ÁÓ ÎÅÄÏÓÔÁÔÏÞÎÏ ÐÒÁ× ÄÌÑ ÉÚÍÅÎÅÎÉÑ ACL ÄÌÑ ÜÔÏÇÏ ÆÁÊÌÁ + +attr_eattrs=îÅ ÕÄÁÌÏÓØ ÓÞÉÔÁÔØ ÁÔÒÉÂÕÔÙ : $1 +attr_efs=æÁÊÌÏ×ÁÑ ÓÉÓÔÅÍÁ $1 ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÁÔÒÉÂÕÔÙ +attr_add=äÏÂÁ×ÉÔØ ÁÔÒÉÂÕÔ +attr_name=îÁÚ×ÁÎÉÅ ÁÔÒÉÂÕÔÁ +attr_value=úÎÁÞÅÎÉÅ ÁÔÒÉÂÕÔÁ +attr_efailed=îÅ ÕÄÁÌÏÓØ ÕÓÔÁÎÏ×ÉÔØ ÁÔÒÉÂÕÔÙ ÄÌÑ $1 : $2 +attr_title=áÔÒÉÂÕÔÙ ÆÁÊÌÁ ÄÌÑ $1 +attr_create=äÏÂÁ×ÉÔØ ÁÔÒÉÂÕÔ +attr_edit=éÚÍÅÎÉÔØ ÁÔÒÉÂÕÔ +attr_ename=îÅ ÕËÁÚÁÎÏ ÎÁÚ×ÁÎÉÅ ÁÔÒÉÂÕÔÁ + +ext_eattrs=îÅ ÕÄÁÌÏÓØ ÐÏÌÕÞÉÔØ ÁÔÒÉÂÕÔÙ EXT : $1 +ext_efs=æÁÊÌÏ×ÁÑ ÓÉÓÔÅÍÁ $1 ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ ÁÔÒÉÂÕÔÙ EXT +ext_title=áÔÒÉÂÕÔÙ EXT ÄÌÑ $1 +ext_header=áÔÒÉÂÕÔÙ EXT ÆÁÊÌÁ +ext_efailed=îÅ ÕÄÁÌÏÓØ ÕÓÔÁÎÏ×ÉÔØ ÁÔÒÉÂÕÔÙ EXT $1 : $2 + +eattr_A=îÅ ÏÂÎÏ×ÌÑÔØ ×ÒÅÍÑ ÄÏÓÔÕÐÁ +eattr_a=÷ÏÚÍÏÖÎÏ ÔÏÌØËÏ ÄÏÂÁ×ÌÅÎÉÅ Ë ÆÁÊÌÕ +eattr_c=óÖÉÍÁÔØ ÄÁÎÎÙÅ ÎÁ ÄÉÓËÅ +eattr_d=îÅ ÐÒÏÉÚ×ÏÄÉÔØ ÒÅÚÅÒ×ÎÏÅ ËÏÐÉÒÏ×ÁÎÉÅ Ó ÐÏÍÏÝØÀ dump +eattr_i=úÁÐÒÅÔÉÔØ ÉÚÍÅÎÅÎÉÅ +eattr_s=ïÂÎÕÌÑÔØ ÂÌÏËÉ ÐÒÉ ÕÄÁÌÅÎÉÉ +eattr_S=÷ÓÅÇÄÁ ÓÉÎÈÒÏÎÉÚÉÒÏ×ÁÔØ ÐÏÓÌÅ ÚÁÐÉÓÉ +eattr_u=óÏÈÒÁÎÑÔØ ÓÏÄÅÒÖÉÍÏÅ ÆÁÊÌÁ ÄÌÑ ×ÏÓÓÔÁÎÏ×ÌÅÎÉÑ + diff --git a/file/lang/sk b/file/lang/sk new file mode 100644 index 000000000..58a4ffd1f --- /dev/null +++ b/file/lang/sk @@ -0,0 +1,297 @@ +index_title=Správca Systému Súborov +index_eremote=Žiadny Unixový užívateľ nezodpovedá hodnotám z Webmin prihlásečnia $1. +switch_euser=Tento Unixový užívateľ nejestvuje! + +top_ret=Index +top_down=Ulož +top_edit=Otvor pre zmeny +top_refresh=Obnov +top_info=Info +top_eacl=ACL +top_attr=Atribúty +top_ext=EXT +top_delete=Vymaž +top_new=Nový(á/é) +top_upload=Nalož +top_rename=Premenuj +top_copy=Kópia +top_cut=Vyber +top_paste=Vlož +top_share=Zdieľanie +top_search=Nájdi + +right_name=Meno +right_size=Veľkosť +right_user=Užívateľ +right_group=Skupina +right_date=Dátum + +edit_enormal=Len normálne súbory môžu byť menené +edit_title=Zmeny na $1 +edit_title2=Vytvánie súboru +edit_filename=Meno súboru: +edit_eover=$1 nemôže byť prepísané +edit_esave=NEmoohol uložiť : $1 +edit_eaccess=Nemáš povolenie na ukladanie '$1' + +info_file=Súbor +info_path=Cesta: +info_type=Typ: +info_size=Veľkosť: +info_mod=Zmenené: +info_link=Vázba na: +info_perms=Povolenia +info_user=Užívateľ: +info_group=Skupina: +info_other=Iné: +info_sticky=Lepčkavé: +info_sticky2=Len majitelia môžu vymazať +info_own=Majetok +info_setuid=Setuid: +info_setuid2=Vykonaj ako užívateľ +info_setgid=Setgid: +info_setgid2=Súbory dedia skupinu +info_setgid3=Vykonaj ako skupina +info_apply=AKtivuj zmeny +info_apply1=Len tento adresár +info_apply2=Tento adresár a jeho súbory +info_apply3=Tento adresár a všetky jeho priradené adresáre +info_efailed=Porucha pri zmene $1 : $2 +info_read=Čítaj +info_write=Píš +info_list=Zoznam +info_exec=Exec + +eacl_eacls=Načítavanie ACL súborov nebolo úspešné : $1 +eacl_acltype=Typ ACL +eacl_aclname=Použi na +eacl_aclperms=Povolenia +eacl_add=Pridaj typ ACL : +eacl_remove=Odním ACL +eacl_efs=Súborový systém $1 plne nepodporuje ACLs +eacl_create=Vytvor ACL +eacl_edit=Edituj ACL +eacl_user=Majiteľ súboru $1 +eacl_group=Skupina súboru $1 +eacl_eowner=Užívateľ alebo skupina súboru neexistuje +eacl_efailed=Nemohol som nastaviť ACL pre $1 : $2 +eacl_emask=Maximálne môže byť použitá jedna maskovaná ACL +eacl_edefmask=Maximálne môže byť použitá jedna základná maskovaná ACL +eacl_title=ACL pre $1 +eacl_owner=Majiteľ súboru +eacl_edefaults=Ak súbor má základnú ACL, musí tiež mať základného majiteľa, skupinu a ostatné ACL. + +acltype_user=Užívateľ +acltype_group=Skupina +acltype_other=Iné +acltype_mask=Maska +acltype_default_user=Základný užívateľ +acltype_default_group=Základná skupina +acltype_default_other=Základné Iné +acltype_default_mask=Základná Maska + +delete_mtitle=Vymaž viacero súborov +delete_dtitle=Vymaž adresár +delete_ftitle=Vymaž súbor +delete_ddesc=Si si istý že chceš permanente vymazať adresár $1 a všetok jeho obsah? +delete_fdesc=Si si istý že chceš permanente vymazať súbor $1 ? +delete_mdesc=Si si istý že chceš permanente vymazať adresáre a súbory? : +delete_efailed=Nemožné vymazať $1 : $2 + +mkdir_title=Novo-vytvorený Adresár +mkdir_dir=Nový Adresár: +mkdir_eexists=$1 už jestvuje +mkdir_efailed=Vytvorenie Adresáru nebolo úspešné : $1 +mkdir_eaccess=Nemáš povolenie na vytvorenie '$1' + +link_title=Vytvor Spojenie +link_from=Spojenie z: +link_to=Spojenie na: +link_eexists=$1 už jestvuje +link_efailed=Spojenie nebolo úspešné : $1 +link_efrom=Nemáš dovolené vytvárať spojenia na '$1' +link_efollow=Nemáš dostatočné povolenie na vytváranie symbolických spojení + +rename_title=Premenuj $1 +rename_old=Pôvodné meno: +rename_new=Nové meno: +rename_ok=Premenuj +rename_eexists=Súbor s menom $1 už jestvuje +rename_efailed=Premenovávanie nebolo úspešné : $1 +rename_eold=Nemáš dovolené premenovávať '$1' +rename_enew=Nemáš dovolené premenovávať na '$1' + +file_type0=Adresár +file_type1=Textový súbor +file_type2=Obrázok +file_type3=Binarny súbor +file_type4=Súbor +file_type5=Symbolické spojenie +file_type6=Súbor ovládača +file_type7=Rúrka + +view_enormal=Len normálne súbory môžu byť prezerané +view_enormal2=Len normálne súbory môžu byť sťahované +view_eaccess=Nemáš povolený prístup k $1 +view_eopen=Otvorenie nebolo úspešné $1 : $2 + +paste_ecopy=Musíš najprv vybrať alebo skopírovať ak chceš vkladať +paste_egone=Súbor kopírovaný $1 už neexiststuje +paste_eover=$1 nemôže byť prepísaný +paste_eself=Nemôžeš vkladať súbor do adresára so súborom s rovnakým menom +paste_emfailed=Premiestnenie nebolo úspešné : $1 +paste_ecfailed=Vytváranie kópie nebolo úspešné : $1 + +over_title=Súbor už Existstuje +over_msg=Súbor $1 už existstuje. Použi políčko nižšie na premenovanie vkladaného súboru. +over_new=Nové meno súboru: +over_ok=Ok + +upload_efailed=Naložený súbor : $1 sa nepodarilo otvoriť +upload_title=Nalož súbor +upload_file=Súbor pre nakladanie +upload_dir=Nalož do adresára +upload_ok=Nalož +upload_conv=Kovertuj DOS-ové symboly pre nový riadok? +upload_efile=Nebol vybratý žiaden súbor na nakladanie. +upload_edir=Adresár na nakladanie neexistuje. +upload_eperm=You are not allowed to create $1 +upload_ewrite=Failed to write to $1 : $2. + +find_eaccess=You are not allowed to access $1 +find_eexist=$1 does not exist in $2 +find_edir=$1 is not a directory in $2 + +cancel=Zruš + +chmod_eaccess=You are not allowed to access '$1' +chmod_euser=$1 : no such user +chmod_egroup=$1 : no such group +chmod_elink=symlink failed : $1 +chmod_echown=chown failed : $1 +chmod_echmod=chmod failed : $1 +chmod_efollow=You are not allowed to edit symbolic links + +copy_efrom=You are not allowed to copy from '$1' +copy_eto=You are not allowed to copy to '$1' +copy_elink=symlink failed : $1 + +delete_eaccess=You are not allowed to delete '$1' + +list_eaccess=You are not allowed to access this directory +list_edir=Failed to list $1 : $2 + +move_eto=You are not allowed to move to '$1' +move_afrom=You are not allowed to move '$1' + +acl_user=Access files on server as user +acl_user_def=Same as Webmin login +acl_umask=Umask for new files +acl_follow=Always follow symlinks? +acl_ro=Read-only mode? +acl_dirs=Only allow access to directories +acl_home=Include home directory of Webmin user +acl_log=Log all file modifications? +acl_goto=Open first allowed directory? + +share_title=Sharing +share_samba=Windows +share_nfs=NFS +share_son=Windows file sharing enabled +share_soff=Windows file sharing disabled +share_writable=Writable? +share_available=Currently active? +share_sheader=Sharing options +share_only=Only +share_guest=Guest access? +share_comment=Comment +share_nheader=NFS export options +share_non=NFS file sharing enabled +share_noff=NFS file sharing disabled +share_desc=Description +share_ro=Read-only hosts +share_rw=Read-write hosts +share_root=Root access hosts +share_none=None +share_all=All +share_listed=Listed.. +share_host=Hosts +share_opts=Options +share_s0=Trust nobody +share_s1=Trust non-root +share_s2=Trust everybody +share_lro=Read-only +share_lrw=Read-write + +log_create_export=Created NFS export $1 +log_modify_export=Modified NFS export $1 +log_delete_export=Deleted NFS export $1 +log_create_share=Created Samba share $1 +log_modify_share=Modified Samba share $1 +log_delete_share=Deleted Samba share $1 +log_save=Saved file $1 +log_chmod=Changed permissions on file $1 +log_mkdir=Created directory $1 +log_upload=Uploaded file $1 +log_link=Created symbolic link $1 to $2 +log_relink=Modified symbolic link $1 to $2 +log_copy=Copied file $1 to $2 +log_move=Moved file $1 to $2 +log_delete=Deleted file $1 +log_attr=Set attributes on file $1 +log_acl=Set ACL on file $1 + +search_eaccess=You are not allowed to search this directory +search_title=Find files +search_ok=Search Now +search_dir=Search directory +search_match=For files matching +search_user=Owned by user +search_group=Owned by group +search_any=Any +search_type=File type +search_types_=Any +search_types_f=File +search_types_d=Directory +search_types_l=Symbolic link +search_types_p=Named pipe +search_size=File size +search_more=More than +search_less=Less than +search_xdev=Search past mounts? +search_edir=Missing or invalid search directory +search_ematch=Missing matching regexp +search_euser=Missing username +search_egroup=Missing group name +search_esize=File size must be an integer +search_crit=Search criteria +search_list=Search results + +facl_eaccess=You are not allowed to set ACLs for this file + +attr_eattrs=Failed to get attributes : $1 +attr_efs=The filesystem $1 does not support attributes +attr_add=Add Attribute +attr_name=Attribute Name +attr_value=Attribute Value +attr_efailed=Failed to set attributes for $1 : $2 +attr_title=File Attributes for $1 +attr_create=Add Attribute +attr_edit=Edit Attribute +attr_ename=Missing attribute name + +ext_eattrs=Failed to get EXT attributes : $1 +ext_efs=The filesystem $1 does not support EXT attributes +ext_title=EXT attributes for $1 +ext_header=EXT file attributes +ext_efailed=Failed to set attributes for $1 : $2 + +eattr_A=Do not update access times +eattr_a=Can only append to file +eattr_c=Compress data on disk +eattr_d=Do not backup with dump +eattr_i=Do not allow modification +eattr_s=Zero blocks when deleting +eattr_S=Always sync after writing +eattr_u=Save contents for undeletion + diff --git a/file/lang/sv b/file/lang/sv new file mode 100644 index 000000000..14a203ada --- /dev/null +++ b/file/lang/sv @@ -0,0 +1,153 @@ +index_title=Filhanterare +index_nojava=Denna modul behöver java för att fungera, men din läsare stödjer inte java + +top_open=Öppna +top_view=Visa +top_edit=Ändra +top_refresh=Uppdatera +top_info=Info +top_delete=Ta bort +top_new=Ny +top_upload=Ladda in +top_rename=Byt namn +top_copy=Kopiera +top_cut=Klipp ut +top_paste=Klistra in + +right_name=Namn +right_size=Storlek +right_user=Användare +right_group=Grupp +right_date=Datum + +edit_enormal=Du kan bara ändra standardfiler +edit_title=Ändrar i $1 +edit_title2=Skapar fil +edit_filename=Filnamn: +edit_eover=$1 får inte skrivas över +edit_esave=Det gick inte att spara filen: $1 +edit_eaccess=Du får inte spara filen '$1' + +info_file=Fil +info_path=Sökväg: +info_type=Typ: +info_size=Storlek: +info_mod=Ändrad: +info_link=Länk till: +info_perms=Rättigheter +info_user=Användare: +info_group=Grupp: +info_other=Övriga: +info_sticky=Sticky: +info_sticky2=Det är bara ägare som får ta bort filer +info_own=Ägare +info_setuid=Setuid: +info_setuid2=Utför som användare +info_setgid=Setgid: +info_setgid2=Filer ärver grupp +info_setgid3=Utför som grupp +info_apply=Utför ändringarna på +info_apply1=Endast denna katalog +info_apply2=Denna katalog och filerna i den +info_apply3=Denna katalog och dess underkataloger +info_efailed=Det gick inte att uppdatera $1 : $2 +info_read=Läs +info_write=Skriv +info_list=Lista +info_exec=Exec + +delete_dtitle=Ta bort katalog +delete_ftitle=Ta bort fil +delete_ddesc=Vill du verkligen ta bort katalogen $1 med innehåll permanent? +delete_fdesc=Vill du verkligen ta bort filen $1 permanent? +delete_efailed=Det gick inte att ta bort $1 : $2 + +mkdir_title=Ny katalog +mkdir_dir=Ny katalog: +mkdir_eexists=$1 finns redan +mkdir_efailed=Det gick inte att skapa katalogen: $1 +mkdir_eaccess=Du får inte skapa '$1' + +link_title=Skapa länk +link_from=Länk från: +link_to=Länk till: +link_eexists=$1 finns redan +link_efailed=Det gick inte att länka: $1 +link_efrom=Du får inte länka från '$1' +link_efollow=Du får inte skapa symboliska länkar + +rename_title=Byt namn på $1 +rename_old=Gammalt namn: +rename_new=Nytt namn: +rename_ok=Byt namn +rename_eexists=Det finns redan en fil som heter $1 +rename_efailed=Det gick inte att byta namn: $1 +rename_eold=Du får inte byta namn på '$1' +rename_enew=Du får inte byta namn till '$1' + +file_type0=Katalog +file_type1=Textfil +file_type2=Bildfile +file_type3=Binärfil +file_type4=Fil +file_type5=Symbolisk länk +file_type6=Device-fil +file_type7=Pipe + +view_enormal=Endast normala filer kan visas +view_eaccess=Du får inte komma åt $1 +view_eopen=Det gick inte att öppna $1: $2 + +paste_ecopy=Något måste klippas ut eller kopieras för att du ska kunna klistra in +paste_egone=Den kopierade filen $1 finns inte längre +paste_eover=$1 får inte skrivas över +paste_eself=En fil får inte klistras in över sig själv +paste_emfailed=Det gick inte att flytta: $1 +paste_ecfailed=Det gick inte att kopiera: $1 + +over_title=Filen finns +over_msg=Filen $1 finns redan. Skriv in ett nytt filnamn för den inklistrade filen i fältet nedan. +over_new=Nytt filnamn: +over_ok=OK + +upload_efailed=Det gick inte att sätta igång nedladdningen: $1 +upload_title=Ladda ned fil +upload_file=Fil att ladda ned +upload_dir=Ladda ned till katalog +upload_ok=Ladda ned +upload_conv=Konvertera DOS-radbrytningar? +upload_efile=Du har inte valt någon fil som ska laddas ned. +upload_edir=Du har inte valt någon katalog att ladda ned till. +upload_eperm=Du får inte skapa $1 +upload_ewrite=Det gick inte att skriva till $1: $2. + +find_eaccess=Du får inte komma åt $1 +find_eexist=$1 finns inte i $2 +find_edir=$1 är inte en katalog i $2 + +cancel=Avbryt + +chmod_eaccess=Du får inte komma åt '$1' +chmod_euser=$1 :användaren finns inte +chmod_egroup=$1 :gruppen finns inte +chmod_elink=symlink misslyckades: $1 +chmod_echown=chown misslyckades: $1 +chmod_echmod=chmod misslyckades: $1 + +copy_efrom=Du får inte kopiera från '$1' +copy_eto=Du får inte kopiera till '$1' +copy_elink=symlink misslyckades: $1 + +delete_eaccess=Du får inte ta bort '$1' + +list_eaccess=Du får inte komma åt denna katalog +list_edir=Det gick inte att lista $1: $2 + +move_eto=Du får inte flytta filer till '$1' +move_afrom=Du får inte flytta på '$1' + +acl_user=Kom åt filer på servern som användare +acl_umask=Umask för nya filer +acl_follow=Ska symboliska länkar alltid följas? +acl_dirs=Tillåt endast åtkomst till kataloger + diff --git a/file/lang/tr b/file/lang/tr new file mode 100644 index 000000000..c5891070e --- /dev/null +++ b/file/lang/tr @@ -0,0 +1,290 @@ +acl_archive=Dizinlerin arþivlerini indirebilir mi? +acl_archmax=Evet, bundan daha küçükse +acl_b=byte +acl_button_acl=ACL (Posix ACL düzenle) +acl_button_copy=Kopyala, Kes ve Yapýþtýr +acl_button_delete=Sil (dosyalarý sil) +acl_button_edit=Düzenle (metin dosyasýný düzenle) +acl_button_info=Bilgi (dosya izinlerini ve sahipliðini düzenle) +acl_button_makelink=Yeni (sembolink link oluþtur) +acl_button_mkdir=Yeni (dizin oluþtur) +acl_button_mount=Mount (dosya sistemini mount et ya da umount et) +acl_button_new=Yeni (metin dosyasý oluþtur) +acl_button_rename=Yeniden Adlandýr (dosyayý yeniden adlandýr) +acl_button_save=Kaydet (dosya indir) +acl_button_search=Bul (dosya bul) +acl_button_sharing=Paylaþtýrma (Samba ve NFS dosya paylaþýmýný ayarla) +acl_button_upload=Yükle (istemciden dosya yükle) +acl_buttons=Araç çubuðundaki eriþilebilir butonlar +acl_chroot=Dosya yöneticisinin tamamý için chroot dizini +acl_dirs=Sadece bu dizinlere eriþime izin ver +acl_follow=Sembolik linkler her zaman takip edilsin mi? +acl_log=Bütün dosya deðiþikliklerinin kayýtlarý tutulsun mu? +acl_max=Maksimum yükleme boyutu +acl_ro=Sadece okunabilir mod? +acl_umask=Yeni dosyalar için umask +acl_unarchive=Yüklenen arþiv dosyalarýný açabilir mi? +acl_unarchive0=$no +acl_unarchive1=$yes +acl_unlim=Limitsiz +acl_user=Sunucudaki dosyalara bu kullanýcý olarak ulaþ : +acl_user_def=Webmin kullanýcý adý ile ayný +acltype_default_group=Öntanýmlý Grup +acltype_default_mask=Öntanýmlý Mask +acltype_default_user=Öntanýmlý Kullanýcý +acltype_group=Grup +acltype_mask=Mask +acltype_other=Diðerleri +acltype_user=Kullanýcý +cancel=Ýptal +chmod_eaccess='$1'e eriþim için izininiz yoktur +chmod_echmod=chmod'da hata oluþtu : $1 +chmod_echown=chown'da hata oluþtu : $1 +chmod_efollow=Sembolink linkleri düzenlemek için izininiz yoktur +chmod_egroup=$1 : böyle bir grup yok +chmod_elink=Sembolik linkte hata oluþtu : $1 +chmod_euser=$1 : böyle bir kullanýcý yok +close=Kapat +copy_efrom='$1'den kopyalamanýza izin verilmemiþtir +copy_elink=Sembolik linkte hata oluþtu : $1 +copy_eto='$1'e kopyalamanýza izin verilmemiþtir +ddir_rusure=$1 'in içeriðini bir arþiv dosyasý olarak indirmek için, aþaðýdaki arþiv tipi butonlarýndan birini týklayýnýz. +ddir_tar=TAR +ddir_tgz=TAR.GZ +ddir_title=Ýndirme Dizini +ddir_zip=ZIP +delete_ddesc=$1 dizinini ve içindekileri silmek istediðinizden emin misiniz? +delete_dtitle=Dizin Sil +delete_eaccess='$1'i silmede hata oluþtu +delete_efailed=$1'i silme iþleminde hata oluþtu : $2 +delete_fdesc=$1 dosyasýný kalýcý olarak silmek istediðinizden emin misiniz? +delete_ftitle=Dosya sil +delete_mdesc=Bu dosya ve dizinleri kalýcý olarak silmek istediðinizden emin misiniz? : +delete_mtitle=Birden fazla dosya sil +eacl_aclperms=Ýzinler +eacl_acltype=ACL Tipi +eacl_create=ACL Oluþtur +eacl_eacls=ACL'lerin okunmasýnda hata oluþtu : $1 +eacl_edefaults=Eðer bir dosyanýn öntanýmlý ACL'si varsa bu dosya öntanýmlý kullanýcý, grup ve diðer ACL'lere de sahip olmalýdýr. +eacl_edit=ACL Düzenle +eacl_efs=$1 dosya sistemi ACL'leri desteklemiyor +eacl_group=Dosya grubu $1 +eacl_owner=Dosya sahibi +eacl_remove=ACL Sil +eacl_user=Dosya sahibi $1 +eattr_A=Eriþim zamanlarýný güncelleme +eattr_S=Yazmadan sonra her zaman senkronize et +eattr_a=Dosyaya sadece ekleme yapýlabilir +eattr_c=Diskteki veriyi sýkýþtýr +eattr_d=Dump ile yedekleme +eattr_i=Deðiþtirilmesine izin verme +ebutton=Bu özellik kullanýlamaz +edit_all=Hepsini deðiþtir +edit_eaccess='$1'e kaydedilmesine izininiz yoktur +edit_efollow=Sembolink link '$1'e yazmak için izininiz yoktur +edit_enormal=Sadece normal dosyalar düzenlenebilir +edit_eover=$1 üzerine yazýlamaz +edit_esave=Dosyanýn kaydedilmesinde hata oluþtu : $1 +edit_filename=Dosya Ýsmi: +edit_find=Bul +edit_goto=Git +edit_gotoline=Satýra git +edit_notfound=$1 metini bulunamadý +edit_replace=Deðiþtir +edit_replaceby=Bununla deðiþtir +edit_saveclose=Kaydet & Kapat +edit_title=$1 düzenleniyor +edit_title2=Dosya oluþturuluyor +eopen=Ýndirmede hata : $1 +facl_eaccess=Bu dosyanýn ACL'lerini belirlemek için izininiz yoktur +file_type0=Dizin +file_type1=Metin Dosyasý +file_type2=Resim Dosyasý +file_type3=Ýkili Dosya +file_type4=Dosya +file_type5=Sembolik Link +file_type6=Aygýt dosyasý +file_type7=Pipe +find_eaccess=$1'e eriþim izininiz yoktur +find_edir=$1, $2'de bir dizin deðil +find_eexist=$1, $2 içinde mevcut deðil +index_eremote=Webmin kullanýcýsý $1 ile eþleþen Unix kullanýcýsý yok. +index_nojava=Bu modül java gerektirir, fakat sizin tarayýcýnýz java'yi desteklemiyor +index_title=Dosya Yöneticisi +info_apply=Deðiþiklikleri uygula ... +info_apply1=Sadece bu dizine +info_apply2=Bu dizin ve dosyalarýna +info_apply3=Bu dizin ve alt dizinlerine +info_efailed=Güncellemede hata oluþtu $1 : $2 +info_exec=Çalýþtýr +info_file=Dosya +info_group=Grup: +info_link=Link to: +info_list=Listele +info_mod=Deðiþtirildi: +info_octal=Sekizli: +info_other=Diðerleri: +info_own=Sahiplik +info_path=Yol: +info_perms=Ýzinler +info_read=Oku +info_setgid=Setgid: +info_setgid2=Dosyalar grubun olsun +info_setgid3=Grup olarak çalýþtýr +info_setuid=Setuid: +info_setuid2=Kullanýcý olarak çalýþtýr +info_size=Boyut: +info_sticky=Sticky: +info_sticky2=Dosyalarý sadece sahipleri silebilir +info_type=Tip: +info_user=Kullanýcý: +info_write=Yaz +link_eexists=$1 zaten mevcut +link_efailed=Link yapýlýrken hata oluþtu : $1 +link_efollow=Sembolik link oluþturmak için izininiz yoktur +link_efrom=Link kaynaðý tam olarak verilmelidir +link_efrom2='$1'den link yapmak için izininiz yoktur +link_from=Link buradan: +link_title=Link Oluþtur +link_to=Buraya link oluþtur: +list_eaccess=Bu dizine eriþim izininiz yoktur +log_chmod=$1 dosyasýnýn haklarý deðiþtirildi +log_copy=$1 dosyasý $2'ye kopyalandý +log_create_export=NFS sunumu $1 oluþturuldu +log_create_share=Samba paylaþýmý $1 oluþturuldu +log_delete=$1 dosyasý silindi +log_delete_export=NFS sunumu $1 silindi +log_delete_share=Samba paylaþýmý $1 silindi +log_link=$2'ye sembolik link $1 oluþturuldu +log_mkdir=$1 dizini oluþturuldu +log_modify_export=NFS sunumu $1 deðiþtirildi +log_modify_share=Samba paylaþýmý $1 deðiþtirildi +log_move=$1 dosyasý $2'ye taþýndý +log_relink=$2'ye sembolik link $1 deðiþtirildi +log_save=$1 dosyasý kaydedildi +log_upload=$1 dosyasý yüklendi +mkdir_dir=Yeni dizin: +mkdir_eaccess='$1' dizini oluþturmaya hakkýnýz yok +mkdir_eexists=$1 dizini mevcut +mkdir_efailed=Dizin oluþturmada hata oluþtu : $1 +mkdir_title=Yeni Dizin +mount_eaccess=Dosya sistemini mount etmek için izininiz yoktur +mount_efstab=Bu mount noktasýnda bir dosya sistemi mevcut deðildir +mount_epoint=$1 bir mount noktasý deðildir +mount_err1=$1 'in mount edilmesinde hata oluþtu : $2 +mount_err2=$1 'in umount edilmesinde hata oluþtu : $2 +mount_rusure1=$1 'i $2 'ye mount etmek istediðinize emin misiniz ? +mount_rusure2=$1 'i $2 'den umount etmek istediðinize emin misiniz ? +mount_title1=Dosya sistemi mount et +mount_title2=Dosya sistemi umount et +move_afrom='$1'i taþýmak için izininiz yoktur +move_eto='$1'e taþýmak için izininiz yoktur +over_msg=$1 dosyasý zaten mevcut. Yapýþtýrýlan dosyaya yeni bir isim girmek için aþaðýdaki alaný kullanýnýz. +over_new=Yeni dosya ismi: +over_ok=Tamam +over_title=Dosya Mevcut +paste_ecfailed=Kopyalamada hata oluþtu : $1 +paste_ecopy=Yapýþtýrmadan önce kopyalamalý veya kesmelisiniz +paste_egone=Kopyalanan dosya $1 artýk yok +paste_emfailed=Taþýmada hata oluþtu : $1 +paste_eover=$1 üzerine yazýlamaz +paste_eself=Dosyayý kendi üzerine yapýþtýramazsýnýz +rename_eexists=$1 dosyasý zaten mevcut +rename_efailed=Yeniden adlandýrmada hata oluþtu : $1 +rename_enew='$1' olarak yeniden adlandýrmak için izininiz yoktur +rename_eold='$1'i yeniden adlandýrmak için izininiz yoktur +rename_new=Yeni Ýsim: +rename_ok=Yeniden Adlandýr +rename_old=Eski Ýsim: +rename_title=Yeniden Adlandýr $1 +right_date=Tarih +right_group=Grup +right_name=Ýsim +right_size=Boyut +right_user=Kullanýcý +search_crit=Armama kriteri +search_dir=Arama dizini +search_eaccess=Bu dizinde arama yapmak için izininiz yoktur +search_edir=Eksik ya da geçersiz arama dizini +search_egroup=Grup adý girilmemiþ +search_esize=Dosya boyutu bir tamsayý olmalýdýr +search_euser=Kullanýcý adý girilmemiþ +search_list=Arama sonuçlarý +search_ok=Þimdi Ara +search_size=Dosya boyutu +search_title=Dosya bul +search_type=Dosya tipi +search_types_=Hepsi +search_types_d=Dizin +search_types_f=Dosya +search_types_l=Sembolink link +share_all=Hepsi +share_available=Aktif mi? +share_comment=Yorum +share_desc=Açýklama +share_guest=Ziyaretçi eriþimi? +share_host=Makineler +share_listed=Listeli... +share_lro=Sadece okunur +share_lrw=Okunur-yazýlýr +share_nfs=NFS +share_nheader=NFS sunum seçenekleri +share_noff=NFS dosya paylaþýmý kapalý +share_non=NFS dosya paylaþýmý açýk +share_none=Hiçbiri +share_only=Sadece +share_opts=Seçenekler +share_ro=Sadece okuma izinli makineler +share_root=Root giriþli makineler +share_rw=Okuma-yazma izinli makineler +share_s0=Hiçkimseye güvenme +share_s1=Root olmayanlara güven +share_s2=Herkese güven +share_samba=Windows +share_sheader=Paylaþým seçenekleri +share_soff=Windows dosya paylaþýmý kapalý +share_son=Windows dosya paylaþýmý açýk +share_title=Paylaþtýrma +share_writable=Yazýlabilir? +switch_euser=Unix kullanýcýsý mevcut deðil! +top_config=Yapýlandýrma +top_copy=Kopyala +top_cut=Kes +top_delete=Sil +top_down=Kaydet +top_eacl=ACL +top_edit=Düzenle +top_ext=EXT +top_info=Bilgi +top_mount=Mount +top_new=Yeni +top_paste=Yapýþtýr +top_refresh=Yenile +top_rename=Yeniden Adlandýr +top_ret=Ýndeks +top_search=Ara +top_share=Paylaþtýrma +top_upload=Yükleme +upload_already=$1 dosyasý zaten mevcut. Üzerine yazmak istediðinizden emin misiniz? +upload_conv=DOS satýrlarý çevirilsin mi? +upload_dir=Dizine Yükle +upload_edir=Yükleme dizini mevcut deðil +upload_efailed=Dosyanýn yüklenmesinde hata oluþtu : $1 +upload_efile=Yüklenecek dosya seçilmedi. +upload_eperm=$1 oluþturmanýza izin verilmedi +upload_ewrite=$1'i yazmada hata oluþtu : $2. +upload_file=Yüklenecek dosya +upload_ok=Yükle +upload_title=Dosyayý Yükle +upload_zip=ZIP ya da TAR dosyasý açýlsýn mý? +view_eaccess=$1'e eriþim izininiz yoktur +view_earchive=Arþivleri indirmek için izininiz yoktur +view_earchmax=Seçili dizin arþivleme için izin verilen maksimum boyuttan ($1 byte) daha büyük +view_ecomp=Arþiv oluþturulmasýnda hata oluþtu : $1 +view_edir=Bir arþiv sadece bir dizin için oluþturulabilir +view_enormal=Sadece normal dosyalar görüntülenebilir +view_enormal2=Sadece normal dosyalar indirilebilir +view_eopen=$1 'in açýlmasýnda hata oluþtu : $2 +zip_ename=Bir zip, tar ya da tar.gz gibi görünmüyor +zip_err=Dosya açýlamýyor : $1 +zip_euntar=Tar dosyasýnýn açýlmasýnda hata oluþtu : $1 diff --git a/file/lang/tr.bak b/file/lang/tr.bak new file mode 100644 index 000000000..b3cf5ad4a --- /dev/null +++ b/file/lang/tr.bak @@ -0,0 +1,198 @@ +index_title=Dosya Yöneticisi +index_nojava=Bu modül java gerektirir, fakat sizin tarayýcýnýz java'yi desteklemiyor + +top_open=Aç +top_view=Göster +top_edit=Deðiþtir +top_refresh=Yenile +top_info=Bilgi +top_delete=Sil +top_new=Yeni +top_upload=Yükleme(Upload) +top_rename=Yeniden Adlandýr +top_copy=Kopyala +top_cut=Kes +top_paste=Yapýþtýr +top_share=Paylaþtýr + +right_name=Ad +right_size=Boyut +right_user=Kullanýcý +right_group=Grup +right_date=Tarih + +edit_enormal=Sadece normal dosyalar deðiþtirilebilir +edit_title=$1 deðiþtiriliyor +edit_title2=Dosya oluþturuluyor +edit_filename=Dosya Ýsmi: +edit_eover=$1 üzerine yazýlamaz +edit_esave=Dosyanýn kaydedilmesinde hata oluþtu : $1 +edit_eaccess='$1' kaydedilmesine izininiz yoktur + +info_file=Dosya +info_path=Yol: +info_type=Tip: +info_size=Boyut: +info_mod=Deðiþtirildi: +info_link=Link to:##### +info_perms=Haklar +info_user=Kullanýcý: +info_group=Grup: +info_other=Diðerleri: +info_sticky=Sticky: +info_sticky2=Dosyalarý sadece sahipleri silebilir +info_own=Sahiplik +info_setuid=Uid'yi belirt: +info_setuid2=Kullanýcý Olarak Çalýþtýr +info_setgid=Gid'yi Oluþtur: +info_setgid2=Dosyalar grubun olsun +info_setgid3=Grup olarak çalýþtýr +info_apply=Deðiþiklikleri uygula ... +info_apply1=Sadece bu dizine +info_apply2=Bu dizin ve dosyalarýna +info_apply3=Bu dizin ve alt dizinlerine +info_efailed=Güncellemede hata oluþtu $1 : $2 +info_read=Oku +info_write=Yaz +info_list=Listele +info_exec=Çalýþtýr + +delete_dtitle=Dizin Sil +delete_ftitle=Dosya Sil +delete_ddesc=$1 dizinini ve içindekileri silmek istediðinizden eminmisiniz? +delete_fdesc=$1 dizinini silmek istediinizden eminmisiniz? +delete_efailed=Silme iþleminde hata oluþtu $1 : $2 + +mkdir_title=Yeni Dizin +mkdir_dir=Yeni dizin: +mkdir_eexists=$1 dizini mevcut +mkdir_efailed=Dizin oluþturmada hata oluþtu : $1 +mkdir_eaccess='$1' dizini oluþturmaya hakkýnýz yok + +link_title=Link Oluþtur +link_from=Link buradan: +link_to=Link buraya: +link_eexists=$1 her zaman mevcut +link_efailed=Link oluþturulurken hata oluþtu : $1 +link_efrom='$1' den link oluþturmaya hakkýnýz yoktur +link_efollow=Sembolik linkler oluþturmaya hakkýnýz yoktur + +rename_title=Yeniden Adlandýr $1 +rename_old=Eski Ýsmi: +rename_new=Yeni Ýsmi: +rename_ok=Yeniden Adlandýr +rename_eexists=$1 dosyasý her zaman mevcut +rename_efailed=Yeniden adlandýrmada hata oluþtu : $1 +rename_eold='$1'i yeniden adlandýrmaya hakkýnýz yoktur +rename_enew='$1' olarak yeniden adlandyrmaya hakkynyz yoktur + +file_type0=Dizin +file_type1=Yazý Dosyasý +file_type2=Resim Dosyasý +file_type3=Ýkili Dosya +file_type4=Dosya +file_type5=Sembolik Link +file_type6=Araç Dosyasý +file_type7=Boru + +view_enormal=Sadece normal dosyalar görüntülenebilir +view_eaccess=$1'e eriþime hakkýnýz yoktur +view_eopen=Açma iþleminde hata oluþtu $1 : $2 + +paste_ecopy=Yapýþtýrmadan önce kopyalamalý veya kesmelisiniz +paste_egone=Kopyalanan dosya $1 artýk yok +paste_eover=$1 üzerine yazýlamaz +paste_eself=Dosyayý kendi üzerine yapýþtýramazsýnýz +paste_emfailed=Taþýmada hata oluþtu : $1 +paste_ecfailed=Kopyalamada hata olutu : $1 + +over_title=Dosya Mevcut +over_msg=$1 dosyasý her zaman mevcut. Yapýþtýrýlan dosyaya yeni bir isim girmek için boþ formu kullanýnýz. +over_new=Yeni dosya ismi +over_ok=Tamam + +upload_efailed=Dosyanýn yüklenmesinde hata oluþtu : $1 +upload_title=Dosyayý Yükle +upload_file=Yüklecek Dosya +upload_dir=Dizine Yükleme +upload_ok=Yükle +upload_conv=DOS satýrlarý çevirilsin mi? +upload_efile=Yüklenecek dosya seçilmedi. +upload_edir=Yükleme dizini mevcut deðil +upload_eperm=$1 oluþturmanýza izin verilmedi +upload_ewrite=$1'i yazmada hata oluþtu : $2. + +find_eaccess=$1'e eriþim izininiz yoktur +find_eexist=$1, $2 içinde mevcut deðil +find_edir=$1, $2'de bir dizin deðil + +cancel=Ýptal + +chmod_eaccess='$1'e eriim izininiz yoktur +chmod_euser=$1 : Kullanýýcý yok +chmod_egroup=$1 : Grup yok +chmod_elink=Sembolik linkte hata oluþtu : $1 +chmod_echown=chown'da hata oluþtu : $1 +chmod_echmod=chmod'da hata olustu : $1 + +copy_efrom='$1'den kopyalamanýza izin verilmemiþtir +copy_eto='$1'e kopyalamanýza izin verilmemiþtir +copy_elink=Sembolik linkte hata oluþtu : $1 + +delete_eaccess='$1'i silmede hata oluþtu + +list_eaccess=Bu dizine giriþ izininiz yoktur + +move_eto='$1'e taþýmaya hakkýnýz yoktur +move_afrom='$1'i taþýmaya hakkynyz yoktur + +acl_user=Sunucuda kullanýcý olarak dosyalara ulaþ +acl_umask=Yeni dosyalar için umask +acl_follow=Sembolik linkleri her zaman takip et. +acl_dirs=Sadece dizinlere giriþlere izin ver. + +share_title=Paylaþtýrma +share_samba=Windows +share_nfs=NFS +share_son=Windows dosya paylaþýmý açýk +share_soff=Windows dosya paylaþýmý kapalý +share_writable=Yazýlabilir? +share_available=Aktif mi? +share_sheader=Paylaþým seçenekleri +share_only=Sadece +share_guest=Ziyaretçi giriþleri? +share_comment=Açýklama +share_nheader=NFS sunum seçenekleri +share_non=NFS dosya paylaþýmý açýk +share_noff=NFS dosya paylaþýmý kapalý +share_desc=Açýklama +share_ro=Sadece okuma izinli makineler +share_rw=Okuma-yazma izinli makineler +share_root=Root giriþli makineler +share_none=Hiçbiri +share_all=Hepsi +share_listed=Listeli... +share_host=Makineler +share_opts=Seçenekler +share_s0=Hiçkimseye güvenme +share_s1=Root dýþýndakilere güven +share_s2=Herkese güven +share_lro=Sadece okunur +share_lrw=Okunur-yazýlýr + +log_create_export=NFS sunumu $1 oluþturuldu +log_modify_export=NFS sunumu $1 deðiþtirildi +log_delete_export=NFS sunumu $1 silindi +log_create_share=Samba paylaþýmý $1 oluþturuldu +log_modify_share=Samba paylaþýmý $1 deðiþtirildi +log_delete_share=Samba paylaþýmý $1 silindi +log_save=$1 dosyasý kaydedildi +log_chmod=$1 dosyasýnýn haklarý deðiþtirildi +log_mkdir=$1 dizini oluþturuldu +log_upload=$1 dosyasý yüklendi +log_link=$2'ye sembolik link $1 oluþturuldu +log_relink=$2'ye sembolik link $1 deðiþtirildi +log_copy=$1 dosyasý $2'ye kopyalandý +log_move=$1 dosyasý $2'ye taþýndý +log_delete=$1 dosyasý silindi + diff --git a/file/lang/uk_UA b/file/lang/uk_UA new file mode 100644 index 000000000..548b8b481 --- /dev/null +++ b/file/lang/uk_UA @@ -0,0 +1,269 @@ +top_delete=Âèäàëèòè +info_apply=Çàñòîñóâàòè çì³íè +info_perms=Ïðàâà +info_file=Ôàéë +view_enormal=Ìîæíà ïåðåãëÿäàòè ò³ëüêè çâè÷àéí³ ôàéëè +top_upload=Çàâàíòàæèòè +edit_esave=Íå óäàëîñÿ çáåðåãòè ôàéë : $1 +upload_ewrite=Íå óäàëîñÿ çàïèñàòè â $1 : $2. +chmod_elink=Ïîìèëêà ïðè âèêëèêó symlink : $1 +upload_ok=Çàâàíòàæèòè +view_eaccess=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ äîñòóïó äî $1 +info_group=Ãðóïè: +edit_title2=Ñòâîðåííÿ ôàéëó +top_info=Âëàñòèâîñò³ +move_afrom=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ ïåðåì³ùåííÿ '$1' +link_efailed=Ñòâîðèòè ïîñèëàííÿ íå óäàëîñÿ : $1 +info_setuid2=Âèêîíóâàòè â³ä ³ìåí³ êîðèñòóâà÷à +chmod_euser=$1 : íåìຠòàêîãî êîðèñòóâà÷à +link_efrom=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ ñòâîðåííÿ ïîñèëàííÿ '$1' +info_mod=Çì³íåíèé: +right_date=Äàòà +copy_efrom=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ êîï³þâàííÿ ç '$1' +info_sticky2=Ò³ëüêè âëàñíèêè ìîæóòü âèäàëÿòè ôàéëè +rename_old=Ñòàðå ³ì'ÿ: +find_eaccess=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ äîñòóïó äî $1 +mkdir_eexists=$1 âæå ³ñíóº +upload_dir=Çàâàíòàæóâàòè â êàòàëîã +rename_enew=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ ïåðåéìåíóâàííÿ â '$1' +find_edir=$1 íå º êàòàëîãîì ó $2 +upload_efile=Íå îáðàíèé ôàéë äëÿ çàâàíòàæåííÿ. +info_type=Òèï: +info_setuid=Á³ò setuid: +right_group=Ãðóïà +upload_efailed=Íå óäàëîñÿ ïî÷àòè çàâàíòàæåííÿ : $1 +top_cut=Âèð³çóâàòè +info_read=×èòàííÿ +acl_user=Çâåðòàòèñÿ äî ôàéë³â íà ñåðâåð³ ï³ä ³ì'ÿì êîðèñòóâà÷à +paste_ecopy=Ïåðåä âñòàâêîþ íåîáõ³äíî ÷è âèð³çóâàòè êîï³þâàòè +info_exec=Âèêîíàííÿ +delete_ddesc=Íàçàâæäè âèäàëèòè êàòàëîã $1 ³ç óñ³ì éîãî âì³ñòîì? +info_link=Ïîñèëàííÿ íà: +link_to=̳ñöå ïðèçíà÷åííÿ: +info_size=Ðîçì³ð: +info_path=Øëÿõ: +copy_eto=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ êîï³þâàííÿ â '$1' +rename_ok=Ïåðåéìåíóâàòè +chmod_egroup=$1 : íåìຠòàêî¿ ãðóïè +info_own=Ïðèíàëåæí³ñòü +upload_conv=Ïåðåòâîðèòè ïåðåêëàäè ðÿäê³â DOS? +cancel=Ñêàñóâàííÿ +info_list=Ïåðåãëÿä +index_nojava=Äëÿ ôóíêö³îíóâàííÿ öüîãî ìîäóëÿ ïîòð³áíî java, îäíàê âàø áðàóçåð java íå ï³äòðèìóº +paste_eover=$1 íå ìîæå áóòè ïåðåçàïèñàíèé +info_user=Êîðèñòóâà÷à: +delete_fdesc=Íàçàâæäè âèäàëèòè ôàéë $1 ? +edit_title=Ðåäàãóâàííÿ $1 +paste_egone=Êîï³éîâàí ôàéë $1 á³ëüøå íå ³ñíóº +top_paste=Óñòàâèòè +chmod_echmod=Ïîìèëêà ïðè âèêëèêó chmod : $1 +edit_filename=²ì'ÿ ôàéëó: +link_eexists=$1 âæå ³ñíóº +edit_enormal=Ìîæíà ðåäàãóâàòè ò³ëüêè çâè÷àéí³ ôàéëè +info_setgid2=Ôàéëè óñïàäêîâóþòü ãðóïó +info_setgid3=Âèêîíóâàòè â³ä ³ìåí³ ãðóïè +top_copy=Êîï³þâàòè +edit_eaccess=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ çáåðåæåííÿ '$1' +right_name=²ì'ÿ +rename_efailed=Ïåðåéìåíóâàòè íå óäàëîñÿ : $1 +upload_edir=Êàòàëîã äëÿ çàâàíòàæåííÿ íå ³ñíóº. +rename_new=Íîâå ³ì'ÿ: +delete_dtitle=Âèäàëåííÿ êàòàëîãó +link_from=Äæåðåëî: +index_title=Ìåíåäæåð ôàéë³â +file_type0=Êàòàëîã +file_type1=Òåêñòîâèé ôàéë +file_type2=Ôàéë çîáðàæåííÿ +file_type3=Á³íàðíèé ôàéë +file_type4=Ôàéë +file_type5=Ñèìâîëüíå ïîñèëàííÿ +file_type6=Ôàéë ïðèñòðîþ +file_type7=Êàíàë +info_sticky=Á³ò sticky: +upload_title=Çàâàíòàæåííÿ ôàéëó +top_edit=Çì³íèòè +upload_eperm=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ ñòâîðåííÿ $1 +move_eto=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ ïåðåì³ùåííÿ â '$1' +paste_eself=Íå ìîæíà ïåðåïèñàòè ôàéë ñàìèì ñîáîþ +copy_elink=Ïîìèëêà ïðè âèêëèêó symlink : $1 +chmod_echown=Ïîìèëêà ïðè âèêëèêó chown : $1 +acl_umask=Umask äëÿ íîâèõ ôàéë³â +mkdir_dir=Íîâèé êàòàëîã: +info_other=²íøèõ: +mkdir_title=Íîâèé êàòàëîã +delete_ftitle=Âèäàëåííÿ ôàéëó +find_eexist=$1 íå ³ñíóº â $2 +right_size=Ðîçì³ð +edit_eover=$1 íå ìîæå áóòè ïåðåçàïèñàíèé +paste_emfailed=Íå óäàëîñÿ ïåðåì³ñòèòè : $1 +link_title=Ñòâîðåííÿ ïîñèëàííÿ +info_apply1=Ò³ëüêè äî öüîãî êàòàëîãó +info_apply2=Äî öüîãî êàòàëîãó ³ éîãî ôàéë³â +info_apply3=Äî Öüîãî êàòàëîãó ³ âñ³õ éîãî ï³äêàòàëîã³â +info_efailed=Íå óäàëîñÿ îáíîâèòè $1 : $2 +acl_follow=Çàâæäè ïåðåõîäèòè ïî ñèìâîëüíèõ ïîñèëàííÿõ? +upload_file=Ôàéë äëÿ çàâàíòàæåííÿ +info_setgid=Á³ò setgid: +paste_ecfailed=Íå óäàëîñÿ ñêîï³þâàòè : $1 +mkdir_eaccess=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ ñòâîðåííÿ '$1' +right_user=Êîðèñòóâà÷ +rename_eold=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ ïåðåéìåíóâàííÿ '$1' +link_efollow=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ ñòâîðåííÿ ïîñèëàíü +rename_title=Ïåðåéìåíóâàííÿ $1 +top_new=Ïîñèëàííÿ +mkdir_efailed=Íå óäàëîñÿ ñòâîðèòè êàòàëîã : $1 +info_write=Çàïèñ +rename_eexists=Ôàéë ç ³ì'ÿì $1 âæå ³ñíóº +acl_dirs=Äîçâîëÿòè äîñòóï ò³ëüêè äî êàòàëîã³â +chmod_eaccess=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ äîñòóïó äî '$1' +top_refresh=Îáíîâèòè +delete_eaccess=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ âèäàëåííÿ '$1' +view_eopen=Íå óäàëîñÿ â³äêðèòè $1 : $2 +top_rename=Ïåðåéìåíóâàòè +list_eaccess=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ äîñòóïó äî öüîãî êàòàëîãó +delete_efailed=Íå óäàëîñÿ âèäàëèòè $1 : $2 +log_chmod=Çì³íåí³ ïðàâà íà ôàéë $1 +eacl_edefmask=There can be at most one default mask ACL entry +acl_log=Âåñòè æóðíàë óñ³õ çì³í ôàéë³â? +eacl_eacls=Íå óäàëîñÿ ââàæàòè ACL : $1 +search_eaccess=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ ïîøóêó â öüîìó êàòàëîç³ +over_msg=Ôàéë $1 âæå ³ñíóº. Óêàæ³òü äëÿ ôàéëó, ùî âñòàâëÿºòüñÿ, íîâå ³ì'ÿ. +share_nfs=NFS +log_copy=Ñêîï³éîâàíèé ôàéë $1 ó $2 +acltype_default_group=Ãðóïà çà çàìîâ÷óâàííÿì +eacl_aclname=Çàñòîñóâàòè äî +search_size=Ðîçì³ð ôàéëó +log_upload=Çàâàíòàæåíèé ôàéë $1 +attr_create=Äîäàòè àòðèáóò +search_types_d=Êàòàëîã +ext_eattrs=Íå óäàëîñÿ îäåðæàòè àòðèáóòè EXT : $1 +search_group=Ïðèíàëåæí³ ãðóï³ +search_types_f=Ôàéë +index_eremote=Íåìຠêîðèñòóâà÷à Unix â³äïîâ³äíîãî êîðèñòóâà÷ó Webmin $1. +search_types_l=Ñèìâîëüíå ïîñèëàííÿ +search_types_p=²ìåíîâàíèé êàíàë +search_dir=Øóêàòè â êàòàëîç³ +acltype_user=Êîðèñòóâà÷ +acl_user_def=Êîðèñòóâà÷à Webmin +top_share=Ìåðåæà +switch_euser=Êîðèñòóâà÷ Unix íå ³ñíóº! +acl_home=Âêëþ÷àþ÷è äîìàøí³é êàòàëîã êîðèñòóâà÷à Webmin +search_match=Ôàéëè ñï³âïàäàþ÷³ ç +share_writable=Çàïèñ äîçâîëåíèé? +delete_mtitle=Âèäàëåííÿ äåê³ëüêîõ ôàéë³â +search_less=Ìåíø +top_attr=Àòðèáóòè +log_link=Ñòâîðåíà ñèìâîëüíå ïîñèëàííÿ $1 íà $2 +log_create_export=Ñòâîðåíèé ðåñóðñ NFS $1 +eacl_acltype=Òèï ACL +share_s0=Äîâ³ðÿòè nobody +share_s1=Äîâ³ðÿòè íå-root +share_s2=Äîâ³ðÿòè âñ³ì +ext_header=Àòðèáóòè EXT ôàéëó +search_title=Ïîøóê ôàéë³â +search_types_=Ëþáîþ +log_move=Ïåðåì³ùåíèé ôàéë $1 ó $2 +acl_goto=³äêðèâàòè ïåðøèé äîñòóïíèé êàòàëîã? +top_search=Çíàéòè +share_none=Íåìຠ+log_delete=Âèëó÷åíèé ôàéë $1 +share_opts=Íàñòðîþâàííÿ +share_ro=Âóçëè, ùî ìàþòü äîñòóï ò³ëüêè äëÿ ÷èòàííÿ +share_rw=Âóçëè, ùî ìàþòü äîñòóï äëÿ ÷èòàííÿ ³ çàïèñó +share_guest=Äîñòóï áåç àóòåíòèô³êàö³¿ (Guest)? +share_nheader=Íàñòðîþâàííÿ äîñòóïó ïî ïðîòîêîë³ NFS +over_title=Ôàéë ³ñíóº +over_new=Íîâå ³ì'ÿ ôàéëó: +share_host=Âóçëè +search_esize=Ðîçì³ð ôàéëó ïîâèííèé áóòè ö³ëèì ÷èñëîì +acltype_other=²íø³ +ext_efailed=Íå óäàëîñÿ óñòàíîâèòè àòðèáóòè EXT $1 : $2 +share_title=Äîñòóï ïî ìåðåæ³ +share_only=Ò³ëüêè +attr_edit=Çì³íèòè àòðèáóò +eacl_eowner=Íå çàçíà÷åíèé ÷è êîðèñòóâà÷ ãðóïà äëÿ ÿêèé âíîñÿòüñÿ çì³íè +view_enormal2=Ìîæíà çàâàíòàæóâàòè ò³ëüêè çâè÷àéí³ ôàéëè +search_user=Ïðèíàëåæí³ êîðèñòóâà÷ó +log_mkdir=Ñòâîðåíèé êàòàëîã $1 +attr_ename=Íå çàçíà÷åíà íàçâà àòðèáóòà +search_more=Á³ëüø +eacl_user=Âëàñíèê ôàéëó $1 +ext_efs=Ôàéëîâà ñèñòåìà $1 íå ï³äòðèìóº àòðèáóòè EXT +acltype_default_user=Êîðèñòóâà÷ çà çàìîâ÷óâàííÿì +top_ext=EXT +eacl_efs=Öÿ ôàéëîâà ñèñòåìà $1 íå ï³äòðèìóº ACL +search_egroup=²ì'ÿ ãðóïè ÷è íå çàçíà÷åíå çàçíà÷åíî íåâ³ðíî +share_lro=Ò³ëüêè ÷èòàííÿ +acl_ro=Ðåæèì ò³ëüêè äëÿ ÷èòàííÿ? +eacl_edefaults=If a file has any default ACL, it must have default user, group and other ACLs. +list_edir=Íå óäàëîñÿ ïåðåãëÿíóòè $1 : $2 +eacl_owner=Âëàñíèê ôàéëó +share_lrw=×èòàííÿ/çàïèñ +attr_name=Íàçâà àòðèáóòà +eacl_aclperms=Ïðàâà +acltype_default_other=²íø³ çà çàìîâ÷óâàííÿì +acltype_mask=Ìàñêà +attr_eattrs=Íå óäàëîñÿ ââàæàòè àòðèáóòè : $1 +search_ematch=Ðåãóëÿðíå âèðàæåííÿ äëÿ ïîøóêó ÷è íå çàçíà÷åíå çàçíà÷åíî íåâ³ðíî +eacl_add=Äîäàòè ACL : +log_attr=Çì³íåí³ àòðèáóòè ôàéëó $1 +log_modify_export=Çì³íåíèé ðåñóðñ NFS $1 +attr_efs=Ôàéëîâà ñèñòåìà $1 íå ï³äòðèìóº àòðèáóòè +top_down=Çáåðåãòè +eattr_A=Íå îáíîâëÿòè ÷àñ äîñòóïó +search_crit=Êðèòåð³é ïîøóêó +attr_add=Äîäàòè àòðèáóò +chmod_efollow=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ çì³íè ñèìâîëüíèõ ïîñèëàíü +ext_title=Àòðèáóòè EXT äëÿ $1 +share_son=Äîñòóï ç ìåðåæ³ Windows äîçâîëåíèé +log_create_share=Ñòâîðåíèé ðåñóðñ Samba $1 +search_ok=Øóêàòè +attr_title=Àòðèáóòè ôàéëó äëÿ $1 +eattr_S=Çàâæäè ñèíõðîí³çóâàòè ï³ñëÿ çàïèñó +search_edir=Êàòàëîã äëÿ ïîøóêó ÷è íå çàçíà÷åíèé çàçíà÷åíèé íåâ³ðíî +share_non=Äîñòóï ïî NFS äîçâîëåíèé +eattr_a=Ìîæëèâî ò³ëüêè äîäàâàííÿ äî ôàéëó +share_samba=Windows +eattr_c=Ñòèñêàòè äàí³ íà äèñêó +eattr_d=Íå çä³éñíþâàòè ðåçåðâíå êîï³þâàííÿ çà äîïîìîãîþ dump +search_xdev=Øóêàòè â ï³äìîíòîâàíèõ ôàéëîâèõ ñèñòåìàõ? +eacl_edit=Çì³íèòè ACL +eattr_³=Çàáîðîíèòè çì³íà +share_soff=Äîñòóï ç ìåðåæ³ Windows çàáîðîíåíèé +search_euser=²ì'ÿ êîðèñòóâà÷à ÷è íå çàçíà÷åíå çàçíà÷åíî íåâ³ðíî +eattr_s=Îáíóëÿòè áëîêè ïðè âèäàëåíí³ +eattr_u=Çáåð³ãàòè óì³ñò ôàéëó äëÿ â³äíîâëåííÿ +top_ret=Ìåíþ +log_delete_share=Âèëó÷åíèé ðåñóðñ Samba $1 +eacl_emask=There can be at most one mask ACL entry +log_delete_export=Âèëó÷åíèé ðåñóðñ NFS $1 +eacl_group=Ãðóïà ôàéëó $1 +share_noff=Äîñòóï ïî NFS çàáîðîíåíèé +share_available=Äîñòóïíèé ó äàíèé ìîìåíò? +info_octal=Âîñüìåðè÷íèé âèä: +attr_efailed=Íå óäàëîñÿ óñòàíîâèòè àòðèáóòè äëÿ $1 : $2 +acltype_default_mask=Ìàñêà çà çàìîâ÷óâàííÿì +log_modify_share=Çì³íåíèé ðåñóðñ Samba $1 +log_save=Çáåðåæåíèé ôàéë $1 +share_comment=Êîìåíòàð +share_desc=Îïèñ +eacl_remove=Âèäàëèòè ACL +attr_value=Çíà÷åííÿ àòðèáóòà +search_any=Ëþáîþ +search_type=Òèï ôàéëó +eacl_title=ACL äëÿ $1 +top_eacl=ACL +facl_eaccess=Ó âàñ íåäîñòàòíüî ïðàâèé äëÿ çì³íè ACL äëÿ öüîãî ôàéëó +share_root=Âóçëè, äëÿ ÿêèõ äîçâîëåíèé äîñòóï ³ç ïðàâàìè root +eacl_efailed=Íå óäàëîñÿ óñòàíîâèòè ACL äëÿ $1 : $2 +share_all=Óñ³ +delete_mdesc=Íàçàâæäè âèäàëèòè çàçíà÷åí³ ôàéëè ³ êàòàëîãè? : +acltype_group=Ãðóïà +log_acl=Äëÿ ôàéëó $1 ïðèçíà÷åíèé ACL +share_listed=Çàçíà÷åí³.. +share_sheader=Íàñòðîþâàííÿ äîñòóïó +search_list=Ðåçóëüòàòè ïîøóêó +eacl_create=Ñòâîðèòè ACL +log_relink=Çì³íåíà ñèìâîëüíå ïîñèëàííÿ $1 íà $2 +over_ok=ÎÊ + diff --git a/file/lang/zh_CN b/file/lang/zh_CN new file mode 100644 index 000000000..f7ff6f2bf --- /dev/null +++ b/file/lang/zh_CN @@ -0,0 +1,323 @@ +index_title=Îļþ¹ÜÀíÆ÷ +index_nojava=±¾Ä£¿éÐèÒªjavaÖ§³Ö²ÅÄܹ¤×÷£¬µ«ÊÇÄúµÄä¯ÀÂÆ÷²»Ö§³Öjava +index_eremote=ûÓÐÇøÅä WebminµÇ¼Ãû $1 µÄUnixÓû§¡£ +switch_euser=Unix Óû§²»´æÔÚ£¡ + +top_ret=Ë÷Òý +top_down=±£´æ +top_edit=±à¼­ +top_refresh=ˢР+top_info=ÐÅÏ¢ +top_eacl=ACL +top_attr=ÊôÐÔ +top_ext=À©Õ¹ +top_delete=ɾ³ý +top_new=н¨ +top_upload=ÉÏ´« +top_rename=¸ÄÃû +top_copy=¸´ÖÆ +top_cut=¼ôÇÐ +top_paste=Õ³Ìù +top_share=¹²Ïí +top_mount=¼ÓÔØ +top_search=²éÕÒ +top_config=ÅäÖà + +right_name=Ãû³Æ +right_size=´óС +right_user=Óû§ +right_group=×é +right_date=ÈÕÆÚ + +edit_enormal=Ö»Äܱ༭Õý³£Îļþ +edit_title=ÕýÔڱ༭ $1 +edit_title2=ÕýÔÚ´´½¨Îļþ +edit_filename=ÎļþÃû£º +edit_goto=תµ½ +edit_find=²éÕÒ +edit_gotoline=תµ½ÐÐ +edit_replace=Ìæ»» +edit_all=È«²¿Ìæ»» +edit_searchfor=ËÑË÷ +edit_replaceby=±»Ìæ»» +edit_eover=$1 ²»Äܱ»¸²¸Ç +edit_esave=±£´æÎļþʧ°Ü £º $1 +edit_eaccess=Äãδ±»ÔÊÐí±£´æ '$1' +edit_notfound=δÕÒµ½Îı¾ $1 +edit_saveclose=±£´æ²¢¹Ø±Õ + +info_file=Îļþ +info_path=·¾¶£º +info_type=ÀàÐÍ£º +info_size=´óС£º +info_mod=Ð޸ģº +info_link=Áª½áµ½£º +info_perms=Ðí¿É +info_user=Óû§£º +info_group=×飺 +info_other=ÆäËü£º +info_octal=°Ë½øÖÆ£º +info_sticky=Õ³ÐÔ£º +info_sticky2=Ö»ÓÐËùÓÉÕß²ÅÄÜɾ³ýÎļþ +info_own=ËùÓÐȨ +info_setuid=ÉèÖà uid£º +info_setuid2=ÒÔÓû§Ö´ÐÐ +info_setgid=ÉèÖà gid£º +info_setgid2=Îļþ¼Ì³Ð×é +info_setgid3=ÒÔ×éÖ´ÐÐ +info_apply=Ó¦Óøü¸ÄÖÁ +info_apply1=½ö´ËĿ¼ +info_apply2=±¾Ä¿Â¼¼°ÆäÎļþ +info_apply3=±¾Ä¿Â¼¼°ÆäËùÓÐ×ÓĿ¼ +info_efailed=¸üР$1 £º$2 ʧ°Ü +info_read=¶ÁÈ¡ +info_write=дÈë +info_list=Áбí +info_exec=Ö´ÐÐ + +eacl_eacls=¶ÁÈ¡ ACLs ʧ°Ü £º $1 +eacl_acltype=ACL ÀàÐÍ +eacl_aclname=Ó¦Óõ½ +eacl_aclperms=Ðí¿É +eacl_add=Ìí¼Ó ÀàÐ͵ÄACL£º +eacl_remove=ÒÆ³ýACL +eacl_efs=Îļþϵͳ $1 ²»Ö§³Ö ACLs +eacl_create=´´½¨ ACL +eacl_edit=±à¼­ ACL +eacl_user=ÎļþËùÓÐÕß $1 +eacl_group=Îļþ×é $1 +eacl_eowner=ȱÉÙÒªÓ¦Óõ½µÄÓû§»ò×é +eacl_efailed=Ϊ$1 £º $2ÉèÖÃACLsʧ°Ü +eacl_emask=×î¶àÖ»ÄÜÓÐÒ»¸öÑÚÂë ACL ÌõÄ¿ +eacl_edefmask=×î¶àÖ»ÄÜÓÐÒ»¸öĬÈÏÑÚÂë ACL ÌõÄ¿ +eacl_title=$1µÄACL +eacl_owner=ÎļþËùÓÐÕß +eacl_edefaults=Èç¹ûÒ»¸öÎļþÓÐÈκÎĬÈϵÄACL£¬ÔòËü±ØÐëÓÐĬÈÏÓû§£¬×éºÍÆäËûµÄACLs¡£ + +acltype_user=Óû§ +acltype_group=×é +acltype_other=ÆäËû +acltype_mask=ÑÚÂë +acltype_default_user=ĬÈÏÓû§ +acltype_default_group=ĬÈÏ×é +acltype_default_other=ĬÈÏÆäËû +acltype_default_mask=ĬÈÏÑÚÂë + +delete_mtitle=ɾ³ý¶à¸öÎļþ +delete_dtitle=ɾ³ýĿ¼ +delete_ftitle=ɾ³ýÎļþ +delete_ddesc=ȷʵҪÓÀ¾Ãɾ³ýĿ¼ $1 ¼°ÆäÄÚÈÝ£¿ +delete_fdesc=ȷʵҪÓÀ¾Ãɾ³ýÎļþ $1£¿ +delete_mdesc=ȷʵҪÓÀ¾Ãɾ³ýÕâЩĿ¼ºÍÎļþ£¿ £º +delete_efailed=ɾ³ý $1 £º$2 ʧ°Ü + +mkdir_title=н¨Ä¿Â¼ +mkdir_dir=н¨Ä¿Â¼£º +mkdir_eexists=$1 ÒѾ­´æÔÚ +mkdir_efailed=´´½¨Ä¿Â¼ $1 ʧ°Ü +mkdir_eaccess=ÄãÎÞȨ´´½¨ '$1' + +link_title=´´½¨Á´½Ó +link_from=Á´½Ó×Ô£º +link_to=Á´½Óµ½£º +link_eexists=$1 ÒѾ­´æÔÚ +link_efailed=Á´½Óʧ°Ü£º$1 +link_efrom=ÄãÎÞȨÁ´½Ó×Ô '$1' +link_efollow=ÄãÎÞȨ´´½¨·ûºÅÁ´½Ó + +rename_title=ÖØÃüÃû$1 +rename_old=Ô­Ãû£º +rename_new=ÐÂÃû£º +rename_ok=ÖØÃüÃû +rename_eexists=Îļþ $1 ÒÑ´æÔÚ +rename_efailed=ÖØÃüÃûʧ°Ü£º $1 +rename_eold=ÄãÎÞÈ¨ÖØÃüÃû '$1' +rename_enew=ÄãÎÞÈ¨ÖØÃüÃûΪ '$1' + +file_type0=Ŀ¼ +file_type1=Îı¾Îļþ +file_type2=Ó³ÏóÎļþ +file_type3=¶þ½øÖÆÎļþ +file_type4=Îļþ +file_type5=·ûºÅÁ´½Ó +file_type6=É豸Îļþ +file_type7=¹ÜµÀ + +view_enormal=Ö»Äܲ鿴Õý³£Îļþ +view_enormal2=Ö»ÄÜÏÂÔØÕý³£Îļþ +view_eaccess=ÄãÎÞȨ·ÃÎÊ $1 +view_eopen=´ò¿ª $1£º $2 ʧ°Ü + +paste_ecopy=ÔÚÕ³Ìù֮ǰ±ØÐë¼ôÇлò¿½±´ +paste_egone=¿½±´µÄÎļþ $1 ÒѾ­²»´æÔÚ +paste_eover=$1 ²»Äܸ²¸Ç +paste_eself=²»Äܽ«ÎļþÕ³ÌùÖÁ×ÔÉí +paste_emfailed=ÒÆ¶¯Ê§°Ü£º$1 +paste_ecfailed=¿½±´Ê§°Ü£º$1 + +over_title=Îļþ´æÔÚ +over_msg=Îļþ $1 ÒѾ­´æÔÚ¡£ÔÚÏÂÃæµÄ×Ö¶ÎÖÐΪҪճÌùµÄÎļþÊäÈëÒ»¸öÐÂÃû¡£ +over_new=ÐÂÎļþÃû£º +over_ok=È·¶¨ + +upload_efailed=´ò¿ªÉÏ´«Ê§°Ü£º$1 +upload_title=ÉÏ´«Îļþ +upload_file=ÒªÉÏ´«µÄÎļþ +upload_dir=ÉÏ´«µ½Ä¿Â¼ +upload_ok=ÉÏ´« +upload_conv=ÊÇ·ñת»»DOS»»ÐзûºÅ£¿ +upload_efile=ûÓÐÑ¡¶¨ÒªÉÏ´«µÄÎļþ¡£ +upload_edir=ÉÏ´«Ä¿Â¼²»´æÔÚ¡£ +upload_eperm=ÄãÎÞȨ´´½¨ $1 +upload_ewrite=дÈë $1£º$2 ʧ°Ü¡£ +upload_already=Îļþ $1 ÒѾ­´æÔÚ¡£ÄúÈ·¶¨Òª¸²¸ÇËüÂ𣿠+ +find_eaccess=ÄãÎÞȨ·ÃÎÊ $1 +find_eexist=ÔÚ$2Öв»´æÔÚ$1 +find_edir=$1 ²»ÊÇ $2 ÖеÄĿ¼ + +cancel=È¡Ïû +close=¹Ø±Õ + +chmod_eaccess=ÄãÎÞȨ·ÃÎÊ '$1' +chmod_euser=$1£ºÎÞ´ËÓû§ +chmod_egroup=$1£ºÎÞ´ËÓû§×é +chmod_elink=symlink ʧ°Ü£º$1 +chmod_echown=chown ʧ°Ü£º$1 +chmod_echmod=chmod ʧ°Ü£º$1 +chmod_efollow=Äúδ±»ÔÊÐí±à¼­·ûºÅÁ´½Ó + +copy_efrom=ÄãÎÞȨ´Ó '$1' ¿½±´ +copy_eto=ÄãÎÞȨ¿½±´µ½ '$1' +copy_elink=symlink ʧ°Ü '$1' + +delete_eaccess=ÄãÎÞȨɾ³ý '$1' + +list_eaccess=ÄãÎÞȨ·ÃÎÊ´ËĿ¼ +list_edir=ÏÔʾÁбíʧ°Ü $1 £º $2 + +move_eto=ÄãÎÞÈ¨ÒÆ¶¯µ½ '$1' +move_afrom=ÄãÎÞÈ¨ÒÆ¶¯ '$1' + +acl_user=×÷ΪÓû§·ÃÎÊ·þÎñÆ÷µÄÎļþ +acl_user_def=ÓëWebminµÇ¼Ïàͬ +acl_umask=¶ÔÐÂÎļþÈ¥³ýÑÚÂë +acl_follow=ÊÇ·ñ×ÜÊǸúËæ·ûºÅÁ´½Ó£¿ +acl_ro=Ö»¶Áģʽ£¿ +acl_dirs=½öÔÊÐí·ÃÎÊĿ¼ +acl_home=°üº¬WebminÓû§µÄÖ÷Ŀ¼£¿ +acl_log=¶ÔËùÓÐÎļþµÄÐ޸ı£´æÈÕÖ¾£¿ +acl_goto=´ò¿ª×îÏÈÔÊÐíµÄĿ¼£¿ + +share_title=¹²Ïí +share_samba=Windows +share_nfs=NFS +share_son=ÆôÓà Windows Îļþ¹²Ïí +share_soff=½ûÓà Windows Îļþ¹²Ïí +share_writable=¿ÉдÈ룿 +share_available=ÏÖÔڻÂ𣿠+share_sheader=¹²ÏíÑ¡Ïî +share_only=½ö +share_guest=Guest ·ÃÎÊ£¿ +share_comment=×¢ÊÍ +share_nheader=NFS µ¼³öÑ¡Ïî +share_non=ÒÑÆôÓà NFS Îļþ¹²Ïí +share_noff=ÒѽûÓà NFS Îļþ¹²Ïí +share_desc=ÃèÊö +share_ro=Ö»¶ÁÖ÷»ú +share_rw=¶ÁдÖ÷»ú +share_root=Root ·ÃÎÊÖ÷»ú +share_none=ÎÞ +share_all=ËùÓÐ +share_listed=ÒÑÁгöµÄ¡­ +share_host=Ö÷»ú +share_opts=Ñ¡Ïî +share_s0=²»ÐÅÈÎÈκÎÈË +share_s1=ÐÅÈÎ·Ç Root Óû§ +share_s2=ÐÅÈÎËùÓÐÈË +share_lro=Ö»¶Á +share_lrw=¶Áд + +log_create_export=ÒÑ´´½¨µÄ NFS µ¼³ö $1 +log_modify_export=ÒÑÐÞ¸ÄµÄ NFS µ¼³ö $1 +log_delete_export=ÒÑɾ³ýµÄ NFS µ¼³ö $1 +log_create_share=ÒÑ´´½¨µÄ Samba ¹²Ïí $1 +log_modify_share=ÒÑÐÞ¸ÄµÄ Samba ¹²Ïí $1 +log_delete_share=ÒÑɾ³ýµÄ Samba ¹²Ïí $1 +log_save=Òѱ£´æÎļþ $1 +log_chmod=ÒѸıäÎļþ $1 µÄȨÏÞ +log_mkdir=ÒÑ´´½¨µÄĿ¼ $1 +log_upload=ÒÑÉÏ´«µÄÎļþ $1 +log_link=ÒÑ´´½¨µÄ·ûºÅÁ¬½Ó $1 µ½ $2 +log_relink=ÒÑÐ޸ĵķûºÅÁ¬½Ó $1 µ½ $2 +log_copy=ÒÑ¿½±´µÄÎļþ $1 µ½ $2 +log_move=ÒÑÒÆ¶¯µÄÎļþ $1 µ½ $2 +log_delete=ÒÑɾ³ýµÄÎļþ $1 +log_attr=ÉèÖÃÎļþ $1 µÄÊôÐÔ +log_acl=ÉèÖÃÎļþ $1 µÄACL + +search_eaccess=ÄúÎÞȨËÑË÷´ËĿ¼ +search_title=ÕÒµ½Îļþ +search_ok=ÏÖÔÚËÑË÷ +search_dir=ËÑË÷Ŀ¼ +search_match=ÎļþÆ¥Åä +search_user=Óû§ËùÓÐ +search_group=×éËùÓÐ +search_any=ÈκΠ+search_type=ÎļþÀàÐÍ +search_types_=ÈκΠ+search_types_f=Îļþ +search_types_d=Ŀ¼ +search_types_l=·ûºÅÁ¬½Ó +search_types_p=ÃüÃû¹ÜµÀ +search_size=Îļþ´óС +search_more=¶àÓÚ +search_less=ÉÙÓÚ +search_xdev=ËÑË÷ÒÔǰµÄ¼ÓÔØ£¿ +search_edir=¶ªÊ§»òÎÞЧµÄËÑË÷Ŀ¼ +search_ematch=¶ªÊ§Æ¥ÅäµÄÕýÔò±í´ïʽ +search_euser=¶ªÊ§Óû§Ãû +search_egroup=¶ªÊ§×éÃû +search_esize=Îļþ´óСֵ±ØÐëÊÇÕûÊý +search_crit=ËÑË÷±ê×¼ +search_list=ËÑË÷½á¹û + +facl_eaccess=Äãδ±»ÔÊÐíÉèÖôËÎļþµÄACLs + +attr_eattrs=»ñÈ¡ÊôÐÔʧ°Ü£º$1 +attr_efs=Îļþϵͳ $1 ²»Ö§³ÖÊôÐÔ +attr_add=Ìí¼ÓÊôÐÔ +attr_name=ÊôÐÔÃû³Æ +attr_value=ÊôÐÔÖµ +attr_efailed=Ϊ $1 £º $2 ÉèÖÃÊôÐÔʧ°Ü +attr_title=$1µÄÎļþÊôÐÔ +attr_create=Ìí¼ÓÊôÐÔ +attr_edit=±à¼­ÊôÐÔ +attr_ename=ȱÉÙÊôÐÔÃû³Æ + +ext_eattrs=»ñÈ¡À©Õ¹ÊôÐÔʧ°Ü£º $1 +ext_efs=Îļþϵͳ $1 ²»Ö§³ÖÀ©Õ¹ÊôÐÔ +ext_title=$1 µÄÀ©Õ¹ÊôÐÔ +ext_header=À©Õ¹ÎļþÊôÐÔ +ext_efailed=Ϊ $1 £º $2ÉèÖÃÊôÐÔʧ°Ü + +eattr_A=²»¸üзÃÎÊ´ÎÊý +eattr_a=Ö»ÄÜÌí¼Óµ½Îļþĩβ +eattr_c=ѹËõ´ÅÅÌÊý¾Ý +eattr_d=²»Ê¹ÓÃdump±¸·Ý +eattr_i=²»ÔÊÐíÐÞ¸Ä +eattr_s=ɾ³ýʱ½«¿é¹éÁã +eattr_S=дÈëºó×ÜÊÇͬ²½ +eattr_u=Ϊ·´É¾³ý±£´æÄÚÈÝ + +mount_eaccess=Äãδ±»ÔÊÐí¼ÓÔØÎļþϵͳ +mount_efstab=´Ë¼ÓÔØµãÉϲ»´æÔÚÎļþϵͳ +mount_epoint=$1 ²»ÊǼÓÔØµã +mount_rusure1=ÄãÈ·¶¨Òª´Ó $2¼ÓÔØ $1 Â𣿠+mount_rusure2=ÄãÈ·¶¨Òª´Ó $2Ð¶ÔØ $1 Â𣿠+mount_err1=¼ÓÔØÊ§°Ü $1 £º $2 +mount_err2=Ð¶ÔØÊ§°Ü $1 £º $2 +mount_title1=¼ÓÔØÎļþϵͳ +mount_title2=Ð¶ÔØÎļþϵͳ + + diff --git a/file/lang/zh_CN.UTF-8 b/file/lang/zh_CN.UTF-8 new file mode 100644 index 000000000..a69b9f07f --- /dev/null +++ b/file/lang/zh_CN.UTF-8 @@ -0,0 +1,323 @@ +index_title=文件管ç†å™¨ +index_nojava=本模å—需è¦javaæ”¯æŒæ‰èƒ½å·¥ä½œï¼Œä½†æ˜¯æ‚¨çš„æµç¼†å™¨ä¸æ”¯æŒjava +index_eremote=æ²¡æœ‰åŒºé… Webmin登录å $1 çš„Unix用户。 +switch_euser=Unix 用户ä¸å­˜åœ¨ï¼ + +top_ret=索引 +top_down=ä¿å­˜ +top_edit=编辑 +top_refresh=刷新 +top_info=ä¿¡æ¯ +top_eacl=ACL +top_attr=属性 +top_ext=扩展 +top_delete=删除 +top_new=新建 +top_upload=上传 +top_rename=改å +top_copy=å¤åˆ¶ +top_cut=剪切 +top_paste=粘贴 +top_share=共享 +top_mount=加载 +top_search=查找 +top_config=é…ç½® + +right_name=åç§° +right_size=å¤§å° +right_user=用户 +right_group=组 +right_date=日期 + +edit_enormal=åªèƒ½ç¼–辑正常文件 +edit_title=正在编辑 $1 +edit_title2=正在创建文件 +edit_filename=文件å: +edit_goto=转到 +edit_find=查找 +edit_gotoline=转到行 +edit_replace=æ›¿æ¢ +edit_all=å…¨éƒ¨æ›¿æ¢ +edit_searchfor=æœç´¢ +edit_replaceby=è¢«æ›¿æ¢ +edit_eover=$1 ä¸èƒ½è¢«è¦†ç›– +edit_esave=ä¿å­˜æ–‡ä»¶å¤±è´¥ : $1 +edit_eaccess=你未被å…许ä¿å­˜ '$1' +edit_notfound=未找到文本 $1 +edit_saveclose=ä¿å­˜å¹¶å…³é—­ + +info_file=文件 +info_path=路径: +info_type=类型: +info_size=大å°ï¼š +info_mod=修改: +info_link=è”结到: +info_perms=è®¸å¯ +info_user=用户: +info_group=组: +info_other=其它: +info_octal=八进制: +info_sticky=粘性: +info_sticky2=åªæœ‰æ‰€ç”±è€…æ‰èƒ½åˆ é™¤æ–‡ä»¶ +info_own=æ‰€æœ‰æƒ +info_setuid=设置 uid: +info_setuid2=以用户执行 +info_setgid=设置 gid: +info_setgid2=文件继承组 +info_setgid3=以组执行 +info_apply=应用更改至 +info_apply1=仅此目录 +info_apply2=本目录åŠå…¶æ–‡ä»¶ +info_apply3=本目录åŠå…¶æ‰€æœ‰å­ç›®å½• +info_efailed=æ›´æ–° $1 :$2 失败 +info_read=è¯»å– +info_write=写入 +info_list=列表 +info_exec=执行 + +eacl_eacls=è¯»å– ACLs 失败 : $1 +eacl_acltype=ACL 类型 +eacl_aclname=应用到 +eacl_aclperms=è®¸å¯ +eacl_add=添加 类型的ACL: +eacl_remove=移除ACL +eacl_efs=文件系统 $1 䏿”¯æŒ ACLs +eacl_create=创建 ACL +eacl_edit=编辑 ACL +eacl_user=文件所有者 $1 +eacl_group=文件组 $1 +eacl_eowner=缺少è¦åº”用到的用户或组 +eacl_efailed=为$1 : $2设置ACLs失败 +eacl_emask=最多åªèƒ½æœ‰ä¸€ä¸ªæŽ©ç  ACL æ¡ç›® +eacl_edefmask=最多åªèƒ½æœ‰ä¸€ä¸ªé»˜è®¤æŽ©ç  ACL æ¡ç›® +eacl_title=$1çš„ACL +eacl_owner=文件所有者 +eacl_edefaults=如果一个文件有任何默认的ACL,则它必须有默认用户,组和其他的ACLs。 + +acltype_user=用户 +acltype_group=组 +acltype_other=å…¶ä»– +acltype_mask=æŽ©ç  +acltype_default_user=默认用户 +acltype_default_group=默认组 +acltype_default_other=默认其他 +acltype_default_mask=é»˜è®¤æŽ©ç  + +delete_mtitle=删除多个文件 +delete_dtitle=删除目录 +delete_ftitle=删除文件 +delete_ddesc=ç¡®å®žè¦æ°¸ä¹…删除目录 $1 åŠå…¶å†…容? +delete_fdesc=ç¡®å®žè¦æ°¸ä¹…删除文件 $1? +delete_mdesc=ç¡®å®žè¦æ°¸ä¹…删除这些目录和文件? : +delete_efailed=删除 $1 :$2 失败 + +mkdir_title=新建目录 +mkdir_dir=新建目录: +mkdir_eexists=$1 å·²ç»å­˜åœ¨ +mkdir_efailed=创建目录 $1 失败 +mkdir_eaccess=ä½ æ— æƒåˆ›å»º '$1' + +link_title=创建链接 +link_from=链接自: +link_to=链接到: +link_eexists=$1 å·²ç»å­˜åœ¨ +link_efailed=链接失败:$1 +link_efrom=ä½ æ— æƒé“¾æŽ¥è‡ª '$1' +link_efollow=ä½ æ— æƒåˆ›å»ºç¬¦å·é“¾æŽ¥ + +rename_title=é‡å‘½å$1 +rename_old=原å: +rename_new=æ–°å: +rename_ok=é‡å‘½å +rename_eexists=文件 $1 已存在 +rename_efailed=é‡å‘½å失败: $1 +rename_eold=ä½ æ— æƒé‡å‘½å '$1' +rename_enew=ä½ æ— æƒé‡å‘½å为 '$1' + +file_type0=目录 +file_type1=文本文件 +file_type2=映象文件 +file_type3=二进制文件 +file_type4=文件 +file_type5=符å·é“¾æŽ¥ +file_type6=设备文件 +file_type7=ç®¡é“ + +view_enormal=åªèƒ½æŸ¥çœ‹æ­£å¸¸æ–‡ä»¶ +view_enormal2=åªèƒ½ä¸‹è½½æ­£å¸¸æ–‡ä»¶ +view_eaccess=ä½ æ— æƒè®¿é—® $1 +view_eopen=打开 $1: $2 失败 + +paste_ecopy=在粘贴之å‰å¿…é¡»å‰ªåˆ‡æˆ–æ‹·è´ +paste_egone=æ‹·è´çš„æ–‡ä»¶ $1 å·²ç»ä¸å­˜åœ¨ +paste_eover=$1 ä¸èƒ½è¦†ç›– +paste_eself=ä¸èƒ½å°†æ–‡ä»¶ç²˜è´´è‡³è‡ªèº« +paste_emfailed=移动失败:$1 +paste_ecfailed=æ‹·è´å¤±è´¥ï¼š$1 + +over_title=文件存在 +over_msg=文件 $1 å·²ç»å­˜åœ¨ã€‚在下é¢çš„字段中为è¦ç²˜è´´çš„æ–‡ä»¶è¾“入一个新å。 +over_new=新文件å: +over_ok=确定 + +upload_efailed=打开上传失败:$1 +upload_title=上传文件 +upload_file=è¦ä¸Šä¼ çš„æ–‡ä»¶ +upload_dir=上传到目录 +upload_ok=上传 +upload_conv=是å¦è½¬æ¢DOSæ¢è¡Œç¬¦å·ï¼Ÿ +upload_efile=没有选定è¦ä¸Šä¼ çš„æ–‡ä»¶ã€‚ +upload_edir=上传目录ä¸å­˜åœ¨ã€‚ +upload_eperm=ä½ æ— æƒåˆ›å»º $1 +upload_ewrite=写入 $1:$2 失败。 +upload_already=文件 $1 å·²ç»å­˜åœ¨ã€‚您确定è¦è¦†ç›–它å—? + +find_eaccess=ä½ æ— æƒè®¿é—® $1 +find_eexist=在$2中ä¸å­˜åœ¨$1 +find_edir=$1 䏿˜¯ $2 中的目录 + +cancel=å–æ¶ˆ +close=关闭 + +chmod_eaccess=ä½ æ— æƒè®¿é—® '$1' +chmod_euser=$1:无此用户 +chmod_egroup=$1:无此用户组 +chmod_elink=symlink 失败:$1 +chmod_echown=chown 失败:$1 +chmod_echmod=chmod 失败:$1 +chmod_efollow=您未被å…许编辑符å·é“¾æŽ¥ + +copy_efrom=ä½ æ— æƒä»Ž '$1' æ‹·è´ +copy_eto=ä½ æ— æƒæ‹·è´åˆ° '$1' +copy_elink=symlink 失败 '$1' + +delete_eaccess=ä½ æ— æƒåˆ é™¤ '$1' + +list_eaccess=ä½ æ— æƒè®¿é—®æ­¤ç›®å½• +list_edir=显示列表失败 $1 : $2 + +move_eto=ä½ æ— æƒç§»åŠ¨åˆ° '$1' +move_afrom=ä½ æ— æƒç§»åЍ '$1' + +acl_user=作为用户访问æœåŠ¡å™¨çš„æ–‡ä»¶ +acl_user_def=与Webminç™»å½•ç›¸åŒ +acl_umask=å¯¹æ–°æ–‡ä»¶åŽ»é™¤æŽ©ç  +acl_follow=æ˜¯å¦æ€»æ˜¯è·Ÿéšç¬¦å·é“¾æŽ¥ï¼Ÿ +acl_ro=åªè¯»æ¨¡å¼ï¼Ÿ +acl_dirs=ä»…å…许访问目录 +acl_home=包å«Webmin用户的主目录? +acl_log=对所有文件的修改ä¿å­˜æ—¥å¿—? +acl_goto=打开最先å…许的目录? + +share_title=共享 +share_samba=Windows +share_nfs=NFS +share_son=å¯ç”¨ Windows 文件共享 +share_soff=ç¦ç”¨ Windows 文件共享 +share_writable=å¯å†™å…¥ï¼Ÿ +share_available=现在活动å—? +share_sheader=共享选项 +share_only=ä»… +share_guest=Guest 访问? +share_comment=注释 +share_nheader=NFS 导出选项 +share_non=å·²å¯ç”¨ NFS 文件共享 +share_noff=å·²ç¦ç”¨ NFS 文件共享 +share_desc=æè¿° +share_ro=åªè¯»ä¸»æœº +share_rw=读写主机 +share_root=Root 访问主机 +share_none=æ—  +share_all=所有 +share_listed=已列出的… +share_host=主机 +share_opts=选项 +share_s0=ä¸ä¿¡ä»»ä»»ä½•人 +share_s1=ä¿¡ä»»éž Root 用户 +share_s2=信任所有人 +share_lro=åªè¯» +share_lrw=读写 + +log_create_export=已创建的 NFS 导出 $1 +log_modify_export=已修改的 NFS 导出 $1 +log_delete_export=已删除的 NFS 导出 $1 +log_create_share=已创建的 Samba 共享 $1 +log_modify_share=已修改的 Samba 共享 $1 +log_delete_share=已删除的 Samba 共享 $1 +log_save=å·²ä¿å­˜æ–‡ä»¶ $1 +log_chmod=å·²æ”¹å˜æ–‡ä»¶ $1 çš„æƒé™ +log_mkdir=已创建的目录 $1 +log_upload=已上传的文件 $1 +log_link=已创建的符å·è¿žæŽ¥ $1 到 $2 +log_relink=已修改的符å·è¿žæŽ¥ $1 到 $2 +log_copy=已拷è´çš„æ–‡ä»¶ $1 到 $2 +log_move=已移动的文件 $1 到 $2 +log_delete=已删除的文件 $1 +log_attr=设置文件 $1 的属性 +log_acl=设置文件 $1 çš„ACL + +search_eaccess=æ‚¨æ— æƒæœç´¢æ­¤ç›®å½• +search_title=找到文件 +search_ok=现在æœç´¢ +search_dir=æœç´¢ç›®å½• +search_match=æ–‡ä»¶åŒ¹é… +search_user=用户所有 +search_group=组所有 +search_any=任何 +search_type=文件类型 +search_types_=任何 +search_types_f=文件 +search_types_d=目录 +search_types_l=符å·è¿žæŽ¥ +search_types_p=命åç®¡é“ +search_size=æ–‡ä»¶å¤§å° +search_more=多于 +search_less=少于 +search_xdev=æœç´¢ä»¥å‰çš„加载? +search_edir=丢失或无效的æœç´¢ç›®å½• +search_ematch=丢失匹é…çš„æ­£åˆ™è¡¨è¾¾å¼ +search_euser=丢失用户å +search_egroup=丢失组å +search_esize=文件大å°å€¼å¿…须是整数 +search_crit=æœç´¢æ ‡å‡† +search_list=æœç´¢ç»“æžœ + +facl_eaccess=你未被å…许设置此文件的ACLs + +attr_eattrs=获å–属性失败:$1 +attr_efs=文件系统 $1 䏿”¯æŒå±žæ€§ +attr_add=添加属性 +attr_name=属性åç§° +attr_value=属性值 +attr_efailed=为 $1 : $2 设置属性失败 +attr_title=$1的文件属性 +attr_create=添加属性 +attr_edit=编辑属性 +attr_ename=缺少属性åç§° + +ext_eattrs=èŽ·å–æ‰©å±•属性失败: $1 +ext_efs=文件系统 $1 䏿”¯æŒæ‰©å±•属性 +ext_title=$1 的扩展属性 +ext_header=扩展文件属性 +ext_efailed=为 $1 : $2设置属性失败 + +eattr_A=䏿›´æ–°è®¿é—®æ¬¡æ•° +eattr_a=åªèƒ½æ·»åŠ åˆ°æ–‡ä»¶æœ«å°¾ +eattr_c=压缩ç£ç›˜æ•°æ® +eattr_d=ä¸ä½¿ç”¨dump备份 +eattr_i=ä¸å…许修改 +eattr_s=删除时将å—å½’é›¶ +eattr_S=å†™å…¥åŽæ€»æ˜¯åŒæ­¥ +eattr_u=为å删除ä¿å­˜å†…容 + +mount_eaccess=你未被å…许加载文件系统 +mount_efstab=此加载点上ä¸å­˜åœ¨æ–‡ä»¶ç³»ç»Ÿ +mount_epoint=$1 䏿˜¯åŠ è½½ç‚¹ +mount_rusure1=你确定è¦ä»Ž $2加载 $1 å—? +mount_rusure2=你确定è¦ä»Ž $2å¸è½½ $1 å—? +mount_err1=加载失败 $1 : $2 +mount_err2=å¸è½½å¤±è´¥ $1 : $2 +mount_title1=加载文件系统 +mount_title2=å¸è½½æ–‡ä»¶ç³»ç»Ÿ + + diff --git a/file/lang/zh_TW.Big5 b/file/lang/zh_TW.Big5 new file mode 100644 index 000000000..7d1cfec23 --- /dev/null +++ b/file/lang/zh_TW.Big5 @@ -0,0 +1,197 @@ +index_title=Àɮ׺޲zªÌ +index_nojava=³o­Ó¼Ò²Õ»Ý­n Java ¤~¯à¥¿½Tªº¹B§@, ¦ý¬O±zªºÂsÄý¾¹¦ü¥G¤£¤ä´© Java + +top_ret=ªð¦^ +top_config=³]©w +top_down=¤U¸ü +top_open=¶}±Ò +top_view=À˵ø +top_edit=½s¿è +top_refresh=­«Åª +top_info=¸ê°T +top_search=·j´M +top_delete=§R°£ +top_new=·s¼W +top_upload=¤W¶Ç +top_rename=§ï¦W +top_copy=½Æ»s +top_cut=°Å¤U +top_paste=¶K¤W + +right_name=¦WºÙ +right_size=¤j¤p +right_user=¨Ï¥ÎªÌ +right_group=¸s²Õ +right_date=¤é´Á + +edit_enormal=¥u¯à½s¿è¤@¯ëªºÀÉ®× +edit_title=½s¿è $1 ¤¤ +edit_title2=«Ø¥ßÀɮפ¤ +edit_filename=ÀɮצWºÙ: +edit_goto=«e©¹ +edit_find=´M§ä +edit_gotoline=«e©¹ªº¦C¼Æ +edit_replace=¨ú¥N +edit_all=¥þ³¡¨ú¥N +edit_searchfor=´M§ä¤º®e +edit_replaceby=¨ú¥N¦¨¬° +edit_eover=$1 µLªk³QÂл\ +edit_esave=µLªkÀx¦sÀÉ®× : $1 +edit_eaccess=±z¤£³Q¤¹³\Àx¦s '$1' +edit_efollow=±z¤£³Q¤¹³\¼g¤J²Å¸¹³sµ² '$1' +edit_notfound=§ä¤£¨ì³o­Ó $1 ¤å¥ó +edit_saveclose=Àx¦s¨ÃÃö³¬ +edit_elength=Àɮ׳QºIÂ_¡I + +info_file=ÀÉ®× +info_path=¸ô®|: +info_type=Ãþ§O: +info_size=¤j¤p: +info_mod=­×§ï®É¶¡: +info_link=³sµ²¨ì: +info_perms=Åv­­ +info_user=¨Ï¥ÎªÌ: +info_group=¸s²Õ: +info_other=¨ä¥L: +info_sticky=³]©w¦ì¤¸: +info_sticky2=¥u¦³¾Ö¦³ªÌ¤~¯à§R°£ÀÉ®× +info_own=©Ò¦³Åv +info_setuid=³]©w UID: +info_setuid2=¥H¨Ï¥ÎªÌÅv­­°õ¦æ +info_setgid=³]©w GID: +info_setgid2=ÀÉ®×Ä~©Ó¸s²Õ +info_setgid3=¥H¸s²ÕÅv­­°õ¦æ +info_apply=®M¥ÎÅܧó¨ì +info_apply1=¥u¦³³o­Ó¥Ø¿ý +info_apply2=³o­Ó¥Ø¿ý»P¨ä¤¤ªºÀÉ®× +info_apply3=³o­Ó¥Ø¿ý»P©Ò¦³ªº¤l¥Ø¿ý +info_efailed=µLªk­«Åª $1 : $2 +info_read=Ū¨ú +info_write=¼g¤J +info_list=¦C¥X +info_exec=°õ¦æ + +search_eaccess=±z¤£³Q¤¹³\·j´M³o­Ó¥Ø¿ý +search_title=·j´MÀÉ®× +search_ok=·j´M +search_dir=·j´M¥Ø¿ý +search_match=²Å¦XªºÀɮצWºÙ +search_user=¾Ö¦³ªº¨Ï¥ÎªÌ +search_group=¾Ö¦³ªº¸s²Õ +search_any=¥ô·N +search_type=ÀɮתºÃþ«¬ +search_types_=¥ô·N +search_types_f=ÀÉ®× +search_types_d=¥Ø¿ý +search_types_l=²Å¸¹³sµ²(Symbolic link) +search_types_p=¨ã¦WºÞ¹D(Named pipe) +search_size=Àɮפj¤p +search_more=¶W¹L +search_less=¤p©ó +search_xdev=Search past mounts? +search_edir=¥¼§ä¨ì©ÎµL®Äªº·j´M¥Ø¿ý +search_ematch=¥¼§ä¨ì²Å¦Xªº regexp +search_euser=¥¼§ä¨ì¨Ï¥ÎªÌ¦WºÙ +search_egroup=¥¼§ä¨ì¸s²Õ¦WºÙ +search_esize=Àɮתº¤j¤p¥²¶·¬O¾ã¼Æ +search_crit=·j´M±ø¥ó +search_list=·j´Mµ²ªG + +delete_dtitle=§R°£¥Ø¿ý +delete_ftitle=§R°£ÀÉ®× +delete_mtitle=§R°£¦h­ÓÀÉ®× +delete_ddesc=±z½T©w­n¥Ã¤[ªº§R°£¥Ø¿ý $1 »P¨ä©Ò¦³¤º®e¶Ü¡H +delete_fdesc=±z½T©w­n¥Ã¤[ªº§R°£ÀÉ®× $1 ¶Ü¡H +delete_mdesc=±z½T©w­n¥Ã¤[ªº§R°£³o¨ÇÀɮשM¥Ø¿ý¶Ü¡H : +delete_efailed=µLªk§R°£ $1 : $2 + +mkdir_title=·s¼W¥Ø¿ý +mkdir_dir=¥Ø¿ý: +mkdir_eexists=$1 ¤w¸g¦s¦b +mkdir_efailed=«Ø¥ß¥Ø¿ý¥¢±Ñ : $1 +mkdir_eaccess=±z¤£³Q¤¹³\«Ø¥ß '$1' + +link_title=«Ø¥ß³sµ² +link_from=³sµ²¦Û: +link_to=³sµ²¨ì: +link_eexists=$1 ¤w¸g¦s¦b +link_efailed=³sµ²¥¢±Ñ : $1 +link_efrom=±z¤£³Q¤¹³\³sµ² '$1' +link_efollow=±z¤£³Q¤¹³\«Ø¥ß²Å¸¹³sµ² + +rename_title=Åܧó¦WºÙ $1 +rename_old=ÂÂÀɦW: +rename_new=Åܧó¬°: +rename_ok=§ï¦W +rename_eexists=¥s°µ $1 ªºÀɮפw¸g¦s¦b +rename_efailed=§ï¦W¥¢±Ñ : $1 +rename_eold=±z¤£³Q¤¹³\§ï¦W¦Û '$1' +rename_enew=±z¤£³Q¤¹³\§ï¦W¦¨ '$1' + +file_type0=¥Ø¿ý +file_type1=¤å¦rÀÉ +file_type2=¼v¹³ÀÉ +file_type3=¤G¶i¦ìÀÉ +file_type4=ÀÉ®× +file_type5=²Å¸¹³sµ² +file_type6=³]³Æ±±¨îÀÉ +file_type7=ºÞ½u + +view_enormal=¥u¦³¤@¯ëªºÀÉ®×¥i¥H³QÀ˵ø +view_eaccess=±z¤£³Q¤¹³\¦s¨ú $1 +view_eopen=µLªk¶}±Òn $1 : $2 + +paste_ecopy=¦b±z¶K¤W­n¥ý°Å¤U©Î½Æ»s +paste_egone=½Æ»sªºÀÉ®× $1 ¤w¸g¤£¦s¦b +paste_eover=$1 µLªk³Q»\¼g +paste_eself=±z¤£¯à§âÀÉ®×¶K¨ì¥»¨­¤W +paste_emfailed=²¾°Ê¥¢±Ñ : $1 +paste_ecfailed=«þ¨©¥¢±Ñ : $1 + +upload_efailed=¶}±Ò¤W¶Ç¥¢±Ñ : $1 +upload_title=¤W¶ÇÀÉ®× +upload_file=­n¤W¶ÇªºÀÉ®× +upload_dir=¤W¶Ç¨ì¥Ø¿ý +upload_ok=¤W¶Ç +upload_conv=¬O§_­n§ïÅÜ DOS ªº´«¦æ²Å¸¹? +upload_efile=¨S¦³¿ï¾Ü­n¤W¶ÇªºÀÉ®×. +upload_edir=¤W¶Çªº¥Ø¿ý¤£¦s¦b. +upload_eperm=±z¤£³Q¤¹³\«Ø¥ß $1 +upload_ewrite=µLªk¼g¤J¨ì $1 : $2. +upload_already=ÀÉ®× $1 ¤w¸g¦s¦b¡A±z½T©w­nÂл\¥¦¶Ü¡H +upload_elink=µLªk¤W¶Ç²Å¸¹³sµ² +upload_zip=­n¸ÑÀ£ÁY ZIP ©Î TAR ªºÀÉ®×¶Ü¡H +upload_yes=¬Oªº¡AµM«á§R°£ + + +find_eaccess=±z¤£³Q¤¹³\¦s¨ú $1 +find_eexist=$1 ¤£¦s¦b©ó $2 +find_edir=$1 ¤£¬O¤@­Ó¥Ø¿ý¦b $2 + +cancel=¨ú®ø +close=Ãö³¬ +eopen=¤U¸ü¥¢±Ñ¡G$1 + +chmod_eaccess=±z¤£³Q¤¹³\¦s¨ú '$1' +chmod_euser=$1 : ¨S¦³³o­Ó¨Ï¥ÎªÌ +chmod_egroup=$1 : ¨S¦³³o­Ó¸s²Õ +chmod_elink=²Å¸¹³sµ²¥¢±Ñd : $1 +chmod_echown=Åܧó¾Ö¦³ªÌ¥¢±Ñ : $1 +chmod_echmod=ÅܧóÅv­­¥¢±Ñ : $1 + +copy_efrom=±z¤£³Q¤¹³\«þ¨©¦Û '$1' +copy_eto=±z¤£³Q¤¹³\«þ¨©¨ì '$1' +copy_elink=²Å¸¹³sµ²¥¢±Ñ : $1 + +delete_eaccess=±z¤£³Q¤¹³\§R°£ '$1' + +list_eaccess=±z¤£³Q¤¹³\¦s¨ú³o­Ó¥Ø¿ý + +move_eto=±z¤£³Q¤¹³\²¾°Ê¨ì '$1' +move_afrom=±z¤£³Q¤¹³\²¾°Ê¦Û '$1' + +acl_user=¥H¨Ï¥ÎªÌÅv­­¦s¨ú¦øªA¾¹¤WªºÀÉ®× +acl_umask=«Ø¥ßÀɮתº¾B¸n +acl_follow=¬O§_¸òÀH²Å¸¹³sµ²? +acl_dirs=¥u¤¹³\¦s¨ú¨ì¥Ø¿ý + diff --git a/file/lang/zh_TW.UTF-8 b/file/lang/zh_TW.UTF-8 new file mode 100644 index 000000000..86bb5ee10 --- /dev/null +++ b/file/lang/zh_TW.UTF-8 @@ -0,0 +1,197 @@ +index_title=檔案管ç†è€… +index_nojava=é€™å€‹æ¨¡çµ„éœ€è¦ Java æ‰èƒ½æ­£ç¢ºçš„é‹ä½œ, 但是您的ç€è¦½å™¨ä¼¼ä¹Žä¸æ”¯æ´ Java + +top_ret=返回 +top_config=設定 +top_down=下載 +top_open=開啟 +top_view=檢視 +top_edit=編輯 +top_refresh=é‡è®€ +top_info=資訊 +top_search=æœå°‹ +top_delete=刪除 +top_new=新增 +top_upload=上傳 +top_rename=改å +top_copy=複製 +top_cut=剪下 +top_paste=貼上 + +right_name=å稱 +right_size=å¤§å° +right_user=使用者 +right_group=群組 +right_date=日期 + +edit_enormal=åªèƒ½ç·¨è¼¯ä¸€èˆ¬çš„æª”案 +edit_title=編輯 $1 中 +edit_title2=建立檔案中 +edit_filename=檔案å稱: +edit_goto=å‰å¾€ +edit_find=尋找 +edit_gotoline=å‰å¾€çš„列數 +edit_replace=å–代 +edit_all=全部å–代 +edit_searchfor=尋找內容 +edit_replaceby=å–代æˆç‚º +edit_eover=$1 無法被覆蓋 +edit_esave=無法儲存檔案 : $1 +edit_eaccess=您ä¸è¢«å…許儲存 '$1' +edit_efollow=您ä¸è¢«å…è¨±å¯«å…¥ç¬¦è™Ÿé€£çµ '$1' +edit_notfound=找ä¸åˆ°é€™å€‹ $1 文件 +edit_saveclose=儲存並關閉 +edit_elength=æª”æ¡ˆè¢«æˆªæ–·ï¼ + +info_file=檔案 +info_path=路徑: +info_type=類別: +info_size=大å°: +info_mod=修改時間: +info_link=連çµåˆ°: +info_perms=æ¬Šé™ +info_user=使用者: +info_group=群組: +info_other=å…¶ä»–: +info_sticky=設定ä½å…ƒ: +info_sticky2=åªæœ‰æ“有者æ‰èƒ½åˆªé™¤æª”案 +info_own=所有權 +info_setuid=設定 UID: +info_setuid2=以使用者權é™åŸ·è¡Œ +info_setgid=設定 GID: +info_setgid2=檔案繼承群組 +info_setgid3=以群組權é™åŸ·è¡Œ +info_apply=套用變更到 +info_apply1=åªæœ‰é€™å€‹ç›®éŒ„ +info_apply2=這個目錄與其中的檔案 +info_apply3=這個目錄與所有的å­ç›®éŒ„ +info_efailed=無法é‡è®€ $1 : $2 +info_read=è®€å– +info_write=寫入 +info_list=列出 +info_exec=執行 + +search_eaccess=您ä¸è¢«å…許æœå°‹é€™å€‹ç›®éŒ„ +search_title=æœå°‹æª”案 +search_ok=æœå°‹ +search_dir=æœå°‹ç›®éŒ„ +search_match=符åˆçš„æª”案å稱 +search_user=æ“æœ‰çš„使用者 +search_group=æ“æœ‰çš„群組 +search_any=ä»»æ„ +search_type=檔案的類型 +search_types_=ä»»æ„ +search_types_f=檔案 +search_types_d=目錄 +search_types_l=符號連çµ(Symbolic link) +search_types_p=å…·å管é“(Named pipe) +search_size=æª”æ¡ˆå¤§å° +search_more=è¶…éŽ +search_less=å°æ–¼ +search_xdev=Search past mounts? +search_edir=未找到或無效的æœå°‹ç›®éŒ„ +search_ematch=未找到符åˆçš„ regexp +search_euser=未找到使用者å稱 +search_egroup=未找到群組å稱 +search_esize=檔案的大å°å¿…須是整數 +search_crit=æœå°‹æ¢ä»¶ +search_list=æœå°‹çµæžœ + +delete_dtitle=刪除目錄 +delete_ftitle=刪除檔案 +delete_mtitle=刪除多個檔案 +delete_ddesc=æ‚¨ç¢ºå®šè¦æ°¸ä¹…的刪除目錄 $1 與其所有內容嗎? +delete_fdesc=æ‚¨ç¢ºå®šè¦æ°¸ä¹…的刪除檔案 $1 嗎? +delete_mdesc=æ‚¨ç¢ºå®šè¦æ°¸ä¹…的刪除這些檔案和目錄嗎? : +delete_efailed=無法刪除 $1 : $2 + +mkdir_title=新增目錄 +mkdir_dir=目錄: +mkdir_eexists=$1 已經存在 +mkdir_efailed=建立目錄失敗 : $1 +mkdir_eaccess=您ä¸è¢«å…許建立 '$1' + +link_title=å»ºç«‹é€£çµ +link_from=連çµè‡ª: +link_to=連çµåˆ°: +link_eexists=$1 已經存在 +link_efailed=連çµå¤±æ•— : $1 +link_efrom=您ä¸è¢«å…è¨±é€£çµ '$1' +link_efollow=您ä¸è¢«å…è¨±å»ºç«‹ç¬¦è™Ÿé€£çµ + +rename_title=變更å稱 $1 +rename_old=舊檔å: +rename_new=變更為: +rename_ok=改å +rename_eexists=å«åš $1 的檔案已經存在 +rename_efailed=改å失敗 : $1 +rename_eold=您ä¸è¢«å…許改å自 '$1' +rename_enew=您ä¸è¢«å…è¨±æ”¹åæˆ '$1' + +file_type0=目錄 +file_type1=文字檔 +file_type2=å½±åƒæª” +file_type3=äºŒé€²ä½æª” +file_type4=檔案 +file_type5=ç¬¦è™Ÿé€£çµ +file_type6=設備控制檔 +file_type7=管線 + +view_enormal=åªæœ‰ä¸€èˆ¬çš„æª”案å¯ä»¥è¢«æª¢è¦– +view_eaccess=您ä¸è¢«å…è¨±å­˜å– $1 +view_eopen=無法開啟n $1 : $2 + +paste_ecopy=在您貼上è¦å…ˆå‰ªä¸‹æˆ–複製 +paste_egone=複製的檔案 $1 已經ä¸å­˜åœ¨ +paste_eover=$1 無法被蓋寫 +paste_eself=您ä¸èƒ½æŠŠæª”案貼到本身上 +paste_emfailed=移動失敗 : $1 +paste_ecfailed=æ‹·è²å¤±æ•— : $1 + +upload_efailed=開啟上傳失敗 : $1 +upload_title=上傳檔案 +upload_file=è¦ä¸Šå‚³çš„æª”案 +upload_dir=上傳到目錄 +upload_ok=上傳 +upload_conv=是å¦è¦æ”¹è®Š DOS çš„æ›è¡Œç¬¦è™Ÿ? +upload_efile=æ²’æœ‰é¸æ“‡è¦ä¸Šå‚³çš„æª”案. +upload_edir=上傳的目錄ä¸å­˜åœ¨. +upload_eperm=您ä¸è¢«å…許建立 $1 +upload_ewrite=無法寫入到 $1 : $2. +upload_already=檔案 $1 已經存在,您確定è¦è¦†è“‹å®ƒå—Žï¼Ÿ +upload_elink=ç„¡æ³•ä¸Šå‚³ç¬¦è™Ÿé€£çµ +upload_zip=è¦è§£å£“縮 ZIP 或 TAR 的檔案嗎? +upload_yes=是的,然後刪除 + + +find_eaccess=您ä¸è¢«å…è¨±å­˜å– $1 +find_eexist=$1 ä¸å­˜åœ¨æ–¼ $2 +find_edir=$1 䏿˜¯ä¸€å€‹ç›®éŒ„在 $2 + +cancel=å–æ¶ˆ +close=關閉 +eopen=下載失敗:$1 + +chmod_eaccess=您ä¸è¢«å…è¨±å­˜å– '$1' +chmod_euser=$1 : 沒有這個使用者 +chmod_egroup=$1 : 沒有這個群組 +chmod_elink=符號連çµå¤±æ•—d : $1 +chmod_echown=è®Šæ›´æ“æœ‰è€…失敗 : $1 +chmod_echmod=變更權é™å¤±æ•— : $1 + +copy_efrom=您ä¸è¢«å…許拷è²è‡ª '$1' +copy_eto=您ä¸è¢«å…許拷è²åˆ° '$1' +copy_elink=符號連çµå¤±æ•— : $1 + +delete_eaccess=您ä¸è¢«å…許刪除 '$1' + +list_eaccess=您ä¸è¢«å…許存å–這個目錄 + +move_eto=您ä¸è¢«å…許移動到 '$1' +move_afrom=您ä¸è¢«å…許移動自 '$1' + +acl_user=以使用者權é™å­˜å–伺æœå™¨ä¸Šçš„æª”案 +acl_umask=建立檔案的é®ç½© +acl_follow=是å¦è·Ÿéš¨ç¬¦è™Ÿé€£çµ? +acl_dirs=åªå…許存å–到目錄 + diff --git a/file/list.cgi b/file/list.cgi new file mode 100755 index 000000000..955856b23 --- /dev/null +++ b/file/list.cgi @@ -0,0 +1,47 @@ +#!/usr/local/bin/perl +# list.cgi +# Return a list of files in some directory + +require './file-lib.pl'; +&ReadParse(); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +$d = $in{'dir'} eq "/" ? "" : $in{'dir'}; +if (!&can_list($in{'dir'})) { + print $text{'list_eaccess'},"\n"; + } +elsif (!opendir(DIR, $in{'dir'})) { + # Cannot list the dir .. but maybe we don't have to! + # If a sub-directory was requested, just assume that it exists. + local $err = $!; + local @alt = &accessible_subdir($in{'dir'}); + local $fil = &file_info_line($in{'dir'}); + if (@alt && $fil) { + print "\n"; + foreach $f ("$in{'dir'}/.", "$in{'dir'}/..", @alt) { + $fil = &file_info_line($f); + print "$fil\n" if (defined($fil)); + } + } + else { + print "$err\n"; + } + } +else { + # Can list the directory + print "\n"; + @files = sort { $a cmp $b } readdir(DIR); + if ($hide_dot_files) { + @files = grep { $_ !~ /^\./ } @files; + } + else { + @files = grep { $_ ne "." && $_ ne ".." } @files; + } + @files = grep { &can_list("$d/$_") } @files; + closedir(DIR); + foreach $f (".", "..", @files) { + local $fil = &file_info_line("$d/$f"); + print "$fil\n" if (defined($fil)); + } + } + diff --git a/file/list_exports.cgi b/file/list_exports.cgi new file mode 100755 index 000000000..4f23acbf6 --- /dev/null +++ b/file/list_exports.cgi @@ -0,0 +1,95 @@ +#!/usr/local/bin/perl +# list_exports.cgi +# Output info about NFS exports + +require './file-lib.pl'; +print "Content-type: text/plain\n\n"; +if ($access{'uid'}) { + # User has no access to NFS + print "0\n"; + exit; + } + +&read_acl(\%acl, undef); +%einfo = &get_module_info("exports"); +%dinfo = &get_module_info("dfsadmin"); +#%binfo = &get_module_info("bsdexports"); # too hard + +if (%einfo && &check_os_support(\%einfo)) { + # Linux NFS exports + &module_check("exports"); + if (!&has_command("rpc.nfsd") && !&has_command("nfsd")) { + print "0\n"; + exit; + } + print "1\n"; + &foreign_require("exports", "exports-lib.pl"); + foreach $e (&foreign_call("exports", "list_exports")) { + push(@{$exp{$e->{'dir'}}}, $e) + if ($e->{'dir'} !~ /:/ && $e->{'host'} !~ /:/); + } + foreach $d (keys %exp) { + local $host; + foreach $e (@{$exp{$d}}) { + local $o = $e->{'options'}; + $host .= sprintf ":%s:%d:%d", + $e->{'host'} ? $e->{'host'} : '*', + defined($o->{'ro'}), + defined($o->{'all_squash'}) ? 0 : + defined($o->{'no_root_squash'}) ? 2 : 1; + } + print &make_chroot($d),$host,"\n"; + } + } +elsif (%dinfo && &check_os_support(\%dinfo)) { + # Solaris NFS shares + &module_check("dfsadmin"); + print "2\n"; + &foreign_require("dfsadmin", "dfs-lib.pl"); + foreach $s (&foreign_call("dfsadmin", "list_shares")) { + $opts = &foreign_call("dfsadmin", "parse_options",$s->{'opts'}); + $opts->{'ro'} = '-' if (!defined($opts->{'ro'})); + $opts->{'ro'} =~ s/:/ /g; + $opts->{'rw'} = '-' if (!defined($opts->{'rw'})); + $opts->{'rw'} =~ s/:/ /g; + $opts->{'root'} = '-' if (!defined($opts->{'root'})); + $opts->{'root'} =~ s/:/ /g; + printf "%s:%s:%s:%s:%s\n", + &make_chroot($s->{'dir'}), $opts->{'ro'}, $opts->{'rw'}, + $opts->{'root'}, $s->{'desc'}; + } + } +elsif (%binfo && &check_os_support(\%binfo)) { + # BSD NFS exports + &module_check("bsdexports"); + print "3\n"; + &foreign_require("bsdexports", "bsdexports-lib.pl"); + foreach $e (&foreign_call("bsdexports", "list_exports")) { + foreach $d (@{$e->{'dirs'}}) { + printf "%s:%s", $d, $e->{'ro'} ? 1 : 0; + if ($e->{'network'}) { + printf ":%s/%s\n", + $e->{'network'}, $e->{'mask'}; + } + else { + foreach $h (@{$e->{'hosts'}}) { + print ":$h"; + } + print "\n"; + } + } + } + } +else { + # No NFS modules installed or supported + print "0\n"; + } + +sub module_check +{ +if (!$acl{$base_remote_user,$_[0]}) { + print "0\n"; + exit; + } +} + diff --git a/file/list_shares.cgi b/file/list_shares.cgi new file mode 100755 index 000000000..456e7a1e2 --- /dev/null +++ b/file/list_shares.cgi @@ -0,0 +1,45 @@ +#!/usr/local/bin/perl +# list_shares.cgi +# Output info about samba shares + +require './file-lib.pl'; +print "Content-type: text/plain\n\n"; +if ($access{'uid'}) { + # User has no access to samba + print "0\n"; + exit; + } + +%minfo = &get_module_info("samba"); +&read_acl(\%acl, undef); +if (!%minfo || !&check_os_support(\%minfo) || + !$acl{$base_remote_user,'samba'}) { + # Samba module not installed or supported + print "0\n"; + exit; + } + +&foreign_require("samba", "samba-lib.pl"); +%sconfig = &foreign_config("samba"); +if (!-r $sconfig{'smb_conf'} || !&has_command($sconfig{'samba_server'})) { + # Samba not installed + print "0\n"; + exit; + } + +print "1\n"; +foreach $s (&foreign_call("samba", "list_shares")) { + &foreign_call("samba", "get_share", $s); + if ($s ne 'global' && $s ne 'homes' && $s ne 'printers' && + $samba::share{'path'} =~ /^\/[^\%\s\:]*$/ && + $samba::share{'printable'} !~ /true|yes/i) { + printf "%s:%s:%s:%s:%s\n", + $samba::share{'path'}, + $samba::share{'available'} =~ /no|false/i ? 0 : 1, + $samba::share{'writable'} =~ /yes|true/i ? 1 : 0, + $samba::share{'guest only'} =~ /yes|true/i ? 2 : + $samba::share{'public'} =~ /yes|true/i ? 1 : 0, + $samba::share{'comment'}; + } + } + diff --git a/file/log_parser.pl b/file/log_parser.pl new file mode 100644 index 000000000..6810f45cd --- /dev/null +++ b/file/log_parser.pl @@ -0,0 +1,45 @@ +# log_parser.pl +# Functions for parsing this module's logs + +do 'file-lib.pl'; + +# parse_webmin_log(user, script, action, type, object, ¶ms) +# Converts logged information from this module into human-readable form +sub parse_webmin_log +{ +local ($user, $script, $action, $type, $object, $p) = @_; +if ($type eq 'export' || $type eq 'share') { + return &text("log_${action}_${type}", + "".&html_escape($object).""); + } +elsif ($action eq 'save' || $action eq 'chmod' || $action eq 'mkdir' || + $action eq 'upload' || $action eq 'delete') { + return &text("log_${action}", + "".&html_escape($object).""); + } +elsif ($action eq 'link' || $action eq 'move' || $action eq 'copy') { + return &text("log_${action}", + "".&html_escape($object)."", + "".&html_escape($p->{'to'}).""); + } +elsif ($action eq 'relink') { + return &text('log_relink', + "".&html_escape($object)."", + "".&html_escape($p->{'linkto'}).""); + } +elsif ($action eq 'rename') { + return &text('log_move', + "".&html_escape($object)."", + "".&html_escape($p->{'new'}).""); + } +elsif ($action eq 'attr') { + return &text('log_attr', "".&html_escape($object).""); + } +elsif ($action eq 'acl') { + return &text('log_acl', "".&html_escape($object).""); + } +else { + return undef; + } +} + diff --git a/file/makelink.cgi b/file/makelink.cgi new file mode 100755 index 000000000..de2ad2e08 --- /dev/null +++ b/file/makelink.cgi @@ -0,0 +1,26 @@ +#!/usr/local/bin/perl +# makelink.cgi +# Create a symbolic link + +require './file-lib.pl'; +$disallowed_buttons{'makelink'} && &error($text{'ebutton'}); +&ReadParse(); +&webmin_log("link", undef, $in{'from'}, \%in); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +&lock_file($in{'from'}); +if ($access{'ro'} || !&can_access($in{'from'})) { + print &text('link_efrom2', $in{'from'}),"\n"; + } +elsif ($follow) { + print $text{'link_efollow'},"\n"; + } +elsif (!symlink($in{'to'}, $in{'from'})) { + print "$!\n"; + } +else { + print "\n"; + print &file_info_line($in{'from'}),"\n"; + &unlock_file($in{'from'}); + } + diff --git a/file/mkdir.cgi b/file/mkdir.cgi new file mode 100755 index 000000000..4ff365a87 --- /dev/null +++ b/file/mkdir.cgi @@ -0,0 +1,24 @@ +#!/usr/local/bin/perl +# mkdir.cgi +# Create a directory + +require './file-lib.pl'; +$disallowed_buttons{'mkdir'} && &error($text{'ebutton'}); +&ReadParse(); +&webmin_log("mkdir", undef, $in{'dir'}, \%in); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +&lock_file($in{'dir'}); +if ($access{'ro'} || !&can_access($in{'dir'})) { + print &text('mkdir_eaccess', $in{'dir'}),"\n"; + } +elsif (!mkdir($in{'dir'}, 0777)) { + print "$!\n"; + } +else { + print "\n"; + print &file_info_line($in{'dir'}),"\n"; + &unlock_file($in{'dir'}); + } + + diff --git a/file/module.info b/file/module.info new file mode 100644 index 000000000..d3ac7747d --- /dev/null +++ b/file/module.info @@ -0,0 +1,25 @@ +desc_ko_KR.euc=ÆÄÀÏ °ü¸®ÀÚ +risk=high +desc_ru_SU=íÅÎÅÄÖÅÒ ÆÁÊÌÏ× +desc_zh_TW.Big5=Àɮ׺޲zªÌ +desc_pl=Zarz±dzanie plikami +desc_de=Datei-Manager (Java erforderlich) +name=FileManager +desc_zh_CN=Îļþ¹ÜÀíÆ÷ +desc_pt=Administrador de Ficheiros +desc_tr=Dosya Yöneticisi +desc=File Manager +desc_es=Explorador de Archivos +desc_sv=Filhanterare +desc_fr=Gestionnaire de Fichiers +desc_ja_JP.euc=¥Õ¥¡¥¤¥ë ¥Þ¥Í¡¼¥¸¥ã +desc_ru_RU=Ìåíåäæåð ôàéëîâ +desc_ca=Administrador de Fitxers +desc_pt_BR=Gerenciador de Arquivos +desc_sk=Správca Systému Súborov +longdesc=View, edit and change permissions on files and directories on your system with a Windows-like file manager. +readonly=1 +desc_zh_TW.UTF-8=檔案管ç†è€… +desc_zh_CN.UTF-8=文件管ç†å™¨ +desc_ja_JP.UTF-8=ファイル マãƒãƒ¼ã‚¸ãƒ£ +desc_ko_KR.UTF-8=íŒŒì¼ ê´€ë¦¬ìž diff --git a/file/mount.cgi b/file/mount.cgi new file mode 100755 index 000000000..470704d79 --- /dev/null +++ b/file/mount.cgi @@ -0,0 +1,48 @@ +#!/usr/local/bin/perl +# mount.cgi +# Mount or un-mount some filesystem +# XXX need way to detect current status? +# XXX should return result +# XXX client must force refresh: +# XXX can only deal with stuff in /etc/fstab + +require './file-lib.pl'; +$disallowed_buttons{'mount'} && &error($text{'ebutton'}); +&ReadParse(); +print "Content-type: text/plain\n\n"; +if ($access{'ro'} || $access{'uid'}) { + # User is not allowed to mount + print "$text{'mount_eaccess'}\n"; + exit; + } + +# Get current status +$dir = &unmake_chroot($in{'dir'}); +&foreign_require("mount", "mount-lib.pl"); +@fstab = &mount::list_mounts(); +@mtab = &mount::list_mounted(); +($fstab) = grep { $_->[0] eq $dir } @fstab; +if (!$fstab) { + # Doesn't exist! + print "$text{'mount_efstab'}\n"; + exit; + } +($mtab) = grep { $_->[0] eq $dir } @mtab; + +if ($mtab) { + # Attempt to un-mount now + $err = &mount::unmount_dir(@$mtab); + } +else { + # Attempt to mount now + $err = &mount::mount_dir(@$fstab); + } +if ($err) { + $err =~ s/<[^>]*>//g; + $err =~ s/\n/ /g; + print $err,"\n"; + } +else { + print "\n"; + } + diff --git a/file/move.cgi b/file/move.cgi new file mode 100755 index 000000000..230a37a64 --- /dev/null +++ b/file/move.cgi @@ -0,0 +1,29 @@ +#!/usr/local/bin/perl +# move.cgi +# Move some file or directory + +require './file-lib.pl'; +$disallowed_buttons{'copy'} && &error($text{'ebutton'}); +&ReadParse(); +&webmin_log("move", undef, $in{'from'}, \%in); +&switch_acl_uid(); +print "Content-type: text/plain\n\n"; +unlink($in{'to'}); # in case we are moving a directory +if ($access{'ro'} || !&can_access($in{'to'})) { + print &text('move_eto', $in{'to'}),"\n"; + exit; + } +if (!&can_access($in{'from'})) { + print &text('move_efrom', $in{'from'}),"\n"; + exit; + } +$ok = &rename_logged(&unmake_chroot($in{'from'}), + &unmake_chroot($in{'to'})); +if (!$ok) { + print $!,"\n"; + } +else { + print "\n"; + print &file_info_line(&unmake_chroot($in{'to'})),"\n"; + } + diff --git a/file/preview.cgi b/file/preview.cgi new file mode 100755 index 000000000..51f9f5c7e --- /dev/null +++ b/file/preview.cgi @@ -0,0 +1,124 @@ +#!/usr/local/bin/perl +# Scale some image down to the preview size + +require './file-lib.pl'; +&ReadParse(); +use POSIX; +$p = $ENV{'PATH_INFO'}; + +# Try to guess type from filename +$type = &guess_mime_type($p, undef); +if (!$type) { + # No idea .. use the 'file' command + $out = &backquote_command("file ". + quotemeta(&resolve_links($p)), 1); + if ($out =~ /text|script/) { + $type = "text/plain"; + } + else { + &error_exit(&text('preview_etype', $p)); + } + } + +# Make sure the type is OK +if ($type ne "image/gif" && $type ne "image/jpeg" && $type ne "image/png" && + $type ne "image/tiff" && $type ne "application/pdf" && + $type !~ /^image\/x-portable/ && $type ne "application/postscript") { + &error_exit(&text('preview_etype2', $p)); + } + +&switch_acl_uid_and_chroot(); +if (!&can_access($p)) { + # ACL rules prevent access to file + &error_exit(&text('view_eaccess', $p)); + } + +# Test if the file can be opened +if (!open(FILE, $p)) { + # Unix permissions prevent access + &error_exit(&text('view_eopen', $p, $!)); + } +close(FILE); + +eval "use GD"; +if ($@ || $type eq "image/tiff" || $type eq "application/pdf" || + $type =~ /^image\/x-portable/ || $type eq "application/postscript") { + # Find an appropriate scaler + $pnmcmd = $type eq "image/gif" ? "giftopnm" : + $type eq "image/jpeg" ? "djpeg" : + $type eq "image/png" ? "pngtopnm" : + $type eq "image/tiff" ? "tifftopnm" : + $type =~ /^image\/x-portable/ ? "cat" : + $type eq "application/postscript" ? "pstopnm" : + $type eq "application/pdf" ? "pdftoppm" : + undef; + &has_command($pnmcmd) || + &error_exit(&text('preview_ecmd', $pnmcmd)); + &has_command("pnmscale") || + &error_exit(&text('preview_ecmd', "pnmscale")); + &has_command("cjpeg") || + &error_exit(&text('preview_ecmd', "cjpeg")); + + # Run scaler + $width = $config{'width'} || $userconfig{'width'} || 300; + $errout = &transname(); + print "Content-type: image/jpeg\n"; + print "\n"; + if ($type eq "application/pdf") { + # Previewing first page of PDF + $temp = &tempname(); + $out = &backquote_command("$pnmcmd -f 1 -l 1 ".quotemeta($p)." ".$temp." 2>&1"); + if ($? || !-r "$temp-000001.ppm") { + &error_exit("$pnmcmd failed : $out"); + } + open(SCALE, "(cat $temp-000001.ppm | pnmscale --width $width | cjpeg) 2>$errout |"); + push(@main::temporary_files, "$temp-000001.ppm"); + } + elsif ($type eq "application/postscript") { + # Previewing first page of a postscript file + $temp = &transname(); + mkdir($temp, 0755); + ©_source_dest($p, "$temp/file.ps"); + $out = &backquote_command("$pnmcmd $temp/file.ps 2>&1"); + if ($? || !-r "$temp/file001.ppm") { + &error_exit("$pnmcmd failed : $out"); + } + open(SCALE, "(cat $temp/file001.ppm | pnmscale --width $width | cjpeg) 2>$errout |"); + } + else { + # Converting to JPEG + open(SCALE, "($pnmcmd <".quotemeta($p)." | pnmscale --width $width | cjpeg) 2>$errout |"); + } + $err = &read_file_contents($errout); + print STDERR $err; + while() { + print; + } + close(SCALE); + } +else { + # Use the GD library + $image = $type eq "image/gif" ? GD::Image->newFromGif($p) : + $type eq "image/jpeg" ? GD::Image->newFromJpeg($p) : + $type eq "image/png" ? GD::Image->newFromPng($p) : undef; + $image || &error_exit(&text('preview_egd')); + + $width = $config{'width'} || $userconfig{'width'} || 300; + $height = $image->height * (($width*1.0) / $image->width); + + $scaled = new GD::Image($width, $height); + $scaled->copyResampled($image, 0, 0, 0, 0, $width, $height, + $image->width, $image->height); + print "Content-type: image/jpeg\n"; + print "\n"; + print $scaled->jpeg(); + } + +sub error_exit +{ +print "Content-type: text/plain\n"; +print "Content-length: ",length($_[0]),"\n\n"; +print $_[0]; +exit; +} + diff --git a/file/rename.cgi b/file/rename.cgi new file mode 100755 index 000000000..836ff9b37 --- /dev/null +++ b/file/rename.cgi @@ -0,0 +1,24 @@ +#!/usr/local/bin/perl +# rename.cgi +# Rename some file + +require './file-lib.pl'; +$disallowed_buttons{'rename'} && &error($text{'ebutton'}); +&ReadParse(); +&webmin_log("rename", undef, $in{'old'}, \%in); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +if ($access{'ro'} || !&can_access($in{'old'})) { + print &text('rename_eold', $in{'old'}),"\n"; + } +elsif (!&can_access($in{'new'})) { + print &text('rename_enew', $in{'new'}),"\n"; + } +elsif (!&rename_logged($in{'old'}, $in{'new'})) { + print "$!\n"; + } +else { + print "\n"; + } + + diff --git a/file/root.cgi b/file/root.cgi new file mode 100755 index 000000000..7da2ce258 --- /dev/null +++ b/file/root.cgi @@ -0,0 +1,8 @@ +#!/usr/local/bin/perl +# root.cgi +# Return information about the root directory + +require './file-lib.pl'; +print "Content-type: text/plain\n\n"; +&go_chroot(); +print &file_info_line("/"),"\n"; diff --git a/file/save.cgi b/file/save.cgi new file mode 100755 index 000000000..7c2000b9d --- /dev/null +++ b/file/save.cgi @@ -0,0 +1,39 @@ +#!/usr/local/bin/perl +# save.cgi +# Write data to a file + +require './file-lib.pl'; +$disallowed_buttons{'edit'} && &error($text{'ebutton'}); +$p = $ENV{'PATH_INFO'}; +&webmin_log("save", undef, $p) if ($access{'uid'}); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; + +# Read posted data +$clen = $ENV{'CONTENT_LENGTH'}; +&read_fully(STDIN, \$buf, $clen) == $clen || + &error("Failed to read POST input : $!"); + +if (defined($in{'length'}) && length($buf) != $in{'length'}) { + print &text('edit_elength'),"\n"; + } +else { + &lock_file($p); + if ($access{'ro'} || !&can_access($p)) { + print &text('edit_eaccess', $p),"\n"; + } + elsif (-l $p && !&must_follow($p)) { + print &text('edit_efollow', $p),"\n"; + } + elsif (!&open_tempfile(FILE, ">$p", 1)) { + print "$!\n"; + } + else { + &print_tempfile(FILE, $buf); + &close_tempfile(FILE); + &unlock_file($p); + print "\n"; + print &file_info_line($p),"\n"; + &webmin_log("save", undef, $p) if (!$access{'uid'}); + } + } diff --git a/file/save_export.cgi b/file/save_export.cgi new file mode 100755 index 000000000..b3d7b91da --- /dev/null +++ b/file/save_export.cgi @@ -0,0 +1,144 @@ +#!/usr/local/bin/perl +# save_export.cgi +# Update, create or delete an NFS export + +require './file-lib.pl'; +$disallowed_buttons{'sharing'} && &error($text{'ebutton'}); +&ReadParse(); +print "Content-type: text/plain\n\n"; +if ($access{'ro'} || $access{'uid'}) { + # User has no access to NFS + print "0\n"; + exit; + } + +&read_acl(\%acl, undef); +%einfo = &get_module_info("exports"); +%dinfo = &get_module_info("dfsadmin"); +%binfo = &get_module_info("bsdexports"); + +if (%einfo && &check_os_support(\%einfo)) { + # Linux NFS exports + &module_check("exports"); + &foreign_require("exports", "exports-lib.pl"); + %econfig = &foreign_config("exports"); + &lock_file($econfig{'exports_file'}); + foreach $e (&foreign_call("exports", "list_exports")) { + push(@{$exp{$e->{'dir'}}}, $e); + } + if ($in{'delete'}) { + # Delete all exports for some dir + foreach $e (reverse(@{$exp{$in{'path'}}})) { + &foreign_call("exports", "delete_export", $e); + } + } + else { + # Adding or updating an export + if (!$in{'new'}) { + # Updating, so delete old exports first + foreach $e (reverse(@{$exp{$in{'path'}}})) { + $host{$e->{'host'}} = $e; + &foreign_call("exports", "delete_export", $e); + } + } + for($i=0; $in{"host$i"}; $i++) { + $h = $in{"host$i"} eq '*' ? '' : $in{"host$i"}; + $e = $host{$h}; + $e = { 'active' => 1, + 'host' => $h, + 'dir' => $in{'path'} } if (!$e); + delete($e->{'options'}->{'ro'}); + if ($in{"ro$i"}) { + $e->{'options'}->{'ro'} = ''; + } + delete($e->{'options'}->{'all_squash'}); + delete($e->{'options'}->{'no_root_squash'}); + if ($in{"squash$i"} == 0) { + $e->{'options'}->{'all_squash'} = ''; + } + elsif ($in{"squash$i"} == 2) { + $e->{'options'}->{'no_root_squash'} = ''; + } + &foreign_call("exports", "create_export", $e); + } + } + &unlock_file($econfig{'exports_file'}); + + # Apply configuration + &exports::restart_mountd(); + + &webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify', + 'export', $in{'path'}); + print "1\n"; + } +elsif (%dinfo && &check_os_support(\%dinfo)) { + # Solaris NFS shares + &module_check("dfsadmin"); + &foreign_require("dfsadmin", "dfs-lib.pl"); + %iconfig = &foreign_config("dfsadmin"); + &lock_file($iconfig{'dfstab_file'}); + @shlist = &foreign_call("dfsadmin", "list_shares"); + foreach $s (@shlist) { + $share = $s if ($s->{'dir'} eq $in{'path'}); + } + if ($in{'delete'}) { + # Delete existing share + &foreign_call("dfsadmin", "delete_share", $share); + } + elsif ($in{'new'}) { + # Create new share + foreach $r ('ro', 'rw', 'root') { + if ($in{$r} ne '-') { + $in{$r} =~ s/\s+/:/g; + $opts->{$r} = $in{$r}; + } + } + $share->{'dir'} = $in{'path'}; + $share->{'desc'} = $in{'desc'}; + $share->{'opts'} = + &foreign_call("dfsadmin", "join_options", $opts); + &foreign_call("dfsadmin", "create_share", $share); + } + else { + # Update existing share + $opts = &foreign_call("dfsadmin", "parse_options", + $share->{'opts'}); + foreach $r ('ro', 'rw', 'root') { + if ($in{$r} eq '-') { delete($opts->{$r}); } + else { + $in{$r} =~ s/\s+/:/g; + $opts->{$r} = $in{$r}; + } + } + $share->{'dir'} = $in{'path'}; + $share->{'desc'} = $in{'desc'}; + $share->{'opts'} = + &foreign_call("dfsadmin", "join_options", $opts); + &foreign_call("dfsadmin", "modify_share", $share); + } + &unlock_file($iconfig{'dfstab_file'}); + + # Apply changes to NFS daemon + &dfsadmin::apply_configuration(); + + &webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify', + 'export', $in{'path'}); + print "1\n"; + } +elsif (%binfo && &check_os_support(\%binfo)) { + # BSD NFS exports + &module_check("bsdexports"); + } +else { + # No NFS modules installed or supported + print "0\n"; + } + +sub module_check +{ +if (!$acl{$base_remote_user,$_[0]}) { + print "0\n"; + exit; + } +} + diff --git a/file/save_html.cgi b/file/save_html.cgi new file mode 100755 index 000000000..04995b880 --- /dev/null +++ b/file/save_html.cgi @@ -0,0 +1,36 @@ +#!/usr/local/bin/perl +# Write data from an HTML editor + +require './file-lib.pl'; +$disallowed_buttons{'edit'} && &error($text{'ebutton'}); +&ReadParseMime(); +&error_setup($text{'html_err'}); + +# Try to write the file +$p = $in{'file'}; +&switch_acl_uid_and_chroot(); +if ($access{'ro'} || !&can_access($p)) { + &popup_error(&text('edit_eaccess', $p)); + } +elsif (-l $p && !&must_follow($p)) { + &popup_error(&text('edit_efollow', $p)); + } +elsif (!&open_tempfile(FILE, ">$p", 1)) { + &popup_error("$!"); + } +else { + &print_tempfile(FILE, $in{'body'}); + &close_tempfile(FILE); + + # Show JS to close page + &popup_header($text{'html_title'}); + + $info = &file_info_line($p); + print "\n"; + + &popup_footer(); + } diff --git a/file/save_share.cgi b/file/save_share.cgi new file mode 100755 index 000000000..cda75ef8a --- /dev/null +++ b/file/save_share.cgi @@ -0,0 +1,101 @@ +#!/usr/local/bin/perl +# save_share.cgi +# Create, update or delete a samba share + +require './file-lib.pl'; +$disallowed_buttons{'sharing'} && &error($text{'ebutton'}); +&ReadParse(); +print "Content-type: text/plain\n\n"; +if ($access{'ro'} || $access{'uid'}) { + # User has no access to samba + print "0\n"; + exit; + } + +%minfo = &get_module_info("samba"); +&read_acl(\%acl, undef); +if (!%minfo || !&check_os_support(\%minfo) || + !$acl{$base_remote_user,'samba'}) { + # Samba module not installed or supported + print "0\n"; + exit; + } + +&foreign_require("samba", "samba-lib.pl"); +%sconfig = &foreign_config("samba"); +&lock_file($sconfig{'smb_conf'}); +@shares = &foreign_call("samba", "list_shares"); + +if ($in{'delete'}) { + # Deleting an old share + foreach $s (@shares) { + &foreign_call("samba", "get_share", $s); + if ($samba::share{'path'} && + $samba::share{'path'} eq $in{'path'}) { + &foreign_call("samba", "delete_share", $s); + last; + } + } + print "1\n"; + } +elsif ($in{'new'}) { + # Creating a new share + map { $taken{$_}++ } @shares; + if ($in{'path'} =~ /\/([^\/]+)$/) { + $base = $1; + } + else { + $base = "root"; + } + if ($taken{$base}) { + for($i=2; $taken{$base.$i}; $i++) { } + $base = $base.$i; + } + $samba::share{'path'} = $in{'path'}; + $samba::share{'available'} = $in{'available'} ? 'yes' : 'no'; + $samba::share{'writable'} = $in{'writable'} ? 'yes' : 'no'; + $samba::share{'comment'} = $in{'comment'}; + if ($in{'guest'} == 2) { + $samba::share{'public'} = 'yes'; + $samba::share{'guest only'} = 'yes'; + } + elsif ($in{'guest'} == 1) { + $samba::share{'public'} = 'yes'; + } + &foreign_call("samba", "create_share", $base); + print "1\n"; + } +else { + # Updating an existing share + foreach $s (@shares) { + &foreign_call("samba", "get_share", $s); + if ($samba::share{'path'} && + $samba::share{'path'} eq $in{'path'}) { + # found the share to update + $samba::share{'available'} = $in{'available'} ? 'yes' + : 'no'; + $samba::share{'writable'} = $in{'writable'} ? 'yes' + : 'no'; + $samba::share{'comment'} = $in{'comment'}; + if ($in{'guest'} == 2) { + $samba::share{'public'} = 'yes'; + $samba::share{'guest only'} = 'yes'; + } + elsif ($in{'guest'} == 1) { + $samba::share{'public'} = 'yes'; + delete($samba::share{'guest only'}); + } + else { + delete($samba::share{'public'}); + delete($samba::share{'guest only'}); + } + &foreign_call("samba", "modify_share", $s, $s); + last; + } + } + print "1\n"; + } +&unlock_file($sconfig{'smb_conf'}); +&webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify', + 'share', $in{'path'}); + diff --git a/file/search.cgi b/file/search.cgi new file mode 100755 index 000000000..2a63cedfa --- /dev/null +++ b/file/search.cgi @@ -0,0 +1,63 @@ +#!/usr/local/bin/perl +# search.cgi +# Find files under some directory + +require './file-lib.pl'; +$disallowed_buttons{'search'} && &error($text{'ebutton'}); +&ReadParse(); +&switch_acl_uid(); +print "Content-type: text/plain\n\n"; +if (!&can_access($in{'dir'})) { + print $text{'search_eaccess'},"\n"; + } + +$in{'dir'} =~ s/^\/+/\//g; +if ($in{'dir'} ne '/') { + $in{'dir'} =~ s/\/$//; + } +$cmd = "find ".quotemeta(&unmake_chroot($in{'dir'}))." -name ".quotemeta($in{'match'}); +if ($in{'type'}) { + $cmd .= " -type $in{'type'}"; + } +if ($in{'user'}) { + $cmd .= " -user $in{'user'}"; + } +if ($in{'group'}) { + $cmd .= " -group $in{'group'}"; + } +if ($in{'size'}) { + $cmd .= " -size $in{'size'}"; + } +if ($in{'xdev'}) { + $cmd .= " -mount"; + } + +print "\n"; +open(CMD, "$cmd 2>/dev/null |"); +while($f = ) { + chop($f); + if (defined($in{'cont'})) { + # Check the file contents for the given pattern + $found = 0; + if ($f =~ /\.pdf$/i && &has_command("pdftotext")) { + # Convert PDF to text + open(FILE, "pdftotext -raw ".quotemeta($f)." - |"); + } + else { + open(FILE, $f); + } + while() { + if (/\Q$in{'cont'}\E/i) { + $found = 1; + last; + } + } + close(FILE); + next if (!$found); + } + local $rf = &make_chroot($f); + local $fil = &file_info_line($f, $rf); + print $fil,"\n" if (defined($fil)); + } +close(CMD); + diff --git a/file/setattrs.cgi b/file/setattrs.cgi new file mode 100755 index 000000000..278b4c236 --- /dev/null +++ b/file/setattrs.cgi @@ -0,0 +1,44 @@ +#!/usr/local/bin/perl +# setattrs.cgi +# Sets all the XFS attributes for a file + +require './file-lib.pl'; +$disallowed_buttons{'attr'} && &error($text{'ebutton'}); +&ReadParse(); +&webmin_log("attr", undef, $in{'file'}, \%in); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +if ($access{'ro'} || !&can_access($in{'file'})) { + print $text{'facl_eaccess'},"\n"; + } +else { + # Set given attribs + $temp = &transname(); + for($i=0; defined($n = $in{"name$i"}); $i++) { + $v = $in{"value$i"}; + open(TEMP, ">$temp"); + print TEMP $v; + close(TEMP); + $out = `attr -s '$n' '$in{'file'}' <$temp 2>&1`; + unlink($temp); + if ($?) { + print $out,"\n"; + exit; + } + $set{$n}++; + } + + # Remove those that no longer exist + $out = `attr -l '$in{'file'}' 2>&1`; + foreach $l (split(/[\r\n]+/, $out)) { + if ($l =~ /Attribute\s+"(.*)"/i && !$set{$1}) { + $out = `attr -r '$1' '$in{'file'}' 2>&1`; + if ($?) { + print $out,"\n"; + exit; + } + } + } + print "\n"; + } + diff --git a/file/setext.cgi b/file/setext.cgi new file mode 100755 index 000000000..20fcf98d0 --- /dev/null +++ b/file/setext.cgi @@ -0,0 +1,23 @@ +#!/usr/local/bin/perl +# setext.cgi +# Sets the EXT attributes for some file + +require './file-lib.pl'; +$disallowed_buttons{'ext'} && &error($text{'ebutton'}); +&ReadParse(); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +if ($access{'ro'} || !&can_access($in{'file'})) { + print $text{'facl_eaccess'},"\n"; + } +else { + $cmd = "chattr '=$in{'attrs'}' '$in{'file'}'"; + $out = `$cmd 2>&1`; + if ($?) { + print $out,"\n"; + } + else { + print "\n"; + } + } + diff --git a/file/setfacl.cgi b/file/setfacl.cgi new file mode 100755 index 000000000..c862f5ed6 --- /dev/null +++ b/file/setfacl.cgi @@ -0,0 +1,45 @@ +#!/usr/local/bin/perl +# setfacl.cgi +# Sets the ACLs for some file + +require './file-lib.pl'; +$disallowed_buttons{'acl'} && &error($text{'ebutton'}); +&ReadParse(); +&webmin_log("acl", undef, $in{'file'}, \%in); +&switch_acl_uid_and_chroot(); +print "Content-type: text/plain\n\n"; +if ($access{'ro'} || !&can_access($in{'file'})) { + print $text{'facl_eaccess'},"\n"; + } +else { + pipe(ACLINr, ACLINw); + pipe(ACLOUTr, ACLOUTw); + $pid = fork(); + if (!$pid) { + untie(*STDIN); + untie(*STDOUT); + untie(*STDERR); + open(STDIN, "<&ACLINr"); + open(STDOUT, ">&ACLOUTw"); + open(STDERR, ">&ACLOUTw"); + close(ACLINw); + close(ACLOUTr); + exec("$config{'setfacl'} '$in{'file'}'"); + print "Exec failed : $!\n"; + exit(1); + } + close(ACLINr); + close(ACLOUTw); + print ACLINw $in{'acl'},"\n"; + close(ACLINw); + waitpid($pid, 0); + $rv = ; + close(ACLOUTr); + if ($rv) { + print $rv; + } + else { + print "\n"; + } + } + diff --git a/file/show.cgi b/file/show.cgi new file mode 100755 index 000000000..b2acc11e0 --- /dev/null +++ b/file/show.cgi @@ -0,0 +1,161 @@ +#!/usr/local/bin/perl +# show.cgi +# Output some file for the browser + +require './file-lib.pl'; +&ReadParse(); +use POSIX; +$p = $ENV{'PATH_INFO'}; +if ($in{'type'}) { + # Use the supplied content type + $type = $in{'type'}; + $download = 1; + } +elsif ($in{'format'} == 1) { + # Type comes from compression format + $type = "application/zip"; + } +elsif ($in{'format'} == 2) { + $type = "application/x-gzip"; + } +elsif ($in{'format'} == 3) { + $type = "application/x-tar"; + } +else { + # Try to guess type from filename + $type = &guess_mime_type($p, undef); + if (!$type) { + # No idea .. use the 'file' command + $out = &backquote_command("file ". + quotemeta(&resolve_links($p)), 1); + if ($out =~ /text|script/) { + $type = "text/plain"; + } + else { + $type = "application/unknown"; + } + } + } + +# Dump the file +$temp = &transname(); +&switch_acl_uid(); +$p = &unmake_chroot($p); +if (!&can_access($p)) { + # ACL rules prevent access to file + &error_exit(&text('view_eaccess', $p)); + } + +if ($in{'format'}) { + # An archive of a directory was requested .. create it + $archive || &error_exit($text{'view_earchive'}); + if ($in{'format'} == 1) { + $p =~ s/\.zip$//; + } + elsif ($in{'format'} == 2) { + $p =~ s/\.tgz$//; + } + elsif ($in{'format'} == 3) { + $p =~ s/\.tar$//; + } + -d $p || &error_exit($text{'view_edir'}." ".$p); + if ($archive == 2 && $archmax > 0) { + # Check if directory is too large to archive + local $kb = &disk_usage_kb($p); + if ($kb*1024 > $archmax) { + &error_exit(&text('view_earchmax', $archmax)); + } + } + + # Work out the base directory and filename + if ($p =~ /^(.*\/)([^\/]+)$/) { + $pdir = $1; + $pfile = $2; + } + else { + $pdir = "/"; + $pfile = $p; + } + + # Work out the command to run + if ($in{'format'} == 1) { + &has_command("zip") || &error_exit(&text('view_ecmd', "zip")); + $cmd = "zip -r $temp ".quotemeta($pfile); + } + elsif ($in{'format'} == 2) { + &has_command("tar") || &error_exit(&text('view_ecmd', "tar")); + &has_command("gzip") || &error_exit(&text('view_ecmd', "gzip")); + $cmd = "tar cf - ".quotemeta($pfile)." | gzip -c >$temp"; + } + elsif ($in{'format'} == 3) { + &has_command("tar") || &error_exit(&text('view_ecmd', "tar")); + $cmd = "tar cf $temp ".quotemeta($pfile); + } + + if ($in{'test'}) { + # Don't actually do anything if in test mode + &ok_exit(); + } + + # Run the command, and send back the resulting file + local $qpdir = quotemeta($pdir); + local $out = `cd $qpdir ; ($cmd) 2>&1 使用者和群組 模組,ä½ çš„ /etc/passwdå’Œ /etc/shadow檔案會被附加上去。 +acl_feedback1=是,但ä¸èƒ½åŒ…å«çµ„態檔案 +feedback_emodule=åœ¨ä¿¡ä»¶ä¸­æ‚¨é¸æ“‡äº†åŒ…嫿¨¡çµ„組態設定,但廿²’有é¸å–模組。 +month_1=一月 +smonth_6=六月 +users_ok=確定 +paste_ecfailed=æ‹·è²å¤±æ•— : $1 +top_upload=上傳 +feedback_os=在寄é€éƒµä»¶ä¸­åŒ…å«ä½œæ¥­ç³»çµ±è³‡è¨Š? +top_new=增加 +sday_6=星期六 +index_nojava=é€™å€‹æ¨¡çµ„éœ€è¦ Java æ‰èƒ½æ­£ç¢ºçš„é‹ä½œ, 但是您的ç€è¦½å™¨ä¼¼ä¹Žä¸æ”¯æ´ Java +month_8=八月 +referer_warn_unknown=警告! Webmin發ç¾ç¨‹å¼ $2從ä¸çŸ¥åçš„ä½ç½®é€£çµä¾†çš„,出ç¾åœ¨ Webmin以外。並ä¼åœ–嘗試在您的伺æœå™¨åŸ·è¡Œå±éšªçš„æŒ‡ä»¤ã€‚ +rename_eold=您ä¸è¢«å…許改å自 '$1' +link_to=連çµåˆ°: +yes=是 +acl_rpc2=åªæœ‰ root 或 admin +main_title=Webmin $1 在 $2 ($3) +chooser_ok=確定 +info_own=所有權 +referer_title=安全警告 +mkdir_eaccess=您ä¸è¢«å…許建立 '$1' +header_config=模組組態 +category_=å…¶ä»– +right_group=群組 +users_title1=鏿“‡ä½¿ç”¨è€…... +session_mesg2=您必須輸入使用者å稱和密碼來登入 +right_name=å稱 +top_refresh=é‡è®€ +groups_sel=鏿“‡çš„群組 +helpsearch=æœå°‹æ–‡ä»¶ +acl_umask=建立檔案的é®ç½© +info_sticky=設定ä½å…ƒ: +help_err=無法顯示說明 +top_edit=編輯 +top_info=資訊 +top_copy=複製 +day_1=星期一 +upload_title=上傳檔案 +chooser_title2=鏿“‡ç›®éŒ„... +link_from=連çµè‡ª: +error=錯誤 +acl_rpc=å¯ä»¥ä½¿ç”¨RPC ? +month_10=åæœˆ +create=建立 +upload_file=è¦ä¸Šå‚³çš„æª”案 +feedback_text=æè¿°å•題或建議 +top_paste=貼上 +move_eto=您ä¸è¢«å…許移動到 '$1' +list_eaccess=您ä¸è¢«å…許存å–這個目錄 +feedback_email=您的電å­éƒµä»¶ +skill_medium=中等 +delete_fdesc=æ‚¨ç¢ºå®šè¦æ°¸ä¹…的刪除檔案 $1 å—Ž? +rename_old=舊檔å: +users_sel=鏿“‡çš„使用者 +chmod_echmod=變更權é™å¤±æ•— : $1 +acl_rpc1=是 +month_7=七月 +file_type7=管線 +smonth_1=一月 +default=é è¨­ +info_type=類別: +info_link=連çµåˆ°: +groups_cancel=å–æ¶ˆ +category_net=網路 +day_4=星期四 +category_syslet=網管 +upload_edir=上傳的目錄ä¸å­˜åœ¨. +smonth_5=五月 +header_help=說明... +help_epath=éºå¤±èªªæ˜Žæª”路徑 +groups_ok=確定 +category_cluster=電腦å¢é›† +chmod_egroup=$1 : 沒有這個群組 +rename_eexists=å«åš $1 的檔案已經存在 +modify=修改 +mkdir_dir=目錄: +longcategory_net=網路和網路æœå‹™çµ„態模組 +emodule=å­˜å–æ‹’絕 : 使用者 $1 ä¸å…許使用 $2 模組 +top_view=檢視 +acl_feedback2=是 +top_cut=剪下 +header_module=模組索引 +find_eexist=$1 ä¸å­˜åœ¨æ–¼ $2 +referer_ok=繼續執行Webminç¨‹å¼ +skill_low=新手 +sday_5=星期五 +save=儲存 +feedback_header=回饋內容 +month_9=乿œˆ +info_efailed=無法é‡è®€ $1 : $2 +upload_ok=上傳 +session_save=記得上次登入帳號? +config_err=儲存組態錯誤 +longcategory_hardware=列表機,ç£ç¢Ÿå’Œå…¶ä»–硬體組態模組 +acl_dirs=åªå…許存å–到目錄 +find_eaccess=您ä¸è¢«å…è¨±å­˜å– $1 +feedback_econfig=您沒有完整的權é™ä¾†é¸å–模組 +right_date=日期 +file_type6=設備控制檔 +edit_filename=檔案å稱: +category_info=資訊 +info_read=è®€å– +main_skill=Skill level +main_switch=切æ›ä½¿ç”¨è€…... +info_write=寫入 +delete=刪除 +referer_warn=警告! Webmin發ç¾ç¨‹å¼ $2從 URL $1連çµä¾†çš„,出ç¾åœ¨ Webmin以外。並ä¼åœ–嘗試在您的伺æœå™¨åŸ·è¡Œå±éšªçš„æŒ‡ä»¤ã€‚ +info_setuid2=以使用者權é™åŸ·è¡Œ +config_eaccess=您ä¸è¢«å…許存å–這個模組 +mkdir_title=增加目錄 +groups_title2=鏿“‡ç¾¤çµ„... +ok=確定 +progress_data2=下載 $1 ä½å…ƒçµ„ +link_efailed=連çµå¤±æ•— : $1 +help_eexec=$1 失敗 : $2 +delete_ftitle=刪除檔案 +rename_efailed=改å失敗 : $1 +view_eopen=無法開啟n $1 : $2 +top_delete=刪除 +index=索引 +feedback_mailserver=傳é€ç¶“ç”±SMTP伺æœå™¨ +day_3=星期三 +feedback_title=回饋Webmin +progress_size=下載中 $1 ($2 ä½å…ƒçµ„) .. +month_12=å二月 +info_group=群組: +acl_uedit_group=使用者群組 +paste_eover=$1 無法被蓋寫 +info_apply3=這個目錄與所有的å­ç›®éŒ„ +feedback_enoto=沒有填寫傳é€å›žé¥‹ä½å€ä½ç½® +main_title2=Webmin +feedback_err=寄é€å›žé¥‹æ™‚發生錯誤 +top_rename=改å +efilewrite=寫入$1失敗 : $2 +feedback_all=所有模組 +month_6=六月 +programname=Webmin +copy_elink=符號連çµå¤±æ•— : $1 +config_setto=Set to +help_eheader=éºå¤± <標頭> 倿®µ +edit_eaccess=您ä¸è¢«å…許儲存 '$1' +acl_uedit_only=åªæœ‰ä½¿ç”¨è€… +category_system=系統 +smonth_10=åæœˆ +longcategory_=無法分類的其他模組 +month_3=三月 +file_type1=文字檔 +delete_dtitle=刪除目錄 +day_5=星期五 +feedback_via=傳é€å›žé¥‹ä¿¡ä»¶åˆ° $1ç¶“ç”± SMTP伺æœå™¨ $2 +acl_gedit_except=所有群組除了 +acl_follow=是å¦è·Ÿéš¨ç¬¦è™Ÿé€£çµ? +smonth_9=乿œˆ +file_type4=檔案 +acl_gedit_gid=群組GIDç¯„åœæ˜¯ +session_login=登入 +link_title=å»ºç«‹é€£çµ +move_afrom=您ä¸è¢«å…許移動自 '$1' +category_servers=伺æœå™¨ +rename_ok=改å +info_setgid=設定 GID: +progress_done=.. ä¸‹è¼‰å®Œæˆ +find_edir=$1 䏿˜¯ä¸€å€‹ç›®éŒ„在 $2 +upload_efile=æ²’æœ‰é¸æ“‡è¦ä¸Šå‚³çš„æª”案. +smonth_4=四月 +day_2=星期二 +upload_eperm=您ä¸è¢«å…許建立 $1 +users_clear=清除 +info_other=å…¶ä»–: +feedback_desc=這表單å¯ä»¥è®“你回報錯誤(bugs)和建議Webmin發展群關於任何å•é¡Œæˆ–æ‰€å¿½ç•¥çš„ç‰¹è‰²ï¼Œç•¶æŒ‰ä¸‹å‚³é€æŒ‰éˆ•後,這é çš„內容將會寄到 $1。 +edit_eover=$1 無法被蓋寫 +progress_nosize=正在下載 $1 .. +feedback_mailserver_def=本地sendmailç¨‹å¼ +acl_feedback0=å¦ +right_size=å¤§å° +file_type2=å½±åƒæª” +longcategory_webmin=組態Webmin自己的模組 +sday_1=星期一 +info_apply=套用變更到 +users_cancel=å–æ¶ˆ +acl_uedit=鏿“‡å¯ä»¥çœ‹åˆ°çš„使用者 +rename_enew=您ä¸è¢«å…è¨±æ”¹åæˆ '$1' +info_setgid2=檔案繼承群組 +file_type5=ç¬¦è™Ÿé€£çµ +feedback_attach=加入è¦é™„上的檔案 +smonth_11=å一月 +link_efollow=您ä¸è¢«å…è¨±å»ºç«‹ç¬¦è™Ÿé€£çµ +acl_uedit_none=沒有使用者 +main_version=版本 $1 在 $2 ($3) +upload_dir=上傳到目錄 +session_pass=密碼 +find=找尋 +chmod_euser=$1 : 沒有這個使用者 +skill_high=專家 +longcategory_cluster=從單一介é¢ç®¡ç†å¤šé‡æœå‹™ +main_return=回到 $1 +info_exec=執行 +feedback_send=傳é€å›žé¥‹ +acl_gedit_only=åªæœ‰ç¾¤çµ„ +longcategory_system=使用者,檔案系統,工作排程和其他系統設定 +rename_new=變更為: +upload_efailed=開啟上傳失敗 : $1 +info_file=檔案 +month_5=五月 +chmod_elink=符號連çµå¤±æ•—d : $1 +acl_root=檔案é¸å–時的根目錄 +groups_all=全部的群組 +feedback_name=您的姓å +feedback_osdesc=如果é¸å–此項目,會自動在回饋信件中加上您的作業系統å稱和版本。 +info_sticky2=åªæœ‰æ“有者æ‰èƒ½åˆªé™¤æª”案 +switch_remote_euser=Unix使用者 $1 並ä¸å­˜åœ¨ +paste_emfailed=移動失敗 : $1 +view_enormal=åªæœ‰ä¸€èˆ¬çš„æª”案å¯ä»¥è¢«æª¢è¦– +config_header=給 $1 çš„å¯çµ„æ…‹é¸é … +link_essl=æ‚¨çš„ç³»çµ±å°šæœªå®‰è£ Net::SSLeay Perl模組所需è¦ä½¿ç”¨çš„HTTPS連線。 +longcategory_servers=web, email, FTP和其他æœå‹™çš„組態模組 +view_eaccess=您ä¸è¢«å…è¨±å­˜å– $1 +mkdir_efailed=建立目錄失敗 : $1 +day_6=星期六 +info_mod=修改時間: +session_clear=清除 +edit_title2=建立檔案中 +main_feedback=回饋... +info_setuid=設定 UID: +chmod_eaccess=您ä¸è¢«å…è¨±å­˜å– '$1' +help_einclude=無法引入 $1 +edit_esave=無法儲存檔案 : $1 +smonth_8=八月 +cancel=å–æ¶ˆ +session_user=使用者å稱 +users_all=全部的使用者 +info_path=路徑: +edit_enormal=åªèƒ½ç·¨è¼¯ä¸€èˆ¬çš„æª”案 +feedback_emodule2=é¸å–的模組ä¸å­˜åœ¨ +config_ecannot=您ä¸è¢«å…許組態這個模組 +session_timed_out=連線逾時於$1åˆ†é˜ +sday_0=星期日 +acl_user=以使用者權é™å­˜å–伺æœå™¨ä¸Šçš„æª”案 +reset=é‡è¨­ +progress_data=下載 $1 ä½å…ƒçµ„ ($2 %) +upload_conv=是å¦è¦æ”¹è®Š DOS çš„æ›è¡Œç¬¦è™Ÿ? +index_title=檔案管ç†è€… +day_0=星期日 +help_eif=$1 失敗 : $2 +feedback_esend=使用sendmail或本地SMTP伺æœå™¨å‚³é€å›žé¥‹éƒµä»¶éŒ¯èª¤ +info_list=列出 +users_title2=鏿“‡ä½¿ç”¨è€…... +info_apply2=這個目錄與其中的檔案 +month_2=二月 +file_type3=äºŒé€²ä½æª” +link_efrom=您ä¸è¢«å…è¨±é€£çµ '$1' +category_hardware=硬體 diff --git a/file/upform.cgi b/file/upform.cgi new file mode 100755 index 000000000..d3199307c --- /dev/null +++ b/file/upform.cgi @@ -0,0 +1,39 @@ +#!/usr/local/bin/perl +# upform.cgi +# Display the upload form + +require './file-lib.pl'; +$disallowed_buttons{'upload'} && &error($text{'ebutton'}); +&ReadParse(undef, undef, 1); +&popup_header($text{'upload_title'}); +$upid = time().$$; +$args = ($in{'extra'} ? $in{'extra'}."&" : "?")."id=$upid"; + +print &ui_form_start("upload.cgi$args", "form-data", undef, + &read_parse_mime_javascript($upid, [ "file" ])); +print &ui_table_start($text{'upload_title'}, "width=100%", 2); + +print &ui_table_row($text{'upload_file'}, + &ui_upload("file", 20)); + +print &ui_table_row($text{'upload_dir'}, + &ui_textbox("dir", $in{'dir'}, 20)."\n". + &ui_submit($text{'upload_ok'})); + +if ($dostounix == 1) { + print &ui_table_row($text{'upload_conv'}, + &ui_yesno_radio("dos", 0)); + } + +if ($unarchive == 1) { + print &ui_table_row($text{'upload_zip'}, + &ui_radio("zip", 0, + [ [ 2, $text{'upload_yes'} ], + [ 1, $text{'yes'} ], + [ 0, $text{'no'} ] ])); + } + +print &ui_table_end(); +print &ui_form_end(); +&popup_footer(); + diff --git a/file/upload.cgi b/file/upload.cgi new file mode 100755 index 000000000..00cd97762 --- /dev/null +++ b/file/upload.cgi @@ -0,0 +1,76 @@ +#!/usr/local/bin/perl +# upload.cgi +# Upload a file + +require './file-lib.pl'; +$disallowed_buttons{'upload'} && &error($text{'ebutton'}); +&popup_header(); +&ReadParse(\%getin, "GET"); +$upid = $getin{'id'}; +&ReadParseMime($upload_max, \&read_parse_mime_callback, [ $upid ]); + +$realdir = &unmake_chroot($in{'dir'}); +if (!$in{'file_filename'}) { + print "

$text{'upload_efile'}

\n"; + } +elsif (!-d $realdir) { + print "

$text{'upload_edir'}

\n"; + } +else { + $in{'file_filename'} =~ /([^\\\/]+)$/; + $path = "$in{'dir'}/$1"; + $realpath = "$realdir/$1"; + if (-e $realpath) { + # File exists .. ask the user if he is sure + &switch_acl_uid(); + $temp = &tempname(); + &open_tempfile(TEMP, ">$temp"); + if ($dostounix == 1 && $in{'dos'}) { + $in{'file'} =~ s/\r\n/\n/g; + } + &print_tempfile(TEMP, $in{'file'}); + &close_tempfile(TEMP); + print "

\n"; + foreach $i (keys %prein) { + print "\n"; + } + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print "
\n"; + print &text('upload_already', "$path"),"

\n"; + print "\n"; + print "\n"; + print "

\n"; + } + else { + # Go ahread and do it! + &webmin_log("upload", undef, $path); + &switch_acl_uid(); + if ($access{'ro'} || !&can_access($path)) { + print "

",&text('upload_eperm', $path),"

\n"; + } + elsif (-l $path && !&must_follow($realpath)) { + print "

",&text('upload_elink', $path),"

\n"; + } + elsif (!&open_tempfile(FILE, ">$realpath", 1)) { + print "

",&text('upload_ewrite', $path, $!),"

\n"; + } + else { + if ($dostounix == 1 && $in{'dos'}) { + $in{'file'} =~ s/\r\n/\n/g; + } + &print_tempfile(FILE, $in{'file'}); + &close_tempfile(FILE); + &post_upload($path, $in{'dir'}, $in{'zip'}); + } + } + } + +&popup_footer(); diff --git a/file/upload2.cgi b/file/upload2.cgi new file mode 100755 index 000000000..a01fec2ca --- /dev/null +++ b/file/upload2.cgi @@ -0,0 +1,38 @@ +#!/usr/local/bin/perl +# upload2.cgi +# Rename a file that has already been uploaded + +require './file-lib.pl'; +$disallowed_buttons{'upload'} && &error($text{'ebutton'}); +&header(); +&ReadParse(); + +if ($in{'yes'}) { + # Put it in place, overwriting any other file + &webmin_log("upload", undef, $in{'path'}); + &switch_acl_uid(); + if ($access{'ro'} || !&can_access($in{'path'})) { + print "

",&text('upload_eperm', $in{'path'}),"

\n"; + } + elsif (!&open_tempfile(FILE, ">".&unmake_chroot($in{'path'}), 1)) { + print "

",&text('upload_ewrite', $in{'path'}, $!),"

\n"; + } + else { + open(TEMP, $in{'temp'}); + ©data(TEMP, FILE) || + &error(&text('upload_ewrite', $in{'path'}, $!)); + close(TEMP); + &close_tempfile(FILE); + &post_upload($in{'path'}, $in{'dir'}, $in{'zip'}); + } + unlink($in{'temp'}); + } +else { + # Just delete the temp file + &switch_acl_uid(); + unlink($in{'temp'}); + print "\n"; + } + diff --git a/file/xinha b/file/xinha new file mode 120000 index 000000000..04a6e3b5b --- /dev/null +++ b/file/xinha @@ -0,0 +1 @@ +../mailboxes/xinha \ No newline at end of file diff --git a/mailboxes/CHANGELOG b/mailboxes/CHANGELOG new file mode 100644 index 000000000..e956ddbe7 --- /dev/null +++ b/mailboxes/CHANGELOG @@ -0,0 +1,37 @@ +---- Changes since 1.130 ---- +The first version of this module, which extracts the mail reading functionality from the Sendmail, Postfix and Qmail modules and puts it into a more powerful server-independent user email module instead. +---- Changes since 1.150 ---- +Added a basic HTML editor for sending and replying to email in HTML format. Requires Java 1.4+ in the browser. Must be enabled on the Module Config page, as it is still rather unstable. +Included support for SMTP authentication when sending email, configurable on the Module Config page. +---- Changes since 1.160 ---- +Added buttons for reporting a message as spam and adding the sender to the global SpamAssassin blacklist. +---- Changes since 1.170 ---- +Added button for deleting all mail in a folder (disabled by default in the Module Config). +---- Changes since 1.180 ---- +Added support for two new mail systems - VPopMail and Qmail+LDAP. Both of these access mail for users in external databases, rather than Unix users. +---- Changes since 1.200 ---- +Added a Module Config option (on by default) to get the From: address for users from Virtualmin, if installed. +---- Changes since 1.210 ---- +Added Module Config options to show the number of messages in each users' inbox and sent-mail folder, and to attached a signature to sent mail. +---- Changes since 1.220 ---- +All Webmin users can now report spam, rather than just those that have access to the SpamAssassin module. +---- Changes since 1.240 ---- +Output from sa-learn or spamassassin is now show when reporting multiple messages as spam. +---- Changes since 1.250 ---- +Added a Module Config option for selecting users to not display, thanks to Brad Kester. +The displayed size of mailboxes in Maildir format includes all files in the directory, rather than just those in the cur, tmp and new subdirectories in older Webmin releases. +---- Changes since 1.260 ---- +When the module is configured to display only users with mail and no users have mail, then nothing will be displayed. +---- Changes since 1.270 ---- +Added a Module Config option for setting the date format. +Added a Module Config option to enable pager arrows at the bottom of mail list and individual message pages. +Placed a Delete All button at the bottom of each user's mail list, for deleting all mail in a folder. +Added a Module Config option for setting the timezone for dates. +The simple search box accepts inputs like from: jcameron or size: 10000 to search on a single specific field. +Added a Module Config option for opening user email messages in separate windows. +---- Changes since 1.300 ---- +The number of folders each user has is displayed in the user list. +---- Changes since 1.310 ---- +Use ~username instead of the full home directory path in the folders list. +---- Changes since 1.330 ---- +Replaced the HTMLarea widget for composing email with Xinha. diff --git a/mailboxes/Makefile b/mailboxes/Makefile new file mode 100644 index 000000000..d76398ded --- /dev/null +++ b/mailboxes/Makefile @@ -0,0 +1,2 @@ +HTMLEditor.class: HTMLEditor.java + CLASSPATH=/usr/local/netscape7/plugins/java2/lib/javaplugin.jar:. javac HTMLEditor.java diff --git a/mailboxes/acl_security.pl b/mailboxes/acl_security.pl new file mode 100644 index 000000000..8c6f09eb9 --- /dev/null +++ b/mailboxes/acl_security.pl @@ -0,0 +1,124 @@ + +require 'mailboxes-lib.pl'; + +# acl_security_form(&options) +# Output HTML for editing security options for the sendmail module +sub acl_security_form +{ +# Users whose mail can be read +print " $text{'acl_read'} \n"; +printf " $text{'acl_none'}\n", + $_[0]->{'mmode'} == 0 ? "checked" : ""; + +printf " $text{'acl_same'}\n", + $_[0]->{'mmode'} == 4 ? "checked" : ""; + +printf " $text{'acl_all'}
\n", + $_[0]->{'mmode'} == 1 ? "checked" : ""; + +printf " $text{'acl_users'}\n", + $_[0]->{'mmode'} == 2 ? "checked" : ""; +printf " %s
\n", + $_[0]->{'mmode'} == 2 ? $_[0]->{'musers'} : "", + &user_chooser_button("musers", 1); + +printf " $text{'acl_userse'}\n", + $_[0]->{'mmode'} == 3 ? "checked" : ""; +printf " %s
\n", + $_[0]->{'mmode'} == 3 ? $_[0]->{'musers'} : "", + &user_chooser_button("muserse", 1); + +printf " $text{'acl_usersg'}\n", + $_[0]->{'mmode'} == 5 ? "checked" : ""; +printf " %s\n", + $_[0]->{'mmode'} == 5 ? join(" ", map { scalar(getgrgid($_)) } + split(/\s+/, $_[0]->{'musers'})) : "", + &group_chooser_button("musersg", 1); +printf " %s
\n", + $_[0]->{'msec'} ? "checked" : "", $text{'acl_sec'}; + +printf " $text{'acl_usersu'}\n", + $_[0]->{'mmode'} == 7 ? "checked" : ""; +printf " -\n", + $_[0]->{'mmode'} == 7 ? $_[0]->{'musers'} : ""; +printf "
\n", + $_[0]->{'mmode'} == 7 ? $_[0]->{'musers2'} : ""; + +printf " $text{'acl_usersm'}\n", + $_[0]->{'mmode'} == 6 ? "checked" : ""; +printf " \n", + $_[0]->{'mmode'} == 6 ? $_[0]->{'musers'} : ""; + +# Directory for arbitrary files +print " $text{'acl_dir'} \n"; +print &ui_opt_textbox("dir", $_[0]->{'dir'}, 40, $text{'acl_dirauto'}."
"); +print " \n"; + +# Allowed From: addresses +print " $text{'acl_from'} \n"; +printf " $text{'acl_any'}
\n", + $_[0]->{'fmode'} == 0 ? "checked" : ""; +printf " $text{'acl_fdoms'}\n", + $_[0]->{'fmode'} == 1 ? "checked" : ""; +printf "
\n", + $_[0]->{'fmode'} == 1 ? $_[0]->{'from'} : ''; +printf " $text{'acl_faddrs'}\n", + $_[0]->{'fmode'} == 2 ? "checked" : ""; +printf "
\n", + $_[0]->{'fmode'} == 2 ? $_[0]->{'from'} : ''; +printf " $text{'acl_fdom'}\n", + $_[0]->{'fmode'} == 3 ? "checked" : ""; +printf "
\n", + $_[0]->{'fmode'} == 3 ? $_[0]->{'from'} : ''; +print " \n"; + +print " $text{'acl_fromname'}\n"; +print " \n"; + +print " $text{'acl_attach'} \n"; +printf " %s\n", + $_[0]->{'attach'}<0 ? 'checked' : '', $text{'acl_unlimited'}; +printf "\n", + $_[0]->{'attach'}<0 ? '' : 'checked'; +printf " kB\n", + $_[0]->{'attach'}<0 ? '' : $_[0]->{'attach'}; +print " \n"; + +print " $text{'acl_canattach'}\n"; +printf " %s\n", + $_[0]->{'canattach'} ? 'checked' : '', $text{'yes'}; +printf " %s\n", + $_[0]->{'canattach'} ? '' : 'checked', $text{'no'}; + +print "$text{'acl_candetach'}\n"; +printf " %s\n", + $_[0]->{'candetach'} ? 'checked' : '', $text{'yes'}; +printf " %s \n", + $_[0]->{'candetach'} ? '' : 'checked', $text{'no'}; +} + +# acl_security_save(&options) +# Parse the form for security options for the sendmail module +sub acl_security_save +{ +$_[0]->{'mmode'} = $in{'mmode'}; +$_[0]->{'musers'} = $in{'mmode'} == 2 ? $in{'musers'} : + $in{'mmode'} == 3 ? $in{'muserse'} : + $in{'mmode'} == 5 ? join(" ", map { scalar(getgrnam($_)) } + split(/\s+/, $in{'musersg'})) : + $in{'mmode'} == 6 ? $in{'musersm'} : + $in{'mmode'} == 7 ? $in{'musersu1'} : ""; +$_[0]->{'musers2'} = $in{'mmode'} == 7 ? $in{'musersu2'} : ""; +$_[0]->{'msec'} = $in{'msec'}; +$_[0]->{'fmode'} = $in{'fmode'}; +$_[0]->{'from'} = $in{'fmode'} == 0 ? undef : + $in{'fmode'} == 1 ? $in{'fdoms'} : + $in{'fmode'} == 2 ? $in{'faddrs'} : $in{'fdom'}; +$_[0]->{'fromname'} = $in{'fromname'}; +$_[0]->{'attach'} = $in{'attach_def'} ? -1 : $in{'attach'}; +$_[0]->{'canattach'} = $in{'canattach'}; +$_[0]->{'candetach'} = $in{'candetach'}; +$_[0]->{'dir'} = $in{'dir_def'} ? undef : $in{'dir'}; +} + diff --git a/mailboxes/boxes-lib.pl b/mailboxes/boxes-lib.pl new file mode 100644 index 000000000..d1024cc1b --- /dev/null +++ b/mailboxes/boxes-lib.pl @@ -0,0 +1,2282 @@ +# boxes-lib.pl +# Functions to parsing user mail files + +use POSIX; +if ($userconfig{'date_tz'} || $config{'date_tz'}) { + # Set the timezone for all date calculations, and force a conversion + # now as in some cases the first on fails! + $ENV{'TZ'} = $userconfig{'date_tz'} || + $config{'date_tz'}; + strftime('%H:%M', localtime(time())); + } +use Time::Local; + +# Always use DBM indexing +$config{'index_dbm'} = 2; +$config{'index_min'} = 1000000; + +# list_mails(user|file, [start], [end]) +# Returns a subset of mail from a mbox format file +sub list_mails +{ +local (@rv, $h, $done); +my (@index, %index, $itype); +$itype = &index_type($_[0]); +if ($itype == 0) { + @index = &build_index($_[0]); + } +else { + &build_dbm_index($_[0], \%index); + } +local ($start, $end); +local $isize = $itype == 0 ? scalar(@index) : $index{'mailcount'}; +if (@_ == 1 || !defined($_[1]) && !defined($_[2])) { + $start = 0; $end = $isize-1; + } +elsif ($_[2] < 0) { + $start = $isize+$_[2]-1; $end = $isize+$_[1]-1; + $start = $start<0 ? 0 : $start; + } +else { + $start = $_[1]; $end = $_[2]; + $end = $isize-1 if ($end >= $isize); + } +$rv[$isize-1] = undef if ($isize); # force array to right size +local $dash = &dash_mode($_[0]); +open(MAIL, &user_mail_file($_[0])); +$start = 0 if ($start < 0); +for($i=$start; $i<=$end; $i++) { + # Seek to mail position + local $startline; + if ($itype == 0) { + seek(MAIL, $index[$i]->[0], 0); + $startline = $index[$i]->[1]; + } + else { + local @idx = split(/\0/, $index{$i}); + seek(MAIL, $idx[0], 0); + $startline = $idx[1]; + } + + # Read the mail + local $mail = &read_mail_fh(MAIL, $dash ? 2 : 1, 0); + $mail->{'line'} = $startline; + $mail->{'eline'} = $startline + $mail->{'lines'} - 1; + $mail->{'idx'} = $i; + $rv[$i] = $mail; + } +return @rv; +} + +# select_mails(user|file, &indexes, headersonly) +# Returns a list of messages with the given indexes +sub select_mails +{ +local (@rv); +my (@index, %index, $itype); +$itype = &index_type($_[0]); +if ($itype == 0) { + @index = &build_index($_[0]); + } +else { + &build_dbm_index($_[0], \%index); + } +local $isize = $itype == 0 ? scalar(@index) : $index{'mailcount'}; +open(MAIL, &user_mail_file($_[0])); +foreach my $i (@{$_[1]}) { + # Seek to mail position + local $startline; + if ($itype == 0) { + seek(MAIL, $index[$i]->[0], 0); + $startline = $index[$i]->[1]; + } + else { + local @idx = split(/\0/, $index{$i}); + seek(MAIL, $idx[0], 0); + $startline = $idx[1]; + } + + # Read the mail + local $mail = &read_mail_fh(MAIL, $dash ? 2 : 1, $_[2]); + $mail->{'line'} = $startline; + $mail->{'eline'} = $startline + $mail->{'lines'} - 1; + $mail->{'idx'} = $i; + push(@rv, $mail); + } +close(MAIL); +return @rv; +} + +# search_mail(user, field, match) +# Returns an array of messages matching some search +sub search_mail +{ +return &advanced_search_mail($_[0], [ [ $_[1], $_[2] ] ], 1); +} + +# advanced_search_mail(user|file, &fields, andmode, [&limits]) +# Returns an array of messages matching some search +sub advanced_search_mail +{ +local $itype = &index_type($_[0]); +local (@index, %index, @rv, $i); +local $dash = &dash_mode($_[0]); +local @possible; # index positions of possible mails +local $possible_certain = 0; # is possible list authoratative? +local ($min, $max); +if ($itype == 0) { + # We have only a plain index .. + @index = &build_index($_[0]); + $min = 0; + $max = scalar(@index)-1; + if ($_[3] && $_[3]->{'latest'}) { + $min = $max - $_[3]->{'latest'}; + } + @possible = ($min .. $max); + } +else { + # We have a DBM index .. if the search includes the from and subject + # fields, scan it first to cut down on the total time + &build_dbm_index($_[0], \%index); + + # Check which fields are used in search + local @dbmfields = grep { $_->[0] eq 'from' || + $_->[0] eq 'subject' } @{$_[1]}; + local $alldbm = (scalar(@dbmfields) == scalar(@{$_[1]})); + + $min = 0; + $max = $index{'mailcount'}-1; + if ($_[3] && $_[3]->{'latest'}) { + $min = $max - $_[3]->{'latest'}; + } + + # Only check DBM if it contains some fields, and if it contains all + # fields when in 'or' mode. + if (@dbmfields && ($alldbm || $_[2])) { + # Scan the DBM to build up a list of 'possibles' + for($i=$min; $i<=$max; $i++) { + local @idx = split(/\0/, $index{$i}); + local $fake = { 'header' => { 'from', $idx[2], + 'subject', $idx[3] } }; + local $m = &mail_matches(\@dbmfields, $_[2], $fake); + push(@possible, $i) if ($m); + } + $possible_certain = $alldbm; + } + else { + # None of the DBM fields are in the search .. have to scan all + @possible = ($min .. $max); + } + } + +# Need to scan through possible messages to find those that match +open(MAIL, &user_mail_file($_[0])); +foreach $i (@possible) { + # Seek to mail position + local $startline; + if ($itype == 0) { + seek(MAIL, $index[$i]->[0], 0); + $startline = $index[$i]->[1]; + } + else { + local @idx = split(/\0/, $index{$i}); + seek(MAIL, $idx[0], 0); + $startline = $idx[1]; + } + + # Read the mail + local $mail = &read_mail_fh(MAIL, $dash ? 2 : 1, 0); + $mail->{'line'} = $startline; + $mail->{'eline'} = $startline + $mail->{'lines'} - 1; + $mail->{'idx'} = $i; + push(@rv, $mail) if ($possible_certain || + &mail_matches($_[1], $_[2], $mail)); + } +return @rv; +} + +# build_index(user|file) +sub build_index +{ +local @index; +local $ifile = &user_index_file($_[0]); +local $umf = &user_mail_file($_[0]); +local @ist = stat($ifile); +local @st = stat($umf); + +if (open(INDEX, $ifile)) { + @index = map { /(\d+)\s+(\d+)/; [ $1, $2 ] } ; + close(INDEX); + } + +if (!@ist || !@st || $ist[9] < $st[9] || $st[7] < $config{'index_min'}) { + # The mail file is newer than the index, or we are always re-indexing + local $fromok = 1; + local ($l, $ll); + local $dash = &dash_mode($umf); + if ($st[7] < $config{'index_min'}) { + $fromok = 0; # Always re-index + open(MAIL, $umf); + } + else { + if (open(MAIL, $umf)) { + local $il = $#index; + local $i; + for($i=($il>100 ? 100 : $il); $i>=0; $i--) { + $l = $index[$il-$i]; + seek(MAIL, $index[$il-$i]->[0], 0); + $ll = ; + $fromok = 0 if ($ll !~ /^From\s+(\S+).*\d+\r?\n/ || + ($1 eq '-' && !$dash)); + } + } + else { + $fromok = 0; # No mail file yet + } + } + local ($pos, $lnum); + if (scalar(@index) && $fromok && $st[7] > $l->[0]) { + # Mail file seems to have gotten bigger, most likely + # because new mail has arrived ... only reindex the new mails + $pos = $l->[0] + length($ll); + $lnum = $l->[1] + 1; + } + else { + # Mail file has changed in some other way ... do a rebuild + $pos = 0; + $lnum = 0; + undef(@index); + seek(MAIL, 0, 0); + } + while() { + if (/^From\s+(\S+).*\d+\r?\n/ && ($1 ne '-' || $dash)) { + push(@index, [ $pos, $lnum ]); + } + $pos += length($_); + $lnum++; + } + close(MAIL); + open(INDEX, ">$ifile"); + print INDEX map { $_->[0]." ".$_->[1]."\n" } @index; + close(INDEX); + } +return @index; +} + +# build_dbm_index(user|file, &index) +# Returns a reference to a DBM hash that indexes the given mail file. +# Hash contains keys 0, 1, 2 .. each of which has a value containing the +# position of the mail in the file, line number, subject and sender. +# Special key lastchange = time index was last updated +# mailcount = number of messages in index +sub build_dbm_index +{ +local $ifile = &user_index_file($_[0]); +local $umf = &user_mail_file($_[0]); +local @st = stat($umf); +local $index = $_[1]; + +dbmopen(%$index, $ifile, 0600); +if (!@st || $index->{'lastchange'} < $st[9] || $st[7] < $config{'index_min'}) { + # The mail file is newer than the index, or we are always re-indexing + local $fromok = 1; + local ($ll, @idx); + local $dash = &dash_mode($umf); + if ($st[7] < $config{'index_min'}) { + $fromok = 0; # Always re-index + open(MAIL, $umf); + } + else { + if (open(MAIL, $umf)) { + # Check the last 100 messages (at most) + local $il = $index->{'mailcount'}-1; + local $i; + for($i=($il>100 ? 100 : $il); $i>=0; $i--) { + @idx = split(/\0/, $index->{$il-$i}); + seek(MAIL, $idx[0], 0); + $ll = ; + $fromok = 0 if ($ll !~ /^From\s+(\S+).*\d+\r?\n/ || + ($1 eq '-' && !$dash)); + } + } + else { + $fromok = 0; # No mail file yet + } + } + local ($pos, $lnum, $istart); + if ($index->{'mailcount'} && $fromok && $st[7] > $idx[0]) { + # Mail file seems to have gotten bigger, most likely + # because new mail has arrived ... only reindex the new mails + $pos = $idx[0] + length($ll); + $lnum = $idx[1] + 1; + $istart = $index->{'mailcount'}; + } + else { + # Mail file has changed in some other way ... do a rebuild + $istart = 0; + $pos = 0; + $lnum = 0; + seek(MAIL, 0, 0); + } + local ($doingheaders, @nidx); + while() { + if (/^From\s+(\S+).*\d+\r?\n/ && ($1 ne '-' || $dash)) { + @nidx = ( $pos, $lnum ); + $index->{$istart++} = join("\0", @nidx); + $doingheaders = 1; + } + elsif ($_ eq "\n" || $_ eq "\r\n") { + $doingheaders = 0; + } + elsif ($doingheaders && /^From:\s*(.{0,255})/i) { + $nidx[2] = $1; + $index->{$istart-1} = join("\0", @nidx); + } + elsif ($doingheaders && /^Subject:\s*(.{0,255})/i) { + $nidx[3] = $1; + $index->{$istart-1} = join("\0", @nidx); + } + $pos += length($_); + $lnum++; + } + close(MAIL); + $index->{'lastchange'} = time(); + $index->{'mailcount'} = $istart; + } +} + +# index_type(user|file) +# Returns 0 if an old-style index exists for some mailbox, 1 if not (indicating +# that DBM indexing should be used) +sub index_type +{ +return 0 if (!$config{'index_dbm'}); +return 1 if ($config{'index_dbm'} == 2); +local $ifile = &user_index_file($_[0]); +return -r $ifile ? 0 : 1; +} + +# empty_mail(user|file) +# Truncate a mail file to nothing +sub empty_mail +{ +local $umf = &user_mail_file($_[0]); +local $itype = &index_type($_[0]); +local $ifile = &user_index_file($_[0]); +open(TRUNC, ">$umf"); +close(TRUNC); +if ($itype == 0) { + # Truncate index too + open(TRUNC, ">$ifile"); + close(TRUNC); + } +else { + # Set index size to 0 + local %index; + dbmopen(%index, $ifile, 0600); + $index{'mailcount'} = 0; + $index{'lastchange'} = time(); + dbmclose(%index); + } +} + +# count_mail(user|file) +# Returns the number of messages in some mail file +sub count_mail +{ +my (@index, %index, $itype); +$itype = &index_type($_[0]); +if ($itype == 0) { + @index = &build_index($_[0]); + return scalar(@index); + } +else { + &build_dbm_index($_[0], \%index); + return $index{'mailcount'}; + } +} + +# parse_mail(&mail, [&parent], [savebody]) +# Extracts the attachments from the mail body +sub parse_mail +{ +return if ($_[0]->{'parsed'}++); +local $ct = $_[0]->{'header'}->{'content-type'}; +local (@attach, $h, $a); +if ($ct =~ /multipart\/(\S+)/i && ($ct =~ /boundary="([^"]+)"/i || + $ct =~ /boundary=([^;\s]+)/i)) { + # Multipart MIME message + local $bound = "--".$1; + local @lines = split(/\r?\n/, $_[0]->{'body'}); + local $l; + local $max = @lines; + while($l < $max && $lines[$l++] ne $bound) { + # skip to first boundary + } + while(1) { + # read attachment headers + local (@headers, $attach); + while($lines[$l]) { + $attach->{'raw'} .= $lines[$l]."\n"; + $attach->{'rawheaders'} .= $lines[$l]."\n"; + if ($lines[$l] =~ /^(\S+):\s*(.*)/) { + push(@headers, [ $1, $2 ]); + } + elsif ($lines[$l] =~ /^\s+(.*)/) { + $headers[$#headers]->[1] .= $1 + unless($#headers < 0); + } + $l++; + } + $attach->{'raw'} .= $lines[$l]."\n"; + $l++; + $attach->{'headers'} = \@headers; + foreach $h (@headers) { + $attach->{'header'}->{lc($h->[0])} = $h->[1]; + } + if ($attach->{'header'}->{'content-type'} =~ /^([^;]+)/) { + $attach->{'type'} = lc($1); + } + else { + $attach->{'type'} = 'text/plain'; + } + if ($attach->{'header'}->{'content-disposition'} =~ + /filename\s*=\s*"([^"]+)"/i) { + $attach->{'filename'} = $1; + } + elsif ($attach->{'header'}->{'content-disposition'} =~ + /filename\s*=\s*([^;\s]+)/i) { + $attach->{'filename'} = $1; + } + elsif ($attach->{'header'}->{'content-type'} =~ + /name\s*=\s*"([^"]+)"/i) { + $attach->{'filename'} = $1; + } + + # read the attachment body + while($l < $max && $lines[$l] ne $bound && $lines[$l] ne "$bound--") { + $attach->{'data'} .= $lines[$l]."\n"; + $attach->{'raw'} .= $lines[$l]."\n"; + $l++; + } + $attach->{'data'} =~ s/\n\n$/\n/; # Lose trailing blank line + $attach->{'raw'} =~ s/\n\n$/\n/; + + # decode if necessary + if (lc($attach->{'header'}->{'content-transfer-encoding'}) eq + 'base64') { + # Standard base64 encoded attachment + $attach->{'data'} = &b64decode($attach->{'data'}); + } + elsif (lc($attach->{'header'}->{'content-transfer-encoding'}) eq + 'x-uue') { + # UUencoded attachment + $attach->{'data'} = &uudecode($attach->{'data'}); + } + elsif (lc($attach->{'header'}->{'content-transfer-encoding'}) eq + 'quoted-printable') { + # Quoted-printable text attachment + $attach->{'data'} = "ed_decode($attach->{'data'}); + } + elsif (lc($attach->{'type'}) eq 'application/mac-binhex40' && &has_command("hexbin")) { + # Macintosh binhex encoded attachment + local $temp = &transname(); + mkdir($temp, 0700); + open(HEXBIN, "| (cd $temp ; hexbin -n attach -d 2>/dev/null)"); + print HEXBIN $attach->{'data'}; + close(HEXBIN); + if (!$?) { + open(HEXBIN, "$temp/attach.data"); + local $/ = undef; + $attach->{'data'} = ; + close(HEXBIN); + local $ct = &guess_mime_type($attach->{'filename'}); + $attach->{'type'} = $ct; + $attach->{'header'} = { 'content-type' => $ct }; + $attach->{'headers'} = [ [ 'Content-Type', $ct ] ]; + } + unlink("$temp/attach.data"); + rmdir($temp); + } + + $attach->{'idx'} = scalar(@attach); + $attach->{'parent'} = $_[1] ? $_[1] : $_[0]; + push(@attach, $attach) if (@headers || $attach->{'data'}); + if ($attach->{'type'} =~ /multipart\/(\S+)/i) { + # This attachment contains more attachments .. + # expand them. + local $amail = { 'header' => $attach->{'header'}, + 'body' => $attach->{'data'} }; + &parse_mail($amail, $attach); + $attach->{'attach'} = [ @{$amail->{'attach'}} ]; + map { $_->{'idx'} += scalar(@attach) } + @{$amail->{'attach'}}; + push(@attach, @{$amail->{'attach'}}); + } + elsif (lc($attach->{'type'}) eq 'application/ms-tnef') { + # This attachment is a winmail.dat file, which may + # contain multiple other attachments! + local ($opentnef, $tnef); + if (!($opentnef = &has_command("opentnef")) && + !($tnef = &has_command("tnef"))) { + $attach->{'error'} = "tnef command not installed"; + } + else { + # Can actually decode + local $tempfile = &transname(); + open(TEMPFILE, ">$tempfile"); + print TEMPFILE $attach->{'data'}; + close(TEMPFILE); + local $tempdir = &transname(); + mkdir($tempdir, 0700); + if ($opentnef) { + system("$opentnef -d $tempdir -i $tempfile >/dev/null 2>&1"); + } + else { + system("$tnef -C $tempdir -f $tempfile >/dev/null 2>&1"); + } + pop(@attach); # lose winmail.dat + opendir(DIR, $tempdir); + while($f = readdir(DIR)) { + next if ($f eq '.' || $f eq '..'); + local $data; + open(FILE, "$tempdir/$f"); + while() { + $data .= $_; + } + close(FILE); + local $ct = &guess_mime_type($f); + push(@attach, + { 'type' => $ct, + 'idx' => scalar(@attach), + 'header' => + { 'content-type' => $ct }, + 'headers' => + [ [ 'Content-Type', $ct ] ], + 'filename' => $f, + 'data' => $data }); + } + closedir(DIR); + unlink(glob("$tempdir/*"), $tempfile); + rmdir($tempdir); + } + } + last if ($l >= $max || $lines[$l] eq "$bound--"); + $l++; + } + $_[0]->{'attach'} = \@attach; + } +elsif ($_[0]->{'body'} =~ /begin\s+([0-7]+)\s+(.*)/i) { + # Message contains uuencoded file(s) + local @lines = split(/\n/, $_[0]->{'body'}); + local ($attach, $rest); + foreach $l (@lines) { + if ($l =~ /^begin\s+([0-7]+)\s+(.*)/i) { + $attach = { 'type' => &guess_mime_type($2), + 'idx' => scalar(@{$_[0]->{'attach'}}), + 'parent' => $_[1], + 'filename' => $2 }; + push(@{$_[0]->{'attach'}}, $attach); + } + elsif ($l =~ /^end/ && $attach) { + $attach = undef; + } + elsif ($attach) { + $attach->{'data'} .= unpack("u", $l); + } + else { + $rest .= $l."\n"; + } + } + if ($rest =~ /\S/) { + # Some leftover text + push(@{$_[0]->{'attach'}}, + { 'type' => "text/plain", + 'idx' => scalar(@{$_[0]->{'attach'}}), + 'parent' => $_[1], + 'data' => $rest }); + } + } +elsif (lc($_[0]->{'header'}->{'content-transfer-encoding'}) eq 'base64') { + # Signed body section + $ct =~ s/;.*$//; + $_[0]->{'attach'} = [ { 'type' => lc($ct), + 'idx' => 0, + 'parent' => $_[1], + 'data' => &b64decode($_[0]->{'body'}) } ]; + } +elsif (lc($_[0]->{'header'}->{'content-type'}) eq 'x-sun-attachment') { + # Sun attachment format, which can contain several sections + local $sun; + foreach $sun (split(/----------/, $_[0]->{'body'})) { + local ($headers, $rest) = split(/\r?\n\r?\n/, $sun, 2); + local $attach = { 'idx' => scalar(@{$_[0]->{'attach'}}), + 'parent' => $_[1], + 'data' => $rest }; + if ($headers =~ /X-Sun-Data-Name:\s*(\S+)/) { + $attach->{'filename'} = $1; + } + if ($headers =~ /X-Sun-Data-Type:\s*(\S+)/) { + local $st = $1; + $attach->{'type'} = $st eq "text" ? "text/plain" : + $st eq "html" ? "text/html" : + $st =~ /\// ? $st : "application/octet-stream"; + } + elsif ($attach->{'filename'}) { + $attach->{'type'} = + &guess_mime_type($attach->{'filename'}); + } + else { + $attach->{'type'} = "text/plain"; # fallback + } + push(@{$_[0]->{'attach'}}, $attach); + } + } +else { + # One big attachment (probably text) + local ($type, $body); + ($type = $ct) =~ s/;.*$//; + $type = 'text/plain' if (!$type); + if (lc($_[0]->{'header'}->{'content-transfer-encoding'}) eq 'base64') { + $body = &b64decode($_[0]->{'body'}); + } + elsif (lc($_[0]->{'header'}->{'content-transfer-encoding'}) eq + 'quoted-printable') { + $body = "ed_decode($_[0]->{'body'}); + } + else { + $body = $_[0]->{'body'}; + } + $_[0]->{'attach'} = [ { 'type' => lc($type), + 'idx' => 0, + 'parent' => $_[1], + 'data' => $body } ]; + } +delete($_[0]->{'body'}) if (!$_[2]); +} + +# delete_mail(user|file, &mail, ...) +# Delete mail messages from a user by copying the file and rebuilding the index +sub delete_mail +{ +local @m = sort { $a->{'line'} <=> $b->{'line'} } @_[1..@_-1]; +local $i = 0; +local $f = &user_mail_file($_[0]); +local $ifile = &user_index_file($_[0]); +local $itype = &index_type($_[0]); +local $lnum = 0; +local %dline; +local ($dpos = 0, $dlnum = 0); +local (@index, %index); +if ($itype == 1) { + &build_dbm_index($_[0], \%index); + } + +local $tmpf = $< == 0 ? "$f.del" : + $_[0] =~ /^\/.*\/([^\/]+)$/ ? + "$user_module_config_directory/$1.del" : + "$user_module_config_directory/$_[0].del"; +open(SOURCE, $f) || &error("Read failed : $!"); +open(DEST, ">$tmpf") || &error("Open of $tmpf failed : $!"); +while() { + if ($i >= @m || $lnum < $m[$i]->{'line'}) { + if ($itype == 0 && /^From\s+(\S+).*\d+\r?\n/ && + ($1 ne '-' || $dash)) { + push(@index, [ $dpos, $dlnum ]); + } + $dpos += length($_); + $dlnum++; + local $w = (print DEST $_); + if (!$w) { + local $e = "$!"; + close(DEST); + close(SOURCE); + unlink($tmpf); + &error("Write to $tmpf failed : $e"); + } + } + elsif ($lnum == $m[$i]->{'eline'}) { + $dline{$m[$i]->{'line'}}++; + $i++; + } + $lnum++; + } +close(SOURCE); +close(DEST) || &error("Write to $tmpf failed : $?"); +local @st = stat($f); +unlink($f) if ($< == 0); +if ($itype == 0) { + open(INDEX, ">$ifile"); + print INDEX map { $_->[0]." ".$_->[1]."\n" } @index; + close(INDEX); + } +else { + # Just force a total index re-build (XXX lazy!) + $index{'mailcount'} = $in{'lastchange'} = 0; + } +if ($< == 0) { + rename($tmpf, $f); + } +else { + system("cat ".quotemeta($tmpf)." > ".quotemeta($f). + " && rm -f ".quotemeta($tmpf)); + } +chown($st[4], $st[5], $f); +chmod($st[2], $f); +} + +# modify_mail(user|file, old, new, textonly) +# Modify one email message in a mailbox by copying the file and rebuilding +# the index. +sub modify_mail +{ +local $f = &user_mail_file($_[0]); +local $ifile = &user_index_file($_[0]); +local $itype = &index_type($_[0]); +local $lnum = 0; +local ($sizediff, $linesdiff); +local (@index, %index); +if ($itype == 0) { + @index = &build_index($_[0]); + } +else { + &build_dbm_index($_[0], \%index); + } + +# Replace the email that gets modified +local $tmpf = $< == 0 ? "$f.del" : + $_[0] =~ /^\/.*\/([^\/]+)$/ ? + "$user_module_config_directory/$1.del" : + "$user_module_config_directory/$_[0].del"; +open(SOURCE, $f); +open(DEST, ">$tmpf"); +while() { + if ($lnum < $_[1]->{'line'} || $lnum > $_[1]->{'eline'}) { + # before or after the message to change + local $w = (print DEST $_); + if (!$w) { + local $e = "$?"; + close(DEST); + close(SOURCE); + unlink($tmpf); + &error("Write to $tmpf failed : $e"); + } + } + elsif ($lnum == $_[1]->{'line'}) { + # found start of message to change .. put in the new one + close(DEST); + local @ost = stat($tmpf); + local $nlines = &send_mail($_[2], $tmpf, $_[3], 1); + local @nst = stat($tmpf); + local $newsize = $nst[7] - $ost[7]; + $sizediff = $newsize - $_[1]->{'size'}; + $linesdiff = $nlines - ($_[1]->{'eline'} - $_[1]->{'line'} + 1); + open(DEST, ">>$tmpf"); + } + $lnum++; + } +close(SOURCE); +close(DEST) || &error("Write failed : $!"); + +# Now update the index and delete the temp file +if ($itype == 0) { + # Update old-style index + foreach $i (@index) { + if ($i->[1] > $_[1]->{'line'}) { + # Shift mails after the modified + $i->[0] += $sizediff; + $i->[1] += $linesdiff; + } + } + } +else { + # Update DBM index + for($i=0; $i<$index{'mailcount'}; $i++) { + local @idx = split(/\0/, $index{$i}); + if ($idx[1] > $_[1]->{'line'}) { + $idx[0] += $sizediff; + $idx[1] += $linesdiff; + $index{$i} = join("\0", @idx); + } + } + $index{'lastchange'} = time(); + } +local @st = stat($f); +unlink($f); +if ($itype == 0) { + open(INDEX, ">$ifile"); + print INDEX map { $_->[0]." ".$_->[1]."\n" } @index; + close(INDEX); + } +if ($< == 0) { + rename($tmpf, $f); + } +else { + system("cat $tmpf >$f && rm -f $tmpf"); + } +chown($st[4], $st[5], $f); +chmod($st[2], $f); + +} + +# send_mail(&mail, [file], [textonly], [nocr], [smtp-server], +# [smtp-user], [smtp-pass], [smtp-auth-mode], +# [¬ify-flags], [port]) +# Send out some email message or append it to a file. +# Returns the number of lines written. +sub send_mail +{ +return 0 if (&is_readonly_mode()); +local (%header, $h); +local $lnum = 0; +local $sm = $_[4] || $config{'send_mode'}; +local $eol = $_[3] || !$sm ? "\n" : "\r\n"; +local $port = $_[9] || $config{'smtp_port'} || 25; +foreach $h (@{$_[0]->{'headers'}}) { + $header{lc($h->[0])} = $h->[1]; + } +local @tm = localtime(time()); +push(@{$_[0]->{'headers'}}, + [ 'Date', strftime("%a, %d %b %Y %H:%M:%S %z (%Z)", @tm) ]) + if (!$header{'date'}); +local @from = &address_parts($header{'from'}); +local $esmtp = $_[8] ? 1 : 0; +if ($_[1]) { + # Just append the email to a file using mbox format + open(MAIL, ">>$_[1]") || &error("Write failed : $!"); + $lnum++; + print MAIL $_[0]->{'fromline'} ? $_[0]->{'fromline'}."\n" : + strftime("From $from[0] %a %b %e %H:%M:%S %Y\n", @tm); + } +elsif ($sm) { + # Connect to SMTP server + &open_socket($sm, $port, MAIL); + &smtp_command(MAIL); + if ($esmtp) { + &smtp_command(MAIL, "ehlo ".&get_system_hostname()."\r\n"); + } + else { + &smtp_command(MAIL, "helo ".&get_system_hostname()."\r\n"); + } + + # Get username and password from parameters, or from module config + local $user = $_[5] || $userconfig{'smtp_user'} || $config{'smtp_user'}; + local $pass = $_[6] || $userconfig{'smtp_pass'} || $config{'smtp_pass'}; + local $auth = $_[7] || $userconfig{'smtp_auth'} || + $config{'smtp_auth'} || "Cram-MD5"; + if ($user) { + # Send authentication commands + eval "use Authen::SASL"; + if ($@) { + &error("Perl module Authen::SASL is needed for SMTP authentication"); + } + my $sasl = Authen::SASL->new('mechanism' => uc($auth), + 'callback' => { + 'auth' => $user, + 'user' => $user, + 'pass' => $pass } ); + &error("Failed to create Authen::SASL object") if (!$sasl); + local $conn = $sasl->client_new("smtp", &get_system_hostname()); + local $arv = &smtp_command(MAIL, "auth $auth\r\n", 1); + if ($arv =~ /^(334)\s+(.*)/) { + # Server says to go ahead + $extra = $2; + local $initial = $conn->client_start(); + local $auth_ok; + if ($initial) { + local $enc = &encode_base64($initial); + $enc =~ s/\r|\n//g; + $arv = &smtp_command(MAIL, "$enc\r\n", 1); + if ($arv =~ /^(\d+)\s+(.*)/) { + if ($1 == 235) { + $auth_ok = 1; + } + else { + &error("Unknown SMTP authentication response : $arv"); + } + } + $extra = $2; + } + while(!$auth_ok) { + local $message = &decode_base64($extra); + local $return = $conn->client_step($message); + local $enc = &encode_base64($return); + $enc =~ s/\r|\n//g; + $arv = &smtp_command(MAIL, "$enc\r\n", 1); + if ($arv =~ /^(\d+)\s+(.*)/) { + if ($1 == 235) { + $auth_ok = 1; + } + elsif ($1 == 535) { + &error("SMTP authentication failed : $arv"); + } + $extra = $2; + } + else { + &error("Unknown SMTP authentication response : $arv"); + } + } + } + } + + &smtp_command(MAIL, "mail from: <$from[0]>\r\n"); + local $notify = $_[8] ? " NOTIFY=".join(",", @{$_[8]}) : ""; + local $u; + foreach $u (&address_parts($header{'to'}.",".$header{'cc'}. + ",".$header{'bcc'})) { + &smtp_command(MAIL, "rcpt to: <$u>$notify\r\n"); + } + &smtp_command(MAIL, "data\r\n"); + } +elsif (defined(&send_mail_program)) { + # Use specified mail injector + local $cmd = &send_mail_program($from[0]); + $cmd || &error("No mail program was found on your system!"); + open(MAIL, "| $cmd >/dev/null 2>&1"); + } +elsif ($config{'qmail_dir'}) { + # Start qmail-inject + open(MAIL, "| $config{'qmail_dir'}/bin/qmail-inject"); + } +elsif ($config{'postfix_control_command'}) { + # Start postfix's sendmail wrapper + local $cmd = -x "/usr/lib/sendmail" ? "/usr/lib/sendmail" : + &has_command("sendmail"); + $cmd || &error($text{'send_ewrapper'}); + open(MAIL, "| $cmd -t -f$from[0] >/dev/null 2>&1"); + } +else { + # Start sendmail + &has_command($config{'sendmail_path'}) || + &error(&text('send_epath', "$config{'sendmail_path'}")); + open(MAIL, "| $config{'sendmail_path'} -t -f$from[0] >/dev/null 2>&1"); + } +local $ctype = "multipart/mixed"; +local $msg_id; +foreach $h (@{$_[0]->{'headers'}}) { + if (defined($_[0]->{'body'}) || $_[2]) { + print MAIL $h->[0],": ",$h->[1],$eol; + $lnum++; + } + else { + if ($h->[0] !~ /^(MIME-Version|Content-Type)$/i) { + print MAIL $h->[0],": ",$h->[1],$eol; + $lnum++; + } + elsif (lc($h->[0]) eq 'content-type') { + $ctype = $h->[1]; + } + } + if (lc($h->[0]) eq 'message-id') { + $msg_id++; + } + } +if (!$msg_id) { + # Add a message-id header if missing + print MAIL "Message-Id: <",time().".".$$."\@". + &get_system_hostname(),">",$eol; + } + +# Work out first attachment content type +local ($ftype, $fenc); +if (@{$_[0]->{'attach'}} >= 1) { + local $first = $_[0]->{'attach'}->[0]; + $ftype = "text/plain"; + foreach my $h (@{$first->{'headers'}}) { + if (lc($h->[0]) eq "content-type") { + $ftype = $h->[1]; + } + if (lc($h->[0]) eq "content-transfer-encoding") { + $fenc = $h->[1]; + } + } + } + +if (defined($_[0]->{'body'})) { + # Use original mail body + print MAIL $eol; + $lnum++; + $_[0]->{'body'} =~ s/\r//g; + $_[0]->{'body'} =~ s/\n\.\n/\n\. \n/g; + $_[0]->{'body'} =~ s/\n/$eol/g; + $_[0]->{'body'} .= $eol if ($_[0]->{'body'} !~ /\n$/); + (print MAIL $_[0]->{'body'}) || &error("Write failed : $!"); + $lnum += ($_[0]->{'body'} =~ tr/\n/\n/); + } +elsif (!$_[2] || $ftype !~ /text\/plain/i || + $fenc =~ /quoted-printable|base64/) { + # Sending MIME-encoded email + if ($ctype !~ /multipart\/report/i) { + $ctype =~ s/;.*$//; + } + print MAIL "MIME-Version: 1.0",$eol; + local $bound = "bound".time(); + print MAIL "Content-Type: $ctype; boundary=\"$bound\"",$eol; + print MAIL $eol; + $lnum += 3; + + # Send attachments + print MAIL "This is a multi-part message in MIME format.",$eol; + $lnum++; + foreach $a (@{$_[0]->{'attach'}}) { + print MAIL $eol; + print MAIL "--",$bound,$eol; + $lnum += 2; + local $enc; + foreach $h (@{$a->{'headers'}}) { + print MAIL $h->[0],": ",$h->[1],$eol; + $enc = $h->[1] + if (lc($h->[0]) eq 'content-transfer-encoding'); + $lnum++; + } + print MAIL $eol; + $lnum++; + if (lc($enc) eq 'base64') { + local $enc = &encode_base64($a->{'data'}); + $enc =~ s/\r//g; + $enc =~ s/\n/$eol/g; + print MAIL $enc; + $lnum += ($enc =~ tr/\n/\n/); + } + else { + $a->{'data'} =~ s/\r//g; + $a->{'data'} =~ s/\n\.\n/\n\. \n/g; + $a->{'data'} =~ s/\n/$eol/g; + print MAIL $a->{'data'}; + $lnum += ($a->{'data'} =~ tr/\n/\n/); + if ($a->{'data'} !~ /\n$/) { + print MAIL $eol; + $lnum++; + } + } + } + print MAIL $eol; + (print MAIL "--",$bound,"--",$eol) || &error("Write failed : $!"); + print MAIL $eol; + $lnum += 3; + } +else { + # Sending text-only mail from first attachment + local $a = $_[0]->{'attach'}->[0]; + print MAIL $eol; + $lnum++; + $a->{'data'} =~ s/\r//g; + $a->{'data'} =~ s/\n/$eol/g; + (print MAIL $a->{'data'}) || &error("Write failed : $!"); + $lnum += ($a->{'data'} =~ tr/\n/\n/); + if ($a->{'data'} !~ /\n$/) { + print MAIL $eol; + $lnum++; + } + } +if ($sm && !$_[1]) { + &smtp_command(MAIL, ".$eol"); + &smtp_command(MAIL, "quit$eol"); + } +if (!close(MAIL)) { + # Only bother to report an error on close if writing to a file + if ($_[1]) { + &error("Write failed : $!"); + } + } +return $lnum; +} + +# mail_size(&mail, [textonly]) +# Returns the size of an email message in bytes +sub mail_size +{ +local ($mail, $textonly) = @_; +local $temp = &transname(); +&send_mail($mail, $temp, $textonly); +local @st = stat($temp); +unlink($temp); +return $st[7]; +} + +# b64decode(string) +# Converts a string from base64 format to normal +sub b64decode +{ + local($str) = $_[0]; + local($res); + $str =~ tr|A-Za-z0-9+=/||cd; + $str =~ s/=+$//; + $str =~ tr|A-Za-z0-9+/| -_|; + while ($str =~ /(.{1,60})/gs) { + my $len = chr(32 + length($1)*3/4); + $res .= unpack("u", $len . $1 ); + } + return $res; +} + +# can_read_mail(user) +sub can_read_mail +{ +return 1 if ($_[0] && $access{'sent'} eq $_[0]); +local @u = getpwnam($_[0]); +return 0 if (!@u); +return 0 if ($_[0] =~ /\.\./); +return 0 if ($access{'mmode'} == 0); +return 1 if ($access{'mmode'} == 1); +local $u; +if ($access{'mmode'} == 2) { + foreach $u (split(/\s+/, $access{'musers'})) { + return 1 if ($u eq $_[0]); + } + return 0; + } +elsif ($access{'mmode'} == 4) { + return 1 if ($_[0] eq $remote_user); + } +elsif ($access{'mmode'} == 5) { + return $u[3] eq $access{'musers'}; + } +elsif ($access{'mmode'} == 3) { + foreach $u (split(/\s+/, $access{'musers'})) { + return 0 if ($u eq $_[0]); + } + return 1; + } +elsif ($access{'mmode'} == 6) { + return ($_[0] =~ /^$access{'musers'}$/); + } +elsif ($access{'mmode'} == 7) { + return (!$access{'musers'} || $u[2] >= $access{'musers'}) && + (!$access{'musers2'} || $u[2] <= $access{'musers2'}); + } +return 0; # can't happen! +} + +# from_hostname() +sub from_hostname +{ +local ($d, $masq); +local $conf = &get_sendmailcf(); +foreach $d (&find_type("D", $conf)) { + if ($d->{'value'} =~ /^M\s*(\S*)/) { $masq = $1; } + } +return $masq ? $masq : &get_system_hostname(); +} + +# mail_from_queue(qfile, [dfile|"auto"]) +# Reads a message from the Sendmail mail queue +sub mail_from_queue +{ +local $mail = { 'file' => $_[0] }; +$mail->{'quar'} = $_[0] =~ /\/hf/; +$mail->{'lost'} = $_[0] =~ /\/Qf/; +if ($_[1] eq "auto") { + $mail->{'dfile'} = $_[0]; + $mail->{'dfile'} =~ s/\/(qf|hf|Qf)/\/df/; + } +elsif ($_[1]) { + $mail->{'dfile'} = $_[1]; + } +$mail->{'lfile'} = $_[0]; +$mail->{'lfile'} =~ s/\/(qf|hf|Qf)/\/xf/; +local $_; +local @headers; +open(QF, $_[0]) || return undef; +while() { + s/\r|\n//g; + if (/^M(.*)/) { + $mail->{'status'} = $1; + } + elsif (/^H\?[^\?]*\?(\S+):\s+(.*)/ || /^H(\S+):\s+(.*)/) { + push(@headers, [ $1, $2 ]); + $mail->{'rawheaders'} .= "$1: $2\n"; + } + elsif (/^\s+(.*)/) { + $headers[$#headers]->[1] .= $1 unless($#headers < 0); + $mail->{'rawheaders'} .= $_."\n"; + } + } +close(QF); +$mail->{'headers'} = \@headers; +foreach $h (@headers) { + $mail->{'header'}->{lc($h->[0])} = $h->[1]; + } + +if ($mail->{'dfile'}) { + # Read the mail body + open(DF, $mail->{'dfile'}); + while() { + $mail->{'body'} .= $_; + } + close(DF); + } +local $datafile = $mail->{'dfile'}; +if (!$datafile) { + ($datafile = $mail->{'file'}) =~ s/\/(qf|hf|Qf)/\/df/; + } +local @st0 = stat($mail->{'file'}); +local @st1 = stat($datafile); +$mail->{'size'} = $st0[7] + $st1[7]; +return $mail; +} + +# wrap_lines(text, width) +# Given a multi-line string, return an array of lines wrapped to +# the given width +sub wrap_lines +{ +local @rv; +local $w = $_[1]; +foreach $rest (split(/\n/, $_[0])) { + if ($rest =~ /\S/) { + while($rest =~ /^(.{1,$w}\S*)\s*([\0-\377]*)$/) { + push(@rv, $1); + $rest = $2; + } + } + else { + # Empty line .. keep as it is + push(@rv, $rest); + } + } +return @rv; +} + +# smtp_command(handle, command, no-error) +sub smtp_command +{ +local ($m, $c) = @_; +print $m $c; +local $r = <$m>; +if ($r !~ /^[23]\d+/ && !$_[2]) { + &error(&text('send_esmtp', "".&html_escape($c)."", + "".&html_escape($r)."")); + } +$r =~ s/\r|\n//g; +if ($r =~ /^(\d+)\-/) { + # multi-line ESMTP response! + while(1) { + local $nr = <$m>; + $nr =~ s/\r|\n//g; + if ($nr =~ /^(\d+)\-(.*)/) { + $r .= "\n".$2; + } + elsif ($nr =~ /^(\d+)\s+(.*)/) { + $r .= "\n".$2; + last; + } + } + } +return $r; +} + +# address_parts(string) +# Returns the email addresses in a string +sub address_parts +{ +local @rv; +local $rest = $_[0]; +while($rest =~ /([^<>\s,'"\@]+\@[A-z0-9\-\.\!]+)(.*)/) { + push(@rv, $1); + $rest = $2; + } +return wantarray ? @rv : $rv[0]; +} + +# link_urls(text, separate) +sub link_urls +{ +local $r = $_[0]; +local $tar = $_[1] ? "target=link".int(rand()*100000) : ""; +$r =~ s/((http|ftp|https|mailto):[^><"'\s]+[^><"'\s\.\)])/$1<\/a>/g; +return $r; +} + +# link_urls_and_escape(text, separate) +# HTML escapes some text, as well as properly linking URLs in it +sub link_urls_and_escape +{ +local $l = $_[0]; +local $rv; +local $tar = $_[1] ? " target=link".int(rand()*100000) : ""; +while($l =~ /^(.*?)((http|ftp|https|mailto):[^><"'\s]+[^><"'\s\.\)])(.*)/) { + local ($before, $url, $after) = ($1, $2, $4); + $rv .= &eucconv_and_escape($before)."". + &html_escape($url).""; + $l = $after; + } +$rv .= &eucconv_and_escape($l); +return $rv; +} + +# uudecode(text) +sub uudecode +{ +local @lines = split(/\n/, $_[0]); +local ($l, $data); +for($l=0; $lines[$l] !~ /begin\s+([0-7]+)\s/i; $l++) { } +while($lines[++$l]) { + $data .= unpack("u", $lines[$l]); + } +return $data; +} + +sub simplify_date +{ +local $u = &parse_mail_date($_[0]); +if ($u) { + local $fmt = $userconfig{'date_fmt'} || $config{'date_fmt'} || "dmy"; + local $strf = $fmt eq "dmy" ? "%d/%m/%Y" : + $fmt eq "mdy" ? "%m/%d/%Y" : + "%Y/%m/%d"; + return strftime("$strf %H:%M", localtime($u)); + } +elsif ($_[0] =~ /^(\S+),\s+0*(\d+)\s+(\S+)\s+(\d+)\s+(\d+):(\d+)/) { + return "$2/$3/$4 $5:$6"; + } +elsif ($_[0] =~ /^0*(\d+)\s+(\S+)\s+(\d+)\s+(\d+):(\d+)/) { + return "$1/$2/$3 $4:$5"; + } +return $_[0]; +} + +# simplify_from(from) +# Simplifies a From: address for display in the mail list. Only the first +# address is returned. +sub simplify_from +{ +local $rv = &eucconv(&decode_mimewords($_[0])); +local @sp = &split_addresses($rv); +if (!@sp) { + return $text{'mail_nonefrom'}; + } +else { + local $first = &html_escape($sp[0]->[1] ? $sp[0]->[1] : $sp[0]->[2]); + if (length($first) > 80) { + return substr($first, 0, 80)." .."; + } + else { + return $first.(@sp > 1 ? " , ..." : ""); + } + } +} + +# simplify_subject(subject) +sub simplify_subject +{ +local $rv = &eucconv(&decode_mimewords($_[0])); +$rv = substr($rv, 0, 80)." .." if (length($rv) > 80); +return $rv =~ /\S/ ? &html_escape($rv) : "
"; +} + +# quoted_decode(text) +sub quoted_decode +{ +local $t = $_[0]; +$t =~ s/=\n//g; +$t =~ s/=([a-zA-Z0-9]{2})/pack("c",hex($1))/ge; +return $t; +} + +# quoted_encode(text) +sub quoted_encode +{ +local $t = $_[0]; +$t =~ s/([=\177-\377])/sprintf("=%2.2X",ord($1))/ge; +return $t; +} + +sub decode_mimewords { + my $encstr = shift; + my %params = @_; + my @tokens; + $@ = ''; ### error-return + + ### Collapse boundaries between adjacent encoded words: + $encstr =~ s{(\?\=)\r?\n[ \t](\=\?)}{$1$2}gs; + pos($encstr) = 0; + ### print STDOUT "ENC = [", $encstr, "]\n"; + + ### Decode: + my ($charset, $encoding, $enc, $dec); + while (1) { + last if (pos($encstr) >= length($encstr)); + my $pos = pos($encstr); ### save it + + ### Case 1: are we looking at "=?..?..?="? + if ($encstr =~ m{\G # from where we left off.. + =\?([^?]*) # "=?" + charset + + \?([bq]) # "?" + encoding + + \?([^?]+) # "?" + data maybe with spcs + + \?= # "?=" + }xgi) { + ($charset, $encoding, $enc) = ($1, lc($2), $3); + $dec = (($encoding eq 'q') ? _decode_Q($enc) : _decode_B($enc)); + push @tokens, [$dec, $charset]; + next; + } + + ### Case 2: are we looking at a bad "=?..." prefix? + ### We need this to detect problems for case 3, which stops at "=?": + pos($encstr) = $pos; # reset the pointer. + if ($encstr =~ m{\G=\?}xg) { + $@ .= qq|unterminated "=?..?..?=" in "$encstr" (pos $pos)\n|; + push @tokens, ['=?']; + next; + } + + ### Case 3: are we looking at ordinary text? + pos($encstr) = $pos; # reset the pointer. + if ($encstr =~ m{\G # from where we left off... + ([\x00-\xFF]*? # shortest possible string, + \n*) # followed by 0 or more NLs, + (?=(\Z|=\?)) # terminated by "=?" or EOS + }xg) { + length($1) or die "MIME::Words: internal logic err: empty token\n"; + push @tokens, [$1]; + next; + } + + ### Case 4: bug! + die "MIME::Words: unexpected case:\n($encstr) pos $pos\n\t". + "Please alert developer.\n"; + } + return join('',map {$_->[0]} @tokens); +} + +# _decode_Q STRING +# Private: used by _decode_header() to decode "Q" encoding, which is +# almost, but not exactly, quoted-printable. :-P +sub _decode_Q { + my $str = shift; + $str =~ s/_/\x20/g; # RFC-1522, Q rule 2 + $str =~ s/=([\da-fA-F]{2})/pack("C", hex($1))/ge; # RFC-1522, Q rule 1 + $str; +} + +# _decode_B STRING +# Private: used by _decode_header() to decode "B" encoding. +sub _decode_B { + my $str = shift; + &decode_base64($str); +} + +# user_mail_file(user|file, [other details]) +sub user_mail_file +{ +if ($_[0] =~ /^\//) { + return $_[0]; + } +elsif ($config{'mail_dir'}) { + return &mail_file_style($_[0], $config{'mail_dir'}, + $config{'mail_style'}); + } +elsif (@_ > 1) { + return "$_[7]/$config{'mail_file'}"; + } +else { + local @u = getpwnam($_[0]); + return "$u[7]/$config{'mail_file'}"; + } +} + +# mail_file_style(user, basedir, style) +sub mail_file_style +{ +if ($_[2] == 0) { + return "$_[1]/$_[0]"; + } +elsif ($_[2] == 1) { + return $_[1]."/".substr($_[0], 0, 1)."/".$_[0]; + } +elsif ($_[2] == 2) { + return $_[1]."/".substr($_[0], 0, 1)."/". + substr($_[0], 0, 2)."/".$_[0]; + } +else { + return $_[1]."/".substr($_[0], 0, 1)."/". + substr($_[0], 1, 1)."/".$_[0]; + } +} + +# user_index_file(user|file) +sub user_index_file +{ +local $us = $_[0]; +$us =~ s/\//_/g; +local $f; +local $hn = &get_system_hostname(); +if ($_[0] =~ /^\/.*\/([^\/]+)$/) { + # A file .. the index file is in ~/.usermin/mailbox or + # /etc/webmin/mailboxes + if ($user_module_config_directory && $config{'shortindex'}) { + # Use short name for index file + $f = "$user_module_config_directory/$1.findex"; + } + else { + $f = $user_module_config_directory ? + "$user_module_config_directory/$us.findex" : + "$module_config_directory/$us.findex"; + } + } +else { + # A username .. the index file is in /etc/webmin/mailboxes + $f = $user_module_config_directory ? + "$user_module_config_directory/$_[0].index" : + "$module_config_directory/$_[0].index"; + } +return -r $f && !-r "$f.$hn" ? $f : "$f.$hn"; +} + +# extract_mail(data) +# Converts the text of a message into mail object. +sub extract_mail +{ +local $text = $_[0]; +$text =~ s/^\s+//; +local ($amail, @aheaders, $i); +local @alines = split(/\n/, $text); +while($i < @alines && $alines[$i]) { + if ($alines[$i] =~ /^(\S+):\s*(.*)/) { + push(@aheaders, [ $1, $2 ]); + $amail->{'rawheaders'} .= $alines[$i]."\n"; + } + elsif ($alines[$i] =~ /^\s+(.*)/) { + $aheaders[$#aheaders]->[1] .= $1 unless($#aheaders < 0); + $amail->{'rawheaders'} .= $alines[$i]."\n"; + } + $i++; + } +$amail->{'headers'} = \@aheaders; +foreach $h (@aheaders) { + $amail->{'header'}->{lc($h->[0])} = $h->[1]; + } +splice(@alines, 0, $i); +$amail->{'body'} = join("\n", @alines)."\n"; +return $amail; +} + +# split_addresses(string) +# Splits a comma-separated list of addresses into [ email, real-name, original ] +# triplets +sub split_addresses +{ +local (@rv, $str = $_[0]); +while(1) { + if ($str =~ /^[\s,]*(([^<>\(\)\s]+)\s+\(([^\(\)]+)\))(.*)$/) { + # An address like foo@bar.com (Fooey Bar) + push(@rv, [ $2, $3, $1 ]); + $str = $4; + } + elsif ($str =~ /^[\s,]*("([^"]+)"\s*<([^\s<>,]+)>)(.*)$/ || + $str =~ /^[\s,]*(([^<>]+)\s+<([^\s<>,]+)>)(.*)$/ || + $str =~ /^[\s,]*(([^<>]+)<([^\s<>,]+)>)(.*)$/ || + $str =~ /^[\s,]*(([^<>\[\]]+)\s+\[mailto:([^\s\[\]]+)\])(.*)$/|| + $str =~ /^[\s,]*(()<([^<>,]+)>)(.*)/ || + $str =~ /^[\s,]*(()([^\s<>,]+))(.*)/) { + # Addresses like "Fooey Bar" + # Fooey Bar + # Fooey Bar [mailto:foo@bar.com] + # + # + # foo@bar.com + push(@rv, [ $3, $2, $1 ]); + $str = $4; + } + else { + last; + } + } +return @rv; +} + +$match_ascii = '\x1b\([BHJ]([\t\x20-\x7e]*)'; +$match_jis = '\x1b\$[@B](([\x21-\x7e]{2})*)'; + +sub eucconv { + local($_) = @_; + if ($current_lang eq 'ja_JP.euc') { + s/$match_jis/&j2e($1)/geo; + s/$match_ascii/$1/go; + } + $_; +} + +sub j2e { + local($_) = @_; + tr/\x21-\x7e/\xa1-\xfe/; + $_; +} + +# eucconv_and_escape(string) +sub eucconv_and_escape { + return &html_escape(&eucconv($_[0])); +} + +# list_maildir(file, [start], [end]) +# Returns a subset of mail from a maildir format directory +sub list_maildir +{ +local (@rv, $i, $f); +local @files = &get_maildir_files($_[0]); + +local ($start, $end); +if (!defined($_[1])) { + $start = 0; + $end = @files - 1; + } +elsif ($_[2] < 0) { + $start = @files + $_[2] - 1; + $end = @files + $_[1] - 1; + $start = 0 if ($start < 0); + } +else { + $start = $_[1]; + $end = $_[2]; + $end = @files-1 if ($end >= @files); + } +foreach $f (@files) { + if ($i < $start || $i > $end) { + # Skip files outside requested index range + push(@rv, undef); + $i++; + next; + } + local $mail = &read_mail_file($f); + $mail->{'idx'} = $i++; + push(@rv, $mail); + } +return @rv; +} + +# select_maildir(file, &indexes, headersonly) +# Returns a list of messages with the given indexes, from a maildir directory +sub select_maildir +{ +local @files = &get_maildir_files($_[0]); +local @rv; +foreach my $i (@{$_[1]}) { + local $mail = &read_mail_file($files[$i], $_[2]); + $mail->{'idx'} = $i; + push(@rv, $mail); + } +return @rv; +} + +# Get ordered list of message files (with in-memory and on-disk caching, as +# this can be slow) +# get_maildir_files(directory) +sub get_maildir_files +{ +# Work out last modified time +local $newest; +foreach my $d ("$_[0]/cur", "$_[0]/new") { + local @dst = stat($d); + $newest = $dst[9] if ($dst[9] > $newest); + } + +local @files; +if (defined($main::list_maildir_cache{$_[0]}) && + $main::list_maildir_cache_time{$_[0]} == $newest) { + # Use the in-memory cache cache + @files = @{$main::list_maildir_cache{$_[0]}}; + } +else { + # Check the on-disk cache file + local $cachefile = &get_maildir_cachefile($_[0]); + local @cst = $cachefile ? stat($cachefile) : ( ); + if ($cst[9] >= $newest) { + # Can read the cache + open(CACHE, $cachefile); + while() { + chop; + push(@files, $_[0]."/".$_); + } + close(CACHE); + } + else { + # Really read + local @shorts; + foreach my $d ("cur", "new") { + opendir(DIR, "$_[0]/$d"); + while(my $f = readdir(DIR)) { + push(@shorts, "$d/$f") + if ($f ne "." && $f ne ".."); + } + closedir(DIR); + } + @shorts = sort { substr($a, 4) cmp substr($b, 4) } @shorts; + @files = map { "$_[0]/$_" } @shorts; + + # Write out the on-disk cache + if ($cachefile) { + &open_tempfile(CACHE, ">$cachefile", 1); + my $err; + foreach my $f (@shorts) { + my $ok = (print CACHE $f,"\n"); + $err++ if (!$ok); + } + &close_tempfile(CACHE) if (!$err); + local @st = stat($_[0]); + if ($< == 0) { + # Cache should have some ownership as directory + &set_ownership_permissions($st[4], $st[5], + undef, $cachefile); + } + } + } + $main::list_maildir_cache{$_[0]} = \@files; + $main::list_maildir_cache_time{$_[0]} = $st[7]; + } +return @files; +} + +# search_maildir(file, field, what) +# Search for messages in a maildir directory, and return the results +sub search_maildir +{ +return &advanced_search_maildir($_[0], [ [ $_[1], $_[2] ] ], 1); +} + +# advanced_search_maildir(user|file, &fields, andmode, [&limit]) +# Search for messages in a maildir directory, and return the results +sub advanced_search_maildir +{ +local @rv; +local ($min, $max); +if ($_[3] && $_[3]->{'latest'}) { + $min = -1; + $max = -$_[3]->{'latest'}; + } +foreach $mail (&list_maildir($_[0], $min, $max)) { + push(@rv, $mail) if ($mail && + &mail_matches($_[1], $_[2], $mail)); + } +return @rv; +} + +# delete_maildir(&mail, ...) +# Delete messages from a maildir directory +sub delete_maildir +{ +local $m; + +# Find all maildirs being deleted from +local %dirs; +foreach $m (@_) { + if ($m->{'file'} =~ /^(.*)\/(cur|new)\/([^\/]+)$/) { + $dirs{$1}->{"$2/$3"} = 1; + } + } + +# Delete from caches +foreach my $dir (keys %dirs) { + local $cachefile = &get_maildir_cachefile($dir); + next if (!$cachefile); + local @cst = stat($cachefile); + next if (!@cst); + + # Work out last modified time, and don't update cache if too new + local $newest; + foreach my $d ("$dir/cur", "$dir/new") { + local @dst = stat($d); + $newest = $dst[9] if ($dst[9] > $newest); + } + next if ($newest > $cst[9]); + + local $lref = &read_file_lines($cachefile); + for(my $i=0; $i<@$lref; $i++) { + if ($dirs{$dir}->{$lref->[$i]}) { + # Found an entry to remove + splice(@$lref, $i--, 1); + } + } + &flush_file_lines($cachefile); + } + +# Actually delete the files +foreach $m (@_) { + unlink($m->{'file'}); + } + +} + +# modify_maildir(&oldmail, &newmail, textonly) +# Replaces a message in a maildir directory +sub modify_maildir +{ +unlink($_[0]->{'file'}); +&send_mail($_[1], $_[0]->{'file'}, $_[2], 1); +} + +# write_maildir(&mail, directory, textonly) +# Adds some message in maildir format to a directory +sub write_maildir +{ +# Work out last modified time, and don't update cache if too new +local $cachefile = &get_maildir_cachefile($_[1]); +local $up2date = 0; +if ($cachefile) { + local @cst = stat($cachefile); + if (@cst) { + local $newest; + foreach my $d ("$dir/cur", "$dir/new") { + local @dst = stat($d); + $newest = $dst[9] if ($dst[9] > $newest); + } + $up2date = 1 if ($newest <= $cst[9]); + } + } + +# Select a unique filename and write to it +local $now = time(); +local $hn = &get_system_hostname(); +local $mf; +mkdir($_[1], 0755); +mkdir("$_[1]/cur", 0755); +do { + $mf = "$_[1]/cur/$now.$$.$hn"; + $now++; + } while(-r $mf); +&send_mail($_[0], $mf, $_[2], 1); + +if ($up2date && $cachefile) { + # Bring cache up to date + $now--; + local $lref = &read_file_lines($cachefile); + push(@$lref, "cur/$now.$$.$hn"); + &flush_file_lines($cachefile); + } +} + +# empty_maildir(file) +# Delete all messages in an maildir directory +sub empty_maildir +{ +local $d; +foreach $d ("$_[0]/cur", "$_[0]/new") { + local $f; + opendir(DIR, $d); + while($f = readdir(DIR)) { + unlink("$d/$f") if ($f ne '.' && $f ne '..'); + } + closedir(DIR); + } +local $cachefile = &get_maildir_cachefile($_[0]); +unlink($cachefile) if ($cachefile); +} + +# get_maildir_cachefile(dir) +# Returns the cache file for a maildir directory +sub get_maildir_cachefile +{ +local ($dir) = @_; +local $oldcache = -r "$dir/maildircache" ? "$dir/maildircache" + : "$dir/.usermin-maildircache"; +unlink($oldcache); +local $cd = $user_module_config_directory || $module_config_directory; +local $sd = "$cd/maildircache"; +if (!-d $sd) { + &make_dir($sd, 0755) || return undef; + } +$dir =~ s/\//_/g; +return "$sd/$dir"; +} + +# count_maildir(dir) +# Returns the number of messages in a maildir directory +sub count_maildir +{ +local $d; +local $count = 0; +foreach $d ("$_[0]/cur", "$_[0]/new") { + opendir(DIR, $d); + local @files = grep { $_ !~ /^\./ } readdir(DIR); + $count += scalar(@files); + closedir(DIR); + } +return $count; +} + +# list_mhdir(file, [start], [end]) +# Returns a subset of mail from an MH format directory +sub list_mhdir +{ +local ($start, $end, $f, $i, @rv); +opendir(DIR, $_[0]); +local @files = map { "$_[0]/$_" } + sort { $a <=> $b } + grep { /^\d+$/ } readdir(DIR); +closedir(DIR); +if (!defined($_[1])) { + $start = 0; + $end = @files - 1; + } +elsif ($_[2] < 0) { + $start = @files + $_[2] - 1; + $end = @files + $_[1] - 1; + $start = 0 if ($start < 0); + } +else { + $start = $_[1]; + $end = $_[2]; + $end = @files-1 if ($end >= @files); + } +foreach $f (@files) { + if ($i < $start || $i > $end) { + # Skip files outside requested index range + push(@rv, undef); + $i++; + next; + } + local $mail = &read_mail_file($f); + $mail->{'idx'} = $i++; + push(@rv, $mail); + } +return @rv; +} + +# select_mhdir(file, &indexes, headersonly) +# Returns a list of messages with the given indexes, from an mhdir directory +sub select_mhdir +{ +local @rv; +opendir(DIR, $_[0]); +local @files = map { "$_[0]/$_" } + sort { $a <=> $b } + grep { /^\d+$/ } readdir(DIR); +closedir(DIR); +foreach my $i (@{$_[1]}) { + local $mail = &read_mail_file($files[$i], $_[2]); + $mail->{'idx'} = $i; + push(@rv, $mail); + } +return @rv; +} + +# search_mhdir(file|user, field, what) +# Search for messages in an MH directory, and return the results +sub search_mhdir +{ +return &advanced_search_mhdir($_[0], [ [ $_[1], $_[2] ] ], 1); +} + +# advanced_search_mhdir(file|user, &fields, andmode, &limit) +# Search for messages in an MH directory, and return the results +sub advanced_search_mhdir +{ +local @rv; +local ($min, $max); +if ($_[3] && $_[3]->{'latest'}) { + $min = -1; + $max = -$_[3]->{'latest'}; + } +foreach $mail (&list_mhdir($_[0], $min, $max)) { + push(@rv, $mail) if ($mail && &mail_matches($_[1], $_[2], $mail)); + } +return @rv; +} + +# delete_mhdir(&mail, ...) +# Delete messages from an MH directory +sub delete_mhdir +{ +local $m; +foreach $m (@_) { + unlink($m->{'file'}); + } +} + +# modify_mhdir(&oldmail, &newmail, textonly) +# Replaces a message in a maildir directory +sub modify_mhdir +{ +unlink($_[0]->{'file'}); +&send_mail($_[1], $_[0]->{'file'}, $_[2], 1); +} + +# max_mhdir(dir) +# Returns the maximum message ID in the directory +sub max_mhdir +{ +local $max = 1; +opendir(DIR, $_[0]); +foreach $f (readdir(DIR)) { + $max = $f if ($f =~ /^\d+$/ && $f > $max); + } +closedir(DIR); +return $max; +} + +# empty_mhdir(file) +# Delete all messages in an MH format directory +sub empty_mhdir +{ +local $f; +opendir(DIR, $_[0]); +foreach $f (readdir(DIR)) { + unlink("$_[0]/$f") if ($f =~ /^\d+$/); + } +closedir(DIR); +} + +# count_mhdir(file) +# Returns the number of messages in an MH directory +sub count_mhdir +{ +opendir(DIR, $_[0]); +local @files = grep { /^\d+$/ } readdir(DIR); +closedir(DIR); +return scalar(@files); +} + +# read_mail_file(file, [headersonly]) +# Read a single message from a file +sub read_mail_file +{ +local (@headers, $mail); + +# Open and read the mail file +open(MAIL, $_[0]) || return undef; +$mail = &read_mail_fh(MAIL, 0, $_[1]); +$mail->{'file'} = $_[0]; +close(MAIL); + +local @st = stat($_[0]); +$mail->{'size'} = $st[7]; +return $mail; +} + +# read_mail_fh(handle, [end-mode], [headersonly]) +# Reads an email message from the given file handle, either up to end of +# the file, or a From line. End mode 0 = EOF, 1 = From without -, +# 2 = From possibly with - +sub read_mail_fh +{ +local ($fh, $endmode, $headeronly) = @_; +local (@headers, $mail); + +# Read the headers +local $lnum = 0; +while(1) { + $lnum++; + local $line = <$fh>; + $mail->{'size'} += length($line); + $line =~ s/\r|\n//g; + last if ($line eq ''); + if ($line =~ /^(\S+):\s*(.*)/) { + push(@headers, [ $1, $2 ]); + $mail->{'rawheaders'} .= $line."\n"; + } + elsif ($line =~ /^\s+(.*)/) { + $headers[$#headers]->[1] .= $1 unless($#headers < 0); + $mail->{'rawheaders'} .= $line."\n"; + } + elsif ($line =~ /^From\s+(\S+).*\d+/ && + ($1 ne '-' || $endmode == 2)) { + $mail->{'fromline'} = $line; + } + } +$mail->{'headers'} = \@headers; +foreach $h (@headers) { + $mail->{'header'}->{lc($h->[0])} = $h->[1]; + } + +if (!$headersonly) { + # Read the mail body + if ($endmode == 0) { + # Till EOF + while(read($fh, $buf, 1024) > 0) { + $mail->{'size'} += length($buf); + $mail->{'body'} .= $buf; + } + close(MAIL); + } + else { + # Tell next From line + while(1) { + $line = <$fh>; + last if (!$line || $line =~ /^From\s+(\S+).*\d+\r?\n/ && + ($1 ne '-' || $endmode == 2)); + $lnum++; + $mail->{'size'} += length($line); + $mail->{'body'} .= $line; + } + $mail->{'lines'} = $lnum; + } + } +elsif ($endmode) { + # Not reading the body, but we still need to search till the next + # From: line in order to get the size + while(1) { + $line = <$fh>; + last if (!$line || $line =~ /^From\s+(\S+).*\d+\r?\n/ && + ($1 ne '-' || $endmode == 2)); + $mail->{'size'} += length($line); + } + } +return $mail; +} + +# dash_mode(user|file) +# Returns 1 if the messages in this folder are separated by lines like +# From - instead of the usual From foo@bar.com +sub dash_mode +{ +open(DASH, &user_mail_file($_[0])) || return 0; # assume no +local $line = ; +close(DASH); +return $line =~ /^From\s+(\S+).*\d/ && $1 eq '-'; +} + +# mail_matches(&fields, andmode, &mail) +# Returns 1 if some message matches a search +sub mail_matches +{ +local $count = 0; +local $f; +foreach $f (@{$_[0]}) { + local $field = $f->[0]; + local $what = $f->[1]; + local $neg = ($field =~ s/^\!//); + if ($field eq 'body') { + $count++ + if (!$neg && $_[2]->{'body'} =~ /\Q$what\E/i || + $neg && $_[2]->{'body'} !~ /\Q$what\E/i); + } + elsif ($field eq 'size') { + $count++ + if (!$neg && $_[2]->{'size'} > $what || + $neg && $_[2]->{'size'} < $what); + } + elsif ($field eq 'headers') { + local $headers = $_[2]->{'rawheaders'} || + join("", map { $_->[0].": ".$_->[1]."\n" } + @{$_[2]->{'headers'}}); + $count++ + if (!$neg && $headers =~ /\Q$what\E/i || + $neg && $headers !~ /\Q$what\E/i); + } + elsif ($field eq "status") { + $count++ + if (!$neg && $_[2]->{$field} =~ /\Q$what\E/i|| + $neg && $_[2]->{$field} !~ /\Q$what\E/i); + } + else { + $count++ + if (!$neg && $_[2]->{'header'}->{$field} =~ /\Q$what\E/i|| + $neg && $_[2]->{'header'}->{$field} !~ /\Q$what\E/i); + } + return 1 if ($count && !$_[1]); + } +return $count == @{$_[0]}; +} + +# search_fields(&fields) +# Returns an array of headers/fields from a search +sub search_fields +{ +local @rv; +foreach $f (@{$_[0]}) { + $f->[0] =~ /^\!?(.*)$/; + push(@rv, $1); + } +return &unique(@rv); +} + +# parse_delivery_status(text) +# Returns the fields from a message/delivery-status attachment +sub parse_delivery_status +{ +local @lines = split(/[\r\n]+/, $_[0]); +local (%rv, $l); +foreach $l (@lines) { + if ($l =~ /^(\S+):\s*(.*)/) { + $rv{lc($1)} = $2; + } + } +return \%rv; +} + +# parse_mail_date(string) +# Converts a mail Date: header into a unix time +sub parse_mail_date +{ +open(OLDSTDERR, ">&STDERR"); # suppress STDERR from Time::Local +close(STDERR); +my $rv = eval { + if ($_[0] =~ /^\s*(\S+),\s+(\d+)\s+(\S+)\s+(\d+)\s+(\d+):\s?(\d+):\s?(\d+)\s+(\S+)/) { + # Format like Mon, 13 Dec 2004 14:40:41 +0100 + # or Mon, 13 Dec 2004 14:18:16 GMT + # or Tue, 14 Sep 04 02:45:09 GMT + local $tm = timegm($7, $6, $5, $2, &month_to_number($3), + $4 < 50 ? $4+100 : $4 < 1000 ? $4 : $4-1900); + local $tz = $8; + if ($tz =~ /^(\-|\+)?\d+$/) { + local $tz = int($tz); + $tz = $tz/100 if ($tz >= 50 || $tz <= -50); + $tm -= $tz*60*60; + } + return $tm; + } + elsif ($_[0] =~ /^\s*(\S+),\s+(\d+)\s+(\S+)\s+(\d+)\s+(\d+):\s?(\d+):\s?(\d+)/) { + # Format like Mon, 13 Dec 2004 14:40:41 + # No timezone, so assume local + local $tm = timegm($7, $6, $5, $2, &month_to_number($3), + $4 < 50 ? $4+100 : $4 < 1000 ? $4 : $4-1900); + return $tm; + } + elsif ($_[0] =~ /^\s*(\S+)\s+(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\d+)/) { + # Format like Tue Dec 7 12:58:52 2004 + local $tm = timelocal($6, $5, $4, $3, &month_to_number($2), + $7 < 50 ? $7+100 : $7 < 1000 ? $7 : $7-1900); + return $tm; + } + elsif ($_[0] =~ /^(\d{4})\-(\d+)\-(\d+)\s+(\d+):(\d+)/) { + # Format like 2004-12-07 12:53 + local $tm = timelocal(0, $4, $4, $3, $2-1, + $1 < 50 ? $1+100 : $1 < 1000 ? $1 : $1-1900); + } + elsif ($_[0] =~ /^(\d+)\s+(\S+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\S+)/) { + # Format like 30 Jun 2005 21:01:01 -0000 + local $tm = timegm($6, $5, $4, $1, &month_to_number($2), + $3 < 50 ? $3+100 : $3 < 1000 ? $3 : $3-1900); + local $tz = $7; + if ($tz =~ /^(\-|\+)?\d+$/) { + $tz = int($tz); + $tz = $tz/100 if ($tz >= 50 || $tz <= -50); + $tm -= $tz*60*60; + } + return $tm; + } + else { + return undef; + } + }; +open(STDERR, ">&OLDSTDERR"); +close(OLDSTDERR); +if ($@) { + return undef; + } +return $rv; +} + +# send_text_mail(from, to, cc, subject, body, [smtp-server]) +# A convenience function for sending a email with just a text body +sub send_text_mail +{ +local ($from, $to, $cc, $subject, $body, $smtp) = @_; +local $cs = &get_charset(); +local $attach = $body =~ /[\177-\377]/ ? + { 'headers' => [ [ 'Content-Type', 'text/plain; charset='.$cs ], + [ 'Content-Transfer-Encoding', 'quoted-printable' ] ], + 'data' => "ed_encode($body) } : + { 'headers' => [ [ 'Content-type', 'text/plain' ] ], + 'data' => &entities_to_ascii($body) }; +local $mail = { 'headers' => + [ [ 'From', $from ], + [ 'To', $to ], + [ 'Cc', $cc ], + [ 'Subject', $subject ] ], + 'attach' => [ $attach ] }; +return &send_mail($mail, undef, 1, 0, $smtp); +} + + +1; diff --git a/mailboxes/config b/mailboxes/config new file mode 100644 index 000000000..c9ba8aad3 --- /dev/null +++ b/mailboxes/config @@ -0,0 +1,50 @@ +max_records=200 +show_size=1 +show_size_below=0 +mail_system=3 +auto=1 +mail_dir=/var/mail +mail_style=0 +mail_file=Mailbox +mail_dir=Maildir +wrap_width=80 +perpage=20 +track_read=0 +show_to=0 +sort_mode=1 +index_min=1000000 +fwd_mode=0 +delete_warn=y +index_dbm=2 +top_buttons=2 +view_html=0 +mail_usermin=mail +sync_create=0 +sync_modify=1 +sync_delete=1 +size_mode=1 +no_crlf=0 +sync_perms=0600 +show_mail=0 +html_edit=0 +check_mod=1 +spam_buttons=mail +show_delall=0 +spam_del=0 +spam_report= +mailbox_user=.usermin/mailbox +vpopmail_dir=/home/vpopmail +html_quote=0 +log_read=0 +from_virtualmin=1 +show_count=0 +show_sent=0 +sig_file=* +show_body=0 +column_count=4 +ignore_users= +ignore_users_enabled=0 +link_mode=0 +date_fmt=dmy +arrows=1 +open_mode=0 diff --git a/mailboxes/config.info b/mailboxes/config.info new file mode 100644 index 000000000..a31bec0fa --- /dev/null +++ b/mailboxes/config.info @@ -0,0 +1,76 @@ +line0=Configurable options,11 +wrap_width=Width to wrap mail messages at,0,6 +perpage=Mail messages to display per page,0,6 +track_read=Keep track of read/unread emails,1,1-Yes,0-No +show_to=Show To: address in mailboxes?,1,1-Yes,0-No +max_records=Maximum number of users to display,0,6 +top_buttons=Show buttons at top for,1,2-Mailboxes and mails,1-Mailboxes only,0-Never +arrows=Show pager arrows at bottom for,1,2-Mailboxes and mails,1-Mailboxes only,0-Never +show_delall=Show button to delete entire mailbox?,1,1-Yes,0-No +show_size=User display mode,1,0-Username only,1-Username and size,2-Full details +show_size_below=       Username and size - Where to display size,1,0-To the right of username,1-Below the username +column_count=Number of columns in which to display usernames,1,3-3,4-4,5-5,6-6,7-7,8-8,9-9 +ignore_users=Ignore these usernames (do not show),15,userIgnoreList +ignore_users_enabled=        Ignore list status,1,1-Enabled,0-Disabled +show_count=Show number of messages in inbox?,1,1-Yes,0-No +show_sent=Show number of messages in sent mail folder?,1,1-Yes,0-No +sort_mode=Sort mailboxes by,1,2-Size,1-Username,0-Order in password file +show_mail=Only show users who have mail?,1,1-Yes,0-No +size_mode=Include all folders in size?,1,1-Yes,0-No (first folder only) +fwd_mode=Forward messages with quoting?,1,0-Yes,1-No +delete_warn=Ask for confirmation before deleting?,10,y-Yes,n-No,For mbox files larger than +view_html=Show message body as,4,0-Always plain text,1-Text if possible, HTML otherwise,2-HTML if possible, text otherwise,3-Convert HTML to plain text +html_edit=Use HTML editor for composing?,1,2-Always,1-When replying to HTML email,0-Never +html_quote=HTML quoting mode,1,1-Message below <hr>,0-Message inside <blockquote> +check_mod=Check for mailbox modification when deleting mail?,1,1-Yes,0-No +log_read=Record the reading of mail in the Webmin Actions Log?,1,1-Yes,0-No +bcc_to=Bcc: sent messages to,0 +sig_file=Signature file,10,*-None,.signature-~/.signature,Other file +show_body=Show message body previews in list?,1,1-Yes,0-No +open_mode=Open messages in,1,1-New window,0-List window +link_mode=Open links in,1,1-New window,0-Same window +download=Attachment MIME types to always download,9,20,4,\t +date_fmt=Date format in mail list,1,dmy-DD/MM/YYYY,mdy-MM/DD/YYYY,ymd-YYYY/MM/DD +date_tz=Timezone for date displays,3,System default + +line3=Spam options,11 +spam_buttons=Show spam reporting buttons for,2,list-Mailboxes,mail-Messages +spam_del=Delete spam when reporting?,1,1-Yes,0-No +spam_report=Report spam using,1,sa_learn-sa-learn --spam,spamassassin-spamassasin -r,-Decide automatically + +line3.5=From address options,11 +from_addr=From: address to use when sending email manually,3,From mailbox username +webmin_from=From: address to use when Webmin sends email,3,Default (webmin@yourhost) +from_virtualmin=Get From: address from Virtualmin?,1,1-Yes,0-No +from_dom=Domain to use in From: address,3,System hostname + +line1=System configuration,11 +mail_system=Mail server installed,4,1-Sendmail,0-Postfix,2-Qmail,4-Qmail+LDAP,5-Qmail+VPopMail,3-Detect automatically +send_mode=Send mail using,10,-Mail server program,SMTP server +no_crlf=Add carriage return ( \r ) to each line?,1,0-Yes,1-No +smtp_user=SMTP login name for mail server,3,None +smtp_pass=SMTP password for mail server,3,None +smtp_auth=SMTP authentication method,4,-Default,Cram-MD5-Cram-MD5,Digest-MD5-Digest-MD5,Plain-Plain,Login-Login +auto=Detect location of mail files automatically?,1,1-Yes, based on mail server,0-No, use settings below .. +mail_dir=User mail file directory,3,None +mail_style=Mail file directory style,4,0-mail/username,1-mail/u/username,2-mail/u/us/username,3-mail/u/s/username +mail_file=Mail file in user home directories,3,None +mail_sub=Mail directory in user home directories,3,None +mail_usermin=Usermin-style folders subdirectory in home directory,3,None +mailbox_user=Usermin Read Mail configuration directory in home directory,3,None + +line2=User synchronization,11 +sync_create=Create mailbox when user is created?,1,1-Yes,0-No +sync_modify=Rename mailbox when user is renamed?,1,1-Yes,0-No +sync_delete=Delete mailbox when user is deleted?,1,1-Yes,0-No +sync_perms=Permissions for new mailboxes,0,4 + +line4=VPOPMail options,11 +vpopmail_dir=Base directory for VPOPMail,0 + +line5=Qmail+LDAP options,11 +ldap_host=LDAP server,0 +ldap_port=LDAP port,3,Default +ldap_login=Login for LDAP server,0 +ldap_pass=Password for LDAP server,0 +ldap_base=Base for mail users,0 diff --git a/mailboxes/config.info.ca b/mailboxes/config.info.ca new file mode 100644 index 000000000..f6d2e4524 --- /dev/null +++ b/mailboxes/config.info.ca @@ -0,0 +1,76 @@ +line0=Opcions configurables,11 +wrap_width=Amplada dels missatges de correu,0,6 +perpage=Nombre de missatges a mostrar per pàgina,0,6 +track_read=Porta el compte dels correus llegits/no llegits,1,1-Sí,0-No +show_to=Mostra les adreces To: a les bústies,1,1-Sí,0-No +max_records=Nombre màxim d'usuaris a mostrar,0,6 +top_buttons=Mostra els botons a dalt per a,1,2-Bústies i correus,1-Només les bústies,0-Mai +arrows=Mostra les fletxes de paginació al peu,1,2-Per a les bústies i els correus,1-Només per a les bústies,0-Mai +show_delall=Mostra el botó per suprimir tota la bústia,1,1-Sí,0-No +show_size=Mode de mostrar els usuaris,1,0-Només el nom d'usuari,1-Nom d'usuari i mida,2-Tots els detalls +show_size_below=       Usuari i mida - On es mostra la mida,1,0-A la dreta de l'usuari,1-A sota de l'usuari +column_count=Nombre de columnes per mostrar-hi els noms d'usuari,1,3-3,4-4,5-5,6-6,7-7,8-8,9-9 +ignore_users=Ignora aquests noms d'usuari (no els mostris),15,userIgnoreList +ignore_users_enabled=        Ignora l'estat de la llista,1,1-Activat,0-Desactivat +show_count=Mostra el nombre de missatges d'entrada,1,1-Sí,0-No +show_sent=Mostra el nombre de missatges de la carpeta de coreru enviat,1,1-Sí,0-No +sort_mode=Ordena les bústies per,1,2-Mida,1-Nom d'usuari,0-Ordre del fitxer de contrasenyes +show_mail=Mostra només els usuaris que tenen correu,1,1-Sí,0-No +size_mode=Inclou totes les carpetes a la mida,1,1-Sí,0-No (Només la primera carpeta) +fwd_mode=Reenvia els missatges citats,1,0-Sí,1-No +delete_warn=Demana confirmació abans d'esborrar,10,y-Sí,n-No,Per a bústies més grans de +view_html=Mostra el cos del missatge,4,0-Sempre en text planer,1-En text si és possible, altrament en HTML,2-HTML si és possible, altrament en text,3-Converteix HTML a text planer +html_edit=Utilitza l'editor HTML per a redactar,1,2-Sempre,1-En respondre correus HTML,0-Mai +html_quote=Mode de citat HTML,1,1-Missatge sota <hr>,0-Missatge dins de <blockquote> +check_mod=Comprova la modificació de la bústia en esborrar correu,1,1-Sí,0-No +log_read=Registra la lectura del correu al Fitxer d'Accions de Webmin,1,1-Sí,0-No +bcc_to=Fés còpia cega dels missatges enviats a,0 +sig_file=Fitxer de signatura,10,*-Cap,.signature-~/.signature,Un altre fitxer +show_body=Mostra previsualitzacions del cos del missatge a la llista,1,1-Sí,0-No +open_mode=Obre els missatges,1,1-En una finestra nova,0-En una finestra de la llista +link_mode=Obre els enllaços a,1,1-Finestra nova,0-La mateixa finestra +download=Tipus MIME d'adjuncions que sempres s'han de descarrregar,9,20,4,\t +date_fmt=iFormat de la data a la llista de correu,1,dmy-DD/MM/AAAA,mdy-MM/DD/AAAA,ymd-AAAA/MM/DD +date_tz=Zona horària de la data,3,Valor per defecte del sistema + +line3=Opcions de spam,11 +spam_buttons=Mostra els botons d'informe de spam de,2,list-Les bústies,mail-Els missatges +spam_del=Suprimeix el spam en fer l'informe,1,1-Sí,0-No +spam_report=Informa del spam utilitzant,1,sa_learn-sa-learn --spam,spamassassin-spamassasin -r,-Decideix-ho automàticament + +line3.5=De les opcions de l'adreça,11 +from_addr=Adreça From: a utilitzar quan s'envia correu manualmen,3,Del nom d'usuari de la bústia +webmin_from=Adreça From: a utilitzar quan el Webmin envia correu,3,per defecte (webmin@elteuhost) +from_virtualmin=Obtingues l'adreça From: de Virtualmin,1,1-Sí,0-No +from_dom=Domini a utilitzar a les adreces From:,3,Nom de host del sistema + +line1=Configuració del sistema,11 +mail_system=Servidor de correu instal·lat,1,1-Sendmail,0-Postfix,2-Qmail,3-Detecta'l automàticament,4-Qmail+LDAP,5-Qmail+VPopMail +send_mode=Envia el correu emprant,10,-El programa servidor de correu,El servidor SMTP +no_crlf=Afegeix un retorn de carro ( \r ) a cada línia,1,0-Sí,1-No +smtp_user=Nom d'usuari SMTP al servidor de correu,3,Cap +smtp_pass=Contrasenya SMTP al servidor de correu,3,Cap +smtp_auth=Mètode d'autenticacio SMTP,4,-Defecte,Cram-MD5-Cram-MD5,Digest-MD5-Digest-MD5,Planer-Planer,Login-Login +auto=Detecta la ubicació dels fitxers de correu automàticament,1,1-Sí, basant-se en el servidor de correu,0-No, utilitza la configuració de sota... +mail_dir=Directori del fitxer de correu de l'usuari,3,Cap +mail_style=Estil del directori del fitxer de correu,4,0-mail/usuari,1-mail/u/usuari,2-mail/u/us/usuari,3-mail/u/s/usuari +mail_file=Fitxer de correu en els directoris arrel dels usuaris,3,Cap +mail_sub=Directori de correu en els directoris arrel dels usuaris,3,Cap +mail_usermin=SUbdirectori de carpetes estil Usermin al directori arrel,3,Cap +mailbox_user=Directori de configuració de Correu Llegit Usermin al directori arrel,3,Cap + +line2=Sincronització d'usuaris,11 +sync_create=Crea la bústia quan es creï l'usuari,1,1-Sí,0-No +sync_modify=Renomena la bústia quan es renomeni l'usuari,1,1-Sí,0-No +sync_delete=Suprimeix la bústia quan se suprimeixi l'usuari,1,1-Sí,0-No +sync_perms=Permisos de les bústies noves,0,4 + +line4=Opcions VPOPMail,11 +vpopmail_dir=Directori base de VPOPMail,0 + +line5=Opcions Qmail+LDAP,11 +ldap_host=Servidor LDAP,0 +ldap_port=Port LDAP,3,Defecte +ldap_login=Usuari del servidor LDAP,0 +ldap_pass=Contrasenya del servidor LDAP,0 +ldap_base=Base d'usuaris de correu,0 diff --git a/mailboxes/config.info.de b/mailboxes/config.info.de new file mode 100644 index 000000000..f6ca90267 --- /dev/null +++ b/mailboxes/config.info.de @@ -0,0 +1,54 @@ +line0=Konfigurierbare Optionen,11 +wrap_width=Zeilenumbruch bei Zeichen (70 empfohlen),0,6 +perpage=Anzahl von anzuzeigenden E-Mails pro Seite,0,6 +track_read=E-Mails als gelesen/ungelesen markieren?,1,1-Ja,0-Nein +show_to=Zeige To:-E-Mail-Adressen in E-Mailboxen?,1,1-Ja,0-Nein +max_records=Maximale Anzahl anzuzeigender Benutzer,0,6 +top_buttons=Zeige Buttons oben an für,1,2-E-Mailboxen und E-Mails,1-Nur für E-Mailboxen,0-Niemals +show_delall=Zeige Button an, um die gesammte E-Mailbox löschen zu können?,1,1-Ja (empfohlen),0-Nein +show_size=Benutzeranzeige-Modus,1,0-Nur Benutzername,1-Benutzername und Größe,2-Alle Einzelheiten +sort_mode=Sortiere E-Mailboxen nach,1,2-Größe,1-Benutzername,0-Reihenfolge in Passwortdatei +show_mail=Zeige nur die Benutzer an, die E-Mails haben?,1,1-Ja (empfohlen),0-Nein +size_mode=Alle Ordner in Größenanzeigen einrechnen?,1,1-Ja,0-Nein (nur der oberste Ordner) +fwd_mode=Zitierte Weiterleitung von E-Mails?,1,0-Ja (empfohlen),1-Nein +delete_warn=Bestätigungsabfrage vor dem Löschen von E-Mails?,10,y-Ja (empfohlen),n-Nein,Für mbox-Dateien größer als +index_dbm=Indexierungsart,1,2-DBM,0-Textdatei +index_min=Minimale E-Maildateigröße zum Indexieren,3,Immer indexieren +view_html=Zeige E-Mails an als,4,0-Immer text/plain (empfohlen),1-Text wenn möglich (ansonsten HTML),2-HTML wenn möglich (ansonsten text/plain),3-Konvertiere HTML nach text/plain (geht nicht immer) +html_edit=Benutze den HTML-Editor für das Schreiben von E-Mails?,1,2-Immer (nicht empfohlen),1-Wenn auf HTML-E-Mails geantwortet wird (nicht empfohlen),0-Niemals (sehr empfohlen) +html_quote=HTML-Zitierverhalten,1,1-Nachricht unterhalb <hr>,0-Nachricht innerhalb <blockquote> +check_mod=Auf E-Mailboxänderungen prüfen, wenn E-Mails gelöscht werden?,1,1-Ja,0-Nein +line3=Spam-Optionen,11 +spam_buttons=Zeige Spam-Report-Buttons an für,2,list-E-Mailboxen,mail-E-Mails +spam_del=Lösche Spam nach dem Report?,1,1-Ja,0-Nein +spam_report=Spam-Report-Methode,1,sa_learn-sa-learn --spam,spamassassin-spamassassin -r,-Entscheide Automatisch +line1=Systemkonfiguration,11 +mail_system=Installierter E-Mail-Server,1,1-Sendmail,0-Postfix,2-Qmail +send_mode=Versende E-Mails unter Benutzung von,10,-Mailserver-Binary,SMTP-Server +no_crlf=Einen Wagenrücklauf ( \r ) jeder Zeile hinzufügen,1,0-Ja,1-Nein +smtp_user=SMTP-Login für E-Mailserver,3,kein +smtp_pass=SMTP-Passwort für E-Mailserver,3,Kein +smtp_auth=SMTP-Authentisierungsmethode,4,-Standard,Cram-MD5-Cram-MD5,Digest-MD5-Digest-MD5,Plain-Plain,Login-Login +auto=Erkenne den Speicherort der E-Maildateien automatisch?,1,1-Ja, basierend auf dem Mailserver,0-Nein,benutze folgende Einstellungen .. +mail_dir=Benutzer-E-Mail-Dateiverzeichnis,3,Kein +mail_style=E-Mail-Dateiverzeichnisart,4,0-mail/benutzername,1-mail/u/benutzername,2-mail/u/us/benutzername,3-mail/u/s/benutzername +mail_file=E-Mail-Datei in Benutzer-Heimatverzeichnis,3,Kein +mail_sub=E-Mail-Verzeichnis in Benutzer-Heimatverzeichnis,3,Kein +mail_usermin=Unterverzeichnis in Heimat-Verzeichnis für Usermin-ähnliche Ordner,3,Kein +mailbox_user=Usermin "Lese Benutzer-E-Mail-Konfiguration" im Heimatverzeichnis,3,Keines +from_addr=From:-E-Mail-Adresse, die für das Versenden manuell verschickter E--Mails benutzt werden soll,3,Aus dem E-Mailbox-Benutzernamen generieren +webmin_from=Wenn Webmin E-Mails versendet benutze diese "From"-E-Mail-Adresse,3,Standard (webmin@yourhost) +from_dom=Domaine, die für die From:-E-Mail-Adresse genutzt werden soll,3,System-Hostname +line2=Benutzersynchronisation,11 +sync_create=E-Mailbox beim Anlegen eines Benutzers ebenfalls einrichten?,1,1-Ja,0-Nein +sync_modify=E-Mailbox beim Umbenennen eines Benutzers ebenfalls umbenennen?,1,1-Ja,0-Nein +sync_delete=E-Mailbox beim Löschen eines Benutzers ebenfalls löschen?,1,1-Ja,0-Nein +sync_perms=Dateirechte für neue E-Mailboxen,0,4 +line4=VPOPMail-Optionen,11 +vpopmail_dir=Base-Verzeichnis für VPOPMail,0 +line5=Qmail+LDAP-Optionen,11 +ldap_host=LDAP-Server,0 +ldap_port=LDAP-Port,3,Standard +ldap_login=Login für LDAP-Server,0 +ldap_pass=Passwort für LDAP-Server,0 +ldap_base=LDAP-Base für E-Mail-Benutzer,0 diff --git a/mailboxes/config_info.pl b/mailboxes/config_info.pl new file mode 100644 index 000000000..a9d0312cf --- /dev/null +++ b/mailboxes/config_info.pl @@ -0,0 +1,20 @@ +do '../web-lib-funcs.pl'; + +sub show_userIgnoreList +{ + my($ig_usr) = shift(@_) || ''; + my($preta) = ''; + + return + $preta . + $ig_usr . + $postta . + ' ' . + &user_chooser_button("ignore_users", 1); +} + +sub parse_userIgnoreList +{ + return $in{'ignore_users'}; +} diff --git a/mailboxes/defaultacl b/mailboxes/defaultacl new file mode 100644 index 000000000..3bab5aade --- /dev/null +++ b/mailboxes/defaultacl @@ -0,0 +1,5 @@ +mmode=1 +fmode=0 +attach=-1 +canattach=1 +candetach=1 diff --git a/mailboxes/delete_all.cgi b/mailboxes/delete_all.cgi new file mode 100755 index 000000000..da7e724a4 --- /dev/null +++ b/mailboxes/delete_all.cgi @@ -0,0 +1,38 @@ +#!/usr/local/bin/perl +# Delete all mail in some mailbox, after asking for confirmation + +require './mailboxes-lib.pl'; +&ReadParse(); +&can_user($in{'user'}) || &error($text{'mail_ecannot'}); +&is_user($in{'user'}) || -e $in{'user'} || &error($text{'mail_efile'}); +@folders = &list_user_folders_sorted($in{'user'}); +($folder) = grep { $_->{'index'} == $in{'folder'} } @folders; + +if ($in{'confirm'}) { + # Do it! + $sz = &mailbox_folder_size($folder); + &mailbox_empty_folder($folder); + &webmin_log("delmail", undef, undef, { 'from' => $folder->{'file'}, + 'count' => $sz }); + &redirect("list_mail.cgi?user=$in{'user'}&folder=$in{'folder'}"); + } +else { + # Ask first + &ui_print_header(undef, $text{'delall_title'}, ""); + print &ui_form_start("delete_all.cgi"); + print &ui_hidden("user", $in{'user'}),"\n"; + print &ui_hidden("folder", $in{'folder'}),"\n"; + print "

\n"; + print &text('delall_rusure', + "$folder->{'file'}", + &mailbox_folder_size($folder), + &nice_size(&folder_size($folder))),"

\n"; + print &ui_submit($text{'delall_ok'}, "confirm"),"\n"; + print &ui_form_end(); + print "

\n"; + &ui_print_footer("list_mail.cgi?user=$in{'user'}&folder=$in{'folder'}", + $text{'mail_return'}, + "", $text{'index_return'}); + } + + diff --git a/mailboxes/delete_mail.cgi b/mailboxes/delete_mail.cgi new file mode 100755 index 000000000..221bc3a25 --- /dev/null +++ b/mailboxes/delete_mail.cgi @@ -0,0 +1,213 @@ +#!/usr/local/bin/perl +# delete_mail.cgi +# Delete, mark, move or copy multiple messages + +require './mailboxes-lib.pl'; +&ReadParse(); +&can_user($in{'user'}) || &error($text{'mail_ecannot'}); +@delete = sort { $a <=> $b } split(/\0/, $in{'d'}); +@folders = &list_user_folders($in{'user'}); +$folder = $folders[$in{'folder'}]; + +if ($in{'mark1'} || $in{'mark2'}) { + # Marking emails with some status + @delete || &error($text{'delete_emnone'}); + @mail = &mailbox_list_mails($delete[0], $delete[@delete-1], $folder); + dbmopen(%read, "$module_config_directory/$in{'user'}.read", 0600); + local $m = $in{'mark1'} ? $in{'mode1'} : $in{'mode2'}; + foreach $d (@delete) { + local $hid = $mail[$d]->{'header'}->{'message-id'}; + if ($m) { + $read{$hid} = $m; + } + else { + delete($read{$hid}); + } + } + dbmclose(%read); + $perpage = $folder->{'perpage'} || $config{'perpage'}; + &redirect("list_mail.cgi?start=$in{'start'}&folder=$in{'folder'}&user=$in{'user'}"); + } +elsif ($in{'move1'} || $in{'move2'}) { + # Moving mails to some other user's inbox + &check_modification($folder); + @delete || &error($text{'delete_emovenone'}); + $muser = $in{'move1'} ? $in{'mfolder1'} : $in{'mfolder2'}; + &can_user($muser) || &error($text{'delete_emovecannot'}); + @mfolders = &list_user_folders($muser); + @mfolders || &error($text{'delete_emoveuser'}); + + @mail = &mailbox_list_mails($delete[0], $delete[@delete-1], $folder); + foreach $d (@delete) { + $mail[$d] || &error($text{'mail_eexists'}); + push(@movemail, $mail[$d]); + } + &lock_folder($folder); + &lock_folder($mfolder); + &mailbox_move_mail($folder, $mfolders[0], @movemail); + &unlock_folder($mfolder); + &unlock_folder($folder); + &webmin_log("movemail", undef, undef, { 'from' => $folder->{'file'}, + 'to' => $mfolders[0]->{'file'}, + 'count' => scalar(@delete) } ); + &redirect("list_mail.cgi?start=$in{'start'}&folder=$in{'folder'}&user=$in{'user'}"); + } +elsif ($in{'copy1'} || $in{'copy2'}) { + # Copying mails to some other folder + @delete || &error($text{'delete_ecopynone'}); + $cuser = $in{'copy1'} ? $in{'mfolder1'} : $in{'mfolder2'}; + &can_user($cuser) || &error($text{'delete_ecopycannot'}); + @cfolders = &list_user_folders($cuser); + @cfolders || &error($text{'delete_ecopyuser'}); + + @mail = &mailbox_list_mails($delete[0], $delete[@delete-1], $folder); + foreach $d (@delete) { + $mail[$d] || &error($text{'mail_eexists'}); + push(@copymail, $mail[$d]); + } + &lock_folder($cfolder); + &mailbox_copy_mail($folder, $cfolders[0], @copymail); + &unlock_folder($cfolder); + &webmin_log("copymail", undef, undef, { 'from' => $folder->{'file'}, + 'to' => $cfolders[0]->{'file'}, + 'count' => scalar(@delete) } ); + &redirect("list_mail.cgi?start=$in{'start'}&folder=$in{'folder'}&user=$in{'user'}"); + } +elsif ($in{'forward'}) { + # Forwarding selected mails .. redirect + @delete || &error($text{'delete_efnone'}); + &redirect("reply_mail.cgi?folder=$in{'folder'}&user=$in{'user'}&". + join("&", map { "mailforward=$_" } @delete)); + } +elsif ($in{'new'}) { + # Need to redirect to compose form + &redirect("reply_mail.cgi?new=1&folder=$in{'folder'}&user=$in{'user'}"); + } +elsif ($in{'black'}) { + # Deny all senders + @delete || &error($text{'delete_ebnone'}); + @mail = &mailbox_list_mails($delete[0], $delete[@delete-1], $folder); + foreach $d (@delete) { + push(@addrs, map { $_->[0] } &split_addresses($mail[$d]->{'header'}->{'from'})); + } + &foreign_require("spam", "spam-lib.pl"); + local $conf = &spam::get_config(); + local @from = map { @{$_->{'words'}} } + &spam::find("blacklist_from", $conf); + local %already = map { $_, 1 } @from; + @newaddrs = grep { !$already{$_} } &unique(@addrs); + push(@from, @newaddrs); + &spam::save_directives($conf, 'blacklist_from', + \@from, 1); + &flush_file_lines(); + &redirect("list_mail.cgi?start=$in{'start'}&folder=$in{'folder'}&user=$in{'user'}"); + } +elsif ($in{'razor'}) { + # Report all messages, and show output to the user + @delete || &error($text{'delete_ebnone'}); + + &ui_print_header(undef, $text{'razor_title'}, ""); + print "$text{'razor_report2'}\n"; + print "
";
+
+	# Write all messages to a temp file
+	@mail = &mailbox_list_mails($delete[0], $delete[@delete-1], $folder);
+	$temp = &transname();
+	$cmd = &spam_report_cmd($in{'user'});
+	foreach $d (@delete) {
+		$mail[$d] || &error($text{'mail_eexists'});
+		&send_mail($mail[$d], $temp);
+		push(@delmail, $mail[$d]);
+		}
+
+	# Call reporting command on them
+	&open_execute_command(OUT, "$cmd <$temp 2>&1", 1);
+	local $error;
+	while() {
+		print &html_escape($_);
+		$error++ if (/failed/i);
+		}
+	close(OUT);
+	unlink($temp);
+	print "
\n"; + if ($? || $error) { + print "$text{'razor_err'}

\n"; + } + else { + if ($config{'spam_del'}) { + # Delete spam too + &lock_folder($folder); + &mailbox_delete_mail($folder, @delmail); + &unlock_folder($folder); + print "$text{'razor_deleted'}

\n"; + } + else { + print "$text{'razor_done'}

\n"; + } + } + &ui_print_footer("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}, "", $text{'index_return'}); + } +elsif ($in{'delete'} || $in{'deleteall'}) { + # Just deleting emails + &check_modification($folder); + @delete || $in{'deleteall'} || &error($text{'delete_enone'}); + if (!$in{'confirm'} && &need_delete_warn($folder)) { + # Need to ask for confirmation before deleting + &ui_print_header(undef, $text{'confirm_title'}, ""); + print &check_clicks_function(); + + print "

\n"; + foreach $i (keys %in) { + foreach $v (split(/\0/, $in{$i})) { + print "\n"; + } + } + print "
\n"; + if ($in{'deleteall'}) { + print &text('confirm_warnall'),"
\n"; + } + else { + print &text('confirm_warn', scalar(@delete)),"
\n"; + } + if ($config{'delete_warn'} ne 'y') { + print "$text{'confirm_warn2'}

\n" + } + else { + print "$text{'confirm_warn4'}

\n" + } + print "

\n"; + + &ui_print_footer("list_mail.cgi?start=$in{'start'}&folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}); + } + else { + # Go ahead and delete + &lock_folder($folder); + if ($in{'deleteall'}) { + # Clear the whole folder + $delcount = &mailbox_folder_size($folder); + &mailbox_empty_folder($folder); + } + else { + # Just delete selected messages + @mail = &mailbox_list_mails($delete[0], + $delete[@delete-1], + $folder); + foreach $d (@delete) { + $mail[$d] || &error($text{'mail_eexists'}); + push(@delmail, $mail[$d]); + } + &mailbox_delete_mail($folder, @delmail); + $delcount = scalar(@delmail); + } + &unlock_folder($folder); + &webmin_log("delmail", undef, undef, + { 'from' => $folder->{'file'}, + 'all' => $in{'deleteall'}, + 'count' => $delcount } ); + &redirect("list_mail.cgi?start=$in{'start'}&folder=$in{'folder'}&user=$in{'user'}"); + } + } +&pop3_logout_all(); diff --git a/mailboxes/detach.cgi b/mailboxes/detach.cgi new file mode 100755 index 000000000..41b444b1a --- /dev/null +++ b/mailboxes/detach.cgi @@ -0,0 +1,123 @@ +#!/usr/local/bin/perl +# detach.cgi +# View one attachment from a message + +use Socket; +require './mailboxes-lib.pl'; +&ReadParse(); +&can_user($in{'user'}) || &error($text{'mail_ecannot'}); + +@folders = &list_user_folders($in{'user'}); +$folder = $folders[$in{'folder'}]; +@mail = &mailbox_list_mails($in{'idx'}, $in{'idx'}, $folder); +$mail = $mail[$in{'idx'}]; +&parse_mail($mail); +@sub = split(/\0/, $in{'sub'}); +foreach $s (@sub) { + # We are looking at a mail within a mail .. + local $amail = &extract_mail($mail->{'attach'}->[$s]->{'data'}); + &parse_mail($amail); + $mail = $amail; + } +$attach = $mail->{'attach'}->[$in{'attach'}]; + +if ($in{'scale'}) { + # Scale the gif or jpeg image to 48 pixels high + local $temp = &transname(); + open(TEMP, ">$temp"); + print TEMP $attach->{'data'}; + close(TEMP); + $SIG{'CHLD'} = sub { wait; }; + if ($attach->{'type'} eq 'image/gif') { + ($pnmin, $pnmout) = &pipeopen("giftopnm $temp"); + } + elsif ($attach->{'type'} eq 'image/jpeg') { + ($pnmin, $pnmout) = &pipeopen("djpeg -fast $temp"); + } + else { + &dump_erroricon(); + } + close($pnmin); + $type = <$pnmout>; + $size = <$pnmout>; + unlink($temp); + $type =~ /^P[0-9]/ || &dump_erroricon(); + $size =~ /(\d+)\s+(\d+)/ || &dump_erroricon(); + ($w, $h) = ($1, $2); + if ($w > 48) { + $scale = 48.0 / $w; + } + else { + $scale = 48.0 / $h; + } + ($jpegin, $jpegout) = &pipeopen("pnmscale $scale 2>/dev/null | cjpeg"); + print $jpegin $type; + print $jpegin $size; + while(read($pnmout, $buf, 1024)) { + print $jpegin $buf; + } + close($jpegin); + close($pnmout); + print "Content-type: image/jpeg\n\n"; + while(read($jpegout, $buf, 1024)) { + print $buf; + } + close($jpegout); + } +else { + # Just output the attachment + print "X-no-links: 1\n"; + @download = split(/\t+/, $config{'download'}); + if (&indexof($attach->{'type'}, @download) >= 0) { + # Force download in IE + print "Content-Disposition: Attachment\n"; + } + if ($attach->{'type'} eq 'message/delivery-status') { + print "Content-type: text/plain\n\n"; + } + else { + print "Content-type: $attach->{'type'}\n\n"; + } + if ($attach->{'type'} =~ /^text\/html/i) { + print &safe_urls(&filter_javascript($attach->{'data'})); + } + else { + print $attach->{'data'}; + } + } +&pop3_logout_all(); + +sub dump_erroricon +{ +print "Content-type: image/gif\n\n"; +open(ICON, "images/error.gif"); +while() { print; } +close(ICON); +exit; +} + +# pipeopen(command) +sub pipeopen +{ +$pipe++; +local $inr = "INr$pipe"; +local $inw = "INw$pipe"; +local $outr = "OUTr$pipe"; +local $outw = "OUTw$pipe"; +pipe($inr, $inw); +pipe($outr, $outw); +if (!fork()) { + untie(*STDIN); + untie(*STDOUT); + open(STDIN, "<&$inr"); + open(STDOUT, ">&$outw"); + close($inw); + close($outr); + exec($_[0]); + print STDERR "exec failed : $!\n"; + exit 1; + } +close($inr); +close($outw); +return ($inw, $outr); +} diff --git a/mailboxes/find.cgi b/mailboxes/find.cgi new file mode 100755 index 000000000..a86a5d302 --- /dev/null +++ b/mailboxes/find.cgi @@ -0,0 +1,34 @@ +#!/usr/local/bin/perl +# find.cgi +# Display users matching some criteria + +require './mailboxes-lib.pl'; +&ReadParse(); + +# Build a list of all matching users +foreach $uinfo (&list_mail_users()) { + if (&can_user(@$uinfo)) { + if ($in{'match'} == 0 && lc($in{'user'}) eq $uinfo->[0] || + $in{'match'} == 1 && $uinfo->[0] =~ /\Q$in{'user'}\E/i) { + push(@users, $uinfo); + } + } + } + +if (@users == 1) { + # Can go direct to user + &redirect("list_mail.cgi?user=$users[0]->[0]"); + } +elsif (@users == 0) { + # No matches + &error($text{'find_enone'}); + } +else { + # Show table of matches + &ui_print_header(undef, $text{'find_title'}, ""); + print &text('find_results', $in{'user'}),"

\n"; + &show_users_table(\@users); + &ui_print_footer(); + } + + diff --git a/mailboxes/folders-lib.pl b/mailboxes/folders-lib.pl new file mode 100644 index 000000000..1b66b7ad8 --- /dev/null +++ b/mailboxes/folders-lib.pl @@ -0,0 +1,2450 @@ +# folders-lib.pl +# Functions for dealing with mail folders in various formats + +$pop3_port = 110; +$imap_port = 143; +$cache_directory = $user_module_config_directory || $module_config_directory; + +# mailbox_list_mails(start, end, &folder, [headersonly], [&error]) +# Returns an array whose size is that of the entire folder, with messages +# in the specified range filled in. +sub mailbox_list_mails +{ +if ($_[2]->{'type'} == 0) { + # List a single mbox formatted file + return &list_mails($_[2]->{'file'}, $_[0], $_[1]); + } +elsif ($_[2]->{'type'} == 1) { + # List a qmail maildir + local $md = $_[2]->{'file'}; + return &list_maildir($md, $_[0], $_[1]); + } +elsif ($_[2]->{'type'} == 2) { + # Get mail headers/body from a remote POP3 server + + # Login first + local @rv = &pop3_login($_[2]); + if ($rv[0] != 1) { + # Failed to connect or login + if ($_[4]) { + @{$_[4]} = @rv; + return (); + } + elsif ($rv[0] == 0) { &error($rv[1]); } + else { &error(&text('save_elogin', $rv[1])); } + } + local $h = $rv[1]; + local @uidl = &pop3_uidl($h); + local %onserver = map { &safe_uidl($_), 1 } @uidl; + + # Work out what range we want + local ($start, $end) = &compute_start_end($_[0], $_[1], scalar(@uidl)); + local @rv = map { undef } @uidl; + + # For each message in the range, get the headers or body + local ($i, $f, %cached, %sizeneed); + local $cd = "$cache_directory/$_[2]->{'id'}.cache"; + if (opendir(CACHE, $cd)) { + while($f = readdir(CACHE)) { + if ($f =~ /^(\S+)\.body$/) { + $cached{$1} = 2; + } + elsif ($f =~ /^(\S+)\.headers$/) { + $cached{$1} = 1; + } + } + closedir(CACHE); + } + else { + mkdir($cd, 0700); + } + for($i=$start; $i<=$end; $i++) { + local $u = &safe_uidl($uidl[$i]); + if ($cached{$u} == 2 || $cached{$u} == 1 && $_[3]) { + # We already have everything that we need + } + elsif ($cached{$u} == 1 || !$_[3]) { + # We need to get the entire mail + &pop3_command($h, "retr ".($i+1)); + open(CACHE, ">$cd/$u.body"); + while(<$h>) { + s/\r//g; + last if ($_ eq ".\n"); + print CACHE $_; + } + close(CACHE); + unlink("$cd/$u.headers"); + $cached{$u} = 2; + } + else { + # We just need the headers + &pop3_command($h, "top ".($i+1)." 0"); + open(CACHE, ">$cd/$u.headers"); + while(<$h>) { + s/\r//g; + last if ($_ eq ".\n"); + print CACHE $_; + } + close(CACHE); + $cached{$u} = 1; + } + local $mail = &read_mail_file($cached{$u} == 2 ? + "$cd/$u.body" : "$cd/$u.headers"); + if ($cached{$u} == 1) { + if ($mail->{'body'} ne "") { + $mail->{'size'} = int($mail->{'body'}); + } + else { + $sizeneed{$i} = 1; + } + } + $mail->{'uidl'} = $uidl[$i]; + $mail->{'idx'} = $i; + $rv[$i] = $mail; + } + + # Get sizes for mails if needed + if (%sizeneed) { + &pop3_command($h, "list"); + while(<$h>) { + s/\r//g; + last if ($_ eq ".\n"); + if (/^(\d+)\s+(\d+)/ && $sizeneed{$1-1}) { + # Add size to the mail cache + $rv[$1-1]->{'size'} = $2; + local $u = &safe_uidl($uidl[$1-1]); + open(CACHE, ">>$cd/$u.headers"); + print CACHE $2,"\n"; + close(CACHE); + } + } + } + + # Clean up any cached mails that no longer exist on the server + foreach $f (keys %cached) { + if (!$onserver{$f}) { + unlink($cached{$f} == 1 ? "$cd/$f.headers" + : "$cd/$f.body"); + } + } + + return @rv; + } +elsif ($_[2]->{'type'} == 3) { + # List an MH directory + local $md = $_[2]->{'file'}; + return &list_mhdir($md, $_[0], $_[1]); + } +elsif ($_[2]->{'type'} == 4) { + # Get headers and possibly bodies from an IMAP server + + # Login and select the specified mailbox + local @rv = &imap_login($_[2]); + if ($rv[0] != 1) { + # Something went wrong + if ($_[4]) { + @{$_[4]} = @rv; + return (); + } + elsif ($rv[0] == 0) { &error($rv[1]); } + elsif ($rv[0] == 3) { &error(&text('save_emailbox', $rv[1])); } + elsif ($rv[0] == 2) { &error(&text('save_elogin2', $rv[1])); } + } + local $h = $rv[1]; + local $count = $rv[2]; + return () if (!$count); + + # Work out what range we want + local ($start, $end) = &compute_start_end($_[0], $_[1], $count); + local @mail = map { undef } (0 .. $count-1); + + # Get the headers or body of messages in the specified range + local @rv; + if ($_[3]) { + # Just the headers + @rv = &imap_command($h, + sprintf "FETCH %d:%d (RFC822.SIZE RFC822.HEADER)", + $start+1, $end+1); + } + else { + # Whole messages + @rv = &imap_command($h, + sprintf "FETCH %d:%d RFC822", $start+1, $end+1); + } + + # Parse the headers or whole messages that came back + local $i; + for($i=0; $i<@{$rv[1]}; $i++) { + # Extract the actual mail part + local $mail = &parse_imap_mail($rv[1]->[$i]); + if ($mail) { + $mail->{'idx'} = $start+$i; + $mail[$start+$i] = $mail; + } + } + + return @mail; + } +elsif ($_[2]->{'type'} == 5) { + # Just all of the constituent folders + local @mail; + + # Work out exactly how big the total is + local ($sf, %len, $count); + foreach $sf (@{$_[2]->{'subfolders'}}) { + $len{$sf} = &mailbox_folder_size($sf); + $count += $len{$sf}; + } + + # Work out what range we need + local ($start, $end) = &compute_start_end($_[0], $_[1], $count); + + # Fetch the needed part of each sub-folder + local $pos = 0; + foreach $sf (@{$_[2]->{'subfolders'}}) { + local ($sfstart, $sfend); + $sfstart = $start - $pos; + $sfend = $end - $pos; + $sfstart = $sfstart < 0 ? 0 : + $sfstart >= $len{$sf} ? $len{$sf}-1 : $sfstart; + $sfend = $sfend < 0 ? 0 : + $sfend >= $len{$sf} ? $len{$sf}-1 : $sfend; + local @submail = + &mailbox_list_mails($sfstart, $sfend, $sf, $_[3]); + local $sm; + foreach $sm (@submail) { + if ($sm) { + &push_index($sm, $sf, $sm->{'idx'}+$pos); + } + } + push(@mail, @submail); + $pos += $len{$sf}; + } + + return @mail; + } +elsif ($_[2]->{'type'} == 6) { + # A virtual folder, which just contains indexes into other folders + local $mems = $folder->{'members'}; + local ($start, $end) = &compute_start_end($_[0], $_[1], scalar(@$mems)); + + # Work out which folders we need, and how much + local (%frange, %namemap); + local $i; + for($i=$start; $i<=$end; $i++) { + local $sf = $mems->[$i]->[0]; + local $sfn = &folder_name($sf); + local $idx = $mems->[$i]->[1]; + if ($frange{$sfn}) { + $frange{$sfn}->[0] = $idx if ($idx < $frange{$sfn}->[0]); + $frange{$sfn}->[1] = $idx if ($idx > $frange{$sfn}->[1]); + } + else { + $frange{$sfn} = [ $idx, $idx ]; + } + $namemap{$sfn} = $sf; + } + + # Get all the needed folders + local %sfs; + local $sfn; + foreach $sfn (keys %frange) { + local $sf = $namemap{$sfn}; + local @submail = &mailbox_list_mails($frange{$sfn}->[0], + $frange{$sfn}->[1], + $sf, $_[3]); + $sfs{$sfn} = \@submail; + } + + # Construct the results + local @mail = map { undef } (0 .. @$mems-1); + local $need_save = 0; + local @newmems = @$mems; + for($i=$start; $i<=$end && $i<=@$mems; $i++) { + local $sf = $mems->[$i]->[0]; + local $sfn = &folder_name($sf); + local $idx = $mems->[$i]->[1]; + $mail[$i] = $sfs{$sfn}->[$idx]; + if ($mems->[$i]->[2] && + $mail[$i]->{'header'}->{'message-id'} ne $mems->[$i]->[2]) { + # Argh .. index is wrong! Find message by ID + local $real = &find_by_message_id($sf,$mems->[$i]->[2]); + if ($real) { + $mems->[$i]->[1] = $real->{'idx'}; + $mail[$i] = $real; + $need_save++; + } + else { + # Doesn't exist! Lose from index.. + @newmems = grep { $_ ne $mems->[$i] } @newmems; + $need_save++; + next; + } + } + &push_index($mail[$i], $sf, $i); + } + + if ($need_save) { + $_[2]->{'members'} = \@newmems; + &save_folder($_[2]); + } + return @mail; + } +} + +# mailbox_select_mails(&folder, &indexes, headersonly) +# Returns only messages from a folder with indexes in the given array +sub mailbox_select_mails +{ +local ($folder, $indexes, $headersonly) = @_; +if ($folder->{'type'} == 0) { + # mbox folder + return &select_mails($folder->{'file'}, $indexes, $headersonly); + } +elsif ($folder->{'type'} == 1) { + # Maildir folder + return &select_maildir($folder->{'file'}, $indexes, $headersonly); + } +elsif ($folder->{'type'} == 3) { + # MH folder + return &select_mhdir($folder->{'file'}, $indexes, $headersonly); + } +elsif ($folder->{'type'} == 2) { + # POP folder + + # Login first + local @rv = &pop3_login($folder); + if ($rv[0] != 1) { + # Failed to connect or login + if ($_[4]) { + @{$_[4]} = @rv; + return (); + } + elsif ($rv[0] == 0) { &error($rv[1]); } + else { &error(&text('save_elogin', $rv[1])); } + } + local $h = $rv[1]; + local @uidl = &pop3_uidl($h); + + # Work out what we have cached + local ($i, $f, %cached, %sizeneed); + local @rv; + local $cd = "$cache_directory/$_[2]->{'id'}.cache"; + if (opendir(CACHE, $cd)) { + while($f = readdir(CACHE)) { + if ($f =~ /^(\S+)\.body$/) { + $cached{$1} = 2; + } + elsif ($f =~ /^(\S+)\.headers$/) { + $cached{$1} = 1; + } + } + closedir(CACHE); + } + else { + mkdir($cd, 0700); + } + + # For each requested index, get the headers or body + foreach my $i (@$indexes) { + local $u = &safe_uidl($uidl[$i]); + if ($cached{$u} == 2 || $cached{$u} == 1 && $headersonly) { + # We already have everything that we need + } + elsif ($cached{$u} == 1 || !$headersonly) { + # We need to get the entire mail + &pop3_command($h, "retr ".($i+1)); + open(CACHE, ">$cd/$u.body"); + while(<$h>) { + s/\r//g; + last if ($_ eq ".\n"); + print CACHE $_; + } + close(CACHE); + unlink("$cd/$u.headers"); + $cached{$u} = 2; + } + else { + # We just need the headers + &pop3_command($h, "top ".($i+1)." 0"); + open(CACHE, ">$cd/$u.headers"); + while(<$h>) { + s/\r//g; + last if ($_ eq ".\n"); + print CACHE $_; + } + close(CACHE); + $cached{$u} = 1; + } + local $mail = &read_mail_file($cached{$u} == 2 ? + "$cd/$u.body" : "$cd/$u.headers"); + if ($cached{$u} == 1) { + if ($mail->{'body'} ne "") { + $mail->{'size'} = int($mail->{'body'}); + } + else { + $sizeneed{$i} = 1; + } + } + $mail->{'uidl'} = $uidl[$i]; + $mail->{'idx'} = $i; + push(@rv, $mail); + } + + # Get sizes for mails if needed + if (%sizeneed) { + &pop3_command($h, "list"); + while(<$h>) { + s/\r//g; + last if ($_ eq ".\n"); + if (/^(\d+)\s+(\d+)/ && $sizeneed{$1-1}) { + # Find mail in results, and set its size + local ($ns) = grep { $_->{'idx'} == $1-1 } @rv; + next if (!$ns); + $ns->{'size'} = $2; + local $u = &safe_uidl($uidl[$1-1]); + open(CACHE, ">>$cd/$u.headers"); + print CACHE $2,"\n"; + close(CACHE); + } + } + } + + return @rv; + } +elsif ($folder->{'type'} == 4) { + # IMAP folder + + # Login and select the specified mailbox + local @irv = &imap_login($folder); + if ($irv[0] != 1) { + # Something went wrong + if ($_[4]) { + @{$_[4]} = @irv; + return (); + } + elsif ($irv[0] == 0) { &error($irv[1]); } + elsif ($irv[0] == 3) { &error(&text('save_emailbox', $irv[1])); } + elsif ($irv[0] == 2) { &error(&text('save_elogin2', $irv[1])); } + } + local $h = $irv[1]; + local $count = $irv[2]; + return () if (!$count); + + # Fetch each mail by index + local @rv; + local $wanted = $headersonly ? "(RFC822.SIZE RFC822.HEADER)" + : "RFC822"; + local @idxrv = &imap_command($h, + "FETCH ".join(",", map { $_+1 } @$indexes)." $wanted"); + local $i = 0; + foreach my $idxrv (@{idxrv->[1]}) { + local $mail = &parse_imap_mail($idxrv); + if ($mail) { + $mail->{'idx'} = $indexes->[$i++]; + push(@rv, $mail); + } + } + + return @rv; + } +elsif ($folder->{'type'} == 5) { + # Composite folder .. need to convert each index to a position + # in a sub-folder + # XXX could be faster + my $pos = 0; + my @ranges; + foreach my $sf (@{$folder->{'subfolders'}}) { + my $len = &mailbox_folder_size($sf); + push(@ranges, [ $pos, $pos+$len, $sf ]); + $pos += $len; + } + local @rv; + foreach my $i (@$indexes) { + # Find out which sub-folder this index is in + foreach my $r (@ranges) { + if ($i >= $r->[0] && $i < $r->[1]) { + # Found it! + local ($mail) = &mailbox_select_mails( + $r->[2], [ $i - $r->[0] ], + $headersonly); + &push_index($mail, $r->[2], $i); + push(@rv, $mail); + last; + } + } + } + return @rv; + } +elsif ($folder->{'type'} == 6) { + # Virtual folder .. translate each index to sub-folder index + # XXX could be faster + local $mems = $folder->{'members'}; + local @rv; + local $need_save = 0; + local @newmems = @$mems; + + # Work out how many different sub-folders we have + local $sf; + foreach my $i (@$indexes) { + $sf = $mems->[$i]->[0]; + $sfcount{&folder_name($sf)} = 1; + } + if ((keys %sfcount) == 1) { + # Just one, so we can do one big select + local (@sfindexes, @sfmems); + foreach my $i (@$indexes) { + push(@sfindexes, $mems->[$i]->[1]); + push(@sfmems, $i); + } + local $i = 0; + foreach my $mail (&mailbox_select_mails($sf, \@sfindexes, + $headersonly)) { + $mail->{'mem'} = $mems->[$sfmems[$i]]; + &push_index($mail, $sf, $sfmems[$i]); + push(@rv, $mail); + $i++; + } + } + elsif ((keys %sfcount) > 0) { + # Several sub-folders, so we need to select from each + foreach my $i (@$indexes) { + local $sf = $mems->[$i]->[0]; + local $idx = $mems->[$i]->[1]; + local ($mail) = &mailbox_select_mails($sf, [ $idx ], + $headersonly); + $mail->{'mem'} = $mems->[$i]; + &push_index($mail, $sf, $i); + push(@rv, $mail); + } + } + + # Fix up any mistmatches between indexes and message IDs + foreach $mail (@rv) { + local $mem = $mail->{'mem'}; + if ($mem->[2] && + $mail->{'header'}->{'message-id'} ne $mem->[2]) { + # Message ID mismatch! Fix it.. + local $real = &find_by_message_id( + $mail->{'subfolder'}, $mem->[2]); + if ($real) { + $mem->[1] = $real->{'idx'}; + $mail = $real; + $need_save++; + } + else { + # Doesn't exist! Lose from index.. + @newmems = grep { $_ ne $mem } @newmems; + $need_save++; + } + } + } + if ($need_save) { + $folder->{'members'} = \@newmems; + &save_folder($folder); + } + return @rv; + } +} + +# compute_start_end(start, end, count) +# Given start and end indexes (which may be negative or undef), returns the +# real mail file indexes. +sub compute_start_end +{ +local ($start, $end, $count) = @_; +if (!defined($start)) { + return (0, $count-1); + } +elsif ($end < 0) { + local $rstart = $count+$_[1]-1; + local $rend = $count+$_[0]-1; + $rstart = $rstart < 0 ? 0 : $rstart; + return ($rstart, $rend); + } +else { + local $rend = $_[1]; + $rend = $count - 1 if ($rend >= $count); + return ($start, $rend); + } +} + +# mailbox_list_mails_sorted(start, end, &folder, [headeronly], [&error], +# [sort-field, sort-dir]) +# Returns messages in a folder within the given range, but sorted by the +# given field and condition. +sub mailbox_list_mails_sorted +{ +local ($start, $end, $folder, $headers, $error, $field, $dir) = @_; +if (!$field) { + # Default to current ordering + ($field, $dir) = &get_sort_field($folder); + } +if (!$field || !$folder->{'sortable'}) { + # No sorting .. just return newest first + local @rv = reverse(&mailbox_list_mails( + -$start, -$end-1, $folder, $headers, $error)); + local $i = 0; + foreach my $m (@rv) { + $m->{'sortidx'} = $i++; + } + return @rv; + } + +# Build the appropriate sort index, if missing +local %index; +&build_sort_index($folder, $field, \%index); + +# Get message indexes, sorted by the field +my @sorter; +while(my ($k, $v) = each %index) { + if ($k =~ /^(\d+)_\Q$field\E$/) { + push(@sorter, [ $1, lc($v) ]); + } + } +if ($field eq "size" || $field eq "date" || $field eq "x-spam-status") { + # Numeric sort + @sorter = sort { my $s = $a->[1] <=> $b->[1]; $dir ? $s : -$s } @sorter; + } +else { + # Alpha sort + @sorter = sort { my $s = $a->[1] cmp $b->[1]; $dir ? $s : -$s } @sorter; + } + +# Find those mails within the requested range +($start, $end) = &compute_start_end($start, $end, scalar(@sorter)); +local @rv = map { undef } (0 .. scalar(@sorter)-1); +local @wantindexes = map { $sorter[$_]->[0] } ($start .. $end); +local @mails = &mailbox_select_mails($folder, \@wantindexes, $headers); +for(my $i=0; $i<@mails; $i++) { + $rv[$start+$i] = $mails[$i]; + $mails[$i]->{'sortidx'} = $start+$i; + } +return @rv; +} + +# set_sort_indexes(&folder, &mails, [sort-field, sort-dir]) +# Given a list of messages, sets the sortidx field based on their indexes +# that would be used if the folder was sorted +sub set_sort_indexes +{ +local ($folder, $mails, $field, $dir) = @_; +if (!$field) { + # Default to current ordering + ($field, $dir) = &get_sort_field($folder); + } +if (!$field || !$folder->{'sortable'}) { + # Sort index is the same as the normal index reversed + my $count = &mailbox_folder_size($folder); + foreach my $m (@$mails) { + $m->{'sortidx'} = $count-$m->{'idx'}-1; + } + return; + } + +# Build the appropriate sort index, if missing +local %index; +&build_sort_index($folder, $field, \%index); + +# Get message indexes, sorted by the field +my @sorter; +while(my ($k, $v) = each %index) { + if ($k =~ /^(\d+)_\Q$field\E$/) { + push(@sorter, [ $1, lc($v) ]); + } + } +if ($field eq "size" || $field eq "date") { + # Numeric sort + @sorter = sort { my $s = $a->[1] <=> $b->[1]; $dir ? $s : -$s } @sorter; + } +else { + # Alpha sort + @sorter = sort { my $s = $a->[1] cmp $b->[1]; $dir ? $s : -$s } @sorter; + } + +# Update sort indexes for mails in list +my $i = 0; +my %idxmap = map { $_->{'idx'}, $_ } @$mails; +foreach my $s (@sorter) { + my $m = $idxmap{$s->[0]}; + if ($m) { + $m->{'sortidx'} = $i; + } + $i++; + } +} + +# build_sort_index(&folder, field, &index) +# Builds and/or loads the index for sorting a folder on some field. The +# index uses the mail number as the key, and the field value as the value. +sub build_sort_index +{ +local ($folder, $field, $index) = @_; +return 0 if (!$folder->{'sortable'}); +local $ifile = &folder_sort_index_file($folder); + +&open_dbm_db($index, $ifile, 0600); +if ($index->{'lastchange'} < $folder->{'lastchange'} || + !$folder->{'lastchange'}) { + # The mail file is newer than the index .. add messages not in the index + # to it. + local $realcount = $folder->{'type'} == 6 ? + scalar(@{$folder->{'members'}}) : + &mailbox_folder_size($folder); + local $indexcount = int($index->{'mailcount'}); + if ($realcount < $indexcount) { + # Mail size has decreased! Need total rebuild + $indexcount = 0; + %$index = ( ); + } + local @mails = $realcount ? &mailbox_select_mails($folder, + [ $indexcount .. $realcount-1 ], 1) + : ( ); + my @index_fields = ( "subject", "from", "to", "date", "size", "x-spam-status", "message-id" ); + foreach my $mail (@mails) { + foreach my $f (@index_fields) { + if ($f eq "date") { + # Convert date to Unix time + $index->{$mail->{'idx'}."_date"} = + &parse_mail_date($mail->{'header'}->{'date'}); + } + elsif ($f eq "size") { + # Get mail size + $index->{$mail->{'idx'}."_size"} = + $mail->{'size'}; + } + elsif ($f eq "from" || $f eq "to") { + # From: header .. convert to display version + $index->{$mail->{'idx'}."_".$f} = + &simplify_from($mail->{'header'}->{$f}); + } + elsif ($f eq "subject") { + # Convert subject to display version + $index->{$mail->{'idx'}."_".$f} = + &simplify_subject($mail->{'header'}->{$f}); + } + elsif ($f eq "x-spam-status") { + # Extract spam score + $index->{$mail->{'idx'}."_".$f} = + $mail->{'header'}->{$f} =~ /(hits|score)=([0-9\.]+)/ ? $2 : undef; + } + else { + # Just a header + $index->{$mail->{'idx'}."_".$f} = + $mail->{'header'}->{$f}; + } + } + } + $index->{'lastchange'} = time(); + $index->{'mailcount'} = $realcount; + } +return 1; +} + +# delete_sort_index(&folder) +# Trashes the sort index for a folder, to force a rebuild +sub delete_sort_index +{ +local ($folder) = @_; +local $ifile = &folder_sort_index_file($folder); + +my %index; +&open_dbm_db(\%index, $ifile, 0600); +%index = ( ); +} + +# folder_sort_index_file(&folder) +# Returns the index file to use for some folder +sub folder_sort_index_file +{ +local ($folder) = @_; +return &user_index_file(($folder->{'file'} || $folder->{'id'}).".sort"); +} + +# find_by_message_id(&folder, id) +# Finds a message by ID, and returns the mail object +sub find_by_message_id +{ +local ($folder, $mid) = @_; +local %index; +if (&build_sort_index($folder, undef, \%index)) { + while(my ($k, $v) = each %index) { + if ($k =~ /^(\d+)_message-id$/ && $v eq $mid) { + # Got it! + local ($rv) = &mailbox_select_mails($folder, [ $1 ]); + &set_sort_indexes($folder, [ $rv ]); + return $rv; + } + } + } +return undef; +} + +# find_message_by_index(&mails, &folder, index, mid) +# Finds a message by index (in a sorted folder) or message ID +sub find_message_by_index +{ +local ($mails, $folder, $idx, $mid) = @_; +local $mail = $mails->[$idx]; +if ($mid && (!$mail || $mail->{'header'}->{'message-id'} ne $mid)) { + $mail = &find_by_message_id($folder, $mid); + } +return $mail; +} + +# mailbox_search_mail(&fields, andmode, &folder, [&limit]) +# Search a mailbox for multiple matching fields +sub mailbox_search_mail +{ +# For folders other than mbox and IMAP, build a sort index and use that for +# the search, if it is simple enough (Subject, From and To only) +local @idxfields = grep { $_->[0] eq 'from' || $_->[0] eq 'to' || + $_->[0] eq 'subject' } @{$_[0]}; +if ($_[2]->{'type'} != 0 && $_[2]->{'type'} != 4 && $_[2]->{'type'} != 5 && + scalar(@idxfields) == scalar(@{$_[0]}) && @idxfields && + &get_product_name() eq 'usermin') { + local %index; + &build_sort_index($_[2], undef, \%index); + local @rv; + + # Work out which mail indexes match the requested headers + local %idxmatches = map { ("$_->[0]/$_->[1]", [ ]) } @idxfields; + while(my ($k, $v) = each %index) { + local ($ki, $kf) = split(/_/, $k, 2); + next if (!$kf || $ki eq ''); + + # Check all of the fields to see which ones match + foreach my $if (@idxfields) { + local $iff = $if->[0]; + local ($neg) = ($iff =~ s/^\!//); + next if ($kf ne $iff); + if (!$neg && $v =~ /\Q$if->[1]\E/i || + $neg && $v !~ /\Q$if->[1]\E/i) { + push(@{$idxmatches{"$if->[0]/$if->[1]"}}, $ki); + } + } + } + local @matches; + if ($_[1]) { + # Find indexes in all arrays + local %icount; + foreach my $if (keys %idxmatches) { + foreach my $i (@{$idxmatches{$if}}) { + $icount{$i}++; + } + } + foreach my $i (keys %icount) { + } + local $fif = $idxfields[0]; + @matches = grep { $icount{$_} == scalar(@idxfields) } + @{$idxmatches{"$fif->[0]/$fif->[1]"}}; + } + else { + # Find indexes in any array + foreach my $if (keys %idxmatches) { + push(@matches, @{$idxmatches{$if}}); + } + @matches = &unique(@matches); + } + @matches = sort { $a <=> $b } @matches; + + # Select the actual mails + return &mailbox_select_mails($_[2], \@matches, 0); + } + +if ($_[2]->{'type'} == 0) { + # Just search an mbox format file (which will use its own special + # field-level index) + return &advanced_search_mail($_[2]->{'file'}, $_[0], $_[1], $_[3]); + } +elsif ($_[2]->{'type'} == 1) { + # Search a maildir directory + local $md = $_[2]->{'file'}; + return &advanced_search_maildir($md, $_[0], $_[1], $_[3]); + } +elsif ($_[2]->{'type'} == 2) { + # Get all of the mail from the POP3 server and search it + local ($min, $max); + if ($_[3] && $_[3]->{'latest'}) { + $min = -1; + $max = -$_[3]->{'latest'}; + } + local @mails = &mailbox_list_mails($min, $max, $_[2], + &indexof('body', &search_fields($_[0])) >= 0 ? 0 : 1); + local @rv = grep { $_ && &mail_matches($_[0], $_[1], $_) } @mails; + } +elsif ($_[2]->{'type'} == 3) { + # Search an MH directory + local $md = $_[2]->{'file'}; + return &advanced_search_mhdir($md, $_[0], $_[1], $_[3]); + } +elsif ($_[2]->{'type'} == 4) { + # Use IMAP's remote search feature + # XXX broken! + local @rv = &imap_login($_[2]); + if ($rv[0] == 0) { &error($rv[1]); } + elsif ($rv[0] == 3) { &error(&text('save_emailbox', $rv[1])); } + elsif ($rv[0] == 2) { &error(&text('save_elogin2', $rv[1])); } + local $h = $rv[1]; + + # Do the search to get back a list of matching numbers + local @search; + foreach $f (@{$_[0]}) { + local $field = $f->[0]; + local $neg = ($field =~ s/^\!//); + local $what = $f->[1]; + $what = "\"$what\"" if ($field ne "size"); + $field = "LARGER" if ($field eq "size"); + local $search = uc($field)." ".$what.""; + $search = "NOT $search" if ($neg); + push(@searches, $search); + } + local $searches; + if (@searches == 1) { + $searches = $searches[0]; + } + elsif ($_[1]) { + $searches = join(" ", @searches); + } + else { + $searches = $searches[$#searches]; + for($i=$#searches-1; $i>=0; $i--) { + $searches = "or $searches[$i] ($searches)"; + } + } + @rv = &imap_command($h, "SEARCH $searches"); + &error(&text('save_esearch', $rv[3])) if (!$rv[0]); + + # Get and parse those specific messages + local ($srch) = grep { $_ =~ /^\*\s+SEARCH/i } @{$rv[1]}; + local @ids = split(/\s+/, $srch); + shift(@ids); shift(@ids); # lose * SEARCH + local (@mail, $idx); + foreach $idx (@ids) { + local $realidx = $idx-1; + if ($_[3] && $_[3]->{'latest'}) { + # Don't get message if outside search range + next if ($realidx < $rv[3]-$_[3]->{'latest'}); + } + local @rv = &imap_command($h, + "FETCH $idx (RFC822.SIZE RFC822.HEADER)"); + &error(&text('save_esearch', $rv[3])) if (!$rv[0]); + local $mail = &parse_imap_mail($rv[1]->[0]); + if ($mail) { + $mail->{'idx'} = $realidx; + push(@mail, $mail); + } + } + return reverse(@mail); + } +elsif ($_[2]->{'type'} == 5) { + # Search each sub-folder and combine the results - taking any count + # limits into effect + local $sf; + local $pos = 0; + local @mail; + local (%start, %len); + foreach $sf (@{$_[2]->{'subfolders'}}) { + $len{$sf} = &mailbox_folder_size($sf); + $start{$sf} = $pos; + $pos += $len{$sf}; + } + local $limit = $_[3] ? { %{$_[3]} } : undef; + foreach $sf (reverse(@{$_[2]->{'subfolders'}})) { + local @submail = &mailbox_search_mail($_[0], $_[1], $sf, $limit); + foreach $sm (@submail) { + &push_index($sm, $sf, $sm->{'idx'}+$start{$sf}); + } + push(@mail, reverse(@submail)); + if ($limit && $limit->{'latest'}) { + # Adjust latest down by size of this folder + $limit->{'latest'} -= $len{$sf}; + last if ($limit->{'latest'} <= 0); + } + } + return reverse(@mail); + } +elsif ($_[2]->{'type'} == 6) { + # Just run a search on the sub-mails + local @rv; + local ($min, $max); + if ($_[3] && $_[3]->{'latest'}) { + $min = -1; + $max = -$_[3]->{'latest'}; + } + local $mail; + foreach $mail (&mailbox_list_mails($min, $max, $_[2])) { + push(@rv, $mail) if ($mail && &mail_matches($_[0],$_[1],$mail)); + } + return @rv; + } +} + +# mailbox_delete_mail(&folder, mail, ...) +# Delete multiple messages from some folder +sub mailbox_delete_mail +{ +return undef if (&is_readonly_mode()); +local $f = shift(@_); +if ($userconfig{'delete_mode'} == 1 && !$f->{'trash'} && !$f->{'spam'}) { + # Copy to trash folder first + local ($trash) = grep { $_->{'trash'} } &list_folders(); + local $m; + foreach $m (@_) { + &write_mail_folder($m, $trash); + } + } + +if ($f->{'type'} == 0) { + # Delete from mbox + &delete_mail($f->{'file'}, @_); + } +elsif ($f->{'type'} == 1) { + # Delete from Maildir + &delete_maildir(@_); + } +elsif ($f->{'type'} == 2) { + # Login and delete from the POP3 server + local @rv = &pop3_login($f); + if ($rv[0] == 0) { &error($rv[1]); } + elsif ($rv[0] == 2) { &error(&text('save_elogin', $rv[1])); } + local $h = $rv[1]; + local @uidl = &pop3_uidl($h); + local $m; + local $cd = "$cache_directory/$f->{'id'}.cache"; + foreach $m (@_) { + local $idx = &indexof($m->{'uidl'}, @uidl); + if ($idx >= 0) { + &pop3_command($h, "dele ".($idx+1)); + local $u = &safe_uidl($m->{'uidl'}); + unlink("$cd/$u.headers", + "$cd/$u.body"); + } + } + } +elsif ($f->{'type'} == 3) { + # Delete from MH dir + &delete_mhdir(@_); + } +elsif ($f->{'type'} == 4) { + # Delete from the IMAP server + local @rv = &imap_login($f); + if ($rv[0] == 0) { &error($rv[1]); } + elsif ($rv[0] == 3) { &error(&text('save_emailbox', $rv[1])); } + elsif ($rv[0] == 2) { &error(&text('save_elogin2', $rv[1])); } + local $h = $rv[1]; + + local $m; + foreach $m (@_) { + @rv = &imap_command($h, "STORE ".($m->{'idx'}+1). + " +FLAGS (\\Deleted)"); + &error(&text('save_edelete', $rv[3])) if (!$rv[0]); + } + @rv = &imap_command($h, "EXPUNGE"); + &error(&text('save_edelete', $rv[3])) if (!$rv[0]); + } +elsif ($f->{'type'} == 5) { + # Delete from underlying folder(s) + local $sm; + foreach $sm (@_) { + local ($subfolder, $idx) = &pop_index($sm); + &mailbox_delete_mail($subfolder, $sm); + &push_index($sm, $subfolder, $idx); + } + } +elsif ($f->{'type'} == 6) { + # Delete from virtual folder + local $sm; + if ($f->{'delete'}) { + # Delete the underlying messages, and remove from index + local %folderdel; + foreach $sm (sort { $b->{'subs'}->[0]->[1] <=> + $a->{'subs'}->[0]->[1] } @_) { + local ($subfolder, $idx) = &pop_index($sm); + &mailbox_delete_mail($subfolder, $sm); + &push_index($sm, $subfolder, $idx); + + # Adjust indexes in virtual list that refer to same + # sub-folder, and have higher numbers + for(my $i=0; $i<@{$f->{'members'}}; $i++) { + my $m = $f->{'members'}->[$i]; + my $subidx = $sm->{'subs'}->[0]->[1]; + if ($m->[0] eq $sm->{'subfolder'}) { + if ($m->[1] == $subidx) { + splice(@{$f->{'members'}}, + $i--, 1); + } + elsif ($m->[1] > $subidx) { + $m->[1]--; + } + } + } + } + } + else { + # Just take out of the virtual index + foreach $sm (sort { $b->{'idx'} <=> $a->{'idx'} } @_) { + splice(@{$f->{'members'}}, $sm->{'idx'}, 1); + } + } + &save_folder($f, $f); + } + +# Update folder index to remove indexes for deleted messages +if ($f->{'sortable'}) { + local %index; + &build_sort_index($f, undef, \%index); + foreach my $m (sort { $b->{'idx'} <=> $a->{'idx'} } @_) { + foreach my $k (sort { $a <=> $b } (keys %index)) { + local ($ki, $kf) = split(/_/, $k, 2); + if ($m->{'idx'} == $ki) { + # Delete this actual mail from the index + delete($index{$k}); + } + elsif ($m->{'idx'} < $ki) { + # Mail is after one being deleted .. shift down + $index{($ki-1)."_".$kf} = $index{$k}; + delete($index{$k}); + } + } + } + $index{'mailcount'} -= scalar(@_); + $index{'lastchange'} = time(); + dbmclose(%index); + } +} + +# mailbox_empty_folder(&folder) +# Remove the entire contents of a mail folder +sub mailbox_empty_folder +{ +return undef if (&is_readonly_mode()); +local $f = $_[0]; +if ($f->{'type'} == 0) { + # mbox format mail file + &empty_mail($f->{'file'}); + } +elsif ($f->{'type'} == 1) { + # qmail format maildir + &empty_maildir($f->{'file'}); + } +elsif ($f->{'type'} == 2) { + # POP3 server .. delete all messages + local @rv = &pop3_login($f); + if ($rv[0] == 0) { &error($rv[1]); } + elsif ($rv[0] == 2) { &error(&text('save_elogin', $rv[1])); } + local $h = $rv[1]; + @rv = &pop3_command($h, "stat"); + $rv[1] =~ /^(\d+)/ || return; + local $count = $1; + local $i; + for($i=1; $i<=$count; $i++) { + &pop3_command($h, "dele ".$i); + } + } +elsif ($f->{'type'} == 3) { + # mh format maildir + &empty_mhdir($f->{'file'}); + } +elsif ($f->{'type'} == 4) { + # IMAP server .. delete all messages + local @rv = &imap_login($f); + if ($rv[0] == 0) { &error($rv[1]); } + elsif ($rv[0] == 3) { &error(&text('save_emailbox', $rv[1])); } + elsif ($rv[0] == 2) { &error(&text('save_elogin2', $rv[1])); } + local $h = $rv[1]; + local $count = $rv[2]; + local $i; + for($i=1; $i<=$count; $i++) { + @rv = &imap_command($h, "STORE ".$i. + " +FLAGS (\\Deleted)"); + &error(&text('save_edelete', $rv[3])) if (!$rv[0]); + } + @rv = &imap_command($h, "EXPUNGE"); + &error(&text('save_edelete', $rv[3])) if (!$rv[0]); + } +elsif ($f->{'type'} == 5) { + # Empty each sub-folder + local $sf; + foreach $sf (@{$f->{'subfolders'}}) { + &mailbox_empty_folder($sf); + } + } +elsif ($f->{'type'} == 6) { + # Just clear the virtual index + $f->{'members'} = [ ]; + &save_folder($f); + } + +# Trash the folder index +if ($folder->{'sortable'}) { + &delete_sort_index($folder); + } +} + +# mailbox_copy_folder(&source, &dest) +# Copy all messages from one folder to another. This is done in an optimized +# way if possible. +sub mailbox_copy_folder +{ +local ($src, $dest) = @_; +if ($src->{'type'} == 0 && $dest->{'type'} == 0) { + # mbox to mbox .. just read and write the files + &open_readfile(SOURCE, $src->{'file'}); + &open_tempfile(DEST, ">>$dest->{'file'}"); + while(read(SOURCE, $buf, 1024) > 0) { + &print_tempfile(DEST, $buf); + } + &close_tempfile(DEST); + close(SOURCE); + } +elsif ($src->{'type'} == 1 && $dest->{'type'} == 1) { + # maildir to maildir .. just copy the files + local @files = &get_maildir_files($src->{'file'}); + foreach my $f (@files) { + local $fn = $f; + $fn =~ s/^.*\///; + ©_source_dest($f, "$dest->{'file'}/$fn"); + } + } +elsif ($src->{'type'} == 1 && $dest->{'type'} == 0) { + # maildir to mbox .. append all the files + local @files = &get_maildir_files($src->{'file'}); + &open_tempfile(DEST, ">>$dest->{'file'}"); + foreach my $f (@files) { + &open_readfile(SOURCE, $f); + while(read(SOURCE, $buf, 1024) > 0) { + &print_tempfile(DEST, $buf); + } + close(SOURCE); + } + &close_tempfile(DEST); + } +else { + # read in all mail and write out, in 100 message blocks + local $max = &mailbox_folder_size($src); + for(my $s=0; $s<$max; $s+=100) { + local $e = $s+99; + $e = $max-1 if ($e >= $max); + local @mail = &mailbox_list_mails($s, $e, $src); + local @want = @mail[$s..$e]; + &mailbox_copy_mail($src, $dest, @want); + } + } +} + +# mailbox_move_mail(&source, &dest, mail, ...) +# Move mail from one folder to another +sub mailbox_move_mail +{ +return undef if (&is_readonly_mode()); +local $src = shift(@_); +local $dst = shift(@_); +local $now = time(); +local $hn = &get_system_hostname(); +&create_folder_maildir($dst); +if (($src->{'type'} == 1 || $src->{'type'} == 3) && $dst->{'type'} == 1) { + # Can just move mail files + local $dd = $dst->{'file'}; + &create_folder_maildir($dst); + foreach $m (@_) { + rename($m->{'file'}, "$dd/cur/$now.$$.$hn"); + $now++; + } + } +elsif (($src->{'type'} == 1 || $src->{'type'} == 3) && $dst->{'type'} == 3) { + # Can move and rename to MH numbering + local $dd = $dst->{'file'}; + local $num = &max_mhdir($dst->{'file'}) + 1; + foreach $m (@_) { + rename($m->{'file'}, "$dd/$num"); + $num++; + } + } +else { + # Append to new folder file, or create in folder directory + local $m; + foreach $m (@_) { + &write_mail_folder($m, $dst); + } + &mailbox_delete_mail($src, @_); + } + +# Force re-generation of source folder index +if ($src->{'sortable'}) { + &delete_sort_index($src); + # XXX could be faster + } +} + +# mailbox_move_folder(&source, &dest) +# Moves all mail from one folder to another, possibly converting the type +sub mailbox_move_folder +{ +return undef if (&is_readonly_mode()); +local ($src, $dst) = @_; +if ($src->{'type'} == $dst->{'type'}) { + # Can just move the file or dir + system("rm -rf ".quotemeta($dst->{'file'})); + system("mv ".quotemeta($src->{'file'})." ".quotemeta($dst->{'file'})); + } +else { + # Need to copy one by one :( + local @mails = &mailbox_list_mails(undef, undef, $src); + &mailbox_move_mail($src, $dst, @mails); + } + +# Delete source folder index +if ($src->{'sortable'}) { + &delete_sort_index($src); + } +} + +# mailbox_copy_mail(&source, &dest, mail, ...) +# Copy mail from one folder to another +sub mailbox_copy_mail +{ +return undef if (&is_readonly_mode()); +local $src = shift(@_); +local $dst = shift(@_); +local $now = time(); +&create_folder_maildir($dst); +local $m; +if ($src->{'type'} == 6 && $dst->{'type'} == 6) { + # Copying from one virtual folder to another, so just copy the + # reference + foreach $m (@_) { + push(@{$dst->{'members'}}, [ $m->{'subfolder'}, $m->{'subid'}, + $m->{'header'}->{'message-id'} ]); + } + } +elsif ($dst->{'type'} == 6) { + # Add this mail to the index of the virtual folder + foreach $m (@_) { + push(@{$dst->{'members'}}, [ $src, $m->{'idx'}, + $m->{'header'}->{'message-id'} ]); + } + &save_folder($dst); + } +else { + # Just write to destination folder + foreach $m (@_) { + &write_mail_folder($m, $dst); + } + } +} + +# folder_type(file_or_dir) +sub folder_type +{ +return -d "$_[0]/cur" ? 1 : -d $_[0] ? 3 : 0; +} + +# create_folder_maildir(&folder) +# Ensure that a maildir folder has the needed new, cur and tmp directories +sub create_folder_maildir +{ +mkdir($folders_dir, 0700); +if ($_[0]->{'type'} == 1) { + local $id = $_[0]->{'file'}; + mkdir("$id/cur", 0700); + mkdir("$id/new", 0700); + mkdir("$id/tmp", 0700); + } +} + +# write_mail_folder(&mail, &folder, textonly) +# Writes some mail message to a folder +sub write_mail_folder +{ +return undef if (&is_readonly_mode()); +&create_folder_maildir($_[1]); +if ($_[1]->{'type'} == 1) { + # Add to a maildir directory + local $md = $_[1]->{'file'}; + &write_maildir($_[0], $md, $_[2]); + } +elsif ($_[1]->{'type'} == 3) { + # Create a new MH file + local $num = &max_mhdir($_[1]->{'file'}) + 1; + local $md = $_[1]->{'file'}; + &send_mail($_[0], "$md/$num", $_[2], 1); + } +elsif ($_[1]->{'type'} == 0) { + # Just append to the folder file + &send_mail($_[0], $_[1]->{'file'}, $_[2], 1); + } +elsif ($_[1]->{'type'} == 4) { + # Upload to the IMAP server + local @rv = &imap_login($_[1]); + if ($rv[0] == 0) { &error($rv[1]); } + elsif ($rv[0] == 3) { &error(&text('save_emailbox', $rv[1])); } + elsif ($rv[0] == 2) { &error(&text('save_elogin2', $rv[1])); } + local $h = $rv[1]; + + # Create a temp file and use it to create the IMAP command + local $temp = &transname(); + &send_mail($_[0], $temp, $_[2], 1); + open(TEMP, $temp); + local $text; + while() { $text .= $_; } + close(TEMP); + unlink($temp); + @rv = &imap_command($h, sprintf "APPEND %s {%d}\r\n%s", + $_[1]->{'mailbox'} || "INBOX", length($text), $text); + &error(&text('save_eappend', $rv[3])) if (!$rv[0]); + } +elsif ($_[1]->{'type'} == 5) { + # Just append to the last subfolder + local @sf = @{$_[1]->{'subfolders'}}; + &write_mail_folder($_[0], $sf[$#sf], $_[2]); + } +elsif ($_[1]->{'type'} == 6) { + # Add mail to first sub-folder, and to virtual index + &error("Cannot add mail to virtual folders"); + } +} + +# mailbox_modify_mail(&oldmail, &newmail, &folder, textonly) +# Replaces some mail message with a new one +sub mailbox_modify_mail +{ +return undef if (&is_readonly_mode()); +if ($_[2]->{'type'} == 1) { + # Just replace the existing file + &modify_maildir($_[0], $_[1], $_[3]); + } +elsif ($_[2]->{'type'} == 3) { + # Just replace the existing file + &modify_mhdir($_[0], $_[1], $_[3]); + } +elsif ($_[2]->{'type'} == 0) { + # Modify the mail file + &modify_mail($_[2]->{'file'}, $_[0], $_[1], $_[3]); + } +elsif ($_[2]->{'type'} == 5 || $_[2]->{'type'} == 6) { + # Modify in the appropriate folder + local ($oldsubfolder, $oldidx) = &pop_index($_[0]); + local ($newsubfolder, $newidx) = &pop_index($_[1]); + &mailbox_modify_mail($_[0], $_[1], $oldsubfolder, $_[3]); + &push_index($_[0], $oldsubfolder, $oldidx); + &push_index($_[1], $newsubfolder, $newidx); + } +else { + &error("Cannot modify mail in this type of folder!"); + } + +# Force re-generation of folder index +if ($_[2]->{'sortable'}) { + &delete_sort_index($_[2]); + # XXX could be faster + } +} + +# mailbox_folder_size(&folder, [estimate]) +# Returns the number of messages in some folder +sub mailbox_folder_size +{ +if ($_[0]->{'type'} == 0) { + # A mbox formatted file + return &count_mail($_[0]->{'file'}); + } +elsif ($_[0]->{'type'} == 1) { + # A qmail maildir + return &count_maildir($_[0]->{'file'}); + } +elsif ($_[0]->{'type'} == 2) { + # A POP3 server + local @rv = &pop3_login($_[0]); + if ($rv[0] != 1) { + if ($rv[0] == 0) { &error($rv[1]); } + else { &error(&text('save_elogin', $rv[1])); } + } + local @st = &pop3_command($rv[1], "stat"); + if ($st[0] == 1) { + local ($count, $size) = split(/\s+/, $st[1]); + return $count; + } + else { + &error($st[1]); + } + } +elsif ($_[0]->{'type'} == 3) { + # An MH directory + return &count_mhdir($_[0]->{'file'}); + } +elsif ($_[0]->{'type'} == 4) { + # An IMAP server + local @rv = &imap_login($_[0]); + if ($rv[0] != 1) { + if ($rv[0] == 0) { &error($rv[1]); } + elsif ($rv[0] == 3) { &error(&text('save_emailbox', $rv[1])); } + elsif ($rv[0] == 2) { &error(&text('save_elogin2', $rv[1])); } + } + return $rv[2]; + } +elsif ($_[0]->{'type'} == 5) { + # A composite folder - the size is just that of the sub-folders + my $rv = 0; + foreach my $sf (@{$_[0]->{'subfolders'}}) { + $rv += &mailbox_folder_size($sf); + } + return $rv; + } +elsif ($_[0]->{'type'} == 6 && !$_[1]) { + # A virtual folder .. we need to exclude messages that no longer + # exist in the parent folders + my $rv = 0; + foreach my $msg (@{$_[0]->{'members'}}) { + if (!$msg->[2] || &find_by_message_id($msg->[0], $msg->[2])) { + $rv++; + } + } + return $rv; + } +elsif ($_[0]->{'type'} == 6 && $_[1]) { + # A virtual folder .. but we can just use the last member count + return scalar(@{$_[0]->{'members'}}); + } +} + +# pop3_login(&folder) +# Logs into a POP3 server and returns a status (1=ok, 0=connect failed, +# 2=login failed) and handle or error message +sub pop3_login +{ +local $h = $pop3_login_handle{$_[0]->{'id'}}; +return (1, $h) if ($h); +$h = time().++$pop3_login_count; +local $error; +&open_socket($_[0]->{'server'}, $_[0]->{'port'} || 110, $h, \$error); +return (0, $error) if ($error); +local $os = select($h); $| = 1; select($os); +local @rv = &pop3_command($h); +return (0, $rv[1]) if (!$rv[0]); +@rv = &pop3_command($h, "user $_[0]->{'user'}"); +return (2, $rv[1]) if (!$rv[0]); +@rv = &pop3_command($h, "pass $_[0]->{'pass'}"); +return (2, $rv[1]) if (!$rv[0]); +return (1, $pop3_login_handle{$_[0]->{'id'}} = $h); +} + +# pop3_command(handle, command) +# Executes a command and returns the status (1 or 0 for OK or ERR) and message +sub pop3_command +{ +local ($h, $c) = @_; +print $h "$c\r\n" if ($c); +local $rv = <$h>; +$rv =~ s/\r|\n//g; +return !$rv ? ( 0, "Connection closed" ) : + $rv =~ /^\+OK\s*(.*)/ ? ( 1, $1 ) : + $rv =~ /^\-ERR\s*(.*)/ ? ( 0, $1 ) : ( 0, $rv ); +} + +# pop3_logout(handle, doquit) +sub pop3_logout +{ +local @rv = $_[1] ? &pop3_command($_[0], "quit") : (1, undef); +local $f; +foreach $f (keys %pop3_login_handle) { + delete($pop3_login_handle{$f}) if ($pop3_login_handle{$f} eq $_[0]); + } +close($_[0]); +return @rv; +} + +# pop3_uidl(handle) +# Returns the uidl list +sub pop3_uidl +{ +local @rv; +local $h = $_[0]; +local @urv = &pop3_command($h, "uidl"); +if (!$urv[0] && $urv[1] =~ /not\s+implemented/i) { + # UIDL is not available?! Use numeric list instead + &pop3_command($h, "list"); + while(<$h>) { + s/\r//g; + last if ($_ eq ".\n"); + if (/^(\d+)\s+(\d+)/) { + push(@rv, "size$2"); + } + } + } +elsif (!$urv[0]) { + &error("uidl failed! $urv[1]") if (!$urv[0]); + } +else { + # Can get normal UIDL list + while(<$h>) { + s/\r//g; + last if ($_ eq ".\n"); + if (/^(\d+)\s+(\S+)/) { + push(@rv, $2); + } + } + } +return @rv; +} + +# pop3_logout_all() +# Properly closes all open POP3 and IMAP sessions +sub pop3_logout_all +{ +local $f; +foreach $f (keys %pop3_login_handle) { + &pop3_logout($pop3_login_handle{$f}, 1); + } +foreach $f (keys %imap_login_handle) { + &imap_logout($imap_login_handle{$f}, 1); + } +} + +# imap_login(&folder) +# Logs into a POP3 server, selects a mailbox and returns a status +# (1=ok, 0=connect failed, 2=login failed, 3=mailbox error), a handle or error +# message, and the number of messages in the mailbox. +sub imap_login +{ +local $h = $imap_login_handle{$_[0]->{'id'}}; +local @rv; +if (!$h) { + # Need to open socket + $h = time().++$imap_login_count; + local $error; + &open_socket($_[0]->{'server'}, $_[0]->{'port'} || + $imap_port, $h, \$error); + return (0, $error) if ($error); + local $os = select($h); $| = 1; select($os); + + # Login normally + @rv = &imap_command($h); + return (0, $rv[3]) if (!$rv[0]); + @rv = &imap_command($h,"login \"$_[0]->{'user'}\" \"$_[0]->{'pass'}\""); + return (2, $rv[3]) if (!$rv[0]); + + $imap_login_handle{$_[0]->{'id'}} = $h; + } + +# Select the right folder (if one was given) +@rv = &imap_command($h, "select ".($_[0]->{'mailbox'} || "INBOX")); +return (3, $rv[3]) if (!$rv[0]); +local $count = $rv[2] =~ /\*\s+(\d+)\s+EXISTS/i ? $1 : undef; +return (1, $h, $count); +} + +# imap_command(handle, command) +# Executes an IMAP command and returns 1 for success or 0 for failure, and +# a reference to an array of results (some of which may be multiline), and +# all of the results joined together, and the stuff after OK/BAD +sub imap_command +{ +local ($h, $c) = @_; +local @rv; + +# Send the command, and read lines until a non-* one is found +local $id = $$."-".$imap_command_count++; +if ($c) { + print $h "$id $c\r\n"; + } +while(1) { + local $l = <$h>; + last if (!$l); + if ($l =~ /^(\*|\+)/) { + # Another response, and possibly the only one if no command + # was sent. + push(@rv, $l); + last if (!$c); + if ($l =~ /\{(\d+)\}\s*$/) { + # Start of multi-line text .. read the specified size + local $size = $1; + local $got; + local $err = "Error reading email"; + while($got < $size) { + local $buf; + local $r = read($h, $buf, $size-$got); + return (0, [ $err ], $err, $err) if ($r < 0); + $rv[$#rv] .= $buf; + $got += $r; + } + } + } + elsif ($l =~ /^(\S+)\s+/ && $1 eq $id) { + # End of responses + push(@rv, $l); + last; + } + else { + # Part of last response + if (!@rv) { + local $err = "Got unknown line $l"; + return (0, [ $err ], $err, $err); + } + $rv[$#rv] .= $l; + } + } +local $j = join("", @rv); +local $lline = $rv[$#rv]; +if ($lline =~ /^(\S+)\s+OK\s*(.*)/) { + # Looks like the command worked + return (1, \@rv, $j, $2); + } +else { + # Command failed! + return (0, \@rv, $j, $lline =~ /^(\S+)\s+(\S+)\s*(.*)/ ? $3 : undef); + } +} + +# imap_logout(handle, doquit) +sub imap_logout +{ +local @rv = $_[1] ? &imap_command($_[0], "close") : (1, undef); +local $f; +foreach $f (keys %imap_login_handle) { + delete($imap_login_handle{$f}) if ($imap_login_handle{$f} eq $_[0]); + } +close($_[0]); +return @rv; +} + +# lock_folder(&folder) +sub lock_folder +{ +return if ($_[0]->{'remote'} || $_[0]->{'type'} == 5 || $_[0]->{'type'} == 6); +local $f = $_[0]->{'file'} ? $_[0]->{'file'} : + $_[0]->{'type'} == 0 ? &user_mail_file($remote_user) : + $qmail_maildir; +if (&lock_file($f)) { + $_[0]->{'lock'} = $f; + } +else { + # Cannot lock if in /var/mail + local $ff = $f; + $ff =~ s/\//_/g; + $ff = "/tmp/$ff"; + $_[0]->{'lock'} = $ff; + &lock_file($ff); + } + +# Also, check for a .filename.pop3 file +if ($config{'pop_locks'} && $f =~ /^(\S+)\/([^\/]+)$/) { + local $poplf = "$1/.$2.pop"; + local $count = 0; + while(-r $poplf) { + sleep(1); + if ($count++ > 5*60) { + # Give up after 5 minutes + &error(&text('epop3lock_tries', "$f", 5)); + } + } + } +} + +# unlock_folder(&folder) +sub unlock_folder +{ +return if ($_[0]->{'remote'}); +&unlock_file($_[0]->{'lock'}); +} + +# folder_file(&folder) +# Returns the full path to the file or directory containing the folder's mail, +# or undef if not appropriate (such as for POP3) +sub folder_file +{ +return $_[0]->{'remote'} ? undef : $_[0]->{'file'}; +} + +# parse_imap_mail(response) +# Parses a response from the IMAP server into a standard mail structure +sub parse_imap_mail +{ +# Extract the actual mail part +local $mail = { }; +local $realsize; +local $imap = $_[0]; +if ($imap =~ /RFC822.SIZE\s+(\d+)/) { + $realsize = $1; + } +$imap =~ s/^\*\s+\d+\s+FETCH.*\{(\d+)\}\r?\n// || return undef; +local $size = $1; +local @lines = split(/\n/, substr($imap, 0, $size)); + +# Parse the headers +local $lnum = 0; +local @headers; +while(1) { + local $line = $lines[$lnum++]; + $mail->{'size'} += length($line); + $line =~ s/\r//g; + last if ($line eq ''); + if ($line =~ /^(\S+):\s*(.*)/) { + push(@headers, [ $1, $2 ]); + } + elsif ($line =~ /^(\s+.*)/) { + $headers[$#headers]->[1] .= $1 + unless($#headers < 0); + } + } +$mail->{'headers'} = \@headers; +foreach $h (@headers) { + $mail->{'header'}->{lc($h->[0])} = $h->[1]; + } + +# Parse the body +while($lnum < @lines) { + $mail->{'size'} += length($lines[$lnum]+1); + $mail->{'body'} .= $lines[$lnum]."\n"; + $lnum++; + } +$mail->{'size'} = $realsize if ($realsize); +return $mail; +} + +# find_body(&mail, mode) +# Returns the plain text body, html body and the one to use +sub find_body +{ +local ($a, $body, $textbody, $htmlbody); +foreach $a (@{$_[0]->{'attach'}}) { + if ($a->{'type'} =~ /^text\/plain/i || $a->{'type'} eq 'text') { + $textbody = $a if (!$textbody && $a->{'data'} =~ /\S/); + } + elsif ($a->{'type'} =~ /^text\/html/i) { + $htmlbody = $a if (!$htmlbody && $a->{'data'} =~ /\S/); + } + } +if ($_[1] == 0) { + $body = $textbody; + } +elsif ($_[1] == 1) { + $body = $textbody || $htmlbody; + } +elsif ($_[1] == 2) { + $body = $htmlbody || $textbody; + } +elsif ($_[1] == 3) { + # Convert HTML to text if needed + if ($textbody) { + $body = $textbody; + } + else { + local $text = &html_to_text($htmlbody->{'data'}); + $body = $textbody = + { 'data' => $text }; + } + } +return ($textbody, $htmlbody, $body); +} + +# safe_html(html) +# Converts HTML to a form safe for inclusion in a page +sub safe_html +{ +local $html = $_[0]; +local $bodystuff; +if ($html =~ s/^[\000-\377]*]*)>//i) { + $bodystuff = $1; + } +$html =~ s/<\/BODY>[\000-\377]*$//i; +$html =~ s/]*>//i; +$html = &filter_javascript($html); +$html = &safe_urls($html); +$bodystuff = &safe_html($bodystuff) if ($bodystuff); +return wantarray ? ($html, $bodystuff) : $html; +} + +# head_html(html) +# Returns HTML in the section of a document +sub head_html +{ +local $html = $_[0]; +return undef if ($html !~ /]*>/i || $html !~ /<\/HEAD[^>]*>/i); +$html =~ s/^[\000-\377]*]*>//gi || &error("Failed to filter

".&html_escape($html)."
"); +$html =~ s/<\/HEAD[^>]*>[\000-\377]*//gi || &error("Failed to filter
".&html_escape($html)."
"); +$html =~ s/]*>//i; +return &filter_javascript($html); +} + +# safe_urls(html) +# Replaces dangerous-looking URLs in HTML +sub safe_urls +{ +local $html = $_[0]; +$html =~ s/((src|href|background)\s*=\s*)([^ '">]+)()/&safe_url($1, $3, $4)/gei; +$html =~ s/((src|href|background)\s*=\s*')([^']+)(')/&safe_url($1, $3, $4)/gei; +$html =~ s/((src|href|background)\s*=\s*")([^"]+)(")/&safe_url($1, $3, $4)/gei; +return $html; +} + +# safe_url(before, url, after) +sub safe_url +{ +local ($before, $url, $after) = @_; +if ($url =~ /^#/) { + # Relative link - harmless + return $before.$url.$after; + } +elsif ($url =~ /^cid:/i) { + # Definately safe (CIDs are harmless) + return $before.$url.$after; + } +elsif ($url =~ /^(http:|https:)/) { + # Possibly safe, unless refers to local + local ($host, $port, $page, $ssl) = &parse_http_url($url); + local ($hhost, $hport) = split(/:/, $ENV{'HTTP_HOST'}); + $hport ||= $ENV{'SERVER_PORT'}; + if ($host ne $hhost || + $port != $hport || + $ssl != (uc($ENV{'HTTPS'}) eq 'ON' ? 1 : 0)) { + return $before.$url.$after; + } + else { + return $before."_unsafe_link_".$after; + } + } +elsif ($url =~ /^mailto:([a-z0-9\.\-\_\@]+)/i) { + # A mailto link, which we can convert + return $before."reply_mail.cgi?new=1&to=".&urlize($1).$after; + } +else { + # Relative URL like foo.cgi or /foo.cgi or ../foo.cgi - unsafe! + return $before."_unsafe_link_".$after; + } +} + +# safe_uidl(string) +sub safe_uidl +{ +local $rv = $_[0]; +$rv =~ s/\/|\./_/g; +return $rv; +} + +# html_to_text(html) +# Attempts to convert some HTML to text form +sub html_to_text +{ +local ($h2, $lynx); +if (($h2 = &has_command("html2text")) || ($lynx = &has_command("lynx"))) { + # Can use a commonly available external program + local $temp = &transname().".html"; + open(TEMP, ">$temp"); + print TEMP $_[0]; + close(TEMP); + open(OUT, ($lynx ? "$lynx -dump $temp" : "$h2 $temp")." 2>/dev/null |"); + while() { + if ($lynx && $_ =~ /^\s*References\s*$/) { + # Start of Lynx references output + $gotrefs++; + } + elsif ($lynx && $gotrefs && + $_ =~ /^\s*(\d+)\.\s+(http|https|ftp|mailto)/) { + # Skip this URL reference line + } + else { + $text .= $_; + } + } + close(OUT); + unlink($temp); + return $text; + } +else { + # Do conversion manually :( + local $html = $_[0]; + $html =~ s/\s+/ /g; + $html =~ s/

/\n\n/gi; + $html =~ s/
/\n/gi; + $html =~ s/<[^>]+>//g; + $html = &entities_to_ascii($html); + return $html; + } +} + +# folder_select(&folders, selected-folder, name, [extra-options], [by-id]) +# Returns HTML for selecting a folder +sub folder_select +{ +local $sel = "\n"; +return $sel; +} + +# folder_size(&folder, ...) +# Sets the 'size' field of one or more folders, and returns the total +sub folder_size +{ +local ($f, $total); +foreach $f (@_) { + if ($f->{'type'} == 0) { + # Single mail file - size is easy + local @st = stat($f->{'file'}); + $f->{'size'} = $st[7]; + } + elsif ($f->{'type'} == 1) { + # Maildir folder size is that of all files in it + $f->{'size'} = &recursive_disk_usage($f->{'file'}); + } + elsif ($f->{'type'} == 3) { + # MH folder size is that of all mail files + local $mf; + $f->{'size'} = 0; + opendir(MHDIR, $f->{'file'}); + while($mf = readdir(MHDIR)) { + next if ($mf eq "." || $mf eq ".."); + local @st = stat("$f->{'file'}/$mf"); + $f->{'size'} += $st[7]; + } + closedir(MHDIR); + } + elsif ($f->{'type'} == 4) { + # Get size of IMAP folder + local ($ok, $h, $count) = &imap_login($f); + if ($ok) { + $f->{'size'} = 0; + local @rv = &imap_command($h, + "FETCH 1:$count (RFC822.SIZE)"); + foreach my $r (@{$rv[1]}) { + if ($r =~ /RFC822.SIZE\s+(\d+)/) { + $f->{'size'} += $1; + } + } + } + } + elsif ($f->{'type'} == 5) { + # Size of a combined folder is the size of all sub-folders + return &folder_size(@{$f->{'subfolders'}}); + } + else { + # Cannot get size of a POP3 folder + $f->{'size'} = undef; + } + $total += $f->{'size'}; + } +return $total; +} + +# parse_boolean(string) +# Separates a string into a series of and/or separated values. Returns a +# mode number (0=or, 1=and, 2=both) and a list of words +sub parse_boolean +{ +local @rv; +local $str = $_[0]; +local $mode = -1; +local $lastandor = 0; +while($str =~ /^\s*"([^"]*)"(.*)$/ || + $str =~ /^\s*"([^"]*)"(.*)$/ || + $str =~ /^\s*(\S+)(.*)$/) { + local $word = $1; + $str = $2; + if (lc($word) eq "and") { + if ($mode < 0) { $mode = 1; } + elsif ($mode != 1) { $mode = 2; } + $lastandor = 1; + } + elsif (lc($word) eq "or") { + if ($mode < 0) { $mode = 0; } + elsif ($mode != 0) { $mode = 2; } + $lastandor = 1; + } + else { + if (!$lastandor && @rv) { + $rv[$#rv] .= " ".$word; + } + else { + push(@rv, $word); + } + $lastandor = 0; + } + } +$mode = 0 if ($mode < 0); +return ($mode, \@rv); +} + +# recursive_files(dir, treat-dirs-as-folders) +sub recursive_files +{ +local ($f, @rv); +opendir(DIR, $_[0]); +local @files = readdir(DIR); +closedir(DIR); +foreach $f (@files) { + next if ($f eq "." || $f eq ".." || $f =~ /\.lock$/i || + $f eq "cur" || $f eq "tmp" || $f eq "new" || + $f =~ /^\.imap/i || $f eq ".customflags" || + $f eq "dovecot-uidlist" || $f =~ /^courierimap/ || + $f eq "maildirfolder" || $f eq "maildirsize" || + $f eq "maildircache" || $f eq ".subscriptions" || + $f eq ".usermin-maildircache" || $f =~ /^dovecot\.index/ || + $f =~ /\.webmintmp(\.\d+)$/); + local $p = "$_[0]/$f"; + local $added = 0; + if ($_[1] || !-d $p || -d "$p/cur") { + push(@rv, $p); + $added = 1; + } + # If this directory wasn't a folder (or it it in Maildir format), + # search it too. + if (-d "$p/cur" || !$added) { + push(@rv, &recursive_files($p)); + } + } +return @rv; +} + +# editable_mail(&mail) +# Returns 0 if some mail message should not be editable (ie. internal folder) +sub editable_mail +{ +return $_[0]->{'header'}->{'subject'} !~ /DON'T DELETE THIS MESSAGE.*FOLDER INTERNAL DATA/; +} + +# fix_cids(html, &attachments, url-prefix, &cid-list) +# Replaces HTML like img src=cid:XXX with img src=detach.cgi?whatever +sub fix_cids +{ +local $rv = $_[0]; +$rv =~ s/(src="|href=")cid:([^"]+)(")/$1.&fix_cid($2,$_[1],$_[2],$_[3]).$3/gei; +$rv =~ s/(src='|href=')cid:([^']+)(')/$1.&fix_cid($2,$_[1],$_[2],$_[3]).$3/gei; +$rv =~ s/(src=|href=)cid:([^\s>]+)()/$1.&fix_cid($2,$_[1],$_[2],$_[3]).$3/gei; +return $rv; +} + +# fix_cid(cid, &attachments, url-prefix, &cid-list) +sub fix_cid +{ +local ($cont) = grep { $_->{'header'}->{'content-id'} eq $_[0] || + $_->{'header'}->{'content-id'} eq "<$_[0]>" } @{$_[1]}; +return "cid:$_[0]" if (!$cont); +push(@{$_[3]}, $cont) if ($_[3]); +return "$_[2]&attach=$cont->{'idx'}"; +} + +# quoted_message(&mail, quote-mode, sig, 0=any,1=text,2=html) +# Returns the quoted text, html-flag and body attachment +sub quoted_message +{ +local ($mail, $qu, $sig, $bodymode) = @_; +local $mode = $bodymode == 1 ? 1 : + $bodymode == 2 ? 2 : + defined(%userconfig) ? $userconfig{'view_html'} : + $config{'view_html'}; +local ($plainbody, $htmlbody) = &find_body($mail, $mode); +local ($quote, $html_edit, $body); +local $cfg = defined(%userconfig) ? \%userconfig : \%config; +local @writers = &split_addresses($mail->{'header'}->{'from'}); +local $writer = &decode_mimewords($writers[0]->[1] || $writers[0]->[0]). + " wrote .."; +local $tm; +if ($cfg->{'reply_date'} && + ($tm = &parse_mail_date($_[0]->{'header'}->{'date'}))) { + local $tmstr = &make_date($tm); + $writer = "On $tmstr $writer"; + } +local $qm = defined(%userconfig) ? $userconfig{'html_quote'} + : $config{'html_quote'}; +if (($cfg->{'html_edit'} == 2 || + $cfg->{'html_edit'} == 1 && $htmlbody) && + $bodymode != 1) { + # Create quoted body HTML + if ($htmlbody) { + $body = $htmlbody; + $sig =~ s/\n/
\n/g; + if ($qu && $qm == 0) { + # Quoted HTML as cite + $quote = "$writer\n". + "

\n". + &safe_html($htmlbody->{'data'}). + "
".$sig."
\n"; + } + elsif ($qu && $qm == 1) { + # Quoted HTML below line + $quote = "
$sig
". + "$writer
\n". + &safe_html($htmlbody->{'data'}); + } + else { + # Un-quoted HTML + $quote = &safe_html($htmlbody->{'data'}). + $sig."
\n"; + } + } + elsif ($plainbody) { + $body = $plainbody; + local $pd = $plainbody->{'data'}; + $pd =~ s/^\s+//g; + $pd =~ s/\s+$//g; + if ($qu && $qm == 0) { + # Quoted plain text as HTML as cite + $quote = "$writer\n". + "
\n". + "
$pd
". + "
".$sig."
\n"; + } + elsif ($qu && $qm == 1) { + # Quoted plain text as HTML below line + $quote = "
$sig
". + "$writer
\n". + "
$pd

\n"; + } + else { + # Un-quoted plain text as HTML + $quote = "
$pd
". + $sig."
\n"; + } + } + $html_edit = 1; + } +else { + # Create quoted body text + if ($plainbody) { + $body = $plainbody; + $quote = $plainbody->{'data'}; + } + elsif ($htmlbody) { + $body = $htmlbody; + $quote = &html_to_text($htmlbody->{'data'}); + } + if ($quote && $qu) { + $quote = join("", map { "> $_\n" } + &wrap_lines($quote, 70)); + } + $quote = $writer."\n".$quote if ($quote && $qu); + $quote .= "$sig\n" if ($sig); + } +return ($quote, $html_edit, $body); +} + +# modification_time(&folder) +# Returns the unix time on which this folder was last modified, or 0 if unknown +sub modification_time +{ +if ($_[0]->{'type'} == 0) { + # Modification time of file + local @st = stat($_[0]->{'file'}); + return $st[9]; + } +elsif ($_[0]->{'type'} == 1) { + # Greatest modification time of cur/new directory + local @stcur = stat("$_[0]->{'file'}/cur"); + local @stnew = stat("$_[0]->{'file'}/new"); + return $stcur[9] > $stnew[9] ? $stcur[9] : $stnew[9]; + } +elsif ($_[0]->{'type'} == 2 || $_[0]->{'type'} == 4) { + # Cannot know for POP3 or IMAP folders + return 0; + } +elsif ($_[0]->{'type'} == 3) { + # Modification time of MH folder + local @st = stat($_[0]->{'file'}); + return $st[9]; + } +else { + # Huh? + return 0; + } +} + +# requires_delivery_notification(&mail) +sub requires_delivery_notification +{ +return $_[0]->{'header'}->{'disposition-notification-to'} || + $_[0]->{'header'}->{'read-reciept-to'}; +} + +# send_delivery_notification(&mail, [from-addr], manual) +# Send an email containing delivery status information +sub send_delivery_notification +{ +local ($mail, $from) = @_; +$from ||= $mail->{'header'}->{'to'}; +local $host = &get_display_hostname(); +local $to = &requires_delivery_notification($mail); +local $product = &get_product_name(); +$product = ucfirst($product); +local $version = &get_webmin_version(); +local ($taddr) = &split_addresses($mail->{'header'}->{'to'}); +local $disp = $manual ? "manual-action/MDN-sent-manually" + : "automatic-action/MDN-sent-automatically"; +local $dsn = <[0] +Final-Recipient: rfc822;$taddr->[0] +Original-Message-ID: $mail->{'header'}->{'message-id'} +Disposition: $disp; displayed +EOF +local $dmail = { + 'headers' => + [ [ 'From' => $from ], + [ 'To' => $to ], + [ 'Subject' => 'Delivery notification' ], + [ 'Content-type' => 'multipart/report; report-type=disposition-notification' ], + [ 'Content-Transfer-Encoding' => '7bit' ] ], + 'attach' => [ + { 'headers' => [ [ 'Content-type' => 'text/plain' ] ], + 'data' => "This is a delivery status notification for the email sent to:\n$mail->{'header'}->{'to'}\non the date:\n$mail->{'header'}->{'date'}\nwith the subject:\n$mail->{'header'}->{'subject'}\n" }, + { 'headers' => [ [ 'Content-type' => + 'message/disposition-notification' ], + [ 'Content-Transfer-Encoding' => '7bit' ] ], + 'data' => $dsn } + ] }; +eval { local $main::errors_must_die = 1; &send_mail($dmail); }; +return $to; +} + +# find_named_folder(name, &folders, [&cache]) +# Finds a folder by ID, filename, server name or displayed name +sub find_named_folder +{ +local $rv; +if ($_[2] && exists($_[2]->{$_[0]})) { + # In cache + $rv = $_[2]->{$_[0]}; + } +else { + # Need to lookup + ($rv) = grep { $_->{'id'} eq $_[0] } @{$_[1]} if (!$rv); + ($rv) = grep { my $escfile = $_->{'file'}; + $escfile =~ s/\s/_/g; + $escfile eq $_[0] || + $_->{'file'} eq $_[0] || + $_->{'server'} eq $_[0] } @{$_[1]} if (!$rv); + ($rv) = grep { my $escname = $_->{'name'}; + $escname =~ s/\s/_/g; + $escname eq $_[0] || + $_->{'name'} eq $_[0] } @{$_[1]} if (!$rv); + $_[2]->{$_[0]} = $rv if ($_[2]); + } +return $rv; +} + +# folder_name(&folder) +# Returns a unique identifier for a folder, based on it's filename or ID +sub folder_name +{ +my $rv = $_[0]->{'id'} || + $_[0]->{'file'} || + $_[0]->{'server'} || + $_[0]->{'name'}; +$rv =~ s/\s/_/g; +return $rv; +} + +# set_folder_lastmodified(&folders) +# Sets the last-modified time and sortable flag on all given folders +sub set_folder_lastmodified +{ +local ($folders) = @_; +foreach my $folder (@$folders) { + if ($folder->{'type'} == 0 || $folder->{'type'} == 3) { + # For an mbox or MH folder, the last modified date is just that + # of the file or directory itself + local @st = stat($folder->{'file'}); + $folder->{'lastchange'} = $st[9]; + $folder->{'sortable'} = 1; + } + elsif ($folder->{'type'} == 1) { + # For a Maildir folder, the date is that of the newest + # sub-directory (cur, tmp or new) + $folder->{'lastchange'} = 0; + foreach my $sf ("cur", "tmp", "new") { + local @st = stat("$folder->{'file'}/$sf"); + $folder->{'lastchange'} = $st[9] + if ($st[9] > $folder->{'lastchange'}); + } + $folder->{'sortable'} = 1; + } + elsif ($folder->{'type'} == 6) { + # For a virtual folder, the date is that of the newest + # sub-folder, OR the folder file itself + local @st = stat($folder->{'folderfile'}); + $folder->{'lastchange'} = $st[9]; + my %done; + foreach my $m (@{$folder->{'members'}}) { + if (!$done{$m->[0]}++) { + &set_folder_lastmodified([ $m->[0] ]); + $folder->{'lastchange'} = + $m->[0]->{'lastchange'} + if ($m->[0]->{'lastchange'} > + $folder->{'lastchange'}); + } + } + $folder->{'sortable'} = 1; + } + else { + # For POP3 and IMAP folders, we don't know the last change + $folder->{'lastchange'} = undef; + $folder->{'sortable'} = 1; + } + } +} + +# push_index(&mail, &folder, new-index) +# Adjusts the index of some email to the new one, and stores the old +# index and folder +sub push_index +{ +local ($mail, $folder, $newidx) = @_; +unshift(@{$mail->{'subs'}}, [ $mail->{'subfolder'}, $mail->{'idx'} ]); +$mail->{'subidx'} = $mail->{'subs'}->[0]->[1]; +$mail->{'subfolder'} = $folder; +$mail->{'idx'} = $newidx; +} + +# pop_index(&mail) +# Removes the stored sub-folder and index, and restores the original index. +# Returns the original sub-folder and index. +sub pop_index +{ +local ($mail) = @_; +local $old = shift(@{$mail->{'subs'}}); +$mail->{'subidx'} = $mail->{'subs'}->[0]->[1]; +local @rv = ( $mail->{'subfolder'}, $mail->{'idx'} ); +$mail->{'subfolder'} = $old->[0]; +$mail->{'idx'} = $old->[1]; +return @rv; +} + +# mail_preview(&mail) +# Returns a short text preview of a message body +sub mail_preview +{ +local ($textbody, $htmlbody, $body) = &find_body($_[0], 0); +local $data = $body->{'data'}; +$data =~ s/\r?\n/ /g; +$data = substr($data, 0, 100); +if ($data =~ /\S/) { + return $data; + } +return undef; +} + +# open_dbm_db(&hash, file, mode) +# Attempts to open a DBM, first using SDBM_File, and then NDBM_File +sub open_dbm_db +{ +local ($hash, $file, $mode) = @_; +eval "use SDBM_File"; +dbmopen(%$hash, $file, $mode); +eval { $hash->{'1111111111'} = 'foo bar' }; +if ($@) { + dbmclose(%$hash); + eval "use NDBM_File"; + dbmopen(%$hash, $file, $mode); + } +} + +1; + diff --git a/mailboxes/images/attach.gif b/mailboxes/images/attach.gif new file mode 100644 index 0000000000000000000000000000000000000000..8cba6f2a1d434ff4ec09869bdd3e53c3e9762957 GIT binary patch literal 77 zcmZ?wbhEHbal_Mx4xKuD z@$AJLN6u{9ef`3P!}qS9y?6iN)qPK{K74lN@$)CIUOql`8!;kuh*%uaiMIZgmKoL6@eYc`?(dIyJS2!Ejh_4$iQF?0Au{S AJpcdz literal 0 HcmV?d00001 diff --git a/mailboxes/images/error.gif b/mailboxes/images/error.gif new file mode 100644 index 0000000000000000000000000000000000000000..df4546ac9f3029d3cf87b45785e8bb999548218a GIT binary patch literal 457 zcmZ?wbhEHbG+;1bc+9|X=FFM@|NqaNIWsLSjp0ATe;{H20-zXnp!k!8k%57OK?kG? zWCjDvKY^2;tM^(2AMX9P;Hsyr_`E33X>zapbY%9w&{=Jgk#EiRry-!fefJ-x69@D| zk8FsVl3cV)#MJnFXUVBhw)|z6i*M`dx6e0`v6KA$wJKui%_U(1| z_CL6OA@#)i=N!$~jy{^R@586|8`xhqSuZ6m_K)eD(v4R6Ni9sQs~$5H zUUO>Tl25C-etyyM#_~!byDcl+o_O>r|E>I^Y?NfdCl*?FC*_j7%v9afCZ3rr>Sy~o zQqL7xZhGR@E*CH5VP2T&>?-}WFsbE>nC-IGRc5KTo(6}meEH@Bw}i=}o0~I~?Km@1 oUHH`Uw9iy>tDWiEQS$KC+}YDTW@y)by~q28N&n$?K?VkE0G}1xQ~&?~ literal 0 HcmV?d00001 diff --git a/mailboxes/images/icon.gif b/mailboxes/images/icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..7416f19eb8edd12045e0c3d9a279153a1a8dfa14 GIT binary patch literal 367 zcmZ?wbhEHbG+;1bc+9|X=FFM@|NqaNIWsLSjp0ATe;{H20-zXnp!ko^H!&qup**uB zL&4qCH-JI$CkrD30|$c+NFT^l29|#UCp}m1wRnAY_x}WqzLd;)E7;aJNUd{}S)<2( z+9EdE{N4GrvWvcJzX~|ANGQWgZ~pQA&z`Ae%dX~3VLwqdJ=*iTcNm-cnk`jl^L8(O zyy=emf)e&-2D|?2=Tli48(CQxOEc=@npoM`THBMVYA1JEG_mxuwv|l{o!-(vXRbdB zJNxw69gDq}E?d5E)oR!2O)DpEil5-TW9K5K6sCjwjSfccD%{z&|7cs>al_Mx4xKuD z@$AJLN6u{9ef`3P!}qS9y?6iN)qPK{K74lN@$)CIUOql`8!;kuh*%uaiMIZgmKoL6@eYc`?(dIyJS2!Ejh_4$iQF?0Au{S AJpcdz literal 0 HcmV?d00001 diff --git a/mailboxes/images/p1.gif b/mailboxes/images/p1.gif new file mode 100644 index 0000000000000000000000000000000000000000..5fd162f10842d55ef4a8838a2c6939da8025981f GIT binary patch literal 55 zcmZ?wbhEHbWMklFXkcLY4@Cd}EB<6*WME)q&|v@qkPHJ8pASRYis`2wL|@)|Bd?d0 G!5RR5zz;M4 literal 0 HcmV?d00001 diff --git a/mailboxes/images/p2.gif b/mailboxes/images/p2.gif new file mode 100644 index 0000000000000000000000000000000000000000..010cab57fce9d41acb77c0d997d5d7468c5446f5 GIT binary patch literal 55 zcmZ?wbhEHbWMklFXkcL2#lZ0Y|9{1wEQ|~cj0`#qKmd|qVB+&(NLw-e)Pv~DTW{p` IvNBi$0CR2*?*IS* literal 0 HcmV?d00001 diff --git a/mailboxes/images/read.gif b/mailboxes/images/read.gif new file mode 100644 index 0000000000000000000000000000000000000000..fb489284efdf74ec88de7c6285f3dfd66102a8bb GIT binary patch literal 63 zcmZ?wbhEHb0r5dH3`}A@{SDl^uHEaL#AaStEcWhQ MqvW>h($ literal 0 HcmV?d00001 diff --git a/mailboxes/images/smallicon.gif b/mailboxes/images/smallicon.gif new file mode 100644 index 0000000000000000000000000000000000000000..de0ee2d4310f1e84fc4beafea357f2f5f9f7eafa GIT binary patch literal 190 zcmZ?wbh9u|lwgoxc+9}i@V|lKKf|+U&(54VbD#mpZ#eM3!Qnr{|NsAQ-n@C>|AEb$ zH!~ms9S|F&mw}~N;H2m3y%w*}uKeK?UK@8~qIlOzN$s7pXEl`M)}P$1Qavf1i{XI5 zg^zVo4h;?(NozRoxV^Uie^AU`$1P^A`(Ui3#jU+hk&W#Bb*nOKrSw i|IlCFFQ>7*G$U3dtg}mqvuwh|No74#r%e-Num%8YT}|i! literal 0 HcmV?d00001 diff --git a/mailboxes/images/special.gif b/mailboxes/images/special.gif new file mode 100644 index 0000000000000000000000000000000000000000..2bd81f6019fa030199315590983b9d6f8872c93c GIT binary patch literal 62 zcmZ?wbhEHb[1] == $config{'mail_system'} } + @mail_system_modules; + if (!&check_mail_system($ms)) { + &ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1); + &ui_print_endpage(&text('index_esystem2', + "../config.cgi?$module_name")); + } + } + +# Make sure mail system is running +$err = &test_mail_system(); +if ($err) { + &ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1); + &ui_print_endpage(&text('index_esystem3', + "../config.cgi?$module_name", $err)); + } + +# Show main page header +&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1, 0, + undef, undef, undef, + $text{'index_system'.$config{'mail_system'}}); + +# Check for Perl modules for SMTP authentication +if ($config{'smtp_user'}) { + local @needed = ( "Authen::SASL" ); + local $smode = $config{'smtp_auth'} || "Cram-MD5"; + $smode = uc($smode); + $smode =~ s/-/_/g; + push(@needed, "Authen::SASL::Perl::$smode"); + foreach $n (@needed) { + eval "use $n"; + if ($@) { + &ui_print_endpage( + "

".&text('index_eperl', "$n", + "/cpan/download.cgi?source=3&cpan=$n&mode=2&". + "return=/$module_name/&returndesc=". + &urlize($text{'index_return'}))."

\n". + "$text{'index_eperl2'}\n". + "

$@
\n"); + } + } + } + +# Build a list of all available users +@users = &list_mail_users($config{'max_records'}, \&can_user); + +$form = 0; +if (!@users) { + # No users! + print "$text{'index_none'}

\n"; + } +elsif ($config{'max_records'} && @users > $config{'max_records'}) { + # Show input for searching for a user + print $text{'index_toomany'},"

\n"; + print &ui_form_start("find.cgi"); + print &ui_submit($text{'index_find'}),"\n"; + print &ui_select("match", undef, [ [ "0", $text{'index_equals'} ], + [ "1", $text{'index_contains'} ] ]),"\n"; + print &ui_user_textbox("user"),"\n"; + print &ui_form_end(); + $form++; + } +else { + # Show using selected mode and sort + &show_users_table(\@users, $config{'show_mail'}); + } + +if (&allowed_directory()) { + # Show form to view any mail file + print "

\n"; + print &ui_form_start("list_mail.cgi"); + print &ui_submit($text{'index_file'}),"\n"; + print &ui_textbox("user", undef, 40),"\n", + &file_chooser_button("user", $form),"
\n"; + print &ui_form_end(); + } + +&ui_print_footer("/", $text{'index'}); + diff --git a/mailboxes/lang/ca b/mailboxes/lang/ca new file mode 100644 index 000000000..95e6b8a2d --- /dev/null +++ b/mailboxes/lang/ca @@ -0,0 +1,383 @@ +index_title=Lectura del Correu d'Usuaris +index_none=NO tens permís per llegir el correu de cap usuari d'aquest sistema. +index_header=Bústies d'usuaris +index_empty=No hi ha correu +index_return=a la llista d'usuaris +index_esystem=No s'ha detectat al sistema cap dels servidors de correu suportats (Qmail, Postfix i Sendmail). Hauràs d'ajustar la configuració del mòdul per configurar manualment el servidor de correu i possiblement els camins del correu. +index_esystem2=No s'ha trobat al sistema el servidor de correu establert a la configuració del mòdul. Hauràs de modificar la configuració per que faci servir el servidor correcte. +index_esystem3=S'ha produït un error en contactar el sistema de correu establert a la configuració del mòdul: $2. +index_system2=Servidor de correu: Qmail +index_system1=Servidor de correu: Sendmail +index_system0=Servidor de correu: Postfix +index_toomany=Hi ha massa usuaris al sistema com per mostrar-los en una sola pàgina. +index_find=Busca usuaris tals que el nom d'usuari +index_equals=sigui igual que +index_contains=contingui +index_eperl=El mòdul Perl $1 necessari per al mode d'autenticació SMTP seleccionat no està instal·lat o està mancat d'un mòdul dependent. Fes clic aquí per instal·lar-lo ara. +index_file=Llegeix el Correu del Fitxer: +index_nousers=No s'ha trobat cap usuari! +index_nousersmail=No s'ha trobat cap usuari amb correu. + +mail_title=Correu de l'Usuari +mail_from=De +mail_date=Data +mail_subject=Tema +mail_to=A +mail_cc=Cc +mail_bcc=Bcc +mail_pri=Prioritat +mail_highest=Altíssima +mail_high=Alta +mail_normal=Normal +mail_low=Baixa +mail_lowest=Baixíssima +mail_for=A $1 +mail_for2=Per a l'usuari $1 +mail_sent=A la llista de correu enviat +mail_size=Mida +mail_level=Puntuació +mail_delete=Suprimeix +mail_compose=Redacta +mail_open=Obre +mail_return=a la bústia de l'usuari +mail_pos=Missatges $1 a $2 de $3 a $4 +mail_none=Aquest usuari no té cap missatge a $1 +mail_ecannot=No tens permís per llegir el correu d'aquest usuari +mail_all=Selecciona-ho tot. +mail_invert=Inverteix la selecció. +mail_nosort=Reinicia l'ordenació. +mail_search=Busca missatges tals que +mail_body=El cos +mail_match=coincideixi amb +mail_ok=Busca +mail_nonefrom=Cap +mail_mark=Marca com: +mail_mark0=No llegit +mail_mark1=Llegit +mail_mark2=Especial +mail_forward=Reenvia +mail_move=Desplaça a: +mail_copy=Copia a: +mail_rfc=Des de la línia +mail_eexists=El missatge ja no existeix! +mail_fchange=Canvia +mail_indexlink=Torna a la bústia +mail_deleteall=Suprimeix-los Tots +mail_black=Denega els Remitents +mail_white=Permet els Remitents +mail_efile=El fitxer de correu no existeix +mail_fromsrch=El mateix remitent... +mail_subsrch=El mateix assumpte... +mail_tosrch=El mateix destinatari... +mail_unknown=Desconegut/da + +mail_sign=Signa amb la clau +mail_nosign=<No el signis> +mail_crypt=Xifra per a +mail_nocrypt=<No el xifris> +mail_samecrypt=<Claus de les adreces de destinació> +mail_addresses=Gestiona la Llibreta d'Adreces +mail_folders=Gestiona les Carpetes +mail_err=S'ha produït un error en llistar el correu d'aquesta carpeta: $1 +mail_loginheader=Entrada al servidor POP3 +mail_loginheader2=Entrada al servidor IMAP +mail_logindesc=Has d'introduir un usuari i una contrasenya per accedir al correu
d'entrada del servidor de correu $1. +mail_loginuser=Usuari +mail_loginpass=Contrasenya +mail_loginmailbox=Bústia IMAP +mail_login=Entrada +mail_reset=Neteja +mail_logout=Canvia l'entrada POP3 +mail_logout2=Canvia l'entrada IMAP +mail_sig=Edita la Signatura +mail_jump=Salta a la pàgina: +mail_of=de +mail_replyto=Respon a +mail_folder=Carpeta +mail_delall=Suprimeix-ho tot +mail_deltrash=Buida la Paperera +mail_search2=Busca: +mail_search3=Busca amb la puntuació de sobre: +mail_advanced=Recerca Avançada +mail_return2=al Correu de l'Usuari +mail_esystem=S'ha produït un error en contactar amb el sistema de correu: $1. Això ha de ser corregit per l'administrador del sistema. + +view_title=Lectura del Correu +view_desc=Missatge $1 a $2 +view_desc2=Missatge $1 per a l'usuari $2 +view_desc3=Missatge $1 +view_sent=Missatge $1 al la llista de correu enviat +view_qdesc=Missatge $1 en cua +view_headers=Capçaleres de correu +view_body=Text del missatge +view_allheaders=Mostra totes les capçaleres +view_noheaders=Mostra les capçaleres bàsiques +view_attach=Adjuncions +view_reply=Respon +view_reply2=Respon a tots +view_enew=Edita coma nou +view_forward=Reenvia +view_delete=Suprimeix +view_print=Imprimeix +view_strip=Treu les Adjuncions +view_ecannot=No tens permís per llegir el correu d'aquest usuari +view_mark=Marca com: +view_mark0=No llegit +view_mark1=Llegit +view_mark2=Especial +view_return=al correu original +view_sub=Correu Adjunt +view_egone=Aquest missatge ja no existeix +view_eugone=Aquest usuari no existeix + +view_gnupg=Verificació de la signatura GnuPG +view_gnupg_0=La signatura de $1 és vàlida. +view_gnupg_1=La signatura de $1 és vàlida, però no s'ha pogut establir la cadena de fiabilitat. +view_gnupg_2=La signatura de $1 NO és vàlida. +view_gnupg_3=L'ID de clau $1 no és a la teva llista, així que no es pot verificar la signatura. +view_gnupg_4=No he pogut verificar la signatura: $1 +view_crypt=Desxifratge de correu GnuPG +view_crypt_1=El missatge està xifrat, però el suport GnuPG no està instal·lat. +view_crypt_2=No he pogut desxifrar el missatge: $1 +view_crypt_3=El correu s'ha desxifrat correctament. +view_crypt_4=La part xifrada del missatge s'ha desxifrat correctament. +view_recv=Obtingues l'ID de clau $1 del servidor de claus. +view_folder=Torna a la bústia +view_detach=Separa el fitxer: +view_dall=<Tots els fitxers> +view_dir=al fitxer o directori del servidor: +view_black=Denega el Remitent +view_white=Permet el Remitent +view_razor=Informa com a Spam +view_ham=Informa com a Ham +view_razordel=Informa i Suprimeix Spam +view_dstatus=L'estat del lliurament ha fallat +view_dstatusok=Estat de lliurament correcte +view_final-recipient=Destinatari final +view_diagnostic-code=Motiu de l'error +view_remote-mta=Servidor de correu remot +view_reporting-mta=Servidor de correu d'informes +view_astext=Mostra com a text +view_ashtml=Mostra com a HTML +view_raw=Mostra el missatge tal com és + +compose_title=Redacció de Correu + +reply_title=Resposta de Correu +forward_title=Reenviament de Correu +enew_title=Edició de Correu +reply_headers=Capçaleres de correu +reply_attach=Adjuncions reenviades +reply_mailforward=Missatges reenviats +reply_attach2=Adjuncions de la part del client i del servidor +reply_attach3=Adjuncions pujades +reply_send=Envia el Correu +reply_ecannot=No tens permís per enviar correu amb aquest usuari +reply_body=Text del missatge +reply_errc=No he pogut copiar el correu +reply_errm=No he pogut desplaçar el correu +reply_return=a la redacció del correu +reply_efwdnone=No existeix cap dels missatges reenviats + +reply_spell=Comprova l'ortografia +reply_draft=Desa com a Esborrany + +send_err=No he pogut enviar el correu +send_eto=Hi falta l'adreça To +send_efrom=Hi falta l'adreça From +send_esubject=Hi falta l'asssumpte del correu +send_title=Correu Enviat +send_ok=Correu enviat correctament a to $1 +send_sending=Enviant el correu a $1... +send_ecannot=No tens permís per enviar correu amb aquest usuari +send_esmtp=L'ordre SMTP $1 ha fallat: $2 +send_eattach=Les adjuncions no poden fer més de $1 Kb. +send_eperms=L'usuari $1 no pot llegir $2 +send_eperms2=No tens permís per enviar el fitxer $1 +send_epath=L'executable de Sendmail $1 no existeix. +send_efile=No he pogut llegir l'adjunció $1: $2 +send_done=...fet. + +send_epass=No pots signar cap missatge perquè la teva frase de contrasenya encara no està configurada al mòdul de GnuPG. +send_esign=No he pogut signar el missatge: $1 +send_ekey=No he pogut trobar la clau per a l'adreça de correu $1 +send_ecrypt=No he pogut xifrar el missatge: $1 +send_eword=Paraula '$1' incorrecta +send_eword2=Paraula '$1' incorrecta - possible correcció: $2 +send_eline=A la línia $1: +send_espell=S'han trobat els error ortogràfics següents al missatge... +send_draft=El correu per a $1 s'ha desat a la carpeta d'esborranys. +send_drafting=Desant el correu per a $1 a la carpeta d'esborranys... +send_eattachsize=L'adjunció de correu excedeix la mida màxima permesa de $1 bytes + +delete_title=Supressió de Correu +delete_rusure=Segur que vols suprimir les $1 missatges seleccionats de $2? Això pot trigar una mica si el fitxer de correu és gros. No es podrà realitzar cap altra acció fins que no s'hagi acabat la supressió. +delete_rusure2=Segur que voleu suprimir aquest missatge de $1? Això pot trigar una mica si el fitxer de correu és gros. No es podrà realitzar cap altra acció fins que no s'hagi acabat la supressió. +delete_ok=Suprimeix Ara +delete_ecannot=No tens permís per suprimir correus d'aquest usuari +delete_enone=No has seleccionat cap correu per suprimir +delete_emnone=No has seleccionat cap correu per marcar +delete_efnone=No has seleccionat cap correu per reenviar +delete_ebnone=No has seleccionat cap correu per denegar +delete_ewnone=No has seleccionat cap correu per permetre +delete_ernone=No has seleccionat cap correu per informar-lo com a spam +delete_ehnone=No has seleccionat cap correu per informar-lo com a ham +delete_emoveuser=L'usuari per desplaçar-hi el correu no existeix +delete_ecopyuser=L'usuari per copiar-hi el correu no existeix +delete_emovecannot=No tens permís per desplaçar els correus a l'usuari especificat +delete_ecopycannot=No tens permís per copiar els correus a l'usuari especificat +delete_emovenone=No has seleccionat cap correu per desplaçar +delete_ecopynone=No has seleccionat cap correu per copiar +delete_nobutton=No has fet clic a cap botó +delete_ereport=No he pogut informar com a spam: $1 +delete_errc=No he pogut copiar el correu +delete_errm=No he pogut desplaçar el correu + +confirm_title=Confirmació de Supressió +confirm_warn=Segur que vols suprimir els $1 missatges seleccionats? +confirm_warn2=Degut a la mida i el format de la bústia, això pot trigar una mica. No es podrà realitzar cap altra acció fins que no s'hagi acabat la supressió. +confirm_warn3=Segur que vols suprimir aquest missatge? +confirm_warn4=No es podrà realitzar cap altra acció fins que no s'hagi acabat la supressió. +confirm_ok=Suprimeix Ara +confirm_warnall=Segur que vols suprimir tots els missatges d'aquesta carpeta? + +search_title=Resultats de la Recerca +search_ecannot=No tens permís per buscar dins del correu d'aquest usuari +search_ematch=Has d'introduir un text de recerca. +search_escore=Hi falta la puntuació de spam o bé és invàlida +search_efield=Has de seleccionar un tipus de recerca. +search_ewhat=No has introduït cap text de recerca per a la fila $1 +search_enone=No has introduït cap criteri de recerca +search_none=No s'ha trobat cap missatge. +search_results2=$1 missatges de correu que coincideixen amb $2 +search_results3=$1 missatges de correu que no coincideixen amb $2 +search_results4=$1 missatges de correu que coincideixen amb la teva recerca +search_results5=$1 missatges de correu on $2 coincideix amb $3 +search_msg2=Resultats de la recerca per a $1 +search_msg4=Resultats de la recerca +search_msg5=Resultats de la recerca de spam amb puntuació $1 +search_local=A les carpetes locals +search_all=A totes les carpetes +search_limit=(dels darrers $1 missatges) +search_status=Amb estat +search_allstatus=Qualsevol +search_onestatus=Només l'estat +search_latest=Missatges a buscar +search_nolatest=Tots els de la carpeta +search_latestnum=Només els darrers +search_elatest=Hi falta el nombre de missatges a buscar o bé és invàlid +search_withstatus=, amb estat $1 + +folder_inbox=Entrada +folder_sent=Enviat +folder_drafts=Drafts +folder_trash=Trash + +detach_err=No he pogut separar el fitxer +detach_edir=No has introduït cap fitxer o directori per desar +detach_eopen=No he pogut obrir $1: $2 +detach_ewrite=No he pogut gravar a $1: $2 +detach_title=Alliberament de Fitxer +detach_ok=He gravat l'adjunció al fitxer del servidor $1 ($2). + +sform_title=Recerca Avançada +sform_and=Busca missatges que coincideixin amb els criteris de recerca de sota... +sform_or=Busca missatges que coincideixin amb qualsevol dels criteris de recerca de sota... +sform_neg0=conté +sform_neg1=no conté +sform_ok=Busca Ara +sform_folder=a les carpetes +sform_all=<Totes les carpetes> +sform_local=<Carpetes locals> +sform_where=Tal que +sform_text=el text +sform_from=la capçalera From: +sform_subject=la capçalera Subject: +sform_to=la capçalera To: +sform_cc=la capçalera Cc: +sform_bcc=la capçalera Bcc: +sform_date=la capçalera Date: +sform_body=el cos del missatge +sform_headers=qualsevol capçalera +sform_size=la mida del missatge +sform_return=al formulari de recerca avançada + +find_enone=No s'ha trobat cap usuari que coincideixi amb la teva recerca +find_title=Resultats de la Recerca +find_results=Usuaris que coincideixin amb la recerca per a $1... +find_user=Usuari +find_real=Nom real +find_group=Grup +find_home=Director i arrel +find_size=Mida del correu +find_incount=Correus +find_sentcount=Enviats +find_fcount=Carpetes +find_in=$1 a $2 + +acl_none=Cap +acl_same=Usuari amb el mateix nom +acl_all=Tots +acl_read=Usuaris el correu dels quals es pot llegir +acl_users=Només els usuaris +acl_userse=Tots excepte els usuaris +acl_usersg=Membres dels grups +acl_from=Adreces From permissibles +acl_any=Qualsevol adreça +acl_fdoms=Dominis @ de bústies +acl_faddrs=Adreces llistades +acl_fdom=Qualsevol domini @ d'adreça +acl_fromname=Nom real per a l'adreça From +acl_apath=Limita els fitxers i el programa al directori +acl_attach=Mida màxima total de les adjuncions +acl_unlimited=Il·limitada +acl_sent=Emmagatzema el correu enviat a la bústia +acl_canattach=Pot adjuntar fitxers del servidor +acl_candetach=Pot separar fitxers al servidor +acl_usersm=Usuaris que coincideixin amb +acl_asame=Igual que el nom d'usuari +acl_usersu=Amb UID en el rang +acl_sec=Inclou grups secundaris +acl_dir=Pot llegir els fitxer de correu del directori +acl_dirauto=Decideix automàticament (qualsevol lloc si tots els usuaris són visibles, enlloc altrament) + +log_delmail=He suprimit $1 missatges de $2 +log_movemail=He desplaçat $1 missatges de $2 a $3 +log_copymail=He copiat $1 missatges de $2 a $3 +log_send=He enviat el correu a $1 +log_read=He llegit el correu de $1 + +emodified=Aquesta carpeta s'ha modificat des de la darrera visualització! Torna a la llista de correu i torna-ho a provar. + +razor_title=Informant com a Spam +razor_title2=Informant com a Ham +razor_report=Informant aquest missatge a Razor i altres bases de dades de blocatge de spam de SpamAssassin... +razor_report2=Informant dels missatges seleccionats a Razor i altres bases de dades SpamAssassin de blocatge de spam... +razor_report3=Desinformant els missatges seleccionats a Razor i altres bases de dades SpamAssassin de blocatge de spam... +razor_done=... fet. +razor_err=... ha fallat! Mira el missatge d'error de sobre per saber-ne el motiu. +razor_deleted=...fet, i també he suprimit el missatge. + +ham_title=Informant com a Ham +ham_report=Informant aquest missatges com a no spam a Razor i altres base de dades SpamAssassin... + +black_title=Denegant el Remitent +black_done=He afegit l'adreça de correu $1 a la llista d'adreces denegades de SpamAssassin. +black_already=L'adreça de correu $1 ja és a la llista d'adreces denegades de SpamAssassin. + +white_title=Permetent Remitent +white_done=He afegit l'adreça de correu $1 a la llista d'adreces permeses de SpamAssassin. +white_already=L'adreça de correu $1 ja és a la llista d'adreces permeses de SpamAssassin. + +ldap_emod=Falta el mòdul Perl $1 necessari per connectar amb LDAP +ldap_econn=No he pogut connectar amb el servidor LDAP $1 port $2 +ldap_elogin=No he pogut lligar el servidor LDAP $1 com a $2: $3 +ldap_ehost=No hi ha cap servidor LDAP establert a la configuració del mòdul +ldap_eport=No hi ha cap port de servidor vàlid LDAP establert a la configuració del mòdul +ldap_euser=No hi ha cap entrada LDAP establerta a la configuració del mòdul +ldap_ebase=No hi ha cap DN base establert a la configuració del mòdul + +delall_title=Suprimeix Tot el Correu +delall_rusure=Segur que vols suprimir tot el correu de $1? $2 missatges amb un total de $3 seran suprimit per sempre més. +delall_ok=Suprimeix-los Ara + diff --git a/mailboxes/lang/de b/mailboxes/lang/de new file mode 100644 index 000000000..94fb6399b --- /dev/null +++ b/mailboxes/lang/de @@ -0,0 +1,318 @@ +acl_all=Alle +acl_any=Jede Adresse +acl_apath=Beschränke Dateien und Programme auf Verzeichnis +acl_asame=Verwende Benutzernamen +acl_attach=Maximale Gesamtdateianhanggröße +acl_canattach=Darf Dateien vom Serverdateisystem anhängen? +acl_candetach=Darf Dateianhänge im Serverdateisystem speichern? +acl_dir=Darf E-Mail-Dateien lesen in Verzeichnis +acl_dirauto=Entscheide automatisch (überall, wenn alle Benutzer sichtbar sind, ansonsten nirgends) +acl_faddrs=Aufgeführte Adressen +acl_fdom=Jede Adresse @ Domain +acl_fdoms=Mailbox @ Domains +acl_from=Adressen, die für Absenderadressen (FROM) erlaubt sind +acl_fromname=Realname für die Absenderadresse (FROM) +acl_none=Kein +acl_read=Benutzer, deren Post gelesen werden kann +acl_same=Benutzer mit dem gleichen Namen +acl_sec=Sekundäre Gruppen einbeziehen? +acl_sent=Speichere versendete E-Mail in E-Mailbox +acl_users=Nur diese Benutzer +acl_userse=Alle, außer diese Benutzer +acl_usersg=Mitglieder der Gruppen +acl_usersm=Benutzer passend zu/auf +acl_usersu=Mit UID im Bereich +black_already=Die E-Mail-Adresse $1 befindet sich bereits auf der Liste der durch SpamAssassin abgewiesenen Adressen +black_done=Die E-Mail-Adresse wurde der Liste der durch SpamAssassin abgewiesenen Adressen hinzugefügt. +black_title=Absender verbieten +compose_title=Schreibe E-Mail +confirm_ok=Lösche jetzt +confirm_title=Löschen bestätigen +confirm_warn=Sind Sie sicher, daß Sie die ausgewählten $1 E-Mails löschen wollen? +confirm_warn2=Aufgrund der Größe und des Formates Ihrer E-Mailbox wird dies ein wenig dauern. Während des Löschvorganges sollten keine anderen Aktionen stattfinden. Bitte ein wenig Geduld ... +confirm_warn3=Sind Sie sicher, daß Sie diese E-Mail löschen wollen? +confirm_warn4=Während des Löschvorganges sollten keine anderen Aktionen stattfinden. Bitte ein wenig Geduld ... +confirm_warnall=Sind Sie sicher, daß Sie alle E-Mails in diesem Ordner löschen wollen? +delete_ebnone=Es wurde keine E-Mail zum Ablehnen ausgewählt +delete_ecannot=Sie dürfen keine E-Mails von diesem Benutzer löschen +delete_ecopycannot=Sie dürfen keine E-Mails zu dem ausgewählten Benutzer kopieren +delete_ecopynone=Es wurde keine E-Mail für den Kopiervorgang ausgewählt. +delete_ecopyuser=Der Benutzer, zu dem Sie E-Mails kopieren wollen, existiert nicht +delete_efnone=Es wurde keine E-Mail für den Weiterleitungsvorgang ausgewählt. +delete_ehnone=Keine E-Mail wurde für den Report als Nicht-Spam ausgewählt +delete_emnone=Es wurde keine E-Mail für den Markierungsvorgang ausgewählt. +delete_emovecannot=Sie dürfen keine E-Mails zu dem ausgewählten Benutzer verschieben +delete_emovenone=Es wurde keine E-Mail für den Verschiebevorgang ausgewählt. +delete_emoveuser=Der Benutzer, zu dem Sie E-Mails verschieben wollen, existiert nicht +delete_enone=Es wurde keine E-Mail für den Löschvorgang ausgewählt. +delete_ereport=Konnte nicht als Spam melden : $1 +delete_ernone=Es wurde keine E-Mail für den Spam-Report ausgewählt +delete_errc=Konte E-Mail nicht kopieren +delete_errm=Konnte E-Mail nicht verschieben +delete_ewnone=Keine E-Mail wurde für die Whitelist ausgewählt +delete_nobutton=Es wurde kein Button angeklickt +delete_ok=Jetzt löschen +delete_rusure=Sind Sie sicher, daß Sie die ausgewählten $1 E-Mails aus/von $2 löschen wollen? Aufgrund der Größe und des Formates dieser E-Mailbox wird dies ein wenig dauern. Während des Löschvorganges sollten keine anderen Aktionen stattfinden. Bitte ein wenig Geduld ... +delete_rusure2=Sind Sie sicher, daß Sie diese E-Mail aus/von $1 löschen wollen? Aufgrund der Größe und des Formates dieser E-Mailbox wird dies ein wenig dauern. Während des Löschvorganges sollten keine anderen Aktionen stattfinden. Bitte ein wenig Geduld ... +delete_title=E-Mail löschen +detach_edir=Es wurden weder Datei noch ein Verzeichnis für den Speichervorgang ausgewählt. +detach_eopen=Fehler beim Öffnen von $1 : $2 +detach_err=Konnte Datei nicht abhängen/löschen +detach_ewrite=Fehler beim Schreibvorgang zu $1 : $2 +detach_ok=Der Dateianhang wurde auf dem Server in die folgende Datei gespeichert $1 ($2). +detach_title=Dateianhang speichern +emodified=Dieser Order wurde seit dem aktuellen Einlesen verändert! Kehren Sie zur Liste der E-Mails zurück und starten Sie erneut. +enew_title=E-Mail bearbeiten +find_enone=Es wurden keine Benutzer gefunden, die der Suchanfrage entsprechen +find_group=Gruppe +find_home=Heimatverzeichnis +find_real=Realname +find_results=Benutzer, die auf das Suchmuster $1 passen ... +find_size=E-Mail-Größe +find_title=Suchergebnisse +find_user=Benutzername +folder_drafts=Entwürfe +folder_inbox=Posteingang +folder_sent=Versendete E-Mail +folder_trash=Papierkorb +forward_title=E-Mail weiterleiten +ham_report=Diese Nachricht wird als Nicht-Spam an Razor und andere SpamAssassin-Datenbanken gemeldet .. +ham_title=Als Nicht-Spam melden +index_contains=beinhaltet +index_empty=Keine E-Mail +index_eperl=Das Perl-Modul $1, welches für den ausgewählten SMTP-Authentisierungsmodus nötig ist, ist nicht installiert oder es fehlt ein zur Ausführung abhängiges Modul. Klicken Sie hier um dieses zu installieren. +index_equals=ist gleich +index_esystem=Keiner der unterstützten E-Mailserver (Qmail, Postfix und Sendmail) wurde auf Ihrem System gefunden. Sie müssen die Modulkonfiguration manuell anpassen und dort den E-Mailserver und die zugehörigen Serverpfade eintragen. +index_esystem2=Der in der Modulkonfiguration gesetzte E-Mailserver wurde auf ihrem System nicht gefunden. Sie müssen dort die Konfiguration so anpassen, daß der richtige E-Mailserver benutzt wird. +index_file=Lese E-Mail in Datei: +index_find=Finde Benutzer deren Benutzername +index_header=Benutzer-E-Mailboxen +index_none=Sie dürfen die E-Mails der Benutzer auf diesem System nicht lesen. +index_return=Benutzerliste +index_system0=E-Mailserver: Postfix +index_system1=E-Mailserver: Sendmail +index_system2=E-Mailserver: Qmail +index_title=Lese Benutzer-E-Mail +index_toomany=Es gibt mehr Benutzer auf Ihrem System, als hier angezeigt werden können. +ldap_econn=Fehler beim Verbinden zum LDAP-Server $1 Port $2 +ldap_elogin=Konnte nicht zum LDAP-Server $1 als $2 verbinden : $3 +ldap_emod=Das fehlende Perl-Modul $1 wird benötigt, um sich via LDAP zu verbinden +log_copymail=Es wurden $1 E-Mails von $2 nach $3 kopiert +log_delmail=Es wurden $1 E-Mails von $2 gelöscht +log_movemail=Es wurden $1 E-Mails von $2 nach $3 kopiert +log_read=Lese E-Mail für $1 +log_send=Es wurde eine E-Mail nach $1 versandt. +mail_addresses=Adressbuch bearbeiten +mail_advanced=Erweiterte Suche +mail_all=Alle auswählen +mail_bcc=Bcc +mail_black=Absender blockieren +mail_body=Textkörper +mail_cc=Cc +mail_compose=Schreiben +mail_copy=Kopieren nach: +mail_crypt=GnuPG-Verschlüsselung für: +mail_date=Datum +mail_delall=Alle löschen +mail_delete=Löschen +mail_deleteall=Alles löschen +mail_deltrash=Papierkorb leeren +mail_ecannot=Sie dürfen die E-Mails von diesem Benutzer nicht lesen +mail_eexists=Die E-Mail existiert nicht mehr. Eventuell wurde Sie in der Zwischenzeit via POP3 abgerufen oder anderweitig von einem berechtigtem Benutzer gelöscht/verschoben. +mail_efile=Die E-Mail-Datei existiert nicht +mail_err=Beim Auflisten der E-Mails in diesem Ordner ist ein Fehler aufgetreten : $1 +mail_fchange=Ändern +mail_folder=Ordner +mail_folders=Ordner bearbeiten +mail_for=In $1 +mail_for2=Für Benutzer $1 +mail_forward=Weiterleiten +mail_from=Von +mail_fromsrch=Gleicher Absender .. +mail_high=Hoch +mail_highest=Höchste +mail_indexlink=Zurück zur E-Mailbox +mail_invert=Auswahl umkehren +mail_jump=Springe zu Seite : +mail_login=Login +mail_logindesc=Sie müssen Benutzername und Passwort eingeben,
um Ihren Posteingang auf dem E-Mailserver $1 einsehen zu können. +mail_loginheader=POP3-Server-Login +mail_loginmailbox=IMAP E-Mailbox +mail_loginpass=Passwort +mail_loginuser=Benutzername +mail_logout=Ändere POP3-Login +mail_logout2=Ändere IMAP-Login +mail_low=Niedrig +mail_lowest=Niedrigste +mail_mark=Markiere als: +mail_mark0=Ungelesen +mail_mark1=Gelesen +mail_mark2=Spezial +mail_match=passt auf +mail_move=Verschieben nach: +mail_nocrypt=<Nicht verschlüsseln> +mail_none=Dieser Benutzer hat keine E-Mails in $1 +mail_nonefrom=Kein +mail_normal=Normal +mail_nosign=<Nicht signieren> +mail_of=von +mail_ok=Suche +mail_pos=E-Mails $1 bis $2 von $3 in $4 +mail_pri=Priorität +mail_replyto=Antworten an +mail_reset=Löschen +mail_return=Benutzer-E-Mailbox +mail_return2=Benutzer-E-Mail +mail_rfc=From-Zeile +mail_samecrypt=<Schlüssel der Zieladressen> +mail_search=Finde E-Mails wo +mail_search2=Suche nach: +mail_sent=In <Versendete E-Mail<-Liste +mail_sig=Bearbeite Signatur +mail_sign=Unterschreibe mit GnuPG-Schlüssel +mail_size=Größe +mail_subject=Betreff +mail_subsrch=Gleicher Betreff .. +mail_title=Benutzer-E-Mail +mail_to=An +mail_tosrch=Gleicher Empfänger .. +mail_white=Erlaube Absender +razor_deleted=.. erledigt. Die E-Mail wurde gelöscht. +razor_done=.. erledigt +razor_err=.. gescheitert! Oben sehen Sie warum. +razor_report=Diese Nachricht wird sowohl der Razor- als auch anderen durch SpamAssassin genutzten Anti-Spam-Datenbanken gemeldet. +razor_title=Als Spam melden +reply_attach=Weitergeleitete Anhänge +reply_attach2=Client- und serverseitige Anhänge +reply_body=E-Mail-Text +reply_draft=Speichern als Entwurf +reply_ecannot=Sie dürfen keine E-Mails im Namen dieses Benutzers versenden +reply_errc=Konnte E-Mail nicht kopieren +reply_errm=Konnte E-Mail nicht verschieben +reply_headers=E-Mail-Header +reply_mailforward=Weitergeleitete E-Mails +reply_send=E-Mail versenden +reply_spell=Auf Rechtschreibfehler prüfen? +reply_title=Auf E-Mail antworten +search_all=In allen Ordnern +search_allstatus=Jede +search_ecannot=Sie dürfen die E-Mail dieses Benutzers nicht durchsuchen +search_efield=Sie müssen eine Such-/Abfrageart angeben. +search_elatest=Fehlende oder ungültige Anzahl an E-Mails für die Suche +search_ematch=Sie müssen einen Text für die Suche/Abfrage angeben. +search_enone=Sie haben keinerlei Suchkriterien angegeben +search_ewhat=Sie haben keinen Text für die Suche/Abfrage der Spalte $1 angeben. +search_latest=Zu durchsuchende E-Mails +search_latestnum=Nur die neuesten +search_limit=(der letzten $1 E-Mails) +search_local=In lokalen Ordnern +search_nolatest=Alle im Ordner +search_none=Es wurden keine E-Mails gefunden. +search_onestatus=Nur Status +search_results2=$1 E-Mails passen auf $2 +search_results3=$1 E-Mails passen nicht auf $2 +search_results4=$1 E-Mails passen auf Ihre Suchanfrage +search_status=Mit Status +search_title=Suchergebnisse +search_withstatus=, mit Status $1 +send_draft=Die E-Mail an $1 wurde als Entwurf gespeichert. +send_eattach=Die Dateianhänge dürfen zusammen nicht mehr als $1 KiB groß sein. +send_eattachsize=Die Dateianhänge überschreiten die maximal erlaubte Größe von $1 bytes. +send_ecannot=Sie dürfen im Namen dieses Benutzers keine E-Mail versenden +send_ecrypt=Konnte E-Mail nicht verschlüsseln : $1 +send_efile=Konnte Dateianhänge nicht lesen $1 : $2 +send_efrom=Fehlende Absenderadresse (FROM) +send_ekey=Konnte den Schlüssel für die E-Mail-Adresse $1 nicht finden +send_eline=In Zeile $1: +send_epass=Sie können diese E-Mail nicht signieren, da Sie noch keine Passphrase im GnuPG-Modul hinterlegt haben. +send_epath=Das Sendmail-Binary $1 existiert nicht. +send_eperms=Benutzer $1 kann $2 nicht lesen +send_eperms2=Sie dürfen die Datei $1 nicht versenden +send_err=Konnte E-Mail nicht versenden +send_esign=Konnte E-Mail nicht signieren : $1 +send_esmtp=SMTP-Kommando $1 gescheitert : $2 +send_espell=Die folgenden Rechtschreibefehler wurden in Ihrer E-Mail gefunden .. +send_eto=Fehlende Empfängeradresse (TO) +send_eword=Falsch geschriebenes Wort $1 +send_eword2=Falsch geschriebenes Wort $1 - Mögliche Korrektur $2 +send_ok=E-Mail erfolgreich versandt an $1 +send_title=E-Mail versandt +sform_all=<Alle Ordner> +sform_and=Finde E-Mails bei denen folgende Kriterien zutreffen ... +sform_body=E-Mail-Textkörper +sform_cc=Cc:-Zeile +sform_date=Datum:-Zeile +sform_folder=in Ordner(n) +sform_from=From:-Zeile +sform_headers=Jegliche Header-Zeile +sform_local=<Lokale Ordner> +sform_neg0=beinhaltet +sform_neg1=beinhaltet nicht +sform_ok=Jetzt suchen +sform_or=Finde E-Mails, wo irgendeine der folgenden Kritierien zutreffen .. +sform_return=Erweitertes Suchformular +sform_size=Nachrichtengröße +sform_subject=Betreff:-Zeile +sform_text=den Text +sform_title=Erweiterte Suche +sform_to=To:-Zeile +sform_where=Wo +view_allheaders=Zeige alle E-Mail-Header an +view_ashtml=Zeige E-Mail als HTML an (Kann gefährlich sein!) +view_astext=Zeige E-Mail als Text an (Explizit empfohlen) +view_attach=Dateianhänge +view_black=Diesen Absender in die Blacklist aufnehmen! +view_body=E-Mail-Text +view_crypt=GnuPG-E-Mail-Entschlüsselung +view_crypt_1=Diese E-Mail ist verschlüsselt, jedoch wurde GnuPG nicht gefunden oder es ist nicht richtig installiert. +view_crypt_2=Konnte E-Mail nicht entschlüsseln : $1 +view_crypt_3=E-Mail erfolgreich entschlüsselt. +view_crypt_4=Der verschlüsselte Anteil dieser E-Mail wurde erfolgreich entschlüsselt. +view_dall=<Alle Dateien> +view_delete=Löschen +view_desc=E-Mail $1 in $2 +view_desc2=E-Mail $1 des Benutzers $2 +view_desc3=E-Mails $1 +view_detach=Dateianhang speichern: +view_diagnostic-code=Grund des Fehlers +view_dir= in eine Serverdatei oder -Verzeichnis: +view_dstatus=Status des gescheiterten Versands +view_dstatusok=Erfolgreicher Übertragungsstatus +view_ecannot=Sie dürfen die E-Mails dieses Benutzers nicht lesen +view_egone=Die E-Mail existiert nicht mehr. Eventuell wurde Sie in der Zwischenzeit via POP3 abgerufen oder anderweitig von einem berechtigtem Benutzer gelöscht/verschoben. +view_enew=Als neu bearbeiten +view_final-recipient=Entgültiger Empfänger +view_folder=Zurück zur E-Mailbox +view_forward=Weiterleiten +view_gnupg=GnuPG-Signatur-Überprüfung +view_gnupg_0=Die Signatur von $1 ist gültig. +view_gnupg_1=Die Signatur von $1 ist gültig, aber es konnte kein Vertrauensstatus erkannt werden. +view_gnupg_2=Die Signatur von $1 ist NICHT gültig. +view_gnupg_3=Die Schlüssel-ID $1 ist nicht in Ihrer Liste, ergo kann keine GnuPG-Signatur-Überprüfung statfinden. +view_gnupg_4=Konnte Signatur nicht überprüfen : $1 +view_ham=Als Nicht-Spam melden +view_headers=E-Mail-Header +view_mark=Markiere als: +view_mark0=Ungelesen +view_mark1=Gelesen +view_mark2=Spezial +view_noheaders=Einfache Headeranzeige +view_print=Drucken +view_qdesc=E-Mail $1 in Warteschlange +view_raw=Zeige Nachricht im Rohformat an +view_razor=Als Spam melden +view_razordel=Spam-Report und Löschen +view_recv=Hole Schlüssel-ID $1 vom Keyserver. +view_remote-mta=Entfernter E-Mail-Server +view_reply=Anworten +view_reply2=Allen antworten +view_reporting-mta=Berichtender E-Mail-Server +view_return=Original-E-Mail +view_sent=E-Mail $1 in "Versendete E-Mail"-Liste +view_strip=Entferne Dateianhänge +view_sub=Angehängte E-Mail(s) +view_title=E-Mail lesen +view_white=Erlaube Absender +white_already=Die E-Mail-Adresse $1 befindet sich bereits in der Whitelist von SpamAssassin. +white_done=Die E-Mail-Adresse $1 wurde der Whitelist von SpamAssassin hinzugefügt. +white_title=Erlaube Absender diff --git a/mailboxes/lang/en b/mailboxes/lang/en new file mode 100644 index 000000000..bdb5b96bd --- /dev/null +++ b/mailboxes/lang/en @@ -0,0 +1,383 @@ +index_title=Read User Mail +index_none=You are not allowed to read email for any users on this system. +index_header=User mailboxes +index_empty=No mail +index_return=user list +index_esystem=None of the supported mail servers (Qmail, Postfix and Sendmail) were detected on your system. You will need to adjust the module configuration to set the mail server and possibly mail paths manually. +index_esystem2=The mail server set in the module configuration was not found on your system. You will need to adjust the configuration to use the correct server. +index_esystem3=An error occurred contacting the mail system set in the module configuration : $2. +index_system2=Mail server: Qmail +index_system1=Mail server: Sendmail +index_system0=Mail server: Postfix +index_toomany=There are too many users on your system to display on one page. +index_find=Find users where username +index_equals=equals +index_contains=contains +index_eperl=The Perl module $1 needed for the selected SMTP authentication mode is not installed or is missing a dependent module. Click here to install it now. +index_file=Read Mail in File: +index_nousers=No users were found! +index_nousersmail=No users with email were found. + +mail_title=User Email +mail_from=From +mail_date=Date +mail_subject=Subject +mail_to=To +mail_cc=Cc +mail_bcc=Bcc +mail_pri=Priority +mail_highest=Highest +mail_high=High +mail_normal=Normal +mail_low=Low +mail_lowest=Lowest +mail_for=In $1 +mail_for2=For user $1 +mail_sent=In sent mail list +mail_size=Size +mail_level=Score +mail_delete=Delete +mail_compose=Compose +mail_open=Open +mail_return=user mailbox +mail_pos=Messages $1 to $2 of $3 in $4 +mail_none=This user has no messages in $1 +mail_ecannot=You are not allowed to read this user's email +mail_all=Select all. +mail_invert=Invert selection. +mail_nosort=Reset sorting. +mail_search=Find messages where +mail_body=Body +mail_match=matches +mail_ok=Search +mail_nonefrom=None +mail_mark=Mark as: +mail_mark0=Unread +mail_mark1=Read +mail_mark2=Special +mail_forward=Forward +mail_move=Move to: +mail_copy=Copy to: +mail_rfc=From line +mail_eexists=Message no longer exists! +mail_fchange=Change +mail_indexlink=Return to mailbox +mail_deleteall=Delete All +mail_black=Deny Senders +mail_white=Allow Senders +mail_efile=Mail file does not exist +mail_fromsrch=Same sender.. +mail_subsrch=Same subject.. +mail_tosrch=Same recipient.. +mail_unknown=Unknown + +mail_sign=Sign with key +mail_nosign=<Don't sign> +mail_crypt=Encrypt for +mail_nocrypt=<Don't encrypt> +mail_samecrypt=<Keys from destination addresses> +mail_addresses=Manage Address Book +mail_folders=Manage Folders +mail_err=An error occurred listing mail in this folder : $1 +mail_loginheader=POP3 server login +mail_loginheader2=IMAP server login +mail_logindesc=You must enter a username and password to access mail
in your inbox on the mail server $1. +mail_loginuser=Username +mail_loginpass=Password +mail_loginmailbox=IMAP mailbox +mail_login=Login +mail_reset=Clear +mail_logout=Change POP3 login +mail_logout2=Change IMAP login +mail_sig=Edit Signature +mail_jump=Jump to page : +mail_of=of +mail_replyto=Reply to +mail_folder=Folder +mail_delall=Delete All +mail_deltrash=Empty Trash +mail_search2=Search for: +mail_search3=Find with score above: +mail_advanced=Advanced Search +mail_return2=User Email +mail_esystem=An error occurred contacting the mail system : $1. This must be fixied by the system administrator. + +view_title=Read Email +view_desc=Message $1 in $2 +view_desc2=Message $1 for user $2 +view_desc3=Message $1 +view_sent=Message $1 in sent mail list +view_qdesc=Queued message $1 +view_headers=Mail headers +view_body=Message text +view_allheaders=View all headers +view_noheaders=View basic headers +view_attach=Attachments +view_reply=Reply +view_reply2=Reply to all +view_enew=Edit as new +view_forward=Forward +view_delete=Delete +view_print=Print +view_strip=Remove Attachments +view_ecannot=You are not allowed to read this user's email +view_mark=Mark as: +view_mark0=Unread +view_mark1=Read +view_mark2=Special +view_return=original email +view_sub=Attached Email +view_egone=This message no longer exists +view_eugone=This user does not exist + +view_gnupg=GnuPG signature verification +view_gnupg_0=Signature by $1 is valid. +view_gnupg_1=Signature by $1 is valid, but trust chain could not be established. +view_gnupg_2=Signature by $1 is NOT valid. +view_gnupg_3=Key ID $1 is not in your list, so signature could not be verified. +view_gnupg_4=Failed to verify signature : $1 +view_crypt=GnuPG mail decryption +view_crypt_1=Message is encrypted, but GnuPG support is not installed. +view_crypt_2=Failed to decrypt message : $1 +view_crypt_3=Mail was successfully decrypted. +view_crypt_4=Encrypted portion of message was successfully decrypted. +view_recv=Fetch key ID $1 from keyserver. +view_folder=Return to mailbox +view_detach=Detach file: +view_dall=<All files> +view_dir=to server file or directory: +view_black=Deny Sender +view_white=Allow Sender +view_razor=Report As Spam +view_ham=Report As Ham +view_razordel=Report and Delete Spam +view_dstatus=Failed delivery status +view_dstatusok=Successful delivery status +view_final-recipient=Final recipient +view_diagnostic-code=Reason for failure +view_remote-mta=Remote mail server +view_reporting-mta=Reporting mail server +view_astext=View as text +view_ashtml=View as HTML +view_raw=View raw message + +compose_title=Compose Email + +reply_title=Reply to Email +forward_title=Forward Email +enew_title=Edit Email +reply_headers=Mail headers +reply_attach=Forwarded attachments +reply_mailforward=Forwarded messages +reply_attach2=Client and server-side attachments +reply_attach3=Uploaded attachments +reply_send=Send Mail +reply_ecannot=You are not allowed to send mail as this user +reply_body=Message text +reply_errc=Failed to copy mail +reply_errm=Failed to move mail +reply_return=compose mail +reply_efwdnone=None of the forwarded messages exist + +reply_spell=Check for spelling errors? +reply_draft=Save as Draft + +send_err=Failed to send mail +send_eto=Missing To address +send_efrom=Missing From address +send_esubject=Missing email subject +send_title=Mail Sent +send_ok=Mail sent successfully to $1 +send_sending=Sending mail to $1 .. +send_ecannot=You are not allowed to send mail as this user +send_esmtp=SMTP command $1 failed : $2 +send_eattach=Attachments cannot total more that $1 kB in size. +send_eperms=User $1 cannot read $2 +send_eperms2=You are not allowed to send file $1 +send_epath=Sendmail executable $1 does not exist. +send_efile=Failed to read attachment $1 : $2 +send_done=.. done. + +send_epass=You cannot sign a message because your passphrase has not be setup yet in the GnuPG module. +send_esign=Failed to sign message : $1 +send_ekey=Couldn't find key for email address $1 +send_ecrypt=Failed to encrypt message : $1 +send_eword=Misspelt word $1 +send_eword2=Misspelt word $1 - possible corrections $2 +send_eline=In line $1 : +send_espell=The following spelling errors were found in your message .. +send_draft=Mail to $1 saved in drafts folder. +send_drafting=Saving mail to $1 in drafts folder .. +send_eattachsize=The mail attachment exceeded the maximum allowed size of $1 bytes + +delete_title=Delete Mail +delete_rusure=Are you sure you want to delete the $1 selected messages from $2? This may take some time for a large mail file. Until the deletion has finished, no other action should be performed. +delete_rusure2=Are you sure you want to delete this message from $1? This may take some time for a large mail file. Until the deletion has finished, no other action should be performed. +delete_ok=Delete Now +delete_ecannot=You are now allowed to delete mail from this user +delete_enone=No mail selected to delete +delete_emnone=No mail selected to mark +delete_efnone=No mail selected to forward +delete_ebnone=No mail selected to deny +delete_ewnone=No mail selected to allow +delete_ernone=No mail selected to report as spam +delete_ehnone=No mail selected to report as ham +delete_emoveuser=User to move mail to does not exist +delete_ecopyuser=User to copy mail to does not exist +delete_emovecannot=You are not allowed to move mail to the specified user +delete_ecopycannot=You are not allowed to copy mail to the specified user +delete_emovenone=No mail selected to move +delete_ecopynone=No mail selected to copy +delete_nobutton=No button clicked +delete_ereport=Failed to report as spam : $1 +delete_errc=Failed to copy mail +delete_errm=Failed to move mail + +confirm_title=Confirm Delete +confirm_warn=Are you sure you want to delete the $1 selected messages? +confirm_warn2=Because of the size and format of your mailbox, this may take some time. Until the deletion has finished, no other action should be performed. +confirm_warn3=Are you sure you want to delete this message? +confirm_warn4=Until the deletion has finished, no other action should be performed. +confirm_ok=Delete Now +confirm_warnall=Are you sure you want to delete all of the messages in this folder? + +search_title=Search Results +search_ecannot=You are not allowed to search this user's email +search_ematch=You must enter text to match against. +search_escore=Missing or invalid spam score +search_efield=You must select a search type. +search_ewhat=No text to match against entered for row $1 +search_enone=No search criteria entered +search_none=No messages found. +search_results2=$1 mail messages matching $2 +search_results3=$1 mail messages not matching $2 +search_results4=$1 mail messages matching your search +search_results5=$1 mail messages where $2 matches $3 +search_msg2=Search results for $1 +search_msg4=Search results +search_msg5=Search results for spam with score $1 +search_local=In local folders +search_all=In all folders +search_limit=(from last $1 messages) +search_status=With status +search_allstatus=Any +search_onestatus=Only status +search_latest=Messages to search +search_nolatest=All in folder +search_latestnum=Only latest +search_elatest=Missing or invalid number of messages to search +search_withstatus=, with status $1 + +folder_inbox=Inbox +folder_sent=Sent mail +folder_drafts=Drafts +folder_trash=Trash + +detach_err=Failed to detach file +detach_edir=No file or directory to save to entered +detach_eopen=Failed to open $1 : $2 +detach_ewrite=Failed to write to $1 : $2 +detach_title=Detach File +detach_ok=Wrote attachment to server-side file $1 ($2). + +sform_title=Advanced Search +sform_and=Find messages matching all criteria below .. +sform_or=Find messages matches any criteria below .. +sform_neg0=contains +sform_neg1=doesn't contain +sform_ok=Search Now +sform_folder=in folder(s) +sform_all=<All folders> +sform_local=<Local folders> +sform_where=Where +sform_text=the text +sform_from=From: header +sform_subject=Subject: header +sform_to=To: header +sform_cc=Cc: header +sform_bcc=Bcc: header +sform_date=Date: header +sform_body=message body +sform_headers=any header +sform_size=message size +sform_return=advanced search form + +find_enone=No users matching your search were found +find_title=Search Results +find_results=Users matching search for $1 .. +find_user=Username +find_real=Real name +find_group=Group +find_home=Home directory +find_size=Mail size +find_incount=Emails +find_sentcount=Sent +find_fcount=Folders +find_in=$1 in $2 + +acl_none=None +acl_same=User with same name +acl_all=All +acl_read=Users whose mail can be read +acl_users=Only users +acl_userse=All except users +acl_usersg=Members of groups +acl_from=Allowable From addresses +acl_any=Any address +acl_fdoms=Mailbox @ domains +acl_faddrs=Listed addresses +acl_fdom=Any address @ domain +acl_fromname=Real name for From address +acl_apath=Limit files and program to directory +acl_attach=Maximum total attachments size +acl_unlimited=Unlimited +acl_sent=Store sent mail in mailbox +acl_canattach=Can attach server-side files? +acl_candetach=Can detach files to server? +acl_usersm=Users matching +acl_asame=Same as username +acl_usersu=With UID in range +acl_sec=Include secondary groups? +acl_dir=Can read mail files in directory +acl_dirauto=Decide automatically (anywhere if all users are visible, nowhere otherwise) + +log_delmail=Deleted $1 messages from $2 +log_movemail=Moved $1 messages from $2 to $3 +log_copymail=Copied $1 messages from $2 to $3 +log_send=Sent mail to $1 +log_read=Read mail for $1 + +emodified=This folder has been modified since it was last viewed! Return to the mail list and try again. + +razor_title=Reporting As Spam +razor_title2=Reporting As Ham +razor_report=Reporting this message to Razor and other SpamAssassin spam-blocking databases .. +razor_report2=Reporting the selected messages to Razor and other SpamAssassin spam-blocking databases .. +razor_report3=Un-reporting the seleected messages to Razor and other SpamAssassin spam-blocking databases .. +razor_done=.. done +razor_err=.. failed! See the error message above for the reason why. +razor_deleted=.. done, and deleted message too. + +ham_title=Reporting As Ham +ham_report=Reporting this message as non-spam to Razor and other SpamAssassin databases .. + +black_title=Denying Sender +black_done=Added the email address $1 to SpamAssassin's denied addresses list. +black_already=The email address $1 is already on SpamAssassin's denied addresses list. + +white_title=Allowing Sender +white_done=Added the email address $1 to SpamAssassin's allowed addresses list. +white_already=The email address $1 is already on SpamAssassin's allowed addresses list. + +ldap_emod=Missing Perl module $1 needed for connecting to LDAP +ldap_econn=Failed to connect to LDAP server $1 port $2 +ldap_elogin=Failed to bind to LDAP server $1 as $2 : $3 +ldap_ehost=No LDAP server set in module configuration +ldap_eport=No valid LDAP server port set in module configuration +ldap_euser=No LDAP login set in module configuration +ldap_ebase=No LDAP base DN set in module configuration + +delall_title=Delete All Mail +delall_rusure=Are you sure you want to delete all email from $1? $2 messages totalling $3 will be deleted forever. +delall_ok=Delete Now + diff --git a/mailboxes/lang/es b/mailboxes/lang/es new file mode 100644 index 000000000..671c51d57 --- /dev/null +++ b/mailboxes/lang/es @@ -0,0 +1,102 @@ +mail_title=Correo de Usuario +mail_from=Desde +mail_date=Fecha +mail_subject=Asunto +mail_to=Para +mail_pri=Prioridad +mail_highest=La mayor +mail_high=Alta +mail_low=Baja +mail_lowest=La más baja +mail_for=En $1 +mail_for2=Para usuario $1 +mail_sent=En lista de correo enviado +mail_size=Medida +mail_delete=Borrar mensajes seleccionados +mail_compose=Componer nuevo correo +mail_return=correo de usuario +mail_ecannot=No estás autorizado a leer el correo de este usuario +mail_all=Seleccionar todos +mail_invert=Invertir selección +mail_search=Hallar mensajes donde +mail_body=Cuerpo +mail_match=que coincida con +mail_ok=Buscar +mail_nonefrom=Ninguno +mail_mark=Marcar los seleccionados como: +mail_mark0=No leídos +mail_mark1=Leídos +mail_mark2=Especiales +mail_forward=Remitir seleccionado +mail_rfc=Desde línea +view_title=Leer Correo +view_desc=Mensaje $1 en $2 +view_desc2=Mensaje $1 para usuario $2 +view_desc3=Mensaje $1 +view_sent=Mensaje $1 en lista de corre enviado +view_qdesc=Mensaje en cola $1 +view_headers=Cabeceras de Correo +view_allheaders=Ver todas las cabeceras +view_noheaders=Ver cabeceras básicas +view_attach=Adjuntados +view_reply=Responder +view_reply2=Reponder a todos +view_enew=Editar como nuevo +view_forward=Remitir a +view_delete=Borrar +view_strip=Quitar Adjuntados +view_ecannot=No estás autorizado a leer el correo de este usuario +view_mark0=No leído +view_mark1=Leído +view_mark2=Especial +view_return=correo original +view_sub=Correo Adjunto +compose_title=Componer Correo +reply_title=Responder a Correo +forward_title=Remitir Correo +reply_headers=Cabeceras de Correo +reply_attach=Adjuntados remitidos +reply_mailforward=Mensajes remitidos +reply_attach2=Adjuntados desde cliente y servidor +reply_send=Enviar Correo +reply_ecannot=No estás autorizado a enviar correo a este usuario +send_err=Error al enviar correo +send_eto=Dirección 'A' sin poner +send_efrom=Dirección 'De' sin poner +send_title=Correo enviado +send_ok=Correo enviado correctamente a $1 +send_ecannot=No estás autorizado a enviar correo como este usuario +send_esmtp=Ha fallado el comando SMTP $1 : $2 +send_eattach=Los archivos incluídos no pueden exceder más de 1kB de medida +send_eperms=El usuario $1 no puede leer $2 +send_eperms2=No estás autorizado a enviar archivo $1 +send_epath=El ejecutable de Sendmail $1 no existe. +delete_ecannot=No estás autorizado a borrar correo de este usuario +delete_enone=No se ha seleccionado correo para ser borrado +delete_emnone=No hay correo seleccionado para marcar +search_title=Resultados de la búsqueda +search_ecannot=No estás autorizado a buscar en este correo de usuario +search_ematch=Debes de digitar un texto que coincida con algo. +search_none=No se han encontrado mensajes. +search_results3=$1 mensajes de correo no coinciden con $2 +acl_none=Ninguno +acl_same=Usuario con mismo nombre +acl_all=Todos +acl_read=Usuarios cuyo correo puede ser leído +acl_users=Usuarios +acl_userse=Todos excepto los usuarios +acl_usersg=Miembros de grupo +acl_from=Direcciones 'desde' autorizadas +acl_any=Cualquier dirección +acl_fdoms=Buzones en dominios +acl_faddrs=Direcciones listadas +acl_fdom=Cualquier dirección en dominio +acl_fromname=Nombre real para dirección remitente +acl_apath=Limitar archivos y programa a directorio +acl_attach=Medida máxima total de archivos a incluir +acl_sent=Almacenar correo enviado en buzón +acl_canattach=¿Puede adjuntar archivos del lado servidor? +acl_usersm=Usuarios que coincidan +acl_asame=Igual que nombre de usuario +log_delmail=Borrados $1 mensajes de $2 +log_send=Enviado correo a $1 diff --git a/mailboxes/lang/fr b/mailboxes/lang/fr new file mode 100644 index 000000000..dd1bffbfe --- /dev/null +++ b/mailboxes/lang/fr @@ -0,0 +1,105 @@ +acl_all=Tous +acl_any=De toutes les adresses +acl_faddrs=Adresses listées +acl_fdom=Toutes les adresses d'un domaines +acl_fdoms=Boîte aux lettres des domaines +acl_from=Des adresses +acl_none=Aucun +acl_read=Usagers dont les courriers peuvent être lu +acl_users=Seulement les usagers +acl_userse=Tous +compose_title=Écrire un Courrier +confirm_ok=Effacer maintenant +confirm_title=Confirmer la suppression +confirm_warn=Etes vous sur de vouloir supprimer les $1 messages sélectionnées? +confirm_warn3=Etes vous sur de vouloir supprimer ce message? +confirm_warn4=Jusqu'à la fin de l'effacement, aucune autre action ne peut êtes faite. +confirm_warnall=Etes vous sûr de vouloir supprimer tous les messages de ce dossier? +delete_ecannot=Vous n'êtes pas autorisé à supprimer les courriers de cet usager +delete_ecopynone=Aucun message à copier sélectionner +delete_efnone=Aucun message à transmettre sélectionné +delete_emnone=Aucun message à marquer sélectionné +delete_emovenone=Aucun message à déplacer sélectionné +delete_enone=Aucun mail à effacer sélectionné +delete_ernone=Aucun mail à raporter comme spam sélectionné +delete_ok=Effacer maintenant +delete_title=Effacer le message +detach_title=Sauver les fichiers +enew_title=Editer le message +find_size=Taille du message +forward_title=Rediriger un Courrier +index_header=Boîtes aux lettres des usagers +index_return=liste des utilisateurs +index_system0=Serveur mail : Postfix +index_system1=Serveur mail : Sendmail +index_system2=Serveur mail : Qmail +index_title=Lire les mails des usagers +mail_all=Selectionner tout +mail_cc=Copie carbone +mail_compose=Écrire un nouveau courrier +mail_copy=Copier vers: +mail_delall=Tout supprimer +mail_delete=Supprimer les messages sélectionnés +mail_deleteall=Tout supprimer +mail_ecannot=Vous n'êtes pas autorisé à lire les courriers des usagers +mail_for=Dans $1 +mail_forward=Transmettre +mail_from=De +mail_invert=Selectioner l'inverse +mail_mark=Marqué comme: +mail_mark0=Non lu +mail_mark1=Lu +mail_mark2=Spécial +mail_move=Déplacer vers: +mail_of=sur +mail_ok=Chercher +mail_pri=Priorité +mail_replyto=Répondre à +mail_reset=Effacer +mail_return=courrier de l'usager +mail_size=Taille +mail_subject=Sujet +mail_title=Courrier de l'Usager +mail_to=À +razor_done=.. fait +razor_title=Rapporter comme Spam +reply_attach=Attachement envoyé +reply_attach2=Attachements +reply_body=Corps du message +reply_draft=Sauver comme brouillon +reply_ecannot=Vous n'êtes pas autorisé à envoyer un courrier de cet usager +reply_headers=Entêtes du courrier +reply_send=Envoyer +reply_title=Répondre au Courrier +send_ecannot=Vous n'êtes pas autorisé à envoyer un courrier de cet usager +send_efrom=Adresse de l'émetteur manquant +send_err=Impossible d'envoyer le courrier +send_esmtp=Impossible d'exécuter la commande SMTP $1 : $2 +send_eto=Adresse du destinataire manquante +send_ok=Courrier envoyé avec succès à $1 +send_title=Courrier Envoyé +view_allheaders=Voir toutes les entêtes +view_ashtml=Voir en HTML +view_astext=Voir en Texte +view_attach=Attachements +view_black=Refuser l'expéditeur +view_delete=Supprimer +view_desc=Courrier $1 dans $2 +view_detach=Sauver les fichiers: +view_dir=dans le répertoire: +view_ecannot=Vous n'êtes pas autorisé à lire les courriers des usagers +view_forward=Renvoyer +view_headers=Entêtes du courrier +view_mark=Marqué comme: +view_mark0=Non lu +view_mark1=Lu +view_mark2=Spécial +view_print=Imprimer +view_qdesc=Courrier $1 de la file d'attente +view_razor=Rapporter comme Spam +view_razordel=Rapporter et Supprimer +view_reply=Répondre +view_reply2=Répondre à tous +view_return=email original +view_strip=Supprimer les pièces jointes +view_title=Lire un Courrier diff --git a/mailboxes/lang/it b/mailboxes/lang/it new file mode 100755 index 000000000..4205b9539 --- /dev/null +++ b/mailboxes/lang/it @@ -0,0 +1,353 @@ +index_title=Read Utente Mail +index_none=You are not allowed to read email for any utenti on questo system. +index_header=Utente mailboxes +index_empty=No mail +index_return=utente list +index_esystem=None of the supported mail servers (Qmail, Postfix and Sendmail) were detected on your system. You will need to adjust the module configuration to set the mail server and possibly mail paths manually. +index_esystem2=The mail server set in the module configuration was not found on your system. You will need to adjust the configuration to use the correct server. +index_system2=Mail server: Qmail +index_system1=Mail server: Sendmail +index_system0=Mail server: Postfix +index_toomany=There are too many utenti on your system to display on one pagina. +index_find=Cerca utenti where nome utente +index_equals=uguale +index_contains=contiene +index_eperl=The Perl module $1 needed for the selected SMTP authentication mode is not installed or is missing a dependent module. Click here to install it now. +index_file=Leggi posta nel file: + +mail_title=Utente Email +mail_from=Da +mail_date=Data +mail_subject=Oggetto +mail_to=To +mail_cc=Cc +mail_bcc=Bcc +mail_pri=Priorità +mail_highest=Più alta +mail_high=Alta +mail_normal=Normale +mail_low=Bassa +mail_lowest=Più bassa +mail_for=In $1 +mail_for2=For utente $1 +mail_sent=Nella lista inviate +mail_size=Dimensione +mail_delete=Elimina +mail_compose=Scrivi +mail_open=Apri +mail_return=utente mailbox +mail_pos=Messaggi da $1 a $2 di $3 in $4 +mail_none=questo utente non ha messaggi in $1 +mail_ecannot=non hai i permessi per leggere la posta di questo utente +mail_all=Seleziona tutti +mail_invert=Selezione invertita +mail_nosort=Annulla ordinamento +mail_search=Cerca messaggi dove +mail_body=Corpo +mail_match=corrisponde +mail_ok=Cerca +mail_nonefrom=nessuno +mail_mark=Segna come: +mail_mark0=Non letto +mail_mark1=Letto +mail_mark2=Speciale +mail_forward=inoltra +mail_move=sposta in: +mail_copy=copia in : +mail_rfc=da linea +mail_eexists=il messaggio non esiste più! +mail_fchange=cambia +mail_indexlink=torna alla casella di posta +mail_deleteall=elimina tutto +mail_black=blocca mittenti +mail_white=accetta mittenti +mail_efile=il file di Mail non esiste +mail_fromsrch=stesso mittente.. +mail_subsrch=stesso oggetto.. +mail_tosrch=stesso destinatario + +mail_sign=firma con chiave: +mail_nosign=<non firmare> +mail_crypt=crpita per: +mail_nocrypt=<non criptare> +mail_samecrypt=<chiave per destinatari> +mail_addresses=gestione Rubrica +mail_folders=gestione cartelle +mail_err=errore elencando i mesaggi in questa cartella : $1 +mail_loginheader=POP3 server login +mail_logindesc=inserisci nome utente e password per accedere alla posta
nella tua casella del server mail $1. +mail_loginuser=nome utente +mail_loginpass=password +mail_loginmailbox=casella di posta IMAP +mail_login=login +mail_reset=pulisci +mail_logout=cambia POP3 login +mail_logout2=cambia IMAP login +mail_sig=modifica firma +mail_jump=vai a pagina: +mail_of=of +mail_replyto=rispondi a +mail_folder=cartella +mail_delall=elimina tutti +mail_deltrash=svuota cestino +mail_search2=cerca : +mail_advanced=ricerca Avanzata +mail_return2=utente Email + +view_title=leggi email +view_desc=messaggio $1 di $2 +view_desc2=messaggio $1 per utente $2 +view_desc3=messaggio $1 +view_sent=messaggio $1 in elenco posta inviata +view_qdesc=messaggio accodato $1 +view_headers=intestazione mail +view_body=testo del messaggio +view_allheaders=vedi tutte le intestazioni +view_noheaders=vedi intestazioni base +view_attach=allegati +view_reply=rispondi +view_reply2=rispondi a tutti +view_enew=modifica come nuovo +view_forward=inoltra +view_delete=elimina +view_print=stampa +view_strip=elimina allegati +view_ecannot=non hai i permessi di leggere la posta di questo utente +view_mark=segna come +view_mark0=non letto +view_mark1=letto +view_mark2=speciale +view_return=email originale +view_sub=email allegata +view_egone=questo messaggio non esiste più + +view_gnupg=verifica firma GnuPG +view_gnupg_0=la firma di $1 è valida +view_gnupg_1=la firma di $1 è valida, ma il trust chain no è stato stabilito +view_gnupg_2=la firma di $1 NON È valida +view_gnupg_3=Key ID $1 is not in your list, so signature could not be verified. +view_gnupg_4=Failed to verify signature : $1 +view_crypt=GnuPG mail decryption +view_crypt_1=Message is encrypted, but GnuPG support is not installed. +view_crypt_2=Failed to decrypt messaggio : $1 +view_crypt_3=Mail was successfully decrypted. +view_crypt_4=Encrypted portion of messaggio was successfully decrypted. +view_recv=Fetch key ID $1 da keyserver. +view_folder=torna a mailbox +view_detach=Detach file: +view_dall=<All files> +view_dir=a file server o directory +view_black=blocca mittente +view_white=sblocca mittente +view_razor=segnala come spam +view_ham=seganana come ham +view_razordel=segnana ed elimina +view_dstatus=errore stato di consegna +view_dstatusok=stato di consegna ok +view_final-recipient=Final recipient +view_diagnostic-code=dettagli errore +view_remote-mta=mail server remoto +view_reporting-mta=segnalazione a mail server +view_astext=vedi messaggio formato raw testo +view_ashtml=vedi messaggio formato HTML +view_raw=vedi messaggio formato raw + +compose_title=scrivi Email + +reply_title=rispondi a email +forward_title=inoltra email +enew_title=Modifica Email +reply_headers=intestazioni Mail +reply_attach=Inoltrato allegati +reply_mailforward=Inoltrato messaggi +reply_attach2=Client and server-side allegati +reply_send=invia email +reply_ecannot=non hai i permessi per inviare messaggi come questo utente +reply_body=testo del messaggio +reply_errc=errore nella copia +reply_errm=errore nello spostare il messaggio +reply_return=scrivi mail + +reply_spell=controllo ortografico? +reply_draft=salva come bozza + +send_err=errore nell'invio email +send_eto=inserire il destinatario +send_efrom=inserire il mittente +send_title=Mail inviata +send_ok=Mail inviata a $1 +send_sending=invio posta a $1 .. +send_ecannot=Non hai i permessi per inviare mail a questo utente +send_esmtp=SMTP command $1 failed : $2 +send_eattach=gli allegati non possono essere superiori a $1 kB in dimensione. +send_eperms=utente $1 non può leggere $2 +send_eperms2=non hai i permessi per inviare file $1 +send_epath=Sendmail executable $1 does not exist. +send_efile=errore nel leggere allegato $1 : $2 +send_done=.. fatto + +send_epass=non è possibile firmare il messaggio perchè la tua passphrase non risulta imposta nel modulo GnuPG +send_esign=errore nella firma del messaggio : $1 +send_ekey=Couldn't find key for email indirizzo $1 +send_ecrypt=Failed to encrypt messaggio : $1 +send_eword=errore grammaticale $1 +send_eword2=errore grammaticale $1 - correzioni possibili $2 +send_eline=a riga $1 : +send_espell=i seguenti errori grammaticali sono stati trovati nel messaggio .. +send_draft=messaggio a $1 salvato nella cartella bozze +send_drafting=salvataggio mail to $1 nella cartella bozze +send_eattachsize=l'allegato di posta supera il limite massimo consentito di $1 bytes + +delete_title=elimina Mail +delete_rusure=confermi eliminazione dei $1 messaggi selezionati da $2? Questa operazione potrebbe richiedere tempo. Non eseguire altre operazioni fino al messaggio di conferma. +delete_rusure2=confermi eliminazione di questo messaggio da $1? Questa operazione potrebbe richiedere tempo. Non eseguire altre operazioni fino al messaggio di conferma. +delete_ok=elimina ora +delete_ecannot=non hai i permessi per eliminare da questo utente +delete_enone=non risultano selezionate email da eliminare +delete_emnone=non risultano selezionate email da segnare +delete_efnone=non risultano selezionate email da inoltrare +delete_ebnone=non risultano selezionate email da bloccare +delete_ewnone=non risultano selezionate email da sbloccare +delete_ernone=non risultano selezionate email da segnalare come span +delete_ehnone=non risultano selezionate email da segnalare come ham +delete_emoveuser=utente a cui spostare mail non esiste +delete_ecopyuser=utente a cui copiare mail non esiste +delete_emovecannot=non hai i permessi per spostare mail all'utente indicato +delete_ecopycannot=non hai i permessi per copiare mail all'utente indicato +delete_emovenone=non risultano selezionate email da spostare +delete_ecopynone=non risultano selezionate email da copiare +delete_nobutton=nessun bottone clicked +delete_ereport=errore nella segnalazione spam : $1 +delete_errc=errore nella copia mail +delete_errm=errore nello spostamento mail + +confirm_title=conferma elimina +confirm_warn=confermi eliminazione dei $1 messaggi selezionati? +confirm_warn2=Because of the dimensione and format of your mailbox, questo may take some time. Until the deletion has finished, no other action should be performed. +confirm_warn3=Are you sure you want to delete questo messaggio? +confirm_warn4=Until the deletion has finished, no other action should be performed. +confirm_ok=Elimina Now +confirm_warnall=Are you sure you want to delete all of the messaggi in questo cartella? + +search_title=esito ricerca +search_ecannot=non hai i permessi per cercare mail di questo utente +search_ematch=inserisci un testo per il confronto +search_efield=seleziona tipo di ricerca +search_ewhat=No text to match against entered for row $1 +search_enone=inserisci un criterio di ricerca +search_none=nessun messaggio trovato +search_results2=$1 messaggi corrispondenti a $2 +search_results3=$1 messaggi non corrispondenti $2 +search_results4=$1 messaggi corrispondenti alla ricerca +search_msg2=esito ricerca per $1 +search_msg4=esito ricerca +search_local=nella cartelle locali +search_all=in tutte le cartelle +search_limit=(da last $1 messaggi) +search_status=con status +search_allstatus=tutti +search_onestatus=solo status +search_latest=Messaggi da cercare +search_nolatest=tutto in cartella +search_latestnum=più recenti +search_elatest=inserisci un numero valido di messaggio da cercare +search_withstatus=, con status $1 + +folder_inbox=arrivo +folder_sent=inviata +folder_drafts=bozze +folder_trash=cestino + +detach_err=errore in detach file +detach_edir=No file or directory to save to entered +detach_eopen=errore di lettura $1 : $2 +detach_ewrite=erroe di scrittura su $1 : $2 +detach_title=Detach File +detach_ok=scritto allegato al file server-side $1 ($2). + +sform_title=Ricerca avanzata +sform_and=Cerca messaggi con tutti i criteri sotto +sform_or=Cerca messaggi con ogni criterio sotto +sform_neg0=contiene +sform_neg1=non contiene +sform_ok=Cerca ora +sform_folder=in cartella(s) +sform_all=<tuttel el cartelle> +sform_local=<cartelle locali> +sform_where=Dove +sform_text=il testo +sform_from=Da: intestazione +sform_subject=Oggetto: intestazione +sform_to=To: intestazione +sform_cc=Cc: intestazione +sform_date=Date: intestazione +sform_body=messaggio corpo +sform_headers=ogni intestazione +sform_size=messaggio dimensione +sform_return=form ricerca avanzata + +find_enone=Nessun utente corrisponde alla ricerca effettuata +find_title=Cerca risultati +find_results=utenti corrispondenti alla ricerca per $1 .. +find_user=Nome utente +find_real=Nome reale +find_group=Gruppo +find_home=Home directory +find_size=dimensione mail +find_incount=Messaggi +find_sentcount=Inviati + +acl_none=Nessuno +acl_same=Utente con stesso nome +acl_all=tutti +acl_read=utenti ai quali la posta può essere letta +acl_users=Solo utenti +acl_userse=Tutto tranne utenti +acl_usersg=Membri dei gruppi +acl_from=Disponibile da indirizzi +acl_any=Ogni indirizzo +acl_fdoms=Mailbox @ domini +acl_faddrs=indirizzi elencati +acl_fdom=ogni indirizzo @ dominio +acl_fromname=Nome reale per Da indirizzo +acl_apath=Limite file e programi per directory +acl_attach=dimesione totale massima degli allegati +acl_sent=archivia posta inviata in cartella mailbox +acl_canattach=puoi/può allegare file server-side? +acl_candetach=puoi/può detach files al server? +acl_usersm=corrispondenza utente +acl_asame=Stesso come nome utente +acl_usersu=With UID in range +acl_sec=Include secondary gruppi? +acl_dir=puoi/può leggere mail nella directory +acl_dirauto=scelta automatica (ovunque se tutti gli utenti sono visibili, al contrario da nessuna parte) + +log_delmail=eliminati $1 messaggi da $2 +log_movemail=spostati $1 messaggi da $2 a $3 +log_copymail=copiati $1 messaggi da $2 a $3 +log_send=mail inviata a to $1 +log_read=leggi/letta mail per $1 + +emodified=questa cartella è stata modificata dall'ultima visita! torna a lista mail e riprova + +razor_title=segnala come spam +razor_report=sto segnalando questo messaggio a Razor o altri SpamAssassin spam-blocking databases .. +razor_done=.. fatto +razor_err=.. errore! vedi dettagli sopra +razor_deleted=.. fatto , il messaggio è stato eliminato + +ham_title=Reporting As Ham +ham_report=Reporting questo messaggio as non-spam to Razor and other SpamAssassin databases .. + +black_title=Denying Sender +black_done=Added the email indirizzo $1 to SpamAssassin's denied indirizzi list. +black_already=The email indirizzo $1 is already on SpamAssassin's denied indirizzi list. + +white_title=Allowing Sender +white_done=Added the email indirizzo $1 to SpamAssassin's allowed indirizzi list. +white_already=The email indirizzo $1 is already on SpamAssassin's allowed indirizzi list. + +ldap_emod=Missing Perl module $1 needed for connecting to LDAP +ldap_econn=Failed to connect to LDAP server $1 port $2 +ldap_elogin=Failed to bind to LDAP server $1 as $2 : $3 + diff --git a/mailboxes/lang/ja_JP.UTF-8 b/mailboxes/lang/ja_JP.UTF-8 new file mode 100644 index 000000000..567d8e385 --- /dev/null +++ b/mailboxes/lang/ja_JP.UTF-8 @@ -0,0 +1,78 @@ +mail_title=ユーザ E メール +mail_from=é€ä¿¡å…ƒ +mail_date=日付 +mail_subject=ä»¶å +mail_to=宛先 +mail_pri=優先度 +mail_highest=最優先 +mail_high=高 +mail_normal=標準 +mail_low=低 +mail_lowest=最後 +mail_for=$1 内 +mail_sent=é€ä¿¡æ¸ˆã¿ãƒ¡ãƒ¼ãƒ« リスト内 +mail_size=サイズ +mail_delete=é¸æŠžã•れãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’削除 +mail_compose=æ–°è¦ãƒ¡ãƒ¼ãƒ«ã‚’ä½œæˆ +mail_return=ユーザ E メール +mail_ecannot=ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒ¡ãƒ¼ãƒ«ã¯èª­ã‚ã¾ã›ã‚“ +mail_all=ã™ã¹ã¦é¸æŠž +mail_invert=é¸æŠžã®å転 +mail_search=ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®æ¤œç´¢ +mail_body=本文 +mail_match=一致 +mail_ok=検索 +mail_nonefrom=ãªã— +view_title=E メールを読む +view_desc=$2ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ $1 +view_sent=é€ä¿¡æ¸ˆã¿ãƒ¡ãƒ¼ãƒ« リストã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ $1 +view_qdesc=キューã•れãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ $1 +view_headers=メール ヘッダ +view_attach=添付ファイル +view_reply=返信 +view_reply2=全員ã«è¿”ä¿¡ +view_enew=æ–°è¦ã¨ã—ã¦ç·¨é›† +view_forward=è»¢é€ +view_delete=削除 +view_ecannot=ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒ¡ãƒ¼ãƒ«ã¯èª­ã‚ã¾ã›ã‚“ +compose_title=E メールã®ä½œæˆ +reply_title=E メールã¸ã®è¿”ä¿¡ +forward_title=E メールã®è»¢é€ +reply_headers=メール ヘッダ +reply_attach=転é€ã•ã‚ŒãŸæ·»ä»˜ãƒ•ァイル +reply_attach2=添付ファイル +reply_send=é€ä¿¡ +reply_ecannot=ã“ã®ãƒ¦ãƒ¼ã‚¶ã¨ã—ã¦ã¯ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ +send_err=メールをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—㟠+send_eto=To (宛先)アドレスãŒã‚りã¾ã›ã‚“ +send_efrom=From (é€ä¿¡è€…) アドレスãŒã‚りã¾ã›ã‚“ +send_title=é€ä¿¡ã•れãŸãƒ¡ãƒ¼ãƒ« +send_ok=$1 ã¸ã®ãƒ¡ãƒ¼ãƒ«ã®é€ä¿¡ã‚’完了ã—ã¾ã—㟠+send_ecannot=ã“ã®ãƒ¦ãƒ¼ã‚¶ã¨ã—ã¦ã¯ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ +send_esmtp=SMTP コマンド $1 ãŒå¤±æ•—ã—ã¾ã—ãŸ: $2 +send_eattach=添付ファイルã®ã‚µã‚¤ã‚ºã¯ $1 KB ã‚’è¶Šãˆã‚‰ã‚Œã¾ã›ã‚“。 +send_eperms=ユーザ $1 㯠$2 を読ã¿å–れã¾ã›ã‚“ +send_eperms2=ファイル $1 ã¯é€ä¿¡ã§ãã¾ã›ã‚“ +delete_ecannot=ã“ã®ãƒ¦ãƒ¼ã‚¶ã‹ã‚‰ã®ãƒ¡ãƒ¼ãƒ«ã‚’削除ã§ãã¾ã™ +delete_enone=削除ã™ã‚‹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒé¸æŠžã•れã¦ã„ã¾ã›ã‚“ +search_title=æ¤œç´¢çµæžœ +search_ecannot=ã“ã®ãƒ¦ãƒ¼ã‚¶ã®ãƒ¡ãƒ¼ãƒ«ã¯æ¤œç´¢ã§ãã¾ã›ã‚“ +search_ematch=検索ã™ã‚‹ã«ã¯ãƒ†ã‚­ã‚¹ãƒˆã‚’入力ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ +search_none=メッセージãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚ +acl_none=ãªã— +acl_same=åŒåã®ãƒ¦ãƒ¼ã‚¶ +acl_all=ã™ã¹ã¦ +acl_read=メールを読ã¿å–れるユーザ +acl_users=次ã®ãƒ¦ãƒ¼ã‚¶ã®ã¿ +acl_userse=次ã®ãƒ¦ãƒ¼ã‚¶ä»¥å¤–ã™ã¹ã¦ +acl_usersg=グループã®ãƒ¡ãƒ³ãƒãƒ¼ +acl_from=アドレスã‹ã‚‰è¨±å¯ +acl_any=ä»»æ„ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ +acl_fdoms=メールボックス @ ドメイン +acl_faddrs=リストã•れãŸã‚¢ãƒ‰ãƒ¬ã‚¹ +acl_fdom=ä»»æ„ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ @ ドメイン +acl_apath=ディレクトリã¸ã®ãƒ•ァイルã¨ãƒ—ãƒ­ã‚°ãƒ©ãƒ ã‚’åˆ¶é™ +acl_attach=添付ファイルã®åˆè¨ˆã‚µã‚¤ã‚ºã®æœ€å¤§å€¤ +acl_sent=é€ä¿¡æ¸ˆã¿ãƒ¡ãƒ¼ãƒ«ã‚’メールボックスã«ä¿å­˜ +log_delmail=$1 メッセージを $2 ã‹ã‚‰å‰Šé™¤ã—ã¾ã—㟠+log_send=$1 ã«ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã—㟠diff --git a/mailboxes/lang/ja_JP.euc b/mailboxes/lang/ja_JP.euc new file mode 100644 index 000000000..9b74c6bb9 --- /dev/null +++ b/mailboxes/lang/ja_JP.euc @@ -0,0 +1,78 @@ +mail_title=¥æ¡¼¥¶ E ¥á¡¼¥ë +mail_from=Á÷¿®¸µ +mail_date=ÆüÉÕ +mail_subject=·ï̾ +mail_to=°¸Àè +mail_pri=Í¥ÀèÅÙ +mail_highest=ºÇÍ¥Àè +mail_high=¹â +mail_normal=ɸ½à +mail_low=Äã +mail_lowest=ºÇ¸å +mail_for=$1 Æâ +mail_sent=Á÷¿®ºÑ¤ß¥á¡¼¥ë ¥ê¥¹¥ÈÆâ +mail_size=¥µ¥¤¥º +mail_delete=ÁªÂò¤µ¤ì¤¿¥á¥Ã¥»¡¼¥¸¤òºï½ü +mail_compose=¿·µ¬¥á¡¼¥ë¤òºîÀ® +mail_return=¥æ¡¼¥¶ E ¥á¡¼¥ë +mail_ecannot=¤³¤Î¥æ¡¼¥¶¡¼¤Î¥á¡¼¥ë¤ÏÆÉ¤á¤Þ¤»¤ó +mail_all=¤¹¤Ù¤ÆÁªÂò +mail_invert=ÁªÂò¤Îȿž +mail_search=¥á¥Ã¥»¡¼¥¸¤Î¸¡º÷ +mail_body=ËÜʸ +mail_match=°ìÃ× +mail_ok=¸¡º÷ +mail_nonefrom=¤Ê¤· +view_title=E ¥á¡¼¥ë¤òÆÉ¤à +view_desc=$2¤Î¥á¥Ã¥»¡¼¥¸ $1 +view_sent=Á÷¿®ºÑ¤ß¥á¡¼¥ë ¥ê¥¹¥È¤Î¥á¥Ã¥»¡¼¥¸ $1 +view_qdesc=¥­¥å¡¼¤µ¤ì¤¿¥á¥Ã¥»¡¼¥¸ $1 +view_headers=¥á¡¼¥ë ¥Ø¥Ã¥À +view_attach=źÉÕ¥Õ¥¡¥¤¥ë +view_reply=ÊÖ¿® +view_reply2=Á´°÷¤ËÊÖ¿® +view_enew=¿·µ¬¤È¤·¤ÆÊÔ½¸ +view_forward=žÁ÷ +view_delete=ºï½ü +view_ecannot=¤³¤Î¥æ¡¼¥¶¡¼¤Î¥á¡¼¥ë¤ÏÆÉ¤á¤Þ¤»¤ó +compose_title=E ¥á¡¼¥ë¤ÎºîÀ® +reply_title=E ¥á¡¼¥ë¤Ø¤ÎÊÖ¿® +forward_title=E ¥á¡¼¥ë¤ÎžÁ÷ +reply_headers=¥á¡¼¥ë ¥Ø¥Ã¥À +reply_attach=žÁ÷¤µ¤ì¤¿ÅºÉÕ¥Õ¥¡¥¤¥ë +reply_attach2=źÉÕ¥Õ¥¡¥¤¥ë +reply_send=Á÷¿® +reply_ecannot=¤³¤Î¥æ¡¼¥¶¤È¤·¤Æ¤Ï¥á¡¼¥ë¤òÁ÷¿®¤Ç¤­¤Þ¤»¤ó +send_err=¥á¡¼¥ë¤òÁ÷¿®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿ +send_eto=To ¡Ê°¸Àè¡Ë¥¢¥É¥ì¥¹¤¬¤¢¤ê¤Þ¤»¤ó +send_efrom=From (Á÷¿®¼Ô) ¥¢¥É¥ì¥¹¤¬¤¢¤ê¤Þ¤»¤ó +send_title=Á÷¿®¤µ¤ì¤¿¥á¡¼¥ë +send_ok=$1 ¤Ø¤Î¥á¡¼¥ë¤ÎÁ÷¿®¤ò´°Î»¤·¤Þ¤·¤¿ +send_ecannot=¤³¤Î¥æ¡¼¥¶¤È¤·¤Æ¤Ï¥á¡¼¥ë¤òÁ÷¿®¤Ç¤­¤Þ¤»¤ó +send_esmtp=SMTP ¥³¥Þ¥ó¥É $1 ¤¬¼ºÇÔ¤·¤Þ¤·¤¿: $2 +send_eattach=źÉÕ¥Õ¥¡¥¤¥ë¤Î¥µ¥¤¥º¤Ï $1 KB ¤ò±Û¤¨¤é¤ì¤Þ¤»¤ó¡£ +send_eperms=¥æ¡¼¥¶ $1 ¤Ï $2 ¤òÆÉ¤ß¼è¤ì¤Þ¤»¤ó +send_eperms2=¥Õ¥¡¥¤¥ë $1 ¤ÏÁ÷¿®¤Ç¤­¤Þ¤»¤ó +delete_ecannot=¤³¤Î¥æ¡¼¥¶¤«¤é¤Î¥á¡¼¥ë¤òºï½ü¤Ç¤­¤Þ¤¹ +delete_enone=ºï½ü¤¹¤ë¥á¥Ã¥»¡¼¥¸¤¬ÁªÂò¤µ¤ì¤Æ¤¤¤Þ¤»¤ó +search_title=¸¡º÷·ë²Ì +search_ecannot=¤³¤Î¥æ¡¼¥¶¤Î¥á¡¼¥ë¤Ï¸¡º÷¤Ç¤­¤Þ¤»¤ó +search_ematch=¸¡º÷¤¹¤ë¤Ë¤Ï¥Æ¥­¥¹¥È¤òÆþÎϤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ +search_none=¥á¥Ã¥»¡¼¥¸¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿¡£ +acl_none=¤Ê¤· +acl_same=Ʊ̾¤Î¥æ¡¼¥¶ +acl_all=¤¹¤Ù¤Æ +acl_read=¥á¡¼¥ë¤òÆÉ¤ß¼è¤ì¤ë¥æ¡¼¥¶ +acl_users=¼¡¤Î¥æ¡¼¥¶¤Î¤ß +acl_userse=¼¡¤Î¥æ¡¼¥¶°Ê³°¤¹¤Ù¤Æ +acl_usersg=¥°¥ë¡¼¥×¤Î¥á¥ó¥Ð¡¼ +acl_from=¥¢¥É¥ì¥¹¤«¤éµö²Ä +acl_any=Ǥ°Õ¤Î¥¢¥É¥ì¥¹ +acl_fdoms=¥á¡¼¥ë¥Ü¥Ã¥¯¥¹ @ ¥É¥á¥¤¥ó +acl_faddrs=¥ê¥¹¥È¤µ¤ì¤¿¥¢¥É¥ì¥¹ +acl_fdom=Ǥ°Õ¤Î¥¢¥É¥ì¥¹ @ ¥É¥á¥¤¥ó +acl_apath=¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¥Õ¥¡¥¤¥ë¤È¥×¥í¥°¥é¥à¤òÀ©¸Â +acl_attach=źÉÕ¥Õ¥¡¥¤¥ë¤Î¹ç·×¥µ¥¤¥º¤ÎºÇÂçÃÍ +acl_sent=Á÷¿®ºÑ¤ß¥á¡¼¥ë¤ò¥á¡¼¥ë¥Ü¥Ã¥¯¥¹¤ËÊݸ +log_delmail=$1 ¥á¥Ã¥»¡¼¥¸¤ò $2 ¤«¤éºï½ü¤·¤Þ¤·¤¿ +log_send=$1 ¤Ë¥á¡¼¥ë¤òÁ÷¿®¤·¤Þ¤·¤¿ diff --git a/mailboxes/lang/ja_JP.jis b/mailboxes/lang/ja_JP.jis new file mode 100644 index 000000000..d14690071 --- /dev/null +++ b/mailboxes/lang/ja_JP.jis @@ -0,0 +1,78 @@ +mail_title=ƒ†[ƒU E ƒ[ƒ‹ +mail_from=‘—MŒ³ +mail_date=“ú•t +mail_subject=Œ–¼ +mail_to=ˆ¶æ +mail_pri=—Dæ“x +mail_highest=Å—Dæ +mail_high=‚ +mail_normal=•W€ +mail_low=’á +mail_lowest=ÅŒã +mail_for=$1 “à +mail_sent=‘—Mς݃[ƒ‹ ƒŠƒXƒg“à +mail_size=ƒTƒCƒY +mail_delete=‘I‘ð‚³‚ê‚½ƒƒbƒZ[ƒW‚ðíœ +mail_compose=V‹Kƒ[ƒ‹‚ðì¬ +mail_return=ƒ†[ƒU E ƒ[ƒ‹ +mail_ecannot=‚±‚̃†[ƒU[‚̃[ƒ‹‚͓ǂ߂܂¹‚ñ +mail_all=‚·‚ׂđI‘ð +mail_invert=‘I‘ð‚Ì”½“] +mail_search=ƒƒbƒZ[ƒW‚ÌŒŸõ +mail_body=–{•¶ +mail_match=ˆê’v +mail_ok=ŒŸõ +mail_nonefrom=‚È‚µ +view_title=E ƒ[ƒ‹‚ð“Ç‚Þ +view_desc=$2‚̃ƒbƒZ[ƒW $1 +view_sent=‘—Mς݃[ƒ‹ ƒŠƒXƒg‚̃ƒbƒZ[ƒW $1 +view_qdesc=ƒLƒ…[‚³‚ꂽƒƒbƒZ[ƒW $1 +view_headers=ƒ[ƒ‹ ƒwƒbƒ_ +view_attach=“Y•tƒtƒ@ƒCƒ‹ +view_reply=•ÔM +view_reply2=‘Sˆõ‚É•ÔM +view_enew=V‹K‚Æ‚µ‚Ä•ÒW +view_forward=“]‘— +view_delete=íœ +view_ecannot=‚±‚̃†[ƒU[‚̃[ƒ‹‚͓ǂ߂܂¹‚ñ +compose_title=E ƒ[ƒ‹‚Ìì¬ +reply_title=E ƒ[ƒ‹‚Ö‚Ì•ÔM +forward_title=E ƒ[ƒ‹‚Ì“]‘— +reply_headers=ƒ[ƒ‹ ƒwƒbƒ_ +reply_attach=“]‘—‚³‚ꂽ“Y•tƒtƒ@ƒCƒ‹ +reply_attach2=“Y•tƒtƒ@ƒCƒ‹ +reply_send=‘—M +reply_ecannot=‚±‚̃†[ƒU‚Æ‚µ‚Ă̓[ƒ‹‚ð‘—M‚Å‚«‚Ü‚¹‚ñ +send_err=ƒ[ƒ‹‚ð‘—M‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½ +send_eto=To iˆ¶æjƒAƒhƒŒƒX‚ª‚ ‚è‚Ü‚¹‚ñ +send_efrom=From (‘—MŽÒ) ƒAƒhƒŒƒX‚ª‚ ‚è‚Ü‚¹‚ñ +send_title=‘—M‚³‚ꂽƒ[ƒ‹ +send_ok=$1 ‚ւ̃[ƒ‹‚Ì‘—M‚ðŠ®—¹‚µ‚Ü‚µ‚½ +send_ecannot=‚±‚̃†[ƒU‚Æ‚µ‚Ă̓[ƒ‹‚ð‘—M‚Å‚«‚Ü‚¹‚ñ +send_esmtp=SMTP ƒRƒ}ƒ“ƒh $1 ‚ªŽ¸”s‚µ‚Ü‚µ‚½: $2 +send_eattach=“Y•tƒtƒ@ƒCƒ‹‚̃TƒCƒY‚Í $1 KB ‚ð‰z‚¦‚ç‚ê‚Ü‚¹‚ñB +send_eperms=ƒ†[ƒU $1 ‚Í $2 ‚ð“ǂݎæ‚ê‚Ü‚¹‚ñ +send_eperms2=ƒtƒ@ƒCƒ‹ $1 ‚Í‘—M‚Å‚«‚Ü‚¹‚ñ +delete_ecannot=‚±‚̃†[ƒU‚©‚ç‚̃[ƒ‹‚ð휂ł«‚Ü‚· +delete_enone=휂·‚郃bƒZ[ƒW‚ª‘I‘ð‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ +search_title=ŒŸõŒ‹‰Ê +search_ecannot=‚±‚̃†[ƒU‚̃[ƒ‹‚ÍŒŸõ‚Å‚«‚Ü‚¹‚ñ +search_ematch=ŒŸõ‚·‚é‚ɂ̓eƒLƒXƒg‚ð“ü—Í‚·‚é•K—v‚ª‚ ‚è‚Ü‚·B +search_none=ƒƒbƒZ[ƒW‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½B +acl_none=‚È‚µ +acl_same=“¯–¼‚̃†[ƒU +acl_all=‚·‚×‚Ä +acl_read=ƒ[ƒ‹‚ð“ǂݎæ‚ê‚郆[ƒU +acl_users=ŽŸ‚̃†[ƒU‚Ì‚Ý +acl_userse=ŽŸ‚̃†[ƒUˆÈŠO‚·‚×‚Ä +acl_usersg=ƒOƒ‹[ƒv‚̃ƒ“ƒo[ +acl_from=ƒAƒhƒŒƒX‚©‚ç‹–‰Â +acl_any=”CˆÓ‚̃AƒhƒŒƒX +acl_fdoms=ƒ[ƒ‹ƒ{ƒbƒNƒX @ ƒhƒƒCƒ“ +acl_faddrs=ƒŠƒXƒg‚³‚ꂽƒAƒhƒŒƒX +acl_fdom=”CˆÓ‚̃AƒhƒŒƒX @ ƒhƒƒCƒ“ +acl_apath=ƒfƒBƒŒƒNƒgƒŠ‚ւ̃tƒ@ƒCƒ‹‚ƃvƒƒOƒ‰ƒ€‚ð§ŒÀ +acl_attach=“Y•tƒtƒ@ƒCƒ‹‚̇ŒvƒTƒCƒY‚ÌÅ‘å’l +acl_sent=‘—Mς݃[ƒ‹‚ðƒ[ƒ‹ƒ{ƒbƒNƒX‚ɕۑ¶ +log_delmail=$1 ƒƒbƒZ[ƒW‚ð $2 ‚©‚ç휂µ‚Ü‚µ‚½ +log_send=$1 ‚Ƀ[ƒ‹‚ð‘—M‚µ‚Ü‚µ‚½ diff --git a/mailboxes/lang/ko_KR.UTF-8 b/mailboxes/lang/ko_KR.UTF-8 new file mode 100644 index 000000000..81fcb00bf --- /dev/null +++ b/mailboxes/lang/ko_KR.UTF-8 @@ -0,0 +1,80 @@ +mail_title=ç´«é‚切 穿切 äº”æž +mail_from=é™é‡åˆ‡ +mail_date=劾促 +mail_subject=薦鯉 +mail_to=呪é‡åˆ‡ +mail_cc=凧繕 +mail_bcc=需精 凧繕 +mail_pri=酔識 授是 +mail_highest=亜舌 株製 +mail_high=株製 +mail_normal=å·¦æ­ +mail_low=ç¢è£½ +mail_lowest=亜舌 ç¢è£½ +mail_for=$1 +mail_sent=é™é‡ äº”æž é¯‰ç³» +mail_size=滴奄 +mail_delete=識澱廃 五ç£èµ° 肢薦 +mail_compose=æ­¯ äº”æž æ‹™å¤± +mail_return=ç´«é‚切 穿切 äº”æž +mail_ecannot=戚 ç´«é‚切税 穿切 五æžè– çŸ³è– å‘ª 蒸柔艦陥 +mail_all=乞砧 識澱 +mail_invert=鋼ä¼ç¨½ 識澱 +mail_search=五ç£èµ° 伊事 是帖 +mail_body=沙庚 +mail_match=æžå¸– +mail_ok=伊事 +mail_nonefrom=蒸製 +view_title=穿切 äº”æž çŸ³å¥„ +view_desc=$2æ‹­ 赤澗 五ç£èµ° $1 +view_sent=é™é‡ äº”æž é¯‰ç³»æ‹­ 赤澗 五ç£èµ° $1 +view_qdesc=ä¼å¥„伸拭 赤澗 五ç£èµ° $1 +view_headers=äº”æž ä¼¯å¸Œ +view_attach=歎採 ç£æž +view_reply=å™ºé‡ +view_reply2=穿端 å™ºé‡ +view_enew=æ­¯ 五æžç¨½ 畷増 +view_forward=ç©¿å« +view_delete=肢薦 +view_ecannot=戚 ç´«é‚切税 穿切 五æžè– çŸ³è– å‘ª 蒸柔艦陥 +compose_title=穿切 äº”æž æ‹™å¤± +reply_title=穿切 äº”æžæ‹­ å™ºé‡ +forward_title=穿切 äº”æž ç©¿å« +reply_headers=äº”æž ä¼¯å¸Œ +reply_attach=ç©¿å«å‰ 歎採 ç£æž +reply_attach2=歎採 ç£æž +reply_send=穿勺 +reply_ecannot=戚 ç´«é‚切稽 五æžè– ç©¿å‹ºæ‹ å‘ª 蒸柔艦陥 +send_err=五æžè– 穿勺馬走 公梅柔艦陥 +send_eto=蒸澗 呪é‡åˆ‡ 爽社 +send_efrom=蒸澗 é™é‡åˆ‡ 爽社 +send_title=äº”æž ç©¿å‹º 刃戟 +send_ok=$1æ‹­ 五æžè– 穿勺梅柔艦陥. +send_ecannot=戚 ç´«é‚切稽 五æžè– ç©¿å‹ºæ‹ å‘ª 蒸柔艦陥 +send_esmtp=SMTP 誤敬 $1 å”é³¶: $2 +send_eattach=歎採 ç£æžç¨Ž æ¥ æ»´å¥„æ¾— $1KBç ” æ®µå¼•æ‹ å‘ª 蒸柔艦陥. +send_eperms=ç´«é‚切 $1ç²¾(æ¾—) $2è–(ç ”) çŸ³è– å‘ª 蒸柔艦陥 +send_eperms2=ç£æž $1è–(ç ”) 左馨 呪 蒸柔艦陥 +delete_ecannot=戚 ç´«é‚切稽採斗 閤精 五æžè– è‚¢è–¦æ‹ å‘ª 蒸柔艦陥 +delete_enone=è‚¢è–¦æ‹ äº”æžè– 識澱馬走 çœç´¹æŸ”艦陥 +search_title=伊事 衣引 +search_ecannot=戚 ç´«é‚切税 穿切 五æžè– ä¼Šäº‹æ‹ å‘ª 蒸柔艦陥 +search_ematch=ä¼Šäº‹æ‹ åŠªä»€é—˜ç ” 脊径背醤 æ¯è‰¦é™¥. +search_none=五ç£èµ°äºœ 蒸柔艦陥. +acl_none=蒸製 +acl_same=戚硯戚 ç–‘æžå»ƒ ç´«é‚切 +acl_all=乞砧 +acl_read=çŸ³è– å‘ª 赤澗 五æžè– 左鎧澗 ç´«é‚切 +acl_users=ç´«é‚切幻 +acl_userse=ç´«é‚切研 薦須廃 乞砧 +acl_usersg=益血 å§¥å¤±æ® +acl_from=è²·é‚ äºœç®¡å»ƒ é™é‡åˆ‡ 爽社 +acl_any=績税税 爽社 +acl_fdoms=紫辞敗@亀五昔 +acl_faddrs=èŸ¹ä¼¸å‰ çˆ½ç¤¾ +acl_fdom=績税税 爽社@亀五昔 +acl_apath=巨刑塘軒拭 ä¼å»ƒ ç£æž è²¢ 覗稽益轡 薦廃 +acl_attach=穿端 歎採 ç£æžç¨Ž ç½®ä¼ æ»´å¥„ +acl_sent=紫辞敗拭 é™é‡ äº”æž ç…½èˆŒ +log_delmail=$2拭辞 $1鯵 五ç£èµ° 肢薦喫 +log_send=$1拭惟 äº”æž ç©¿å‹º 刃戟 diff --git a/mailboxes/lang/ko_KR.euc b/mailboxes/lang/ko_KR.euc new file mode 100644 index 000000000..540dedfea --- /dev/null +++ b/mailboxes/lang/ko_KR.euc @@ -0,0 +1,80 @@ +mail_title=»ç¿ëÀÚ ÀüÀÚ ¸ÞÀÏ +mail_from=¹ß½ÅÀÚ +mail_date=³¯Â¥ +mail_subject=Á¦¸ñ +mail_to=¼ö½ÅÀÚ +mail_cc=ÂüÁ¶ +mail_bcc=¼ûÀº ÂüÁ¶ +mail_pri=¿ì¼± ¼øÀ§ +mail_highest=°¡Àå ³ôÀ½ +mail_high=³ôÀ½ +mail_normal=º¸Åë +mail_low=³·À½ +mail_lowest=°¡Àå ³·À½ +mail_for=$1 +mail_sent=¹ß½Å ¸ÞÀÏ ¸ñ·Ï +mail_size=Å©±â +mail_delete=¼±ÅÃÇÑ ¸Þ½ÃÁö »èÁ¦ +mail_compose=»õ ¸ÞÀÏ ÀÛ¼º +mail_return=»ç¿ëÀÚ ÀüÀÚ ¸ÞÀÏ +mail_ecannot=ÀÌ »ç¿ëÀÚÀÇ ÀüÀÚ ¸ÞÀÏÀ» ÀÐÀ» ¼ö ¾ø½À´Ï´Ù +mail_all=¸ðµÎ ¼±Åà +mail_invert=¹Ý´ë·Î ¼±Åà +mail_search=¸Þ½ÃÁö °Ë»ö À§Ä¡ +mail_body=º»¹® +mail_match=ÀÏÄ¡ +mail_ok=°Ë»ö +mail_nonefrom=¾øÀ½ +view_title=ÀüÀÚ ¸ÞÀÏ Àбâ +view_desc=$2¿¡ ÀÖ´Â ¸Þ½ÃÁö $1 +view_sent=¹ß½Å ¸ÞÀÏ ¸ñ·Ï¿¡ ÀÖ´Â ¸Þ½ÃÁö $1 +view_qdesc=´ë±â¿­¿¡ ÀÖ´Â ¸Þ½ÃÁö $1 +view_headers=¸ÞÀÏ Çì´õ +view_attach=÷ºÎ ÆÄÀÏ +view_reply=ȸ½Å +view_reply2=Àüü ȸ½Å +view_enew=»õ ¸ÞÀÏ·Î ÆíÁý +view_forward=Àü´Þ +view_delete=»èÁ¦ +view_ecannot=ÀÌ »ç¿ëÀÚÀÇ ÀüÀÚ ¸ÞÀÏÀ» ÀÐÀ» ¼ö ¾ø½À´Ï´Ù +compose_title=ÀüÀÚ ¸ÞÀÏ ÀÛ¼º +reply_title=ÀüÀÚ ¸ÞÀÏ¿¡ ȸ½Å +forward_title=ÀüÀÚ ¸ÞÀÏ Àü´Þ +reply_headers=¸ÞÀÏ Çì´õ +reply_attach=Àü´ÞµÈ ÷ºÎ ÆÄÀÏ +reply_attach2=÷ºÎ ÆÄÀÏ +reply_send=Àü¼Û +reply_ecannot=ÀÌ »ç¿ëÀÚ·Î ¸ÞÀÏÀ» Àü¼ÛÇÒ ¼ö ¾ø½À´Ï´Ù +send_err=¸ÞÀÏÀ» Àü¼ÛÇÏÁö ¸øÇß½À´Ï´Ù +send_eto=¾ø´Â ¼ö½ÅÀÚ ÁÖ¼Ò +send_efrom=¾ø´Â ¹ß½ÅÀÚ ÁÖ¼Ò +send_title=¸ÞÀÏ Àü¼Û ¿Ï·á +send_ok=$1¿¡ ¸ÞÀÏÀ» Àü¼ÛÇß½À´Ï´Ù. +send_ecannot=ÀÌ »ç¿ëÀÚ·Î ¸ÞÀÏÀ» Àü¼ÛÇÒ ¼ö ¾ø½À´Ï´Ù +send_esmtp=SMTP ¸í·É $1 ½ÇÆÐ: $2 +send_eattach=÷ºÎ ÆÄÀÏÀÇ ÃÑ Å©±â´Â $1KB¸¦ ÃʰúÇÒ ¼ö ¾ø½À´Ï´Ù. +send_eperms=»ç¿ëÀÚ $1Àº(´Â) $2À»(¸¦) ÀÐÀ» ¼ö ¾ø½À´Ï´Ù +send_eperms2=ÆÄÀÏ $1À»(¸¦) º¸³¾ ¼ö ¾ø½À´Ï´Ù +delete_ecannot=ÀÌ »ç¿ëÀڷκÎÅÍ ¹ÞÀº ¸ÞÀÏÀ» »èÁ¦ÇÒ ¼ö ¾ø½À´Ï´Ù +delete_enone=»èÁ¦ÇÒ ¸ÞÀÏÀ» ¼±ÅÃÇÏÁö ¾Ê¾Ò½À´Ï´Ù +search_title=°Ë»ö °á°ú +search_ecannot=ÀÌ »ç¿ëÀÚÀÇ ÀüÀÚ ¸ÞÀÏÀ» °Ë»öÇÒ ¼ö ¾ø½À´Ï´Ù +search_ematch=°Ë»öÇÒ ÅØ½ºÆ®¸¦ ÀÔ·ÂÇØ¾ß ÇÕ´Ï´Ù. +search_none=¸Þ½ÃÁö°¡ ¾ø½À´Ï´Ù. +acl_none=¾øÀ½ +acl_same=À̸§ÀÌ µ¿ÀÏÇÑ »ç¿ëÀÚ +acl_all=¸ðµÎ +acl_read=ÀÐÀ» ¼ö ÀÖ´Â ¸ÞÀÏÀ» º¸³»´Â »ç¿ëÀÚ +acl_users=»ç¿ëÀÚ¸¸ +acl_userse=»ç¿ëÀÚ¸¦ Á¦¿ÜÇÑ ¸ðµÎ +acl_usersg=±×·ì ±¸¼º¿ø +acl_from=Çã¿ë °¡´ÉÇÑ ¹ß½ÅÀÚ ÁÖ¼Ò +acl_any=ÀÓÀÇÀÇ ÁÖ¼Ò +acl_fdoms=»ç¼­ÇÔ@µµ¸ÞÀÎ +acl_faddrs=³ª¿­µÈ ÁÖ¼Ò +acl_fdom=ÀÓÀÇÀÇ ÁÖ¼Ò@µµ¸ÞÀÎ +acl_apath=µð·ºÅ丮¿¡ ´ëÇÑ ÆÄÀÏ ¹× ÇÁ·Î±×·¥ Á¦ÇÑ +acl_attach=Àüü ÷ºÎ ÆÄÀÏÀÇ ÃÖ´ë Å©±â +acl_sent=»ç¼­ÇÔ¿¡ ¹ß½Å ¸ÞÀÏ ÀúÀå +log_delmail=$2¿¡¼­ $1°³ ¸Þ½ÃÁö »èÁ¦µÊ +log_send=$1¿¡°Ô ¸ÞÀÏ Àü¼Û ¿Ï·á diff --git a/mailboxes/lang/pl b/mailboxes/lang/pl new file mode 100644 index 000000000..7ec72b388 --- /dev/null +++ b/mailboxes/lang/pl @@ -0,0 +1,95 @@ +mail_title=Poczta u¿ytkownika +mail_from=Od +mail_date=Wys³ano +mail_subject=Temat +mail_to=Do +mail_cc=DW +mail_bcc=UDW +mail_pri=Priorytet +mail_highest=Najwy¿szy +mail_high=Wysoki +mail_normal=Zwyk³y +mail_low=Niski +mail_lowest=Najni¿szy +mail_for=W $1 +mail_for2=Dla u¿ytkownika $1 +mail_sent=Na li¶cie poczty wys³anej +mail_size=Rozmiar +mail_delete=Skasuj wybrane wiadomo¶ci +mail_compose=Utwórz now± wiadomo¶æ +mail_return=skrzynki u¿ytkownika +mail_ecannot=Nie masz uprawnieñ do czytania poczty tego u¿ytkownika +mail_all=Wybierz wszystko +mail_invert=Odwróæ zaznaczenia +mail_search=Znajd¼ wiadomo¶ci, w których +mail_body=Tre¶æ +mail_match=zawiera +mail_ok=Szukaj +mail_nonefrom=Brak +mail_mark=Zaznacz wybrane jako: +mail_mark0=Nie przeczytane +mail_mark1=Przeczytane +mail_mark2=Specjalne +view_title=Czytaj pocztê +view_desc=Wiadomo¶æ $1 w $2 +view_desc2=Wiadomo¶æ $1 dla u¿ytkownika $2 +view_desc3=Wiadomo¶æ $1 +view_sent=Wiadomo¶æ $1 na li¶cie poczty wys³anej +view_qdesc=Wiadomo¶æ w kolejce $1 +view_headers=Nag³ówki wiadomo¶ci +view_attach=Za³±czniki +view_reply=Odpowiedz +view_reply2=Odpowiedz wszystkim +view_enew=Edytuj jako now± +view_forward=Przeka¿ dalej +view_delete=Skasuj +view_strip=Usuñ za³±czniki +view_ecannot=Nie masz uprawnieñ do czytania poczty tego u¿ytkownika +view_mark0=Nie przeczytan± +view_mark1=Przeczytan± +view_mark2=Specjaln± +view_return=pierwotnego adresu e-mail +compose_title=Utwórz wiadomo¶æ +reply_title=Odpowiedz na wiadomo¶æ +forward_title=Przeka¿ dalej +reply_headers=Nag³ówki wiadomo¶ci +reply_attach=Przekazywane za³±czniki +reply_attach2=Za³±czniki +reply_send=Wy¶lij +reply_ecannot=Nie masz uprawnieñ do czytania poczty jako ten u¿ytkownik +send_err=Nie uda³o siê wys³aæ wiadomo¶ci +send_eto=Brak adresu docelowego +send_efrom=Brak adresu ¼ród³owego +send_title=Wiadomo¶æ wys³ana +send_ok=Wiadomo¶æ pomy¶lnie wys³ana do $1 +send_ecannot=Nie masz uprawnieñ do wysy³ania poczty jako ten u¿ytkownik +send_esmtp=Polecenie SMTP $1 zakoñczy³o sie b³êdem : $2 +send_eattach=£±czny rozmiar za³±czników nie mo¿e przekraczaæ $1 kB. +send_eperms=U¿ytkownik $1 nie ma uprawnieñ do czytania $2 +send_eperms2=Nie masz uprawnieñ do wys³ania pliku $1 +delete_ecannot=Nie masz uprawnieñ do kasowania poczty tego u¿ytkownika +delete_enone=Nie wybrano wiadomo¶ci do skasowania +delete_emnone=Nie wybrano wiadomo¶ci do zaznaczenia +search_title=Wyniki poszukiwania +search_ecannot=Nie masz uprawnieñ do przeszukiwania poczty tego u¿ytkownika +search_ematch=Musisz wprowadziæ poszukiwany tekst +search_none=Nie znaleziono ¿adnej wiadomo¶ci +acl_none=¯adne +acl_same=U¿ytkownika o tej samej nazwie +acl_all=Wszystkie +acl_read=U¿ytkownicy, których poczta mo¿e byæ czytana +acl_users=Tylko u¿ytkownicy +acl_userse=Oprócz u¿ytkowników +acl_usersg=Cz³onkowie grupy +acl_from=Dozwolone adresy ¼ród³owe +acl_any=Dowolny adres +acl_fdoms=Skrzynka @ domeny +acl_faddrs=Wymienione adresy +acl_fdom=Dowolny adres @ domena +acl_fromname=Rzeczywista nazwa dla adresu ¼ród³owego +acl_apath=Ograniczyæ pliki i&npsp;programy do umieszczonych w&npsp;katalogu +acl_attach=Maksymalny ³±czny rozmiar za³±czników +acl_sent=Przechowywaæ wys³an± pocztê w skrzynce +acl_canattach=Mo¿e do³±czaæ pliki z serwera? +log_delmail=Usuniêto $1 wiadomo¶ci z $2 +log_send=Wys³ano wiadomo¶æ do $1 diff --git a/mailboxes/lang/pt b/mailboxes/lang/pt new file mode 100644 index 000000000..a5daa2533 --- /dev/null +++ b/mailboxes/lang/pt @@ -0,0 +1,36 @@ +mail_title=Email do Utilizador +mail_from=De +mail_date=Data +mail_subject=Assunto +mail_to=Para +mail_for=Em $1 +mail_compose=Compor novo correio +mail_return=email do utilizador +mail_ecannot=Você não está autorizado para ler o correio deste utilizador +view_title=Ler Correio +view_desc=Mensagem $1 em $2 +view_qdesc=Mensagem em lista de espera $1 +view_headers=Cabaçalhos de correio +view_attach=Anexos +view_reply=Responder ao autor +view_reply2=Responder a todos +view_forward=Reenviar +view_delete=Apagar +view_ecannot=Você não está autorizado para ler o correio deste utilizador +compose_title=Compor Email +reply_title=Responder ao Email +forward_title=Reenviar Email +reply_headers=Cabeçalhos de Correio +reply_attach=Anexos Reenviados +reply_attach2=Anexos +reply_send=Enviar +reply_ecannot=Você não está autorizado para enviar correio como sendo este utilizador +send_err=Erro ao enviar correio +send_eto=Falta o endereço do destinatário +send_title=Correio enviado +send_ok=O correio foi enviado com sucesso para $1 +send_ecannot=Você não está autorizado para enviar correio como sendo este utilizador +acl_none=Nenhum +acl_all=Todos +acl_read=Utilizadores cujo correio pode ser lido +acl_users=Utilizadores diff --git a/mailboxes/lang/sv b/mailboxes/lang/sv new file mode 100644 index 000000000..c1813667e --- /dev/null +++ b/mailboxes/lang/sv @@ -0,0 +1,75 @@ +mail_title=Användar-e-post +mail_from=Från +mail_date=Datum +mail_subject=Ärende +mail_to=Till +mail_cc=Kopia till +mail_bcc=Osynlig kopia till +mail_pri=Prioritet +mail_highest=Högsta +mail_high=Hög +mail_low=Låg +mail_lowest=Lägsta +mail_for=I $1 +mail_size=Storlek +mail_delete=Radera angivna brev +mail_compose=Skriv nytt brev +mail_return=användarpost +mail_ecannot=Du får inte läsa e-post till denna användare +mail_all=Välj allt +mail_invert=Välj allt utom redan valt +mail_search=Sök meddelanden där +mail_body=Brevkroppen +mail_match=innehåller +mail_ok=Sök +mail_nonefrom=Ingen +view_title=Läs e-post +view_desc=Brev $1 i $2 +view_qdesc=Köad e-post $1 +view_headers=Rubriker +view_attach=Bilagor +view_reply=Svara +view_reply2=Svara till alla +view_forward=Skicka vidare +view_delete=Radera +view_ecannot=Du får inte läsa e-post till denna användare +compose_title=Skriv brev +reply_title=Svara på brev +forward_title=Skicka vidare brev +reply_headers=Rubriker +reply_attach=Vidaresända bilagor +reply_attach2=Bilagor +reply_send=Skicka +reply_ecannot=Du får inte skicka e-post som denna användare +send_err=Det gick inte att skicka brevet +send_eto=Mottagaradress saknas +send_efrom=Avsändaradress saknas +send_title=Skickat brev +send_ok=Brevet skickat till $1 +send_ecannot=Du får inte skicka e-post som denna användare +send_esmtp=SMTP-kommando $1 misslyckades: $2 +send_eattach=Den sammanlagda storleken på bilagorna får inte vara större än $1 kB +send_eperms=Användare $1 kan inte läsa $2 +send_eperms2=Du får inte skicka filen $1 +delete_ecannot=Du får inte radera e-post från denna användare +delete_enone=Du har inte angivit vilket meddelande som ska tas bort +search_title=Sökresultat +search_ecannot=Du får inte söka i denna användares e-post +search_ematch=Du måste ange en text som brevet ska innehålla +search_none=Inget brev passade in på angivna villkor +acl_none=Inga +acl_same=Användare med samma namn +acl_all=Alla +acl_read=Användare vars e-post får läsas +acl_users=Endast användare +acl_userse=Alla utom användare +acl_usersg=Medlemmar i grupp +acl_from=Tillåtna avsändaradresser +acl_any=Alla +acl_fdoms=brevlåda@domäner +acl_faddrs=Angivna adresser +acl_fdom=valfri adress@domän +acl_apath=Begränsa filer och program till katalog +acl_attach=Maximal sammanlagd storlek på bilagor +log_delmail=Tog bort $1 brev från $2 +log_send=Skickade e-post till $1 diff --git a/mailboxes/lang/tr b/mailboxes/lang/tr new file mode 100644 index 000000000..9058a1c12 --- /dev/null +++ b/mailboxes/lang/tr @@ -0,0 +1,356 @@ +acl_all=Hepsi +acl_any=Herhangi bir adres +acl_apath=Dizin için program ve dosya limitleri +acl_asame=Kullanýcý adýyla ayný +acl_attach=En çok toplam posta ek dosyalarý boyutu +acl_canattach=Sunucu-sayfalarý dosyalarýný ekleyebilir mi? +acl_candetach=Dosyalarý sunucuya gönderebilir mi? +acl_dir=Dizindeki posta dosyalarýný okuyabilir mi +acl_dirauto=Otomatik olarak karar ver (bütün kullanýcýlarý burda veya baþka yerde görmek istemiyorsanýz) +acl_faddrs=Listelenmiþ alanlar +acl_fdom=Herhangi adres @ alan +acl_fdoms=Posta kutusu @ alanlar +acl_from=Ýzin verilebilir From: adresleri +acl_fromname=Gönderen adresi için gerçek isim +acl_none=Hiçbiri +acl_read=Kullanýcýlarýn okuyabilecekleri postalar +acl_same=Ayný isimli kullanýcý +acl_sec=Ýkincil gruplarý içer? +acl_sent=Gönderilen postalarý depola +acl_unlimited=Sýnýrsýz +acl_users=Sadece kullanýcýlar +acl_userse=Kullanýcýlardan baþka herkes +acl_usersg=Gruplarýn üyeleri +acl_usersm=Kullanýcý eþlemeleri +acl_usersu=Aralýkta UID'le beraber +black_already=$1 e-posta adresi SpamAssassin'in yasaklý listesindedir. +black_done=SpamAssassin tarafýndan yasaklanan adresler listesine $1 e-posta adresi eklendi. +black_title=Göndereni Yasaklama +compose_title=E-posta Gönder +confirm_ok=Þimdi Sil +confirm_title=Silmeyi Onayla +confirm_warn=$1 seçilmiþ mesajý silmeyi istiyor musun? +confirm_warn2=Posta kutusunun boyutu ve biçimi yüzünden, bu biraz zaman alýr. Silme bitene kadar, diger uygulamalar calýþtýrýlmamalýdýr. +confirm_warn3=Bu mesajý silmek istediðinizden emin misiniz? +confirm_warn4=Silme bitene kadar, diger uygulamalar calýþtýrýlmamalýdýr. +confirm_warnall=Bu dosyadaki tüm e-postalarý silmek istediðinizden emin misiniz? +delall_ok=Þimdi Sil +delall_rusure=$1'dan gelen $2 adet, toplamý $3 olan postalarý silmek istediðinizden emin misiniz. +delall_title=Tüm E-posta'yý Sil +delete_ebnone=Yasaklama için hiçbir posta seçilmedi +delete_ecannot=Bu kullanýcý olarak e-posta silmek için izininiz yoktur +delete_ecopycannot=Bu kullanýcýya posta kopyalama izniniz yok +delete_ecopynone=Kopyalama için seçilen posta yok +delete_ecopyuser=Posta kopyalanacak kullanýcý mevcut deðildir +delete_efnone=Yönlendirme hiçbir posta seçilmemiþ +delete_ehnone=Rapor için seçilmiþ posta yoktur +delete_emnone=Ýþaretlenecek posta yoktur +delete_emovecannot=Postayý belirlenmiþ kullanýcýya taþýmanýza izin verilmiyor +delete_emovenone=Taþýma için hiç posta seçilmemiþ +delete_emoveuser=Taþýnan mail için kullanýcý mevcut deðildir +delete_enone=Silmek için posta silinmedi +delete_ereport=Spam olarak raporlanamadý : $1 +delete_ernone=Spam olarak rapor edilmiþ posta yoktur +delete_errc=Posta kopyalama baþarýsýz +delete_errm=Posta taþýma baþarýsýz +delete_ewnone=Ýzin için seçilmiþ posta yoktur +delete_nobutton=Hiçbir tuþa basýlmadý +delete_ok=Þimdi Sil +delete_rusure=$2'nin seçilmiþ $1 mesajýný silmek istediðinizden emin misiniz? Dosya büyük bir dosya olduðu için silme iþlemi biraz zaman alabilir. Silme iþlemi bitinceye kadar, baska bir program caliþtýrmayýn. +delete_rusure2=$1'den gelen mesajý silmek istediðinizden emin misiniz? Dosya boyutunun büyüklüðü yüzünden silme iþlemi uzun sürebilir. Silme iþlemi bitene kadar baþka bir program caliþtýrmayýn. +delete_title=Postayý Sil +detach_edir=Saklamak için dosya veya dizin girilmedi +detach_eopen=$1 : $2 yi açmak baþarýsýz oldu +detach_err=Dosyayý çýkartýrken hata oluþtu +detach_ewrite=$1'e yazarken hata oluþtu : $2 +detach_ok=Sunucu taraflý $1 dosyasýna eklenti yaz ($2). +detach_title=Dosyayý Çýkar +emodified=Bu dizin son gözden geçirildiðinden beri deðiþtirildi! posta liste'ye geri dön ve tekrar dene. +enew_title=E-Postayý Düzenle +find_enone=Aramanýza uyan kullanýcý bulunamadý +find_fcount=Dizinler +find_group=Grup +find_home=Ev dizini +find_in=$1 içinde $2 +find_incount=E-postalar +find_real=Gerçek isim +find_results=$1 için yapýlan aramaya uyan kullanýcýlar .. +find_sentcount=Gönderildi +find_size=Posta boyutu +find_title=Arama Sonuçlarý +find_user=Kullanýcý Adý +folder_drafts=Taslaklar +folder_inbox=Gelen Kutusu +folder_sent=Gönderilen postalar +folder_trash=Çop Kutusu +forward_title=E-postayý Döndür +ham_report=Bu mesajý Razor ve SpamAssassin veritabanlarýna "spam deðil" olarak raporla .. +ham_title=Ýstenen Raporlama +index_contains=içeriyor +index_empty=Posta yok +index_eperl=Seçilen STMP doðrulama modu için $1 Perl modülüne ihtiyaç. buraya týklayara yükleyebilirsiniz +index_equals=Eþitlik +index_esystem=Sisteminizde desteklenen posta sunucularý (Qmail, Postfix ve Sendmail) yoktur. Posta sunucusunu ve mail yolunu açmak için modül yapýlandýrmasý'ný elle ayarlamaya gereksinim duyacaksýnýz. +index_esystem2=modül yapýlandýrma'daki mail sunucu ayarý sisteminizde bulunamadý. Doðru sunucuyu kullanmak için bu yapýlandýrmayý ayarlamanýz gerekmektedir. +index_esystem3=bu adresteki posta sistem ayarýna baglanýrken hata oluþtu : $2 +index_file=Dosyadaki postayý oku: +index_find=Kullanýcýlarý bul +index_header=Kullanýcý posta kutularý +index_none=Bu sistemde herhangi bir kullanýcýnýn e-posta'sýný okuma hakkýnýz yoktur. +index_nousers=Hiçbir kullanýcý bulunamadý' +index_nousersmail=E-posta'sý olan hiçbir kullanýcý bulunamadý. +index_return=kullanýcý listesi +index_system0=Mail sunucusu: Postfix +index_system1=Mail sunucusu: Sendmail +index_system2=Posta sunucusu: Qmail +index_title=Kullanýcý Postasýný Oku +index_toomany=Sisteminizde bir sayfada görüntülenemeyecek kadar çok kullanýcýnýz var. +ldap_ebase=LDAP tabanlý DN ayarý modül yapýlandýrýlmasýnda yoktur +ldap_econn=$2 portundaki LDAP sunucusu $1'e baðlanýrken hata oluþtu +ldap_ehost=Modül yapýlandýrýlmasýnda LDAP sunucu ayarý yoktur +ldap_elogin=LDAP sunucusu $1'e $2 olarak baðlanýrken hata oluþtu : $3 +ldap_emod=LDAP'a baðlanmak için gerekli Perl modülü $1 kayýp +ldap_eport=Modül yapýlandýrýlmasýnda geçerli LDAP sunucu portu yok +ldap_euser=Modül yapýlandýrýlmasýnda LDAP giriþ ayarý yoktur +log_copymail=$1 adet mesaj $2' den $3' e kopyalandý +log_delmail=$2'den $1 mesajý silindi +log_movemail=$1 adet mesaj $2' den $3' e taþýndý +log_read=$1 için postalarý oku +log_send=$1'e posta gönderildi +mail_addresses=Adres Defterini Yönet +mail_advanced=Geliþmiþ Arama +mail_all=Hepsini seç +mail_bcc=Bcc +mail_black=Gönderenleri Yasakla +mail_body=Mesaj içeriði +mail_cc=Cc +mail_compose=Yeni posta oluþtur +mail_copy=Kopyala: +mail_crypt=Þifrele: +mail_date=Tarih +mail_delall=Hepsini Sil +mail_delete=Seçilen mesajlarý sil +mail_deleteall=Hepsini Sil +mail_deltrash=Çöpü Boþalt +mail_ecannot=Bu kullanýcýnýn e-postasýný okumak için izininiz yoktur +mail_eexists=Mesaj artýk mevcut deðil! +mail_efile=Posta dosyasý mevcut deðil +mail_err=Bu klasörde listelenen maillerde bir hata oluþtu : $1 +mail_esystem=$1 posta sistemine baðlanýrken hata oluþtu. Bu hata sistem yöneticisi tarafýndan düzeltilmelidir. +mail_fchange=Deðiþtir +mail_folder=Dizin +mail_folders=Dizinleri Yönet +mail_for=$1'de +mail_for2=Kullanýcý $1 için +mail_forward=Yönlendir +mail_from=Nereden +mail_fromsrch=Ayný gönderici.. +mail_high=Yüksek +mail_highest=En yüksek +mail_indexlink=Posta kutusuna geri dön +mail_invert=Seçimi ters çevir +mail_jump=Sayfaya atla : +mail_level=Skor +mail_login=Sisteme Giriþ +mail_logindesc=$1 posta sunucusunda posta kutunuzdaki
mailinize eriþmek için bir kullanýcý ve þifre girmelinýz. +mail_loginheader=POP3 sunucusuna giriþ yap +mail_loginheader2=IMAP sunucusuna giriþ yap +mail_loginmailbox=IMAP posta kutusu +mail_loginpass=Þifre +mail_loginuser=Kullanýcý adý +mail_logout=POP3 giriþini deðiþtir +mail_logout2=IMAP giriþini deðiþtir +mail_low=Düþük +mail_lowest=en düþük +mail_mark=Ýþaretle: +mail_mark0=Okunmamýþ +mail_mark1=Okunmuþ +mail_mark2=Özel +mail_match=eþleþmeler +mail_move=Taþý: +mail_nocrypt=<Þifreleme yapma> +mail_none=$1'de bu kullanýcýnýn mesajý yoktur +mail_nonefrom=Hiçbiri +mail_normal=Normal +mail_nosign=<Ýmzalama> +mail_nosort=Yeniden sýrala. +mail_of=için +mail_ok=Ara +mail_open=Aç +mail_pos=$4 içerisinde $3 mesajdan $1'den $2'ye kadar olanlar +mail_pri=Öncelik +mail_replyto=Yanýt adresi +mail_reset=Temizle +mail_return=Kullanýcý e-posta +mail_return2=Kullanýcý E-postasý +mail_rfc=Satýrdan +mail_samecrypt=<Varýþ yerlerinden anahtarlar> +mail_search=Mesajlarýn aranýlacaðý yer +mail_search2=Araþtýr: +mail_search3=Yukarýdaki skorla bul: +mail_sent=Gönderilmiþ mesaj listesinde +mail_sig=Ýmzayý Düzenle +mail_sign=Anahtarla iþaretle: +mail_size=Boyut +mail_subject=Konu +mail_subsrch=Ayný konu.. +mail_title=Kullanýcý E-Posta +mail_to=Nereye +mail_tosrch=Ayný alýcý.. +mail_unknown=Bilinmeyen +mail_white=Gönderenlere Ýzin Ver +razor_deleted=.. yapýldý, ve mesaj silindi. +razor_done=.. yapýldý +razor_err=.. hata oluþtu! Hata mesajýnýn nedenini yukarýda görebilirsiniz. +razor_report=Bu mesajý Razor ve diðer SpamAssassin spam-bloklama veritabanlarýna raporla .. +razor_report2=Seçili mesajlarý Razor ve diðer SpamAssassin spam-bloklama veritabanlarýna raporla .. +razor_report3=Seçili mesajlarý Razor ve diðer SpamAssassin spam-bloklama veritabanlarýndan kaldýr .. +razor_title=Spam Olarak Raporla +razor_title2=Seçilmiþ Rapor +reply_attach=Döndürülmüþ ekler +reply_attach2=Ekler +reply_body=Mesaj metni +reply_draft=Taslak olarak Kaydet +reply_ecannot=Bu kullanýcý olarak e-posta göndermek için izininiz yoktur +reply_efwdnone=Yönlendirilmiþ postalarýn hiçbiri mevcut deðil +reply_errc=Posta kopyalama hatasý +reply_errm=Posta taþýma hatasý +reply_headers=Posta baþlýklarý +reply_mailforward=Yönlendirilmiþ mesajlar +reply_return=posta oluþtur +reply_send=Gönder +reply_spell=Heceleme hatalarýný kontrol et? +reply_title=E-postayý Geri Gönder +search_all=Bütün dizinlerde +search_allstatus=Herhangi +search_ecannot=Bu kullanýcý e-postalarýný aramak için izininiz yoktur +search_efield=Bir arama tipi seçmelisiniz. +search_elatest=Arama için hatalý veya gecersiz sayýda mesaj +search_ematch=Takip eden kutuya bir yazý girmelisiniz +search_enone=Arama kriteri girilmedi +search_escore=Hatalý veya geçersiz spam skoru +search_ewhat=$1 satýrý için karþýlaþtýrýlacak metin yok +search_latest=Aranacak mesajlar +search_latestnum=Sadece en son +search_limit=(son $1 mesajdan) +search_local=Yerel klasörlerde +search_msg2=$1 için arama sonuçlarý +search_msg4=Arama sonuçlarý +search_msg5=Spam skoru $1 için arama sonuçlarý +search_nolatest=Klasördekilerin hepsi +search_none=Mesaj bulunamadý. +search_onestatus=Sadece durum +search_results2=$2'ye uyan $1 posta mesajý bulundu +search_results3=$1 eposta mesajý $2'yi karþýlamadý +search_results4=$1 posta mesajý aramanýzla uyumludur +search_results5=$2'nin $3'ü karþýladýðý durumda $1 adet mesaj bulundu +search_status=Durumla beraber +search_title=Arama sonuçlarý +search_withstatus=, durum kodu $1 olan +send_done=.. yapýldý. +send_draft=$1'e gönderilecek mesaj taslak dizinine kaydedildi. +send_drafting=$1'e gönderilecek postayý taslak dizinine kaydediyor .. +send_eattach=Ek dosyalarýn boyutu $1 KB'den daha büyük olmamalýdýrlar. +send_eattachsize=Mail eklentisi maksimum boyut olan $1'i aþtý +send_ecannot=Bu kullanýcý olarak e-posta göndermek için izininiz yoktur +send_ecrypt=Mesajý þifrelerken hata oluþtu : $1 +send_efile=Eklentiyi okurken hata oluþtu $1 : $2 +send_efrom=Nereden adresini girmelisiniz +send_ekey=$1 e-posta için anahtar bulunamamýþtýr +send_eline=$1. satýrda : +send_epass=Bu mesajý imzalayamazsýnýz cünkü geçerli parolanýz GnuPG modülünde tanýmlanmamýþtýr. +send_epath=Sendmail çalýþtýrýlabilir dosyasý $1 mevcut deðildir. +send_eperms=$1 kullanýcýsý $2'yi okuyamaz +send_eperms2=$1 dosyasýný göndermeniz için izin verilmedi +send_err=Postanýn gönderilmesinde hata oluþtu +send_esign=Mesajý imzalarken hata oluþtu : $1 +send_esmtp=SMTP komutu $1'de hata oluþtu : $2 +send_espell=Mesajýnýzda heceleme hatalarý bulundu .. +send_esubject=Hatalý eposta konusu +send_eto=Nereye adresini girmelisiniz +send_eword=$1 yanlýþ hecelendi +send_eword2=$1 yanlýþ hecelendi. Olasý düzeltme $2'dir +send_ok=Posta $1'e baþarýyla gönderildi +send_sending=$1'e posta gönderiliyor .. +send_title=Posta Gönder +sform_all=<Bütün klasörler> +sform_and=Aþaðýdaki tüm kriterleri karþýlayan mesajlarý bul .. +sform_body=mesaj gövdesi +sform_cc=Cc: baþlýk +sform_date=Tarih: baþlýk +sform_folder=dizin(ler)de +sform_from=Kimden: baþlýk +sform_headers=herhangi baþlýk +sform_local=<Yerel klasörler> +sform_neg0=içeriyor +sform_neg1=içermez +sform_ok=Þimdi Ara +sform_or=Aþaðýdaki bazý kriterleri karþýlayan mesajlarý bul .. +sform_return=geliþmiþ arama formu +sform_size=mesaj boyutu +sform_subject=Konu: Baþlýk +sform_text=metin +sform_title=Geliþmiþ Arama +sform_to=Kime: baþlýk +sform_where=Nerede +view_allheaders=Bütün baþlýklarý gözden geçir +view_ashtml=HTML olarak görüntüle +view_astext=Metin olarak görüntüle +view_attach=Ekler +view_black=Göndereni Yasakla +view_body=Mesaj metni +view_crypt=GnuPG posta þifre açma +view_crypt_1=Mesaj þifrelendi, fakat GnuPG desteði yüklenmedi. +view_crypt_2=þifeyi açmak için hata oluþtu : $1 +view_crypt_3=Posta þifresi baþarýlý bir þekilde açýldý +view_crypt_4=Mesajýn þifreli bölümü baþarýlý bir þekilde açýldý. +view_dall=<Bütün dosyalar> +view_delete=Sil +view_desc=Mesaj $1, $2'de +view_desc2=$2 kullanýcýsý için $1 mesajý +view_desc3=Mesaj $1 +view_detach=Ayrýlan dosya: +view_diagnostic-code=Hata nedeni +view_dir=sunucu dosyasý ve ya dizini: +view_dstatus=Hatalý teslimat durumu +view_dstatusok=Baþarýlý teslimat durumu +view_ecannot=Bu kullanýcýnýn e-postasýný okumak için izininiz yoktur +view_egone=Bu mesaj artýk mevcut deðil +view_enew=Yeni olarak düzenle +view_eugone=Bu kullanýcý mevcut deðildir +view_final-recipient=Son alýcý +view_folder=Posta kutusuna geri dön +view_forward=Döndür +view_gnupg=GnuPG imza doðrulamasý +view_gnupg_0=$1'in imzasý geçerli. +view_gnupg_1=$1'in imzasý geçerlidir, fakat güven iliþkisi kurulamadý. +view_gnupg_2=$1'in imzasý geçerli DEÐÝLDÝR. +view_gnupg_3=Anahtar kodu $1 listenizde yoktur, bu yüzden imza dogrulanamadý. +view_gnupg_4=Ýmzayý doðrularken hata oluþtu : $1 +view_ham=Ýstenen Rapor +view_headers=Posta baþlýklarý +view_mark=Ýþaretle: +view_mark0=Okunmamýþ +view_mark1=Oku +view_mark2=Özel +view_noheaders=Temel baþlýklarý gözden geçir +view_print=Yazdýr + +view_qdesc=Kuyruða konulmuþ mesaj $1 +view_raw=Okunmamýþ mesaja gözat +view_razor=Spam Olarak Raporla +view_razordel=Çop Postalarý Raporlama ve Sil +view_recv=Anahtar sunucusundan $1 kodlu anahtarý al. +view_remote-mta=Uzak posta sunucusu +view_reply=Geri gönder +view_reply2=Hepsine geri gönder +view_reporting-mta=Raporlanan posta sunucusu +view_return=orjinal eposta +view_sent=$1 mesajý gönderilmiþ posta listesinde +view_strip=Eklentileri Çýkar +view_sub=Baðlý E-posta +view_title=E-posta oku +view_white=Gönderene Ýzin Ver +white_already=$1 e-posta adresi SpamAssassin'in izinli adres listelerindedir. +white_done=$1 e-posta adresi SpamAssassin'in izinli adres listelerine eklendi. +white_title=Ýzinli Gönderici diff --git a/mailboxes/lang/zh_CN b/mailboxes/lang/zh_CN new file mode 100644 index 000000000..92b116353 --- /dev/null +++ b/mailboxes/lang/zh_CN @@ -0,0 +1,106 @@ +mail_title=Óû§Óʼþ +mail_from=À´×Ô +mail_date=ÈÕÆÚ +mail_subject=Ö÷Ìâ +mail_to=·¢Íù +mail_cc=תËÍ +mail_bcc=ÃÜËÍ +mail_pri=ÓÅÏȼ¶ +mail_highest=×î¸ß +mail_high=¸ß +mail_normal=Ò»°ã +mail_low=µÍ +mail_lowest=×îµÍ +mail_for=ÔÚ $1 +mail_for2=ÓÃÓÚÓû§$1 +mail_sent=ÔÚ·¢ËÍÓʼþÁбíÖÐ +mail_size=´óС +mail_delete=ɾ³ýÑ¡¶¨µÄÓʼþ +mail_compose=±àдÐÂÓʼþ +mail_return=Óû§ÓÊÏä +mail_ecannot=ÄúûÓÐÔĶÁ¸ÃÓû§µÄÓʼþµÄȨÏÞ +mail_all=È«²¿Ñ¡ÖÐ +mail_invert=ÄæÏòѡȡ +mail_search=ѰÕÒÓʼþ£¬ÆäÖÐ +mail_body=ÕýÎÄ +mail_match=Æ¥Åä +mail_ok=ËÑË÷ +mail_nonefrom=ÎÞ +mail_mark=½«ÒÑÑ¡ÖеÄÓʼþ±ê¼ÇΪ£º +mail_mark0=δÔĶÁ +mail_mark1=ÔĶÁ +mail_mark2=ÌØ±ð +mail_forward=ת·¢ÒÑÑ¡ÔñµÄ +mail_rfc=¼Ä¼þÈËÐÐ +view_title=ÔĶÁÓʼþ +view_desc=$2ÖеÄÓʼþ$1 +view_desc2=Óû§$2µÄÓʼþ$1 +view_desc3=Óʼþ$1 +view_sent=ÒÑ·¢ËÍÓʼþÁбíÖеÄÓʼþ$1 +view_qdesc=´ý·¢µÄÓʼþ $1 +view_headers=ÓʼþÍ· +view_allheaders=²é¿´ËùÓÐÓʼþÍ· +view_noheaders=²ì¿´»ù±¾ÓʼþÍ· +view_attach=¸½¼þ +view_reply=»Ø¸´ +view_reply2=»Ø¸´¸øËùÓÐ +view_enew=±à¼­ÐÂÓʼþ +view_forward=ת·¢ +view_delete=ɾ³ý +view_strip=ÒÆ³ý¸½¼þ +view_ecannot=ÄúûÓÐÔĶÁ¸ÃÓû§µÄÓʼþµÄȨÏÞ +view_mark0=δÔĶÁ +view_mark1=ÔĶÁ +view_mark2=ÌØ±ð +view_return=Ô­¼þ +view_sub=´øÓи½¼þµÄÓʼþ +compose_title=±àдÓʼþ +reply_title=»Ø¸´Óʼþ +forward_title=ת·¢Óʼþ +reply_headers=ÓʼþÍ· +reply_attach=ת·¢µÄ¸½¼þ +reply_mailforward=ÒÑת·¢µÄÓʼþ +reply_attach2=¿Í»§¶ËºÍ·þÎñÆ÷µÄ¸½¼þ +reply_send=·¢ËÍ +reply_ecannot=ÄúûÓÐÒÔÕâ¸öÓû§µÄÉí·Ý·¢ËÍÓʼþµÄȨÏÞ +send_err=ÎÞ·¨·¢ËÍÓʼþ +send_eto=δÊäÈë¡°·¢Íù¡±µØÖ· +send_efrom=¶ªÊ§¡°À´×Ô¡±µØÖ· +send_title=ÒÑ·¢Ë͵ÄÓʼþ +send_ok=ÓʼþÒѳɹ¦·¢Ë͵½ $1 +send_ecannot=ÄúûÓÐÒÔÕâ¸öÓû§µÄÉí·Ý·¢ËÍÓʼþµÄȨÏÞ +send_esmtp=SMTP ÃüÁî $1 ʧ°Ü£º$2 +send_eattach=¸½¼þ´óС×ÜÁ¿²»Äܳ¬¹ý $1 kB¡£ +send_eperms=Óû§ $1 ²»ÄÜÔĶÁ $2 +send_eperms2=ÄúûÓз¢ËÍÎļþ$1µÄȨÏÞ +send_epath=Sendmail³ÌÐò $1²»´æÔÚ¡£ +delete_ecannot=ÄúûÓÐɾ³ýÕâ¸öÓû§µÄÓʼþµÄȨÏÞ +delete_enone=ûѡÔñҪɾ³ýµÄÓʼþ +delete_emnone=ûÓÐÑ¡ÔñÒª±ê¼ÇµÄÓʼþ +search_title=ËÑË÷½á¹û +search_ecannot=ÄúûÓÐËÑË÷¸ÃÓû§µÄÓʼþµÄȨÏÞ +search_ematch=Äú±ØÐëÔÙ´ÎÊäÈëÆ¥ÅäµÄÎı¾¡£ +search_none=ÕÒ²»µ½Óʼþ¡£ +search_results2=$1ÓʼþÆ¥Åä$2 +search_results3=$1Óʼþ²»Æ¥Åä$2 +acl_none=ÎÞ +acl_same=ͬÃûµÄÓû§ +acl_all=ËùÓÐ +acl_read=¿ÉÔĶÁÆäÓʼþµÄÓû§ +acl_users=½öÏÞÓû§ +acl_userse=ËùÓÐÓû§³ýÁË +acl_usersg=×éµÄ³ÉÔ± +acl_from=ÔÊÐí¡°À´×Ô¡±µØÖ· +acl_any=ÈκεØÖ· +acl_fdoms=ÓÊÏä @ Óò +acl_faddrs=ÁгöµÄµØÖ· +acl_fdom=ÈκεØÖ· @ Óò +acl_fromname=À´Ô´µØÖ·µÄÕæÃû +acl_apath=ÏÞÖÆÎļþºÍ³ÌÐòµ½Ä¿Â¼ +acl_attach=×î´ó¸½¼þ×Ü´óС +acl_sent=ÔÚÓÊÏäÖд¢´æÒÑ·¢Ë͵ÄÓʼþ +acl_canattach=¿ÉÒÔÕ³¸½·þÎñÆ÷ÎļþÂ𣿠+acl_usersm=Æ¥ÅäµÄÓû§ +acl_asame=ÓëÓû§Ïàͬ +log_delmail=ÒÑ´Ó $2 ɾ³ý $1Óʼþ +log_send=ÒÑ·¢ËÍÓʼþµ½ $1 diff --git a/mailboxes/lang/zh_CN.UTF-8 b/mailboxes/lang/zh_CN.UTF-8 new file mode 100644 index 000000000..fe7967897 --- /dev/null +++ b/mailboxes/lang/zh_CN.UTF-8 @@ -0,0 +1,106 @@ +mail_title=用户邮件 +mail_from=æ¥è‡ª +mail_date=日期 +mail_subject=主题 +mail_to=å‘å¾€ +mail_cc=è½¬é€ +mail_bcc=å¯†é€ +mail_pri=优先级 +mail_highest=最高 +mail_high=高 +mail_normal=一般 +mail_low=低 +mail_lowest=最低 +mail_for=在 $1 +mail_for2=用于用户$1 +mail_sent=在å‘é€é‚®ä»¶åˆ—表中 +mail_size=å¤§å° +mail_delete=删除选定的邮件 +mail_compose=编写新邮件 +mail_return=用户邮箱 +mail_ecannot=您没有阅读该用户的邮件的æƒé™ +mail_all=全部选中 +mail_invert=逆å‘é€‰å– +mail_search=寻找邮件,其中 +mail_body=正文 +mail_match=åŒ¹é… +mail_ok=æœç´¢ +mail_nonefrom=æ—  +mail_mark=将已选中的邮件标记为: +mail_mark0=未阅读 +mail_mark1=阅读 +mail_mark2=特别 +mail_forward=转å‘已选择的 +mail_rfc=寄件人行 +view_title=阅读邮件 +view_desc=$2中的邮件$1 +view_desc2=用户$2的邮件$1 +view_desc3=邮件$1 +view_sent=å·²å‘é€é‚®ä»¶åˆ—表中的邮件$1 +view_qdesc=å¾…å‘的邮件 $1 +view_headers=邮件头 +view_allheaders=查看所有邮件头 +view_noheaders=察看基本邮件头 +view_attach=附件 +view_reply=å›žå¤ +view_reply2=回å¤ç»™æ‰€æœ‰ +view_enew=编辑新邮件 +view_forward=è½¬å‘ +view_delete=删除 +view_strip=移除附件 +view_ecannot=您没有阅读该用户的邮件的æƒé™ +view_mark0=未阅读 +view_mark1=阅读 +view_mark2=特别 +view_return=原件 +view_sub=带有附件的邮件 +compose_title=编写邮件 +reply_title=回å¤é‚®ä»¶ +forward_title=转å‘邮件 +reply_headers=邮件头 +reply_attach=转å‘的附件 +reply_mailforward=已转å‘的邮件 +reply_attach2=客户端和æœåŠ¡å™¨çš„é™„ä»¶ +reply_send=å‘é€ +reply_ecannot=您没有以这个用户的身份å‘é€é‚®ä»¶çš„æƒé™ +send_err=无法å‘é€é‚®ä»¶ +send_eto=未输入“å‘å¾€â€åœ°å€ +send_efrom=丢失“æ¥è‡ªâ€åœ°å€ +send_title=å·²å‘é€çš„邮件 +send_ok=邮件已æˆåŠŸå‘é€åˆ° $1 +send_ecannot=您没有以这个用户的身份å‘é€é‚®ä»¶çš„æƒé™ +send_esmtp=SMTP 命令 $1 失败:$2 +send_eattach=附件大尿€»é‡ä¸èƒ½è¶…过 $1 kB。 +send_eperms=用户 $1 ä¸èƒ½é˜…读 $2 +send_eperms2=您没有å‘逿–‡ä»¶$1çš„æƒé™ +send_epath=Sendmailç¨‹åº $1ä¸å­˜åœ¨ã€‚ +delete_ecannot=您没有删除这个用户的邮件的æƒé™ +delete_enone=没选择è¦åˆ é™¤çš„邮件 +delete_emnone=æ²¡æœ‰é€‰æ‹©è¦æ ‡è®°çš„邮件 +search_title=æœç´¢ç»“æžœ +search_ecannot=您没有æœç´¢è¯¥ç”¨æˆ·çš„邮件的æƒé™ +search_ematch=æ‚¨å¿…é¡»å†æ¬¡è¾“入匹é…的文本。 +search_none=找ä¸åˆ°é‚®ä»¶ã€‚ +search_results2=$1邮件匹é…$2 +search_results3=$1邮件ä¸åŒ¹é…$2 +acl_none=æ—  +acl_same=åŒå的用户 +acl_all=所有 +acl_read=å¯é˜…读其邮件的用户 +acl_users=ä»…é™ç”¨æˆ· +acl_userse=所有用户除了 +acl_usersg=组的æˆå‘˜ +acl_from=å…许“æ¥è‡ªâ€åœ°å€ +acl_any=ä»»ä½•åœ°å€ +acl_fdoms=邮箱 @ 域 +acl_faddrs=åˆ—å‡ºçš„åœ°å€ +acl_fdom=ä»»ä½•åœ°å€ @ 域 +acl_fromname=æ¥æºåœ°å€çš„真å +acl_apath=é™åˆ¶æ–‡ä»¶å’Œç¨‹åºåˆ°ç›®å½• +acl_attach=æœ€å¤§é™„ä»¶æ€»å¤§å° +acl_sent=在邮箱中储存已å‘é€çš„邮件 +acl_canattach=å¯ä»¥ç²˜é™„æœåŠ¡å™¨æ–‡ä»¶å—? +acl_usersm=匹é…的用户 +acl_asame=ä¸Žç”¨æˆ·ç›¸åŒ +log_delmail=已从 $2 删除 $1邮件 +log_send=å·²å‘é€é‚®ä»¶åˆ° $1 diff --git a/mailboxes/lang/zh_TW.Big5 b/mailboxes/lang/zh_TW.Big5 new file mode 100644 index 000000000..7530c3856 --- /dev/null +++ b/mailboxes/lang/zh_TW.Big5 @@ -0,0 +1,265 @@ +acl_all=¥þ³¡ +acl_any=¥ô¦ó¶l¥ó¦ì§} +acl_apath=­­¨îÀɮשMµ{¦¡¨ì¥Ø¿ý +acl_asame=»P¨Ï¥ÎªÌ¬Û¦P +acl_attach=³Ì¤jªþ¥óÁ`¤j¤p +acl_canattach=¥i¥Hªþ¥[¦øªA¾¹ÀɶܡH +acl_candetach=¥i¥Hªþ±aÀÉ®×¨ì¦øªA¾¹? +acl_faddrs=¦C¥Xªº¶l¥ó¦ì§} +acl_fdom=¥ô¦ó¶l¥ó¦ì§}¦bºô°ì +acl_fdoms=«H½c¦bºô°ì +acl_from=¨Ì¾Ú¶l¥ó¦ì§}¤¹³\ +acl_fromname=¨Ó·½¦a§}ªº¯u¹ê¦WºÙ +acl_none=µL +acl_read=¥i¥HŪ¨ú­þ¨Ç¨Ï¥ÎªÌªº¶l¥ó +acl_same=¦P¦Wªº¨Ï¥ÎªÌ +acl_sent=¦b¶l½c¤¤Àx¦s¤wµo°eªº¶l¥ó +acl_users=¥u¦³¨Ï¥ÎªÌ +acl_userse=¥þ³¡, °£¤F¨Ï¥ÎªÌ +acl_usersg=²Õªº¦¨­û +acl_usersm=²Å¦Xªº¨Ï¥ÎªÌ +acl_usersu=¦bUID½d³ò¤º +compose_title=¼g§@¹q¤l¶l¥ó +confirm_ok=²{¦b§R°£ +confirm_title=½T»{§R°£ +confirm_warn=±z½T©w­n§R°£ $1 «Ê¿ï¨úªº°T®§? +confirm_warn2=¦]¬°±zªº«H½c¤j¤p»P®æ¦¡¡A»Ý­n¤@ÂI®É¶¡¡Aª½¨ì§R°£§¹¦¨«á¡A¤£·|°õ¦æ¨ä¥L°Ê§@ +confirm_warn3=±z½T©w­n§R°£°T®§ +confirm_warn4=ª½¨ì§R°£§¹¦¨¡A¤£·|°õ¦æ¨ä¥L°Ê§@¡C +confirm_warnall=±z½T©w­n§R°£¸ê®Æ§¨¤¤©Ò¦³°T®§? +delete_ecannot=±z¤£³Q¤¹³\§R°£³o­Ó¨Ï¥ÎªÌªº¶l¥ó +delete_ecopycannot=±z¤£³Q¤¹³\½Æ»s¶l¥ó¨ì¯S©wªº¨Ï¥ÎªÌ +delete_ecopynone=¥¼¿ï¨ú½Æ»s¶l¥ó +delete_ecopyuser=½Æ»s¶l¥ó¨Ï¥ÎªÌ¤£¦s¦b +delete_efnone=¥¼¿ï¨úÂà±H¶l¥ó +delete_emnone=¨S¦³¿ï¾Ü­n¼Ð°Oªº¶l¥ó +delete_emovecannot=±z¤£³Q¤¹³\²¾°Ê¶l¥ó¨ì¯S©wªº¨Ï¥ÎªÌ +delete_emovenone=¥¼¿ï²¾°Ê±H¶l¥ó +delete_emoveuser=¨Ï¥ÎªÌ²¾°Ê¶l¥ó¤£¦s¦b +delete_enone=¨S¦³¿ï¾Ü­n§R°£ªº¶l¥ó +delete_nobutton=¥¼«ö«ö¶s +delete_ok=²{¦b§R°£ +delete_rusure=±z½T©w­n±q$2§R°£ $1 «Ê¿ï¨úªº°T®§?¤jÀɮתº¶l¥ó»Ý­n¤@¨Ç®É¶¡¡Aª½¨ì§R°£§¹¦¨¡A¤£·|°õ¦æ¨ä¥L°Ê§@¡C +delete_rusure2=±z½T©w­n§R°£ $1 «Ê¿ï¨úªº°T®§?¤jÀɮתº¶l¥ó»Ý­n¤@¨Ç®É¶¡¡Aª½¨ì§R°£§¹¦¨¡A¤£·|°õ¦æ¨ä¥L°Ê§@¡C +delete_title=§R°£¶l¥ó +detach_edir=¨S¦³¿é¤JÀx¦sªºÀɮשΥؿý +detach_eopen=¶}©l$1¥¢±Ñ:$2 +detach_err=ªþ¥[ÀÉ®×¥¢±Ñ +detach_ewrite=¼gµ¹$1¥¢±Ñ:$2 +detach_ok=±q¦øªAºÝªþ¥[ÀÉ®×$1($2) +detach_title=ªþ¥[ÀÉ®× +enew_title=½s¿è¶l¥ó +find_enone=¨S¦³±z·j´M©Ò²Å¦Xªº¨Ï¥ÎªÌ +find_group=¸s²Õ +find_home=®a¥Ø¿ý +find_real=¯u¹ê¦WºÙ +find_results=·j´M$1²Å¦Xªº¨Ï¥ÎªÌ.. +find_size=¶l¥ó¤j¤p +find_title=·j´Mµ²ªG +find_user=¨Ï¥ÎªÌ¦WºÙ +folder_drafts=¯ó½Z +folder_inbox=¦¬¥ó§¨ +folder_sent=¶Ç°e¶l¥ó +folder_trash=©U§£±í +forward_title=Âà±H¨ì¹q¤l¶l¥ó +index_contains=¥]§t +index_empty=µL¶l¥ó +index_equals=µ¥©ó +index_esystem=¦b±zªº¨t²Î¤W§ä¤£¨ì¤ä´©ªº¶l¥ó¦øªA¾¹(Qmail, Postfix ©M Sendmail)¡A±z¥i¥H¤â°Ê½Õ¾ã¼Ò²Õ²ÕºA¨Ó³]©w¶l¥ó¦øªA¾¹©M¶l¥ó¸ô®| +index_esystem2=¦b±zªº¨t²Î¤W§ä¤£¨ì¼Ò²Õ²ÕºA¤¤³]©wªº¶l¥ó¦øªA¾¹¡A±z»Ý­n½Õ¾ã¥¿½Tªº¦øªA¾¹²ÕºA¡C +index_find=¦b¨Ï¥ÎªÌ¦WºÙ¤¤§ä´M¨Ï¥ÎªÌ +index_header=¨Ï¥ÎªÌ«H½c +index_none=±z¤£³Q¤¹³\¥ô¦ó¦¹¨t²Î¤W¨Ï¥ÎªÌŪ¨ú¶l¥ó +index_return=Sendmail ²ÕºA +index_system0=¶l¥ó¦øªA¾¹:Postfix +index_system1=¶l¥ó¦øªA¾¹:Sendmail +index_system2=¶l¥ó¦øªA¾¹:Qmail +index_title=Sendmail ²ÕºA +index_toomany=¦b±zªº¨t²Î¤W¦³¤Ó¦hªº¨Ï¥ÎªÌ¡A©Ò¥HµLªk¦P®ÉÅã¥Ü¦b¤@­¶¤W +log_copymail=±q $2 ¨ì $3 ½Æ»s$1«Ê°T®§ +log_delmail=¤w±q $2 §R°£ $1¶l¥ó +log_movemail=±q $2 ¨ì $3 ²¾°Ê$1«Ê°T®§ +log_send=¤wµo°e¶l¥ó¨ì $1 +mail_addresses=ºÞ²zÁpµ¸¤H +mail_advanced=¶i¶¥·j´M +mail_all=¿ï¾Ü¥þ³¡ +mail_bcc=ÁôÂðƥ» +mail_body=¥»Åé +mail_cc=°Æ¥»§Û°e +mail_compose=¼g§@·s¶l¥ó +mail_copy=½Æ»s¨ì: +mail_crypt=GnuPG¥[±Kµ¹: +mail_date=¤é´Á +mail_delall=¥þ³¡§R°£ +mail_delete=§R°£¿ï¾Üªº¶l¥ó +mail_deltrash=ªÅ©U§£±í +mail_ecannot=±z¤£³Q¤¹³\Ū¨ú³o­Ó¨Ï¥ÎªÌªº¶l¥ó +mail_eexists=°T®§¤£¦s¦b¤F! +mail_err=¦¹¸ê®Æ§¨¤¤¶l¥ó¦Cªíµo¥Í¤@­Ó¿ù»~ : $1 +mail_fchange=Åܧó +mail_folder=¸ê®Æ§¨ +mail_folders=ºÞ²z¸ê®Æ§¨ +mail_for=¦b $1 +mail_for2=¥Î©ó¨Ï¥ÎªÌ$1 +mail_forward=Âà±H¤w¿ï¾Üªº +mail_from=±H¥ó¤H +mail_high=°ª +mail_highest=³Ì°ª +mail_invert=¤Ï¦V¿ï¨ú +mail_jump=¸õ¦Ü­¶­±: +mail_login=µn¤J +mail_logindesc=±z¥²¶·¦b¶l¥ó¥D¾÷$1¤W
¿é¤J¨Ï¥ÎªÌ¦WºÙ©M±K½X¨Ó¶i¤J«H½c +mail_loginheader=POP3µn¤J¦øªA¾¹ +mail_loginmailbox=IMAP«H½c +mail_loginpass=±K½X +mail_loginuser=¨Ï¥ÎªÌ¦WºÙ +mail_logout=ÅܧóPOP3µn¤J +mail_logout2=ÅܧóIMAPµn¤J +mail_low=§C +mail_lowest=³Ì§C +mail_mark=±N¿ï¨úªº¶l¥ó¼Ð°O¬°¡G +mail_mark0=¥¼¾\Ū +mail_mark1=¾\Ū +mail_mark2=¯S§O +mail_match=²Å¦X +mail_move=²¾¦Ü: +mail_nocrypt=<¤£½s½X> +mail_none=«H½c¤¤¨S¦³¶l¥ó +mail_nonefrom=µL +mail_normal=¤@¯ë +mail_nosign=<¤£Ã±ÃÒ> +mail_of=ªº +mail_ok=·j´M +mail_pos=¶l¥ó $1 ¨ì $2 ¦@ $3 +mail_pri=Àu¥ý­È +mail_replyto=¦^¦Ü +mail_reset=²M°£ +mail_return=¨Ï¥ÎªÌ¹q¤l¶l¥ó +mail_return2=¨Ï¥ÎªÌ¶l¥ó +mail_rfc=±H¥ó¤H +mail_samecrypt=<ª÷Æ_±q¥Øªº¦ì¸m> +mail_search=§ä´M¶l¥ó, ¨ä¤¤ +mail_search2=·j´M: +mail_sent=¦bµo°e¶l¥ó¦Cªí¤¤ +mail_sig=½s¿èñ¦W +mail_sign=GnuPG¥[±K: +mail_size=¤j¤p +mail_subject=¥DÃD +mail_title=¨Ï¥ÎªÌ¹q¤l¶l¥ó +mail_to=¦¬¥ó¤H +reply_attach=Âà±Hªþ¥ó§¨±a +reply_attach2=ªþ¥ó§¨±a +reply_body=°T®§¤å¦r +reply_draft=¦s¦Ü¯ó½Z +reply_ecannot=±z¤£³Q¤¹³\¥H³o­Ó¨Ï¥ÎªÌ¦WºÙ°e¥X¶l¥ó +reply_headers=¶l¥ó¼ÐÀY +reply_mailforward=¤wÂà±Hªº¶l¥ó +reply_send=°e¥X +reply_spell=«÷¦rÀˬd? +reply_title=¦^ÂШì¹q¤l¶l¥ó +search_all=¦b©Ò¦³¸ê®Æ§¨ +search_ecannot=±z¤£³Q¤¹³\·j´M³o­Ó¨Ï¥ÎªÌªº¶l¥ó +search_efield=±z¥²¶·¿ï¨ú·j´MÃþ«¬ +search_ematch=±z¥²¶·¿é¤J·j´Mªº±ø¥ó +search_enone=¥¼¿é¤J±ø¥ó +search_ewhat=¥¼¿é¤J¦C$1²Å¦X¤å¦r +search_local=¦b¥»¦a¸ê®Æ§¨ +search_none=§ä¤£¨ì²Å¦Xªº¶l¥ó. +search_results2=$1¶l¥ó²Å¦X$2 +search_results3=$1¶l¥ó¤£²Å¦X$2 +search_results4=$1«Ê¶l¥ó°T®§²Å¦X±zªº·j´M +search_title=·j´Mµ²ªG +send_draft=±Hµ¹$1Àx¦s¨ì¯ó½Z¸ê®Æ§¨ +send_eattach=ªþ¥ó¤j¤pÁ`¦X¤£¯à¶W¹L $1 kB¡C +send_eattachsize=¶l¥óªþ¥[ÀɶW¹L¤¹³\³Ì¤jªº¤j¤p$1 ¦ì¤¸²Õ +send_ecannot=±z¤£³Q¤¹³\¥H³o­Ó¨Ï¥ÎªÌ¦WºÙ°e¥X¶l¥ó +send_ecrypt=°T®§½s½X¥¢±Ñ:$1 +send_efile=¾\Ūªþ±aÀÉ$1¥¢±Ñ : $2 +send_efrom=¿ò¥¢±H¥ó¤H¶l¥ó¦ì§} +send_ekey=¦b¶l¥ó$1§ä¤£¨ìª÷Æ_ +send_eline=¦b½u$1¤W: +send_epass=±z¤£¯à¹ï°T®§§@¼Æ¦ìñ³¹¡A¦]¬°±z©|¥¼³]©wGunPG¼Ò²Õ¸Ìªº³q¦æ½X +send_epath=Sendmailµ{¦¡ $1¤£¦s¦b¡C +send_eperms=¨Ï¥ÎªÌ $1 ¤£¯à¾\Ū $2 +send_eperms2=±z¤£³Q¤¹³\µo°eÀÉ$1 +send_err=¶l¥ó°e¥X¥¢±Ñ +send_esign=¼Æ¦ìñ³¹°T®§¥¢±Ñ: $1 +send_esmtp=SMTP ©R¥O $1 ¥¢±Ñ: $2 +send_espell=¦b±zªº°T®§¤¤§ä¨ì¤U¦C«÷¦r¿ù»~ .. +send_eto=¿ò¥¢¦¬¥ó¤H¶l¥ó¦ì§} +send_eword=¿ù¦r$1 +send_eword2=¿ù¦r$1 - ¥i¯à¥¿½Tªº¬O $2 +send_ok=¶l¥ó¦¨¥\ªº°eµ¹ $1 +send_title=°e¥X¶l¥ó +sform_all=<©Ò¦³¸ê®Æ§¨> +sform_and=§ä¨ì¤U¦C²Å¦X©Ò¦³±ø¥ó°T®§ .. +sform_body=°T®§¤º®e +sform_cc=°Æ¥»: ÀÉÀY +sform_date=¤é´Á:ÀÉÀY +sform_folder=¦b¸ê®Æ§¨ +sform_from=±q:ÀÉÀY +sform_headers=¥ô¦óÀÉÀY +sform_local=<¥»¦a¸ê®Æ§¨> +sform_neg0=¥]§t +sform_neg1=¤£¥]§t +sform_ok=±µ¨ü +sform_or=§ä¨ì¤U¦C²Å¦X¥ô¤@±ø¥ó°T®§ .. +sform_return=¶i¶¥·j´M +sform_size=°T®§¤j¤p +sform_subject=¥D¦®: ÀÉÀY +sform_text=¦b¤å¦r +sform_title=¶i¶¥·j´M +sform_to=¦¬¥ó¤H: ÀÉÀY +sform_where=­þ¸Ì +view_allheaders=¬d¬Ý©Ò¦³¶l¥óÀÉÀY +view_ashtml=À˵øHTML +view_astext=À˵ø¤å¦r +view_attach=ªþ¥ó§¨±a +view_black=«ÊÂê±H¥óªÌ +view_body=°T®§¤å¦r +view_crypt=GnuPG¶l¥ó¸Ñ±K +view_crypt_1=°T®§¤w¥[±K¡A¦ýGnuPG¤ä´©©|¥¼¦w¸Ë +view_crypt_2=¸Ñ±K°T®§¥¢±Ñ: $1 +view_crypt_3=¶l¥ó¦¨¥\¸Ñ±K +view_crypt_4=¥[±K«OÅ@¶l¥ó¦¨¥\¸Ñ±K +view_dall=<©Ò¦³ÀÉ®×> +view_delete=§R°£ +view_desc=¶l¥ó $1 ¦b $2 +view_desc2=¨Ï¥ÎªÌ$2ªº¶l¥ó$1 +view_desc3=¶l¥ó$1 +view_detach=ªþ¥[ÀÉ®×: +view_diagnostic-code=¥¢±Ñ­ì¦] +view_dir=¨ì¦øªA¾¹ÀɮשΥؿý +view_dstatus=¶Ç°eª¬ºA¥¢±Ñ +view_ecannot=±z¤£³Q¤¹³\Ū¨ú³o­Ó¨Ï¥ÎªÌªº¶l¥ó +view_egone=°T®§¤£¦s¦b +view_enew=½s¿è·s¶l¥ó +view_final-recipient=³Ì«á¦¬¥óªÌ +view_folder=ªð¦^«H½c +view_forward=Âà±H +view_gnupg=GnuPG»{ÃÒñ³¹ +view_gnupg_0=$1ñ³¹½T»{ +view_gnupg_1=$1ñ³¹¦³®Ä¡A¦ýµLªk«Ø¥ß©U§£±í +view_gnupg_2=$1ñ³¹©|¥¼½T»{ +view_gnupg_3=±zªº²M³æ¤¤µLª÷Æ_$1¡A©Ò¥Hñ³¹µL®Ä +view_gnupg_4=½T»{ñ³¹ +view_headers=¶l¥ó¼ÐÀY +view_mark=¼Ð°O¬°: +view_mark0=¥¼¾\Ū +view_mark1=¾\Ū +view_mark2=¯S§O +view_noheaders=¹î¬Ý°ò¥»¶l¥óÀÉÀY +view_print=¦C¦L +view_qdesc=¦î¦C¤¤ªº¶l¥ó $1 +view_raw=À˵ø­ì©l°T®§ +view_razor=¦^³øµ¹Razor +view_recv=±qª÷Æ_¥D¾÷¨ú±oª÷Æ_$1. +view_remote-mta=»·ºÝ¶l¥ó¦øªA¾¹ +view_reply=¦^ÂÐ +view_reply2=¦^Âе¹¥þ³¡ +view_reporting-mta=¦^³ø¶l¥ó¦øªA¾¹ +view_return=­ì©l¶l¥ó +view_sent=¤wµo°e¶l¥ó¦Cªí¤¤ªº¶l¥ó$1 +view_strip=²¾°£ªþ¥ó +view_sub=ªþ±aªº¶l¥ó +view_title=Ū¨ú¹q¤l¶l¥ó diff --git a/mailboxes/lang/zh_TW.UTF-8 b/mailboxes/lang/zh_TW.UTF-8 new file mode 100644 index 000000000..78be3cb51 --- /dev/null +++ b/mailboxes/lang/zh_TW.UTF-8 @@ -0,0 +1,265 @@ +acl_all=全部 +acl_any=任何郵件ä½å€ +acl_apath=é™åˆ¶æª”案和程å¼åˆ°ç›®éŒ„ +acl_asame=èˆ‡ä½¿ç”¨è€…ç›¸åŒ +acl_attach=æœ€å¤§é™„ä»¶ç¸½å¤§å° +acl_canattach=å¯ä»¥é™„加伺æœå™¨æª”嗎? +acl_candetach=å¯ä»¥é™„帶檔案到伺æœå™¨? +acl_faddrs=列出的郵件ä½å€ +acl_fdom=任何郵件ä½å€åœ¨ç¶²åŸŸ +acl_fdoms=信箱在網域 +acl_from=便“šéƒµä»¶ä½å€å…許 +acl_fromname=來æºåœ°å€çš„真實å稱 +acl_none=ç„¡ +acl_read=å¯ä»¥è®€å–哪些使用者的郵件 +acl_same=åŒå的使用者 +acl_sent=在郵箱中儲存已發é€çš„郵件 +acl_users=åªæœ‰ä½¿ç”¨è€… +acl_userse=全部, 除了使用者 +acl_usersg=組的æˆå“¡ +acl_usersm=符åˆçš„使用者 +acl_usersu=在UID範åœå…§ +compose_title=寫作電å­éƒµä»¶ +confirm_ok=ç¾åœ¨åˆªé™¤ +confirm_title=確èªåˆªé™¤ +confirm_warn=您確定è¦åˆªé™¤ $1 å°é¸å–的訊æ¯? +confirm_warn2=因為您的信箱大å°èˆ‡æ ¼å¼ï¼Œéœ€è¦ä¸€é»žæ™‚間,直到刪除完æˆå¾Œï¼Œä¸æœƒåŸ·è¡Œå…¶ä»–動作 +confirm_warn3=您確定è¦åˆªé™¤è¨Šæ¯ +confirm_warn4=直到刪除完æˆï¼Œä¸æœƒåŸ·è¡Œå…¶ä»–動作。 +confirm_warnall=您確定è¦åˆªé™¤è³‡æ–™å¤¾ä¸­æ‰€æœ‰è¨Šæ¯? +delete_ecannot=您ä¸è¢«å…許刪除這個使用者的郵件 +delete_ecopycannot=您ä¸è¢«å…許複製郵件到特定的使用者 +delete_ecopynone=未é¸å–複製郵件 +delete_ecopyuser=複製郵件使用者ä¸å­˜åœ¨ +delete_efnone=未é¸å–轉寄郵件 +delete_emnone=æ²’æœ‰é¸æ“‡è¦æ¨™è¨˜çš„郵件 +delete_emovecannot=您ä¸è¢«å…許移動郵件到特定的使用者 +delete_emovenone=未é¸ç§»å‹•寄郵件 +delete_emoveuser=使用者移動郵件ä¸å­˜åœ¨ +delete_enone=æ²’æœ‰é¸æ“‡è¦åˆªé™¤çš„郵件 +delete_nobutton=未按按鈕 +delete_ok=ç¾åœ¨åˆªé™¤ +delete_rusure=您確定è¦å¾ž$2刪除 $1 å°é¸å–的訊æ¯?大檔案的郵件需è¦ä¸€äº›æ™‚間,直到刪除完æˆï¼Œä¸æœƒåŸ·è¡Œå…¶ä»–動作。 +delete_rusure2=您確定è¦åˆªé™¤ $1 å°é¸å–的訊æ¯?大檔案的郵件需è¦ä¸€äº›æ™‚間,直到刪除完æˆï¼Œä¸æœƒåŸ·è¡Œå…¶ä»–動作。 +delete_title=刪除郵件 +detach_edir=沒有輸入儲存的檔案或目錄 +detach_eopen=é–‹å§‹$1失敗:$2 +detach_err=附加檔案失敗 +detach_ewrite=寫給$1失敗:$2 +detach_ok=從伺æœç«¯é™„加檔案$1($2) +detach_title=附加檔案 +enew_title=編輯郵件 +find_enone=沒有您æœå°‹æ‰€ç¬¦åˆçš„使用者 +find_group=群組 +find_home=家目錄 +find_real=真實å稱 +find_results=æœå°‹$1符åˆçš„使用者.. +find_size=éƒµä»¶å¤§å° +find_title=æœå°‹çµæžœ +find_user=使用者å稱 +folder_drafts=è‰ç¨¿ +folder_inbox=收件夾 +folder_sent=傳é€éƒµä»¶ +folder_trash=垃圾桶 +forward_title=轉寄到電å­éƒµä»¶ +index_contains=åŒ…å« +index_empty=無郵件 +index_equals=等於 +index_esystem=在您的系統上找ä¸åˆ°æ”¯æ´çš„郵件伺æœå™¨(Qmail, Postfix å’Œ Sendmail),您å¯ä»¥æ‰‹å‹•調整模組組態來設定郵件伺æœå™¨å’Œéƒµä»¶è·¯å¾‘ +index_esystem2=在您的系統上找ä¸åˆ°æ¨¡çµ„組態中設定的郵件伺æœå™¨ï¼Œæ‚¨éœ€è¦èª¿æ•´æ­£ç¢ºçš„伺æœå™¨çµ„態。 +index_find=在使用者å稱中找尋使用者 +index_header=使用者信箱 +index_none=您ä¸è¢«å…許任何此系統上使用者讀å–郵件 +index_return=Sendmail 組態 +index_system0=郵件伺æœå™¨:Postfix +index_system1=郵件伺æœå™¨:Sendmail +index_system2=郵件伺æœå™¨:Qmail +index_title=Sendmail 組態 +index_toomany=åœ¨æ‚¨çš„ç³»çµ±ä¸Šæœ‰å¤ªå¤šçš„ä½¿ç”¨è€…ï¼Œæ‰€ä»¥ç„¡æ³•åŒæ™‚顯示在一é ä¸Š +log_copymail=從 $2 到 $3 複製$1å°è¨Šæ¯ +log_delmail=已從 $2 刪除 $1郵件 +log_movemail=從 $2 到 $3 移動$1å°è¨Šæ¯ +log_send=已發é€éƒµä»¶åˆ° $1 +mail_addresses=管ç†è¯çµ¡äºº +mail_advanced=進階æœå°‹ +mail_all=鏿“‡å…¨éƒ¨ +mail_bcc=éš±è—副本 +mail_body=本體 +mail_cc=å‰¯æœ¬æŠ„é€ +mail_compose=寫作新郵件 +mail_copy=複製到: +mail_crypt=GnuPG加密給: +mail_date=日期 +mail_delall=全部刪除 +mail_delete=åˆªé™¤é¸æ“‡çš„郵件 +mail_deltrash=空垃圾桶 +mail_ecannot=您ä¸è¢«å…許讀å–這個使用者的郵件 +mail_eexists=訊æ¯ä¸å­˜åœ¨äº†! +mail_err=此資料夾中郵件列表發生一個錯誤 : $1 +mail_fchange=變更 +mail_folder=資料夾 +mail_folders=管ç†è³‡æ–™å¤¾ +mail_for=在 $1 +mail_for2=用於使用者$1 +mail_forward=è½‰å¯„å·²é¸æ“‡çš„ +mail_from=寄件人 +mail_high=高 +mail_highest=最高 +mail_invert=åå‘é¸å– +mail_jump=跳至é é¢: +mail_login=登入 +mail_logindesc=您必須在郵件主機$1上
輸入使用者å稱和密碼來進入信箱 +mail_loginheader=POP3登入伺æœå™¨ +mail_loginmailbox=IMAPä¿¡ç®± +mail_loginpass=密碼 +mail_loginuser=使用者å稱 +mail_logout=變更POP3登入 +mail_logout2=變更IMAP登入 +mail_low=低 +mail_lowest=最低 +mail_mark=å°‡é¸å–的郵件標記為: +mail_mark0=未閱讀 +mail_mark1=閱讀 +mail_mark2=特別 +mail_match=ç¬¦åˆ +mail_move=移至: +mail_nocrypt=<ä¸ç·¨ç¢¼> +mail_none=信箱中沒有郵件 +mail_nonefrom=ç„¡ +mail_normal=一般 +mail_nosign=<ä¸ç°½è­‰> +mail_of=çš„ +mail_ok=æœå°‹ +mail_pos=郵件 $1 到 $2 å…± $3 +mail_pri=優先值 +mail_replyto=回至 +mail_reset=清除 +mail_return=使用者電å­éƒµä»¶ +mail_return2=使用者郵件 +mail_rfc=寄件人 +mail_samecrypt=<金鑰從目的ä½ç½®> +mail_search=找尋郵件, 其中 +mail_search2=æœå°‹: +mail_sent=在發é€éƒµä»¶åˆ—表中 +mail_sig=編輯簽å +mail_sign=GnuPG加密: +mail_size=å¤§å° +mail_subject=主題 +mail_title=使用者電å­éƒµä»¶ +mail_to=收件人 +reply_attach=轉寄附件夾帶 +reply_attach2=附件夾帶 +reply_body=è¨Šæ¯æ–‡å­— +reply_draft=存至è‰ç¨¿ +reply_ecannot=您ä¸è¢«å…許以這個使用者å稱é€å‡ºéƒµä»¶ +reply_headers=郵件標頭 +reply_mailforward=已轉寄的郵件 +reply_send=é€å‡º +reply_spell=拼字檢查? +reply_title=回覆到電å­éƒµä»¶ +search_all=在所有資料夾 +search_ecannot=您ä¸è¢«å…許æœå°‹é€™å€‹ä½¿ç”¨è€…的郵件 +search_efield=您必須é¸å–æœå°‹é¡žåž‹ +search_ematch=您必須輸入æœå°‹çš„æ¢ä»¶ +search_enone=未輸入æ¢ä»¶ +search_ewhat=未輸入列$1ç¬¦åˆæ–‡å­— +search_local=在本地資料夾 +search_none=找ä¸åˆ°ç¬¦åˆçš„郵件. +search_results2=$1郵件符åˆ$2 +search_results3=$1郵件ä¸ç¬¦åˆ$2 +search_results4=$1å°éƒµä»¶è¨Šæ¯ç¬¦åˆæ‚¨çš„æœå°‹ +search_title=æœå°‹çµæžœ +send_draft=寄給$1儲存到è‰ç¨¿è³‡æ–™å¤¾ +send_eattach=附件大å°ç¸½åˆä¸èƒ½è¶…éŽ $1 kB。 +send_eattachsize=郵件附加檔超éŽå…許最大的大å°$1 ä½å…ƒçµ„ +send_ecannot=您ä¸è¢«å…許以這個使用者å稱é€å‡ºéƒµä»¶ +send_ecrypt=訊æ¯ç·¨ç¢¼å¤±æ•—:$1 +send_efile=閱讀附帶檔$1失敗 : $2 +send_efrom=éºå¤±å¯„件人郵件ä½å€ +send_ekey=在郵件$1找ä¸åˆ°é‡‘é‘° +send_eline=在線$1上: +send_epass=您ä¸èƒ½å°è¨Šæ¯ä½œæ•¸ä½ç°½ç« ï¼Œå› ç‚ºæ‚¨å°šæœªè¨­å®šGunPG模組裡的通行碼 +send_epath=Sendmailç¨‹å¼ $1ä¸å­˜åœ¨ã€‚ +send_eperms=使用者 $1 ä¸èƒ½é–±è®€ $2 +send_eperms2=您ä¸è¢«å…è¨±ç™¼é€æª”$1 +send_err=郵件é€å‡ºå¤±æ•— +send_esign=數ä½ç°½ç« è¨Šæ¯å¤±æ•—: $1 +send_esmtp=SMTP 命令 $1 失敗: $2 +send_espell=在您的訊æ¯ä¸­æ‰¾åˆ°ä¸‹åˆ—拼字錯誤 .. +send_eto=éºå¤±æ”¶ä»¶äººéƒµä»¶ä½å€ +send_eword=錯字$1 +send_eword2=錯字$1 - å¯èƒ½æ­£ç¢ºçš„æ˜¯ $2 +send_ok=郵件æˆåŠŸçš„é€çµ¦ $1 +send_title=é€å‡ºéƒµä»¶ +sform_all=<所有資料夾> +sform_and=æ‰¾åˆ°ä¸‹åˆ—ç¬¦åˆæ‰€æœ‰æ¢ä»¶è¨Šæ¯ .. +sform_body=訊æ¯å…§å®¹ +sform_cc=副本: 檔頭 +sform_date=日期:檔頭 +sform_folder=在資料夾 +sform_from=從:檔頭 +sform_headers=任何檔頭 +sform_local=<本地資料夾> +sform_neg0=åŒ…å« +sform_neg1=ä¸åŒ…å« +sform_ok=æŽ¥å— +sform_or=找到下列符åˆä»»ä¸€æ¢ä»¶è¨Šæ¯ .. +sform_return=進階æœå°‹ +sform_size=訊æ¯å¤§å° +sform_subject=主旨: 檔頭 +sform_text=在文字 +sform_title=進階æœå°‹ +sform_to=收件人: 檔頭 +sform_where=哪裡 +view_allheaders=查看所有郵件檔頭 +view_ashtml=檢視HTML +view_astext=檢視文字 +view_attach=附件夾帶 +view_black=å°éŽ–å¯„ä»¶è€… +view_body=è¨Šæ¯æ–‡å­— +view_crypt=GnuPG郵件解密 +view_crypt_1=訊æ¯å·²åŠ å¯†ï¼Œä½†GnuPG支æ´å°šæœªå®‰è£ +view_crypt_2=解密訊æ¯å¤±æ•—: $1 +view_crypt_3=郵件æˆåŠŸè§£å¯† +view_crypt_4=加密ä¿è­·éƒµä»¶æˆåŠŸè§£å¯† +view_dall=<所有檔案> +view_delete=刪除 +view_desc=郵件 $1 在 $2 +view_desc2=使用者$2的郵件$1 +view_desc3=郵件$1 +view_detach=附加檔案: +view_diagnostic-code=失敗原因 +view_dir=到伺æœå™¨æª”案或目錄 +view_dstatus=傳é€ç‹€æ…‹å¤±æ•— +view_ecannot=您ä¸è¢«å…許讀å–這個使用者的郵件 +view_egone=訊æ¯ä¸å­˜åœ¨ +view_enew=編輯新郵件 +view_final-recipient=最後收件者 +view_folder=返回信箱 +view_forward=轉寄 +view_gnupg=GnuPGèªè­‰ç°½ç«  +view_gnupg_0=$1ç°½ç« ç¢ºèª +view_gnupg_1=$1簽章有效,但無法建立垃圾桶 +view_gnupg_2=$1ç°½ç« å°šæœªç¢ºèª +view_gnupg_3=您的清單中無金鑰$1,所以簽章無效 +view_gnupg_4=確èªç°½ç«  +view_headers=郵件標頭 +view_mark=標記為: +view_mark0=未閱讀 +view_mark1=閱讀 +view_mark2=特別 +view_noheaders=察看基本郵件檔頭 +view_print=åˆ—å° +view_qdesc=佇列中的郵件 $1 +view_raw=æª¢è¦–åŽŸå§‹è¨Šæ¯ +view_razor=回報給Razor +view_recv=從金鑰主機å–得金鑰$1. +view_remote-mta=é ç«¯éƒµä»¶ä¼ºæœå™¨ +view_reply=回覆 +view_reply2=回覆給全部 +view_reporting-mta=回報郵件伺æœå™¨ +view_return=原始郵件 +view_sent=已發é€éƒµä»¶åˆ—表中的郵件$1 +view_strip=移除附件 +view_sub=附帶的郵件 +view_title=讀å–é›»å­éƒµä»¶ diff --git a/mailboxes/list_mail.cgi b/mailboxes/list_mail.cgi new file mode 100755 index 000000000..701210577 --- /dev/null +++ b/mailboxes/list_mail.cgi @@ -0,0 +1,245 @@ +#!/usr/local/bin/perl +# list_mail.cgi +# List the mail messages for some user in some folder + +require './mailboxes-lib.pl'; +&ReadParse(); +&can_user($in{'user'}) || &error($text{'mail_ecannot'}); +&is_user($in{'user'}) || -e $in{'user'} || &error($text{'mail_efile'}); +$uuser = &urlize($in{'user'}); + +if ($config{'track_read'}) { + dbmopen(%read, "$module_config_directory/$in{'user'}.read", 0600); + } + +# Make sure the mail system is OK +$err = &test_mail_system(); +if ($err) { + &ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1); + if (!$access{'noconfig'}) { + &ui_print_endpage(&text('index_esystem3', + "../config.cgi?$module_name", $err)); + } + else { + &ui_print_endpage(&text('mail_esystem', $err)); + } + } + +&ui_print_header(undef, $text{'mail_title'}, ""); +print &check_clicks_function(); +@folders = &list_user_folders_sorted($in{'user'}); +($folder) = grep { $_->{'index'} == $in{'folder'} } @folders; + +# Get folder-selection HTML +$sel = &folder_select(\@folders, $folder, "folder"); + +# Work out start from jump page +$perpage = $folder->{'perpage'} || $config{'perpage'}; +if ($in{'jump'} =~ /^\d+$/ && $in{'jump'} > 0) { + $in{'start'} = ($in{'jump'}-1)*$perpage; + } + +# View mail from the most recent +@mail = reverse(&mailbox_list_mails(-$in{'start'}, + -$in{'start'}-$perpage+1, + $folder, 1, \@error)); +if ($in{'start'} >= @mail && $in{'jump'}) { + # Jumped too far! + $in{'start'} = @mail - $perpage; + @mail = reverse(&mailbox_list_mails(-$in{'start'}, + -$in{'start'}-$perpage+1, + $folder, 1, \@error)); + } + +# Show page flipping arrows +&show_arrows(); + +print "

\n"; +print "\n"; +print "\n"; +print "\n"; +print "\n"; +if ($config{'top_buttons'} && @mail) { + &show_buttons(1, \@folders, $folder, \@mail, $in{'user'}); + @links = ( &select_all_link("d", 1), + &select_invert_link("d", 1) ); + print &ui_links_row(\@links); + } + +# Show error opening folder +if (@error) { + print "
\n"; + print &text('mail_err', $error[0] == 0 ? $error[1] : + &text('save_elogin', $error[1])),"\n"; + print "
\n"; + } + +$showto = $folder->{'sent'} || $folder->{'drafts'}; +@tds = ( "width=5", "nowrap", "nowrap", "nowrap", "nowrap" ); +if (@mail) { + # Show mailbox headers + local @hcols; + push(@hcols, ""); + push(@hcols, $showto ? $text{'mail_to'} : $text{'mail_from'}); + push(@hcols, $config{'show_to'} ? $showto ? ( $text{'mail_from'} ) : + ( $text{'mail_to'} ) : ()); + push(@hcols, $text{'mail_date'}); + push(@hcols, $text{'mail_size'}); + push(@hcols, $text{'mail_subject'}); + print &ui_columns_start(\@hcols, 100, 0, \@tds); + } + +# Show rows for actual mail messages +for($i=$in{'start'}; $i<@mail && $i<$in{'start'}+$perpage; $i++) { + local $idx = $mail[$i]->{'idx'}; + local $cols = 0; + local @cols; + local $from = $mail[$i]->{'header'}->{$showto ? 'to' : 'from'}; + $from = $text{'mail_unknown'} if ($from !~ /\S/); + push(@cols, &view_mail_link($in{'user'}, $folder, $idx, $from)); + if ($config{'show_to'}) { + push(@cols, &simplify_from( + $mail[$i]->{'header'}->{$showto ? 'from' : 'to'})); + } + push(@cols, &simplify_date($mail[$i]->{'header'}->{'date'})); + push(@cols, &nice_size($mail[$i]->{'size'}, 1024)); + local $tbl; + $tbl .= "". + "
".&simplify_subject($mail[$i]->{'header'}->{'subject'}). + " "; + if ($mail[$i]->{'header'}->{'content-type'} =~ /multipart\/\S+/i) { + $tbl .= ""; + } + local $p = int($mail[$i]->{'header'}->{'x-priority'}); + if ($p == 1) { + $tbl .= " "; + } + elsif ($p == 2) { + $tbl .= " "; + } + if (!$showto) { + if ($read{$mail[$i]->{'header'}->{'message-id'}} == 2) { + $tbl .= " "; + } + elsif ($read{$mail[$i]->{'header'}->{'message-id'}} == 1) { + $tbl .= " "; + } + } + $tbl .= "
\n"; + push(@cols, $tbl); + + if (&editable_mail($mail[$i])) { + print &ui_checked_columns_row(\@cols, \@tds, "d", $idx); + } + else { + print &ui_columns_row([ "", @cols ], \@tds); + } + + if ($config{'show_body'}) { + # Show part of the body too + &parse_mail($mail[$i]); + local $data = &mail_preview($mail[$i]); + if ($data) { + print " ", + &html_escape($data)," \n"; + } + } + } +if (@mail) { + print &ui_columns_end(); + print &ui_links_row(\@links); + } + +&show_buttons(2, \@folders, $folder, \@mail, $in{'user'}); +print "
\n"; +if ($config{'arrows'} && @mail) { + # Show page flipping arrows at the bottom + &show_arrows(); + } + +if (@mail) { + print "
\n"; + print "\n"; + + # Show simple search form + print "\n"; + + # Show advanced search button + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + + # Show delete all button + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + } + +# Show page jump form +$jumpform = (@mail > $perpage); +if ($jumpform) { + print "\n"; + print "\n"; + print "\n"; + print "\n"; + } +elsif (@mail) { + print "\n"; + } + +if (@mail) { + print "\n"; + print "
\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; + print "
\n"; + print "\n"; + printf " %s %s\n", + int($in{'start'} / $perpage)+1, $text{'mail_of'}, + int(@mail / $perpage)+1; + print "
\n"; + } + +if ($config{'log_read'}) { + &webmin_log("read", undef, $in{'user'}, + { 'file' => $folder->{'file'} }); + } +&ui_print_footer("", $text{'index_return'}); + +sub show_arrows +{ +print "
\n"; +print "
\n"; +print "\n"; +if ($in{'start'}+$perpage < @mail) { + printf "". + "\n", + $in{'start'}+$perpage, $uuser, $in{'folder'}; + } + +local $s = @mail-$in{'start'}; +local $e = @mail-$in{'start'}-$perpage+1; +if (@mail) { + print &text('mail_pos', $s, $e < 1 ? 1 : $e, scalar(@mail), $sel); + } +else { + print &text('mail_none', $sel); + } +print "\n"; + +if ($in{'start'}) { + printf "". + "\n", + $in{'start'}-$perpage, $uuser, $in{'folder'}; + } +print "
\n"; +} + diff --git a/mailboxes/log_parser.pl b/mailboxes/log_parser.pl new file mode 100644 index 000000000..b6d45b920 --- /dev/null +++ b/mailboxes/log_parser.pl @@ -0,0 +1,45 @@ +# log_parser.pl +# Functions for parsing this module's logs + +do 'mailboxes-lib.pl'; + +# parse_webmin_log(user, script, action, type, object, ¶ms) +# Converts logged information from this module into human-readable form +sub parse_webmin_log +{ +local ($user, $script, $action, $type, $object, $p, $long) = @_; +if ($action eq 'delmail') { + return &text("log_delmail", $p->{'count'}, "$p->{'from'}"); + } +elsif ($action eq 'movemail') { + return &text("log_movemail", $p->{'count'}, "$p->{'from'}", + "$p->{'to'}"); + } +elsif ($action eq 'copymail') { + return &text("log_copymail", $p->{'count'}, "$p->{'from'}", + "$p->{'to'}"); + } +elsif ($action eq 'send') { + return &text('log_send', &html_escape(&extract_email($p->{'to'}))); + } +elsif ($action eq 'read') { + return &text('log_read', &html_escape($object)); + } +else { + return undef; + } +} + +sub extract_email +{ +if ($_[0] =~ /([^<>"' \(\)]+\@[^<>"' \(\)]+)/) { + return $1; + } +elsif ($_[0] =~ /<(\S+)>/) { + return $1; + } +else { + return $_[0]; + } +} + diff --git a/mailboxes/mail_search.cgi b/mailboxes/mail_search.cgi new file mode 100755 index 000000000..77a9c0fbd --- /dev/null +++ b/mailboxes/mail_search.cgi @@ -0,0 +1,207 @@ +#!/usr/local/bin/perl +# mail_search.cgi +# Find mail messages matching some pattern + +require './mailboxes-lib.pl'; +&ReadParse(); +&can_user($in{'user'}) || &error($text{'mail_ecannot'}); +@folders = &list_user_folders($in{'user'}); +$uuser = &urlize($in{'user'}); + +if ($in{'simple'}) { + # Make sure a search was entered + $in{'search'} || &error($text{'search_ematch'}); + $ofolder = $folders[$in{'folder'}]; + } +else { + # Validate search fields + for($i=0; defined($in{"field_$i"}); $i++) { + if ($in{"field_$i"}) { + $in{"what_$i"} || &error(&text('search_ewhat', $i+1)); + $neg = $in{"neg_$i"} ? "!" : ""; + push(@fields, [ $neg.$in{"field_$i"}, $in{"what_$i"} ]); + } + } + @fields || &error($text{'search_enone'}); + $ofolder = $folders[$in{'ofolder'}]; + } + +if ($in{'folder'} == -2) { + $desc = $text{'search_local'}; + } +elsif ($in{'folder'} == -1) { + $desc = $text{'search_all'}; + } +else { + $folder = $folders[$in{'folder'}]; + $desc = &text('mail_for', $folder->{'name'}); + } +&ui_print_header($desc, $text{'search_title'}, "", undef, 0, 0, undef, + &folder_link($in{'user'}, $ofolder)); + +if ($in{'simple'}) { + if ($in{'search'} =~ /^(\S+):\s*(.*)$/) { + # A specific field was entered + local ($field, $what) = ($1, $2); + @searchlist = ( [ $field, $what ] ); + @rv = &mailbox_search_mail(\@searchlist, 0, $folder); + print "

",&text('search_results5', scalar(@rv), + "$field", "$what")," ..

\n"; + } + else { + # Just search by Subject and From in one folder + ($mode, $words) = &parse_boolean($in{'search'}); + if ($mode == 0) { + # Can just do a single 'or' search + @searchlist = map { ( [ 'subject', $_ ], + [ 'from', $_ ] ) } @$words; + @rv = &mailbox_search_mail(\@searchlist, 0, $folder); + } + elsif ($mode == 1) { + # Need to do two 'and' searches and combine + @searchlist1 = map { ( [ 'subject', $_ ] ) } @$words; + @rv1 = &mailbox_search_mail(\@searchlist1, 1, $folder); + @searchlist2 = map { ( [ 'from', $_ ] ) } @$words; + @rv2 = &mailbox_search_mail(\@searchlist2, 1, $folder); + @rv = @rv1; + %gotidx = map { $_->{'idx'}, 1 } @rv; + foreach $mail (@rv2) { + push(@rv, $mail) if (!$gotidx{$mail->{'idx'}}); + } + } + else { + &error($text{'search_eboolean'}); + } + print "

",&text('search_results2', scalar(@rv), + "$in{'search'}")," ..

\n"; + } + foreach $mail (@rv) { + $mail->{'folder'} = $folder; + } + } +else { + # Complex search, perhaps over multiple folders! + if ($in{'folder'} == -2) { + @sfolders = grep { !$_->{'remote'} } @folders; + $multi_folder = 1; + } + elsif ($in{'folder'} == -1) { + @sfolders = @folders; + $multi_folder = 1; + } + else { + @sfolders = ( $folder ); + } + foreach $sf (@sfolders) { + local @frv = &mailbox_search_mail(\@fields, $in{'and'}, $sf); + foreach $mail (@frv) { + $mail->{'folder'} = $sf; + } + push(@rv, @frv); + } + print "

",&text('search_results4', scalar(@rv))," ..

\n"; + } +@rv = reverse(@rv); + +$showto = $folder->{'sent'} || $folder->{'drafts'}; +if (@rv) { + print "

\n"; + print "\n"; + print "\n"; + if ($config{'top_buttons'}) { + if (!$multi_folder) { + &show_buttons(1, \@folders, $folder, \@rv, $in{'user'}, + 1); + @links = ( &select_all_link("d", 0), + &select_invert_link("d", 0) ); + print &ui_links_row(\@links); + } + } + + # Show mailbox headers + local @hcols; + push(@hcols, ""); + push(@hcols, $showto ? $text{'mail_to'} : $text{'mail_from'}); + push(@hcols, $config{'show_to'} ? $showto ? ( $text{'mail_from'} ) : + ( $text{'mail_to'} ) : ()); + push(@hcols, $text{'mail_date'}); + push(@hcols, $text{'mail_size'}); + push(@hcols, $text{'mail_subject'}); + print &ui_columns_start(\@hcols, 100, 0, \@tds); + } +foreach $m (@rv) { + local $idx = $m->{'idx'}; + local $mf = $m->{'folder'}; + local @cols; + local $from = &simplify_from($m->{'header'}->{ + $showto ? 'to' : 'from'}); + $from = $text{'mail_unknown'} if ($from !~ /\S/); + push(@cols, "$from"); + if ($config{'show_to'}) { + push(@cols, &simplify_from( + $m->{'header'}->{$showto ? 'from' : 'to'})); + } + push(@cols, &simplify_date($m->{'header'}->{'date'})); + push(@cols, &nice_size($m->{'size'}, 1024)); + local $tbl; + $tbl .= "". + "
".&simplify_subject($m->{'header'}->{'subject'}). + " "; + if ($m->{'header'}->{'content-type'} =~ /multipart\/\S+/i) { + $tbl .= ""; + } + local $p = int($m->{'header'}->{'x-priority'}); + if ($p == 1) { + $tbl .= " "; + } + elsif ($p == 2) { + $tbl .= " "; + } + if (!$showto) { + if ($read{$m->{'header'}->{'message-id'}} == 2) { + $tbl .= " "; + } + elsif ($read{$m->{'header'}->{'message-id'}} == 1) { + $tbl .= " "; + } + } + $tbl .= "
\n"; + push(@cols, $tbl); + + if (&editable_mail($m)) { + print &ui_checked_columns_row(\@cols, \@tds, "d", $idx); + } + elsif ($multi_folder) { + print &ui_columns_row([ $mf->{'name'}, @cols ], \@tds); + } + else { + print &ui_columns_row([ "", @cols ], \@tds); + } + + if ($config{'show_body'}) { + # Show part of the body too + &parse_mail($m); + local $data = &mail_preview($m); + if ($data) { + print " ", + &html_escape($data)," \n"; + } + } + } +if (@rv) { + print &ui_columns_end(); + if (!$multi_folder) { + print &ui_links_row(\@links); + &show_buttons(2, \@folders, $folder, \@rv, $in{'user'}, 1); + } + print "

\n"; + } +else { + print "$text{'search_none'}

\n"; + } + +&ui_print_footer($in{'simple'} ? ( ) : ( "search_form.cgi?folder=$in{'folder'}", + $text{'sform_return'} ), + "list_mail.cgi?user=$in{'user'}&folder=$in{'folder'}", $text{'mail_return'}, + "", $text{'index_return'}); + diff --git a/mailboxes/mailboxes-lib.pl b/mailboxes/mailboxes-lib.pl new file mode 100644 index 000000000..0ee3ebcb0 --- /dev/null +++ b/mailboxes/mailboxes-lib.pl @@ -0,0 +1,1034 @@ +# mailboxes-lib.pl +# Common functions for reading user mailboxes + +do '../web-lib.pl'; +do '../ui-lib.pl'; +do 'boxes-lib.pl'; +do 'folders-lib.pl'; +&init_config(); +%access = &get_module_acl(); +$config{'perpage'} ||= 20; +$config{'column_count'} ||= 4; +$gconfig{'logfiles'} = 0; # file change logging never needs to be done + +# Always detect the mail system if not set +if ($config{'mail_system'} == 3) { + $config{'mail_system'} = &detect_mail_system(); + &save_module_config() if ($config{'mail_system'} != 3); + } + +# send_mail_program(from, to) +# Returns the command for injecting email, based on the mail system in use +sub send_mail_program +{ +if ($config{'mail_system'} == 1 || $config{'mail_system'} == 0) { + # Use sendmail executable, or postfix wrapper + local %sconfig = &foreign_check("sendmail") && + $config{'mail_system'} == 1 ? + &foreign_config("sendmail") : ( ); + local $cmd = &has_command($sconfig{'sendmail_path'} || "sendmail"); + return "$cmd -t -f".quotemeta($_[0]) if ($cmd); + } +elsif ($config{'mail_system'} == 2) { + # Use qmail injector + local %qconfig = &foreign_check("qmailadmin") ? + &foreign_config("qmailadmin") : ( ); + local $cmd = ($qconfig{'qmail_dir'} || "/var/qmail"). + "/bin/qmail-inject"; + return $cmd if (-x $cmd); + } +else { + # Fallback - use sendmail command + local $cmd = &has_command("sendmail"); + return "$cmd -t -f".quotemeta($_[0]) if ($cmd); + } +return undef; +} + +# list_folders() +# Returns a list of all mailboxes for all users +sub list_folders +{ +local (@rv, $uinfo); +foreach $uinfo (&list_mail_users()) { + push(@rv, &list_user_folders(@$uinfo)); + } +return @rv; +} + +# list_user_folders(user, [other info]) +# Returns a list of folders for mailboxes belonging to some user +sub list_user_folders +{ +if ($_[0] =~ /^\//) { + # A path .. return a folder just for it + return ( { 'name' => $_[0], + 'file' => $_[0], + 'type' => &folder_type($_[0]), + 'mode' => 1, + 'index' => 0 } ); + } +else { + # Getting folders for a user + local @uinfo = @_ > 1 ? @_ : &get_mail_user($_[0]); + return ( ) if (!@uinfo); + local ($dir, $style, $mailbox, $maildir) = &get_mail_style(); + local @rv; + + # Check for user-specified mail store + if ($uinfo[10]) { + push(@rv, { 'name' => $uinfo[10], + 'file' => $uinfo[10], + 'type' => &folder_type($uinfo[10]), + 'mode' => 0, + 'index' => scalar(@rv) } ); + } + + # Check for /var/mail/USERNAME file + if ($dir) { + local $mf = &mail_file_style($uinfo[0], $dir, $style); + push(@rv, { 'type' => 0, + 'name' => $mf, + 'file' => $mf, + 'user' => $uinfo[0], + 'index' => scalar(@rv) }); + } + + # Check for file in home dir + if ($mailbox) { + local $mf = "$uinfo[7]/$mailbox"; + if (-r $mf || !@rv) { + push(@rv, { 'type' => 0, + 'name' => "~$uinfo[0]/$mailbox", + 'file' => $mf, + 'user' => $uinfo[0], + 'index' => scalar(@rv) }); + } + } + + # Check for directory in home dir + if ($maildir) { + local $mf = "$uinfo[7]/$maildir"; + if (-d $mf || !@rv) { + push(@rv, { 'type' => 1, + 'name' => "~$uinfo[0]/$maildir/", + 'file' => $mf, + 'user' => $uinfo[0], + 'index' => scalar(@rv) }); + } + } + + # Add any ~/mail files + if ($config{'mail_usermin'}) { + local $folders_dir = "$uinfo[7]/$config{'mail_usermin'}"; + foreach $p (&recursive_files($folders_dir, 1)) { + local $f = $p; + $f =~ s/^\Q$folders_dir\E\///; + push(@rv, { 'file' => $p, + 'name' => "~$uinfo[0]/$config{'mail_usermin'}/$f", + 'type' => &folder_type($p), + 'mode' => 0, + 'sent' => $f eq "sentmail", + 'index' => scalar(@rv) } ); + } + } + + # Add any Usermin external mail files + if ($config{'mailbox_user'}) { + local %userconfig; + &read_file_cached("$uinfo[7]/$config{'mailbox_user'}/config", + \%userconfig); + local $o; + foreach $o (split(/\t+/, $userconfig{'mailboxes'})) { + $o =~ /\/([^\/]+)$/ || next; + push(@rv, { 'name' => $o, + 'file' => $o, + 'type' => &folder_type($o), + 'mode' => 1, + 'index' => scalar(@rv) } ); + } + } + + foreach my $f (@rv) { + $f->{'user'} = $_[0]; + } + return @rv; + } +} + +sub list_user_folders_sorted +{ +return &list_user_folders(@_); +} + +# get_mail_style() +# Returns a list containing the mail base directory, directory style, +# mail file in home dir, and maildir in home dir +sub get_mail_style +{ +if (!defined(@mail_style_cache)) { + if ($config{'auto'}) { + # Based on mail server + if ($config{'mail_system'} == 1) { + # Can get paths from Sendmail module config + local %sconfig = &foreign_config("sendmail"); + if ($sconfig{'mail_dir'}) { + return ($sconfig{'mail_dir'}, $sconfig{'mail_style'}, undef, undef); + } + else { + return (undef, $sconfig{'mail_style'}, $sconfig{'mail_file'}, undef); + } + } + elsif ($config{'mail_system'} == 0) { + # Need to query Postfix module for paths + &foreign_require("postfix", "postfix-lib.pl"); + local @s = &postfix::postfix_mail_system(); + if ($s[0] == 0) { + return ($s[1], 0, undef, undef); + } + elsif ($s[0] == 1) { + return (undef, 0, $s[1], undef); + } + elsif ($s[0] == 2) { + return (undef, 0, undef, $s[1]); + } + } + elsif ($config{'mail_system'} == 2 || + $config{'mail_system'} == 4) { + # Need to check qmail module config for paths + local %qconfig = &foreign_config("qmailadmin"); + if ($qconfig{'mail_system'} == 1) { + return (undef, 0, undef, + $qconfig{'mail_dir_qmail'}); + } + elsif ($qconfig{'mail_dir'}) { + return ($qconfig{'mail_dir'}, $qconfig{'mail_style'}, undef, undef); + } + else { + return (undef, $qconfig{'mail_style'}, $qconfig{'mail_file'}, undef); + } + } + elsif ($config{'mail_system'} == 5) { + # vpopmail always uses ~/Maildir + return ( undef, 0, undef, "Maildir" ); + } + else { + # No mail server set yet! + return (undef, undef, undef, undef); + } + } + else { + # Use config settings + @mail_style_cache = ($config{'mail_dir'}, $config{'mail_style'}, + $config{'mail_file'}, $config{'mail_sub'}); + } + } +return @mail_style_cache; +} + +# can_user(username, [other details]) +sub can_user +{ +if (!&is_user($_[0])) { + # For external files, check if the file is under an allowed + # directory, or owned by an allowed user. + local @st = stat($_[0]); + local @uinfo = &get_mail_uid($st[4]); + return 1 if (@uinfo && &can_user(@uinfo)); + local $dir = &allowed_directory(); + return defined($dir) && &is_under_directory($dir, $_[0]); + } +local @u = @_ > 1 ? @_ : &get_mail_user($_[0]); +return 1 if ($_[0] && $access{'sent'} eq $_[0]); +return 1 if ($access{'mmode'} == 1); +return 0 if (!@u); +return 0 if ($_[0] =~ /\.\./); +return 0 if ($access{'mmode'} == 0); +local $u; +if ($access{'mmode'} == 2) { + # Is user in list of users? + foreach $u (split(/\s+/, $access{'musers'})) { + return 1 if ($u eq $_[0]); + } + return 0; + } +elsif ($access{'mmode'} == 4) { + # Is user the current Webmin user? + return 1 if ($_[0] eq $remote_user); + } +elsif ($access{'mmode'} == 5) { + # Is the user's gid in the list of groups? + local $gid; + foreach $gid (split(/\s+/, $access{'musers'})) { + return 1 if ($u[3] == $gid); + if ($access{'msec'}) { + # Check user's secondary groups too + local @ginfo = getgrgid($gid); + local @m = split(/\s+/, $ginfo[3]); + return 1 if (&indexof($_[0], @m) >= 0); + } + } + } +elsif ($access{'mmode'} == 3) { + # Is the user not in the list of denied users + foreach $u (split(/\s+/, $access{'musers'})) { + return 0 if ($u eq $_[0]); + } + return 1; + } +elsif ($access{'mmode'} == 6) { + # Does the user match a regexp? + return ($_[0] =~ /^$access{'musers'}$/); + } +elsif ($access{'mmode'} == 7) { + # Is the user's UID within the allowed range? + return (!$access{'musers'} || $u[2] >= $access{'musers'}) && + (!$access{'musers2'} || $u[2] <= $access{'musers2'}); + } +return 0; # can't happen! +} + +# movecopy_user_select(number, folders, folder, form-no) +# Returns HTML for entering a username to copy mail to +sub movecopy_user_select +{ +local $rv; +$rv .= ""; +$rv .= ""; +$rv .= &ui_user_textbox("mfolder$_[0]", undef, $_[3]); +return $rv; +} + +# need_delete_warn(&folder) +sub need_delete_warn +{ +return 1 if ($config{'delete_warn'} eq 'y'); +return 0 if ($config{'delete_warn'} eq 'n'); +local $mf; +return $_[0]->{'type'} == 0 && + ($mf = &folder_file($_[0])) && + &disk_usage_kb($mf)*1024 > $config{'delete_warn'}; +} + +@mail_system_modules = ( + [ undef, 4, \&check_qmail_ldap, \&test_qmail_ldap ], + [ undef, 5, \&check_vpopmail ], + [ "qmailadmin", 2 ], + [ "postfix", 0 ], + [ "sendmail", 1 ], + ); + +# detect_mail_system() +# Works out which mail server is installed +sub detect_mail_system +{ +foreach $m (@mail_system_modules) { + return $m->[1] if (&check_mail_system($m)); + } +return 3; +} + +# check_mail_system(&mailsystem) +sub check_mail_system +{ +if ($_[0]->[0]) { + # Just check module + return &foreign_installed($_[0]->[0]); + } +else { + # Call function + local $func = $_[0]->[2]; + return &$func($_[0]); + } +} + +# test_mail_system([&mailsystem]) +# Returns an error message if the mail system is invalid +sub test_mail_system +{ +local $ms; +if (!$ms) { + ($ms) = grep { $_->[1] == $config{'mail_system'} } @mail_system_modules; + } +if ($ms->[3]) { + local $func = $ms->[3]; + return &$func(); + } +return undef; +} + +# check_qmail_ldap() +# Make sure Qmail with LDAP extensions is installed +sub check_qmail_ldap +{ +return 0 if (&foreign_installed("qmailadmin", 1) != 2); +local %qconfig = &foreign_config("qmailadmin"); +return 0 if (!-r "$qconfig{'qmail_dir'}/control/ldapserver"); +return 1; +} + +# check_vpopmail() +# Make sure Qmail with VPopMail extensions is installed +sub check_vpopmail +{ +return 0 if (&foreign_installed("qmailadmin", 1) != 2); +return -x "$config{'vpopmail_dir'}/bin/vadddomain"; +} + +# test_qmail_ldap() +# Returns undef the Qmail+LDAP database can be contacted OK, or an error message +sub test_qmail_ldap +{ +$config{'ldap_host'} || return $text{'ldap_ehost'}; +$config{'ldap_port'} =~ /^\d+$/ || return $text{'ldap_eport'}; +$config{'ldap_login'} || return $text{'ldap_euser'}; +$config{'ldap_base'} || return $text{'ldap_ebase'}; +local $err = &connect_qmail_ldap(1); +return ref($err) ? undef : $err; +} + +# show_users_table(&users-list, [only-with-mail]) +# Outputs HTML for a table of users, with the appropriate sorting and mode +sub show_users_table +{ +local @users = @{$_[0]}; +local ($u, %size, %incount, %sentcount, %foldercount); +if ($config{'sort_mode'} == 2 || $config{'show_size'} > 0 || $_[1] || + $config{'show_count'} || $config{'show_sent'}) { + # Need to check folders + foreach $u (@users) { + next if ($config{'ignore_users_enabled'} == 1 && + $config{'ignore_users'} =~ /$u->[0]/); + local @folders = &list_user_folders(@$u); + $foldercount{$u->[0]} = scalar(@folders); + if ($config{'sort_mode'} == 2 || + $config{'show_size'} > 0 || $_[1]) { + # Compute size of folders + $size{$u->[0]} = $config{'size_mode'} ? + &folder_size(@folders) : + &folder_size($folders[0]); + } + if ($config{'show_count'}) { + # Get number of mails in inbox + $incount{$u->[0]} = &mailbox_folder_size($folders[0]); + } + if ($config{'show_sent'}) { + # Count number of messages in sent mail + local ($sent) = grep { $_->{'sent'} } @folders; + $sentcount{$u->[0]} = &mailbox_folder_size($sent) + if ($sent); + } + } + } + +# Sort by chosen mode +if ($config{'sort_mode'} == 2) { + @users = sort { $size{$b->[0]} <=> $size{$a->[0]} } @users; + } +elsif ($config{'sort_mode'} == 1) { + @users = sort { lc($a->[0]) cmp lc($b->[0]) } @users; + } + +local @allusers = @users; +if ($_[1]) { + # Limit to those with mail + @users = grep { $size{$_->[0]} } @users; + } + +# Show table of users +if (!@allusers) { + print "$text{'index_nousers'}

\n"; + } +elsif (!@users) { + print "$text{'index_nousersmail'}

\n"; + } +elsif ($config{'show_size'} == 2) { + # Show full user details + local %uconfig = &foreign_config("useradmin"); + local @ccols; + push(@ccols, $text{'find_incount'}) if ($config{'show_count'}); + push(@ccols, $text{'find_sentcount'}) if ($config{'show_sent'}); + push(@ccols, $text{'find_fcount'}) if (%foldercount); + print &ui_columns_start( [ $text{'find_user'}, $text{'find_real'}, + $text{'find_group'}, $text{'find_home'}, + $text{'find_size'}, @ccols ], 100); + foreach $u (@users) { + local $g = getgrgid($u->[3]); + next if ($config{'ignore_users_enabled'} == 1 && + $config{'ignore_users'} =~ /$u->[0]/); + $u->[6] =~ s/,.*$// if ($uconfig{'extra_real'}); + local $home = $u->[7]; + if (length($home) > 30) { + $home = "...".substr($home, -30); + } + local @ccols; + if ($config{'show_count'}) { + push(@ccols, int($incount{$u->[0]})) + } + if ($config{'show_sent'}) { + push(@ccols, int($sentcount{$u->[0]})) + } + if (%foldercount) { + push(@ccols, int($foldercount{$u->[0]})) + } + print &ui_columns_row( + [ "$u->[0]", + $u->[6], $g, $home, + $size{$u->[0]} == 0 ? $text{'index_empty'} : + &nice_size($size{$u->[0]}), + @ccols ], + [ undef, undef, undef, undef, "nowrap" ]); + } + print &ui_columns_end(); + } +else { + # Just showing username (and maybe size) + print &ui_table_start($text{'index_header'}, "width=100%", $config{'column_count'}); + local $i = 0; + foreach $u (@users) { + next if ($config{'ignore_users_enabled'} == 1 && + $config{'ignore_users'} =~ /$u->[0]/); + print "\n" if ($i % $config{'column_count'} == 0); + print ""; + print $u->[0]; + if ($config{'show_size'} == 1) { + local @folders = &list_user_folders(@$u); + local $total = &folder_size(@folders); + if ($size{$u->[0]} > 0) { + print $config{'show_size_below'} ? '
' : ' '; + print "("; + if (%foldercount) { + print &text('find_in', + &nice_size($size{$u->[0]}), + $foldercount{$u->[0]}); + } + else { + print &nice_size($size{$u->[0]}); + } + print ")"; + } + } + print "
\n"; + print "\n" if ($i % $config{'column_count'} == ($config{'column_count'} - 1)); + $i++; + } + if ($i % $config{'column_count'}) { + while($i++ % $config{'column_count'}) { print "\n"; } + print "\n"; + } + print &ui_table_end(); + } +} + +# switch_to_user(user) +# Switch to the Unix user that files are accessed as. +sub switch_to_user +{ +if (!defined($old_uid)) { + local @uinfo = &get_mail_user($_[0]); + $old_uid = $>; + $old_gid = $); + $) = "$uinfo[3] $uinfo[3]"; + $> = $uinfo[2]; + } +} + +sub switch_user_back +{ +if (defined($old_uid)) { + $> = $old_uid; + $) = $old_gid; + $old_uid = $old_gid = undef; + } +} + +sub folder_link +{ +return "$text{'mail_return2'}"; +} + +# get_from_address() +# Returns the address to use when sending email from a script +sub get_from_address +{ +local $host = &get_from_domain(); +if ($config{'webmin_from'} =~ /\@/) { + return $config{'webmin_from'}; + } +elsif (!$config{'webmin_from'}) { + return "webmin\@$host"; + } +else { + return "$config{'webmin_from'}\@$host"; + } +} + +# get_from_domain() +# Returns the default domain for From: addresses +sub get_from_domain +{ +return $config{'from_dom'} || &get_display_hostname(); +} + +# get_user_from_address(&uinfo) +# Returns the default From: address for mail sent from some user's mailbox +sub get_user_from_address +{ +local $uinfo = $_[0]; +if ($config{'from_addr'}) { + return $config{'from_addr'}; + } +elsif ($uinfo->[11]) { + return $uinfo->[11]; + } +elsif ($config{'from_virtualmin'} && &foreign_check("virtual-server")) { + # Does Virtualmin manage this user? + &foreign_require("virtual-server", "virtual-server-lib.pl"); + local $d; + foreach $d (&virtual_server::list_domains()) { + local @users = &virtual_server::list_domain_users($d, 0, 0, 1); + local $u; + foreach $u (@users) { + if ($u->{'user'} eq $uinfo->[0] && $u->{'email'}) { + # Found him! + return $u->{'email'}; + } + } + } + } +if ($uinfo->[0] =~ /\@/) { + return $uinfo->[0]; + } +else { + return $uinfo->[0].'@'.&get_from_domain(); + } +} + +# check_modification(&folder) +# Display an error message if a folder has been modified since the time +# in $in{'mod'} +sub check_modification +{ +local $newmod = &modification_time($_[0]); +if ($in{'mod'} && $in{'mod'} != $newmod && $config{'check_mod'}) { + # Changed! + &error(&text('emodified', "list_mail.cgi?user=$in{'user'}&folder=$_[0]->{'index'}")); + } +} + +# spam_report_cmd(user) +# Returns a command for reporting spam, or undef if none +sub spam_report_cmd +{ +local ($user) = @_; +local %sconfig = &foreign_config("spam"); +local $cmd; +if ($config{'spam_report'} eq 'sa_learn') { + $cmd = &has_command($sconfig{'sa_learn'}) ? "$sconfig{'sa_learn'} --spam --mbox" : undef; + } +elsif ($config{'spam_report'} eq 'spamassassin') { + $cmd = &has_command($sconfig{'spamassassin'}) ? "$sconfig{'spamassassin'} --r" : undef; + } +else { + $cmd = &has_command($sconfig{'sa_learn'}) ? + "$sconfig{'sa_learn'} --spam --mbox" : + &has_command($sconfig{'spamassassin'}) ? + "$sconfig{'spamassassin'} --r" : undef; + } +return $user eq "root" ? $cmd : + $cmd ? &command_as_user($user, 0, $cmd) : undef; +} + +# allowed_directory() +# Returns base directory for mail files, or undef if not allowed +sub allowed_directory +{ +if ($access{'dir'}) { + return $access{'dir'}; + } +else { + return $access{'mmode'} == 1 ? "/" : undef; + } +} + +# is_user(user) +sub is_user +{ +return $_[0] !~ /^\//; +} + +# list_mail_users([max], [filterfunc]) +# Returns getpw* style structures for all users who can recieve mail. Those with +# duplicate info are skipped. +sub list_mail_users +{ +local ($max, $filter) = @_; +local @rv; +if ($config{'mail_system'} < 3) { + # Postfix, Sendmail and Qmail all use Unix users + local %found; + local %hfound; + local ($dir, $style, $mailbox, $maildir) = &get_mail_style(); + setpwent(); + while(my (@uinfo) = getpwent()) { + next if ($found{$uinfo[0]}++); # done this username already + next if (!$dir && $hfound{$uinfo[7]}++); + next if ($filter && !&$filter(@uinfo)); + push(@rv, \@uinfo); + last if ($max && @rv > $max); + } + endpwent(); + } +elsif ($config{'mail_system'} == 4) { + # Qmail+LDAP uses an LDAP db + local $ldap = &connect_qmail_ldap(); + local $rv = $ldap->search(base => $config{'ldap_base'}, + filter => "(objectClass=qmailUser)"); + &error($rv->error) if ($rv->code); + local $u; + foreach $u ($rv->all_entries) { + local @uinfo = &qmail_dn_to_user($u); + next if (!$uinfo[10]); # alias only + next if ($filter && !&$filter(@uinfo)); + push(@rv, \@uinfo); + last if ($max && @rv > $max); + } + $ldap->unbind(); + } +elsif ($config{'mail_system'} == 5) { + # Get vpopmail user list for all domains + opendir(DOMS, "$config{'vpopmail_dir'}/domains"); + foreach my $d (readdir(DOMS)) { + next if ($d =~ /^\./); + local @uinfos = &parse_vpopmail_users("-D $d", $d); + if ($filter) { + @uinfos = grep { &$filter(@$_) } @uinfos; + } + push(@rv, @uinfos); + last if ($max && @rv > $max); + } + closedir(DOMS); + } +return @rv; +} + +# parse_vpopmail_users(command, domain) +sub parse_vpopmail_users +{ +local %attr_map = ( "passwd" => 1, + "gecos" => 5, + "dir" => 7 ); +local (@rv, $user); +open(UINFO, "$config{'vpopmail_dir'}/bin/vuserinfo $_[0] |"); +while() { + s/\r|\n//g; + if (/^([^:]+):\s+(.*)$/) { + local ($attr, $value) = ($1, $2); + if ($attr eq "name") { + # Start of a new user + $user = [ "$value\@$_[1]" ]; + $user->[11] = $user->[0]; + push(@rv, $user); + } + local $amapped = $attr_map{$attr}; + $user->[$amapped] = $value if ($amapped); + } + } +close(UINFO); +return @rv; +} + +# get_mail_user(name) +# Looks up a user by name +sub get_mail_user +{ +if ($config{'mail_system'} < 3) { + # Just find Unix user + return getpwnam($_[0]); + } +elsif ($config{'mail_system'} == 4) { + # Lookup in LDAP DB + local $ldap = &connect_qmail_ldap(); + local $rv = $ldap->search(base => $config{'ldap_base'}, + filter => "(&(objectClass=qmailUser)(uid=$_[0]))"); + &error($rv->error) if ($rv->code); + local ($u) = $rv->all_entries; + if ($u) { + # Found in LDAP + local @uinfo = &qmail_dn_to_user($u); + $ldap->unbind(); + return @uinfo; + } + else { + # Fall back to Unix user + return getpwnam($_[0]); + } + } +elsif ($config{'mail_system'} == 5) { + # Find in vpopmail + local ($box, $dom) = split(/\@/, $_[0]); + local @users = &parse_vpopmail_users($_[0], $dom); + return @{$users[0]}; + } +} + +# get_mail_uid(name) +# Looks up a user by UID +sub get_mail_uid +{ +if ($config{'mail_system'} < 3) { + # Just find Unix user + return getpwuid($_[0]); + } +elsif ($config{'mail_system'} == 4) { + # Lookup in LDAP DB + local $ldap = &connect_qmail_ldap(); + local $rv = $ldap->search(base => $config{'ldap_base'}, + filter => "(&(objectClass=qmailUser)(uidNumber=$_[0]))"); + &error($rv->error) if ($rv->code); + local ($u) = $rv->all_entries; + local @uinfo = &qmail_dn_to_user($u); + $ldap->unbind(); + return @uinfo; + } +elsif ($config{'mail_system'} == 5) { + # Find in vpopmail + return ( ); # not possible, since UIDs aren't used! + } +} + +# connect_qmail_ldap([return-error]) +# Connect to the LDAP server used for Qmail. Returns an LDAP handle on success, +# or an error message on failure. +sub connect_qmail_ldap +{ +eval "use Net::LDAP"; +if ($@) { + local $err = &text('ldap_emod', "Net::LDAP"); + if ($_[0]) { return $err; } + else { &error($err); } + } + +# Connect to server +local $port = $config{'ldap_port'} || 389; +local $ldap = Net::LDAP->new($config{'ldap_host'}, port => $port); +if (!$ldap) { + local $err = &text('ldap_econn', + "$config{'ldap_host'}","$port"); + if ($_[0]) { return $err; } + else { &error($err); } + } + +# Start TLS if configured +if ($config{'ldap_tls'}) { + $ldap->start_tls(); + } + +# Login +local $mesg; +if ($config{'ldap_login'}) { + $mesg = $ldap->bind(dn => $config{'ldap_login'}, + password => $config{'ldap_pass'}); + } +else { + $mesg = $ldap->bind(anonymous => 1); + } +if (!$mesg || $mesg->code) { + local $err = &text('ldap_elogin', "$config{'ldap_host'}", + $dn, $mesg ? $mesg->error : "Unknown error"); + if ($_[0]) { return $err; } + else { &error($err); } + } +return $ldap; +} + +# qmail_dn_to_user(&dn) +sub qmail_dn_to_user +{ +local $mms = &add_ldapmessagestore( + scalar($_[0]->get_value("mailMessageStore"))); +if (-d "$mms/Maildir") { + $mms .= "/" if ($mms !~ /\/$/); + $mms .= "Maildir"; + } +return ( scalar($_[0]->get_value("uid")), + scalar($_[0]->get_value("userPassword")), + scalar($_[0]->get_value("uidNumber")), + scalar($_[0]->get_value("gidNumber")), + scalar($_[0]->get_value("mailQuotaSize")), + scalar($_[0]->get_value("cn")), + scalar($_[0]->get_value("cn")), + scalar($_[0]->get_value("homeDirectory")), + scalar($_[0]->get_value("loginShell")), + undef, + $mms, + scalar($_[0]->get_value("mail")), + ); +} + +# add_ldapmessagestore(path) +sub add_ldapmessagestore +{ +if (!$_[0]) { + return $_[0]; + } +elsif ($_[0] =~ /^\//) { + return $_[0]; + } +else { + &foreign_require("qmailadmin", "qmail-lib.pl"); + local $pfx = &qmailadmin::get_control_file("ldapmessagestore"); + return $pfx."/".$_[0]; + } +} + +# show_buttons(number, &folders, current-folder, &mail, user, search-mode) +sub show_buttons +{ +local ($num, $folders, $folder, $mail, $user, $search) = @_; +local $uuser = &urlize($user); +local $spacer = " \n"; +if (@$mail) { + # Delete + print ""; + if ($config{'show_delall'} && !$search) { + print ""; + } + print $spacer; + + # Mark as + print ""; + print ""; + print $spacer; + + if (&is_user($user)) { + # Forward + if ($config{'open_mode'}) { + # Forward messages in a separate window + print ""; + + } + else { + print ""; + } + print $spacer; + } + + # Move/copy + print &movecopy_user_select($_[0], $folders, $folder, 1); + print $spacer; + + # Show spam report buttons + local @modules = &get_available_module_infos(1); + local ($hasspam) = grep { $_->{'dir'} eq "spam" } @modules; + if (&foreign_installed("spam") && + $config{'spam_buttons'} =~ /list/ && + &spam_report_cmd($user)) { + if ($hasspam) { + print ""; + } + if ($config{'spam_del'}) { + print "\n"; + } + else { + print ""; + } + print $spacer; + } + } + +if ($config{'open_mode'}) { + # Show mass open button + print ""; + print $spacer; + } + +# Compose +if (&is_user($user)) { + if ($config{'open_mode'}) { + # In a separate window + print ""; + } + else { + print ""; + } + } +print "
\n"; +} + +# get_signature(user) +# Returns the users signature, if any +sub get_signature +{ +local $sf = &get_signature_file($_[0]); +$sf || return undef; +local $sig; +open(SIG, $sf) || return undef; +while() { + $sig .= $_; + } +close(SIG); +return $sig; +} + +# get_signature_file(user) +# Returns the full path to the file that should contain the user's signature, +# or undef if none is defined +sub get_signature_file +{ +return undef if ($config{'sig_file'} eq '*' || $config{'sig_file'} eq ''); +local $sf = $config{'sig_file'}; +if ($sf !~ /^\//) { + local @uinfo = getpwnam($_[0]); + $sf = "$uinfo[7]/$sf"; + } +return $sf; +} + +# view_mail_link(user, &folder, index, from-to-text) +sub view_mail_link +{ +local ($user, $folder, $idx, $txt) = @_; +local $uuser = &urlize($user); +local $url = "view_mail.cgi?user=$uuser&idx=$idx&folder=$folder->{'index'}"; +if ($config{'open_mode'}) { + return "". + &simplify_from($txt).""; + } +else { + return "".&simplify_from($txt).""; + } +} + +# mail_page_header(title, headstuff, bodystuff, rightstuff) +sub mail_page_header +{ +if ($config{'open_mode'}) { + &popup_header($_[0], $_[1], $_[2]); + } +else { + &ui_print_header(undef, $_[0], "", undef, 0, 0, 0, $_[3], $_[1], $_[2]); + } +} + +# mail_page_footer(link, text, ...) +sub mail_page_footer +{ +if ($config{'open_mode'}) { + &popup_footer(); + } +else { + &ui_print_footer(@_); + } +} + +1; + diff --git a/mailboxes/makelang.pl b/mailboxes/makelang.pl new file mode 100755 index 000000000..c753e13e4 --- /dev/null +++ b/mailboxes/makelang.pl @@ -0,0 +1,54 @@ +#!/usr/local/bin/perl + +@ARGV == 1 || die "usage: makelang.pl "; + +$usermin = "/usr/local/useradmin/mailbox/ulang"; +$mailboxes = "/usr/local/webadmin/mailboxes/lang"; +$sendmail = "/usr/local/webadmin/sendmail/lang"; + +&read_file("$mailboxes/en", \%emailboxes, \@eorder); +&read_file("$sendmail/en", \%esendmail); +&read_file("$usermin/en", \%eusermin); + +&read_file("$mailboxes/$ARGV[0]", \%fmailboxes); +&read_file("$sendmail/$ARGV[0]", \%fsendmail); +&read_file("$usermin/$ARGV[0]", \%fusermin); + +foreach $k (@eorder) { + if ($emailboxes{$k} eq $esendmail{$k} && + $fsendmail{$k} && + $fsendmail{$k} ne $esendmail{$k}) { + print "$k=$fsendmail{$k}\n"; + } + elsif ($emailboxes{$k} eq $eusermin{$k} && + $fusermin{$k} && + $fusermin{$k} ne $eusermin{$k}) { + print "$k=$fusermin{$k}\n"; + } + } + +# read_file(file, &assoc, [&order], [lowercase]) +# Fill an associative array with name=value pairs from a file +sub read_file +{ +local $_; +open(ARFILE, $_[0]) || return 0; +while() { + chomp; + local $hash = index($_, "#"); + local $eq = index($_, "="); + if ($hash != 0 && $eq >= 0) { + local $n = substr($_, 0, $eq); + local $v = substr($_, $eq+1); + $_[1]->{$_[3] ? lc($n) : $n} = $v; + push(@{$_[2]}, $n) if ($_[2]); + } + } +close(ARFILE); +if (defined($main::read_file_cache{$_[0]})) { + %{$main::read_file_cache{$_[0]}} = %{$_[1]}; + } +return 1; +} + + diff --git a/mailboxes/module.info b/mailboxes/module.info new file mode 100644 index 000000000..9e4d03a92 --- /dev/null +++ b/mailboxes/module.info @@ -0,0 +1,11 @@ +desc=Read User Mail +category=servers +longdesc=Read email in users' mailboxes. +desc_de=Lese Benutzer-E-Mail +desc_zh_TW.Big5=Ū¨ú¨Ï¥ÎªÌ¶l¥ó +desc_ca=Lectura del Correu d'Usuaris +desc_fr=Lecture du Courrier des Usagers +readonly=1 +os_support=!windows +desc_es=Lectura de Correo de Usuarios +desc_zh_TW.UTF-8=讀å–使用者郵件 diff --git a/mailboxes/reply_mail.cgi b/mailboxes/reply_mail.cgi new file mode 100755 index 000000000..a0b2ebe86 --- /dev/null +++ b/mailboxes/reply_mail.cgi @@ -0,0 +1,555 @@ +#!/usr/local/bin/perl +# Display a form for replying to or composing an email + +require './mailboxes-lib.pl'; +&ReadParse(); +&can_user($in{'user'}) || &error($text{'mail_ecannot'}); +@uinfo = &get_mail_user($in{'user'}); +@uinfo || &error($text{'view_eugone'}); + +@folders = &list_user_folders($in{'user'}); +$folder = $folders[$in{'folder'}]; +if ($in{'new'}) { + # Composing a new email + $html_edit = 1 if ($config{'html_edit'} == 2); + $sig = &get_signature($in{'user'}); + if ($html_edit) { + $sig =~ s/\n/
\n/g; + $quote = ""; + } + else { + $quote = "\n\n$sig" if ($sig); + } + $to = $in{'to'}; + &mail_page_header($text{'compose_title'}, undef, + $html_edit ? "onload='initEditor()'" : "", + &folder_link($in{'user'}, $folder)); + } +else { + # Replying or forwarding + if ($in{'mailforward'} ne '') { + # Replying to multiple + @mailforward = sort { $a <=> $b } + split(/\0/, $in{'mailforward'}); + @mails = &mailbox_list_mails( + $mailforward[0], $mailforward[@mailforward-1], + $folder); + $mail = $mails[$mailforward[0]]; + } + else { + # Replying to one + @mails = &mailbox_list_mails($in{'idx'}, $in{'idx'}, + $folder); + $mail = $mails[$in{'idx'}]; + &decode_and_sub(); + } + &check_modification($folder) if ($in{'delete'}); + $mail || &error($text{'mail_eexists'}); + + if ($in{'delete'}) { + # Just delete the email + if (!$in{'confirm'} && &need_delete_warn($folder)) { + # Need to ask for confirmation before deleting + &mail_page_header($text{'confirm_title'}, undef, undef, + &folder_link($in{'user'}, $folder)); + print &check_clicks_function(); + + print "

\n"; + foreach $i (keys %in) { + foreach $v (split(/\0/, $in{$i})) { + print "\n"; + } + } + print "
$text{'confirm_warn3'}
\n"; + if ($config{'delete_warn'} ne 'y') { + print "$text{'confirm_warn2'}

\n" + } + else { + print "$text{'confirm_warn4'}

\n" + } + print "

\n"; + + &mail_page_footer("view_mail.cgi?idx=$in{'idx'}&folder=$in{'folder'}&user=$in{'user'}", + $text{'view_return'}, + "list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", + $text{'mail_return'}, + "", $text{'index_return'}); + exit; + } + &lock_folder($folder); + &mailbox_delete_mail($folder, $mail); + &unlock_folder($folder); + &webmin_log("delmail", undef, undef, + { 'from' => $folder->{'file'}, + 'count' => 1 } ); + &redirect("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}"); + exit; + } + elsif ($in{'print'}) { + # Extract the mail body + &decode_and_sub(); + ($textbody, $htmlbody, $body) = + &find_body($mail, $config{'view_html'}); + + # Output HTML header + &PrintHeader(); + print "\n"; + print "",&html_escape(&decode_mimewords( + $mail->{'header'}->{'subject'})),"\n"; + print "\n"; + + # Display the headers + print "\n"; + print "\n"; + print "
$text{'view_headers'}
\n"; + print " ", + "\n"; + print " ", + "\n"; + print " ", + "\n" + if ($mail->{'header'}->{'cc'}); + print " ", + "\n"; + print " ", + "\n"; + print "
$text{'mail_from'}",&eucconv_and_escape($mail->{'header'}->{'from'}),"
$text{'mail_to'}",&eucconv_and_escape($mail->{'header'}->{'to'}),"
$text{'mail_cc'}",&eucconv_and_escape($mail->{'header'}->{'cc'}),"
$text{'mail_date'}",&eucconv_and_escape(&html_escape($mail->{'header'}->{'date'})), + "
$text{'mail_subject'}",&eucconv_and_escape(&decode_mimewords( + $mail->{'header'}->{'subject'})),"

\n"; + + # Just display the mail body for printing + if ($body eq $textbody) { + print "
";
+			foreach $l (&wrap_lines($body->{'data'},
+						$config{'wrap_width'})) {
+				print &eucconv_and_escape($l),"\n";
+				}
+			print "
\n"; + } + elsif ($body eq $htmlbody) { + print "
\n"; + print &safe_html($body->{'data'}); + print "
\n"; + } + + print "\n"; + exit; + } + elsif ($in{'mark1'} || $in{'mark2'}) { + # Just mark the message + dbmopen(%read, "$module_config_directory/$in{'user'}.read", 0600); + $mode = $in{'mark1'} ? $in{'mode1'} : $in{'mode2'}; + if ($mode) { + $read{$mail->{'header'}->{'message-id'}} = $mode; + } + else { + delete($read{$mail->{'header'}->{'message-id'}}); + } + $perpage = $folder->{'perpage'} || $config{'perpage'}; + $s = int((@mails - $in{'idx'} - 1) / $perpage) * $perpage; + &redirect("list_mail.cgi?start=$s&folder=$in{'folder'}&user=$in{'user'}"); + exit; + } + elsif ($in{'detach'}) { + # Detach some attachment to a directory on the server + &error_setup($text{'detach_err'}); + $in{'dir'} || &error($text{'detach_edir'}); + $in{'dir'} = "$uinfo[7]/$in{'dir'}" + if ($in{'dir'} !~ /^\//); + &decode_and_sub(); + + if ($in{'attach'} eq '*') { + # Detaching all attachments, under their filenames + @dattach = grep { $_->{'idx'} ne $in{'bindex'} } + @{$mail->{'attach'}}; + } + else { + # Just one attachment + @dattach = ( $mail->{'attach'}->[$in{'attach'}] ); + } + + local @paths; + foreach $attach (@dattach) { + local $path; + if (-d $in{'dir'}) { + # Just write to the filename in the directory + local $fn; + if ($attach->{'filename'}) { + $fn = &decode_mimewords( + $attach->{'filename'}); + } + else { + $attach->{'type'} =~ /\/(\S+)$/; + $fn = "file.$1"; + } + $path = "$in{'dir'}/$fn"; + } + else { + # Assume a full path was given + $path = $in{'dir'}; + } + push(@paths, $path); + } + + &switch_to_user($in{'user'}); + for($i=0; $i<@dattach; $i++) { + # Try to write the files + &open_tempfile(FILE, ">$paths[$i]", 1, 1) || + &error(&text('detach_eopen', + "$paths[$i]", $!)); + (print FILE $dattach[$i]->{'data'}) || + &error(&text('detach_ewrite', + "$paths[$i]", $!)); + close(FILE) || + &error(&text('detach_ewrite', + "$paths[$i]", $!)); + } + &switch_user_back(); + + # Show a message about the new files + &mail_page_header($text{'detach_title'}, undef, undef, + &folder_link($in{'user'}, $folder)); + + for($i=0; $i<@dattach; $i++) { + local $sz = (int(length($dattach[$i]->{'data'}) / + 1000)+1)." Kb"; + print "

",&text('detach_ok', + "$paths[$i]", $sz),"

\n"; + } + + &mail_page_footer("view_mail.cgi?idx=$in{'idx'}&folder=$in{'folder'}&user=$in{'user'}", $text{'view_return'}, + "list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}, + "", $text{'index_return'}); + exit; + } + elsif ($in{'black'}) { + # Add sender to global SpamAssassin blacklist, and tell user + &mail_page_header($text{'black_title'}); + + &foreign_require("spam", "spam-lib.pl"); + local $conf = &spam::get_config(); + local @from = map { @{$_->{'words'}} } + &spam::find("blacklist_from", $conf); + local %already = map { $_, 1 } @from; + local ($spamfrom) = &address_parts($mail->{'header'}->{'from'}); + if ($already{$spamfrom}) { + print "",&text('black_already', + "$spamfrom"),"

\n"; + } + else { + push(@from, $spamfrom); + &spam::save_directives($conf, 'blacklist_from', + \@from, 1); + &flush_file_lines(); + print "",&text('black_done', + "$spamfrom"),"

\n"; + } + + &mail_page_footer("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}, "", $text{'index_return'}); + exit; + } + elsif ($in{'razor'}) { + # Report message to Razor and tell user + &mail_page_header($text{'razor_title'}); + + print "$text{'razor_report'}\n"; + print "

";
+		local $cmd = &spam_report_cmd($in{'user'});
+		local $temp = &transname();
+		&send_mail($mail, $temp, 0, 1);
+		&open_execute_command(OUT, "$cmd <$temp 2>&1", 1);
+		local $error;
+		while() {
+			print &html_escape($_);
+			$error++ if (/failed/i);
+			}
+		close(OUT);
+		unlink($temp);
+		print "
\n"; + if ($? || $error) { + print "$text{'razor_err'}

\n"; + } + else { + if ($config{'spam_del'}) { + # Delete message too + &lock_folder($folder); + &mailbox_delete_mail($folder, $mail); + &unlock_folder($folder); + print "$text{'razor_deleted'}

\n"; + } + else { + print "$text{'razor_done'}

\n"; + } + } + + &mail_page_footer("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}, "", $text{'index_return'}); + exit; + } + + if (!@mailforward) { + &parse_mail($mail); + @attach = @{$mail->{'attach'}}; + } + + if ($in{'strip'}) { + # Remove all non-body attachments + local $newmail = { 'headers' => $mail->{'headers'}, + 'header' => $mail->{'header'}, + 'fromline' => $mail->{'fromline'} }; + foreach $a (@attach) { + if ($a->{'type'} eq 'text/plain' || + $a->{'type'} eq 'text') { + $newmail->{'attach'} = [ $a ]; + last; + } + } + &lock_folder($folder); + &mailbox_modify_mail($mail, $newmail, $folder); + &unlock_folder($folder); + &redirect("list_mail.cgi?user=$in{'user'}&folder=$in{'folder'}"); + exit; + } + + if ($in{'enew'}) { + # Editing an existing message, so keep same fields + $to = $mail->{'header'}->{'to'}; + $rto = $mail->{'header'}->{'reply-to'}; + $from = $mail->{'header'}->{'from'}; + $cc = $mail->{'header'}->{'cc'}; + $ouser = $1 if ($from =~ /^(\S+)\@/); + } + else { + if (!$in{'forward'} && !@mailforward) { + # Replying to a message, so set To: field + $to = $mail->{'header'}->{'reply-to'}; + $to = $mail->{'header'}->{'from'} if (!$to); + } + if ($in{'rall'}) { + # If replying to all, add any addresses in the original + # To: or Cc: to our new Cc: address. + # XXX should strip own addresses + $cc = $mail->{'header'}->{'to'}; + $cc .= ", ".$mail->{'header'}->{'cc'} + if ($mail->{'header'}->{'cc'}); + } + } + + # Work out new subject, depending on whether we are replying + # our forwarding a message (or neither) + local $qu = !$in{'enew'} && + (!$in{'forward'} || !$config{'fwd_mode'}); + $subject = &html_escape(&decode_mimewords( + $mail->{'header'}->{'subject'})); + $subject = "Re: ".$subject if ($subject !~ /^Re/i && !$in{'forward'} && + !@mailforward && !$in{'enew'}); + $subject = "Fwd: ".$subject if ($subject !~ /^Fwd/i && + ($in{'forward'} || @mailforward)); + + # Construct the initial mail text + $sig = &get_signature($in{'user'}); + ($quote, $html_edit, $body) = "ed_message($mail, $qu, $sig); + if ($in{'forward'} || $in{'enew'}) { + @attach = grep { $_ ne $body } @attach; + } + else { + undef(@attach); + } + + # Show header + &mail_page_header( + $in{'forward'} || @mailforward ? $text{'forward_title'} : + $in{'enew'} ? $text{'enew_title'} : + $text{'reply_title'}, undef, + $html_edit ? "onload='initEditor()'" : "", + &folder_link($in{'user'}, $folder)); + } + +print "

\n"; + +# Output various hidden fields +print "\n"; +print "\n"; +print "\n"; +print "\n"; +print "\n"; +print "\n"; +foreach $s (@sub) { + print "\n"; + } + +print "\n"; +print "\n"; +print "
$text{'reply_headers'}
\n"; + +# Work out and show the From: address +print "\n"; +$from ||= &get_user_from_address(\@uinfo); +if ($access{'fmode'} == 0) { + # Any email addresss + print "\n"; + } +elsif ($access{'fmode'} == 1) { + # User's name in selected domains + local $u = $from || $ouser || $in{'user'}; + $u =~ s/\@.*$//; + print "\n"; + } +elsif ($access{'fmode'} == 2) { + # Listed from addresses + print "\n"; + } +elsif ($access{'fmode'} == 3) { + # Fixed address in fixed domain + print "\n"; + } + +$to = &html_escape($to); +print " ", + "\n"; + +$cc = &html_escape($cc); +print " ", + "\n"; +print " ", + "\n"; +print " ", + "\n"; +print " ", + "\n"; +print "
$text{'mail_from'}$ouser\@$access{'from'}$text{'mail_to'}
$text{'mail_cc'}$text{'mail_bcc'}
$text{'mail_subject'}$text{'mail_pri'}\n", + "\n", + "
\n", + "

\n"; + +# Output message body input +print "\n", + "", + "
$text{'reply_body'}
"; +if ($html_edit) { + # Output HTML editor textarea + print < + _editor_url = "$gconfig{'webprefix'}/$module_name/xinha/"; + _editor_lang = "en"; + + + + +EOF + print "\n"; + } +else { + # Show text editing area + print "\n"; + if (&has_command("ispell")) { + print "
\n"; + print " $text{'reply_spell'}\n"; + } + } +print "

\n"; +print "\n"; + +# Display forwarded attachments +if (@attach) { + print "\n"; + print "\n"; + print "
$text{'reply_attach'}
\n"; + foreach $a (@attach) { + push(@titles, "{'idx'} checked> ".($a->{'filename'} ? $a->{'filename'} : $a->{'type'})); + push(@links, "detach.cgi?idx=$in{'idx'}&folder=$in{'folder'}&attach=$a->{'idx'}$subs"); + push(@icons, "images/boxes.gif"); + } + &icons_table(\@links, \@titles, \@icons, 8); + print "

\n"; + } + +# Display forwarded mails +if (@mailforward) { + print "\n"; + print "\n"; + print "
$text{'reply_mailforward'}
\n"; + foreach $f (@mailforward) { + push(@titles, &simplify_subject($mails[$f]->{'header'}->{'subject'})); + push(@links, "view_mail.cgi?idx=$f&folder=$in{'folder'}&user=$in{'user'}"); + push(@icons, "images/boxes.gif"); + print "\n"; + } + &icons_table(\@links, \@titles, \@icons, 8); + print "

\n"; + } + +# Add form for more attachments +print "\n"; +print "\n"; + +print "\n"; +print "\n"; +print "\n"; + +print "\n"; +print "\n"; +print "\n"; + +if ($access{'canattach'}) { + print "\n"; + print "\n"; + print "\n"; + } + +print "
$text{'reply_attach2'}
", + &file_chooser_button("file0")," ", + &file_chooser_button("file1")," ", + &file_chooser_button("file2"),"

\n"; +print "\n"; +print "

\n"; + +&mail_page_footer("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", + $text{'mail_return'}, + "", $text{'index_return'}); + +sub decode_and_sub +{ +return if (!$mail); +&parse_mail($mail); +@sub = split(/\0/, $in{'sub'}); +$subs = join("", map { "&sub=$_" } @sub); +foreach $s (@sub) { + # We are looking at a mail within a mail .. + local $amail = &extract_mail( + $mail->{'attach'}->[$s]->{'data'}); + &parse_mail($amail); + $mail = $amail; + } +} + diff --git a/mailboxes/search_form.cgi b/mailboxes/search_form.cgi new file mode 100755 index 000000000..7b4833525 --- /dev/null +++ b/mailboxes/search_form.cgi @@ -0,0 +1,54 @@ +#!/usr/local/bin/perl +# search_form.cgi +# Display a form for searching a mailbox + +require './mailboxes-lib.pl'; +&ReadParse(); +&can_user($in{'user'}) || &error($text{'mail_ecannot'}); + +@folders = &list_user_folders_sorted($in{'user'}); +($folder) = grep { $_->{'index'} == $in{'folder'} } @folders; +&ui_print_header(undef, $text{'sform_title'}, "", undef, 0, 0, undef, + &folder_link($in{'user'}, $folder)); + +print "
\n"; +print "\n"; +print "\n"; +print " $text{'sform_and'}\n"; +print " $text{'sform_or'}

\n"; + +print "\n"; +#print " ", +# " ", +# "\n"; +for($i=0; $i<=9; $i++) { + print "\n"; + print "\n"; + print "\n"; + + print "\n"; + + print "\n"; + print "\n"; + print "\n"; + } +print "
$text{'sform_field'}$text{'sform_mode'}$text{'sform_for'}
$text{'sform_where'}$text{'sform_text'}

\n"; + +$extra = "

\n"; + +&ui_print_footer("list_mail.cgi?folder=$in{'folder'}&user=". + &urlize($in{'user'}), $text{'mail_return'}, + "", $text{'index_return'}); + diff --git a/mailboxes/send_mail.cgi b/mailboxes/send_mail.cgi new file mode 100755 index 000000000..140d1e8d2 --- /dev/null +++ b/mailboxes/send_mail.cgi @@ -0,0 +1,288 @@ +#!/usr/local/bin/perl +# send_mail.cgi +# Send off an email message + +require './mailboxes-lib.pl'; +&ReadParseMime(); +&can_user($in{'user'}) || &error($text{'mail_ecannot'}); +@uinfo = &get_mail_user($in{'user'}); +@uinfo || &error($text{'view_eugone'}); + +# Check inputs +@folders = &list_user_folders($in{'user'}); +$folder = $folders[$in{'folder'}]; +&error_setup($text{'send_err'}); +$in{'to'} || &error($text{'send_eto'}); +if ($access{'fmode'} == 0) { + # Any from address allowed + $in{'from'} || &error($text{'send_efrom'}); + } +elsif ($access{'fmode'} == 1) { + # From address must be in an allowed domain, and match username + $validfrom = &get_user_from_address(\@uinfo); + foreach $f (split(/\s+/, $access{'from'})) { + $found++ if ("$in{'user'}\@$f" eq $in{'from'} || + "$in{'ouser'}\@$f" eq $in{'from'} || + $validfrom eq $in{'from'}); + } + &error($text{'send_efrom'}) if (!$found); + } +elsif ($access{'fmode'} == 2) { + # From address must be in allowed list + foreach $f (split(/\s+/, $access{'from'})) { + $found++ if ($f eq $in{'from'}); + } + &error($text{'send_efrom'}) if (!$found); + } +elsif ($access{'fmode'} == 3) { + $in{'from'} .= "\@$access{'from'}"; + } +if ($in{'from'} =~ /^(\S+)\@(\S+)$/ && $access{'fromname'}) { + $in{'from'} = "$access{'fromname'} <$in{'from'}>"; + } +@sub = split(/\0/, $in{'sub'}); +$subs = join("", map { "&sub=$_" } @sub); + +# Construct the email +$in{'from'} || &error($text{'send_efrom'}); +$mail->{'headers'} = [ [ 'From', $in{'from'} ], + [ 'Subject', $in{'subject'} ], + [ 'To', $in{'to'} ], + [ 'Cc', $in{'cc'} ], + [ 'Bcc', $in{'bcc'} ], + [ 'X-Originating-IP', $ENV{'REMOTE_ADDR'} ], + [ 'X-Mailer', "Webmin ".&get_webmin_version() ] ]; +push(@{$mail->{'headers'}}, [ 'X-Priority', $in{'pri'} ]) if ($in{'pri'}); +$in{'body'} =~ s/\r//g; +if ($in{'body'} =~ /\S/) { + if ($in{'spell'}) { + pipe(INr, INw); + pipe(OUTr, OUTw); + select(INw); $| = 1; select(OUTr); $| = 1; select(STDOUT); + if (!fork()) { + close(INw); + close(OUTr); + untie(*STDIN); + untie(*STDOUT); + untie(*STDERR); + open(STDOUT, ">&OUTw"); + open(STDERR, ">/dev/null"); + open(STDIN, "<&INr"); + exec("ispell -a"); + exit; + } + close(INr); + close(OUTw); + local $indent = " " x 4; + local @errs; + foreach $line (split(/\n+/, $in{'body'})) { + next if ($line !~ /\S/); + print INw $line,"\n"; + local @lerrs; + while(1) { + ($spell = ) =~ s/\r|\n//g; + last if (!$spell); + if ($spell =~ /^#\s+(\S+)/) { + # Totally unknown word + push(@lerrs, $indent.&text('send_eword', "".&html_escape($1)."")); + } + elsif ($spell =~ /^&\s+(\S+)\s+(\d+)\s+(\d+):\s+(.*)/) { + # Maybe possible word, with options + push(@lerrs, $indent.&text('send_eword2', "".&html_escape($1)."", "".&html_escape($4)."")); + } + elsif ($spell =~ /^\?\s+(\S+)/) { + # Maybe possible word + push(@lerrs, $indent.&text('send_eword', "".&html_escape($1)."")); + } + } + if (@lerrs) { + push(@errs, &text('send_eline', "".&html_escape($line)."")."
".join("
", @lerrs)."

\n"); + } + } + close(INw); + close(OUTr); + if (@errs) { + # Spelling errors found! + &mail_page_header($text{'compose_title'}, undef, undef, + &folder_link($in{'user'}, $folder)); + print "$text{'send_espell'}

\n"; + print @errs; + &mail_page_footer("index.cgi?user=$in{'user'}&folder=$in{'folder'}", + $text{'mail_return'}); + exit; + } + } + local $mt = $in{'html_edit'} ? "text/html" : "text/plain"; + if ($in{'body'} =~ /[\177-\377]/) { + # Contains 8-bit characters .. need to make quoted-printable + $quoted_printable++; + @attach = ( { 'headers' => [ [ 'Content-Type', $mt ], + [ 'Content-Transfer-Encoding', + 'quoted-printable' ] ], + 'data' => quoted_encode($in{'body'}) } ); + } + else { + # Plain 7-bit ascii text + @attach = ( { 'headers' => [ [ 'Content-Type', $mt ], + [ 'Content-Transfer-Encoding', + '7bit' ] ], + 'data' => $in{'body'} } ); + } + $bodyattach = $attach[0]; + } +$attachsize = 0; +foreach $i (0 .. 5) { + # Add uploaded attachment + next if (!$in{"attach$i"}); + &test_max_attach($attachsize); + local $filename = $in{"attach${i}_filename"}; + $filename =~ s/^.*(\\|\/)//; + local $type = $in{"attach${i}_content_type"}."; name=\"". + $filename."\""; + local $disp = "inline; filename=\"".$filename."\""; + push(@attach, { 'data' => $in{"attach${i}"}, + 'headers' => [ [ 'Content-type', $type ], + [ 'Content-Disposition', $disp ], + [ 'Content-Transfer-Encoding', + 'base64' ] ] }); + $atotal += length($in{"attach${i}"}); + } +foreach $i (0 .. 2) { + # Add server-side attachment + next if (!$in{"file$i"} || !$access{'canattach'}); + @uinfo = &get_mail_user($in{'user'}); + @uinfo || &error($text{'view_eugone'}); + if ($in{"file$i"} !~ /^\//) { + $in{"file$i"} = $uinfo[7]."/".$in{"file$i"}; + } + + local @st = stat($in{"file$i"}); + &test_max_attach($st[7]); + local $data; + &switch_to_user($in{'user'}); + open(DATA, $in{"file$i"}) || &error(&text('send_efile', $in{"file$i"}, $!)); + while() { + $data .= $_; + } + close(DATA); + &switch_user_back(); + $in{"file$i"} =~ s/^.*\///; + local $type = &guess_mime_type($in{"file$i"}). + "; name=\"".$in{"file$i"}."\""; + local $disp = "inline; filename=\"".$in{"file$i"}."\""; + push(@attach, { 'data' => $data, + 'headers' => [ [ 'Content-type', $type ], + [ 'Content-Disposition', $disp ], + [ 'Content-Transfer-Encoding', + 'base64' ] ] }); + $atotal += length($data); + } +@fwd = split(/\0/, $in{'forward'}); +if (@fwd) { + # Add forwarded attachments + @mail = &mailbox_list_mails($in{'idx'}, $in{'idx'}, $folder); + $fwdmail = $mail[$in{'idx'}]; + &parse_mail($fwdmail); + + foreach $s (@sub) { + # We are looking at a mail within a mail .. + local $amail = &extract_mail($fwdmail->{'attach'}->[$s]->{'data'}); + &parse_mail($amail); + $fwdmail = $amail; + } + + foreach $f (@fwd) { + &test_max_attach(length($fwdmail->{'attach'}->[$f]->{'data'})); + push(@attach, $fwdmail->{'attach'}->[$f]); + $atotal += length($fwdmail->{'attach'}->[$f]->{'data'}); + } + } +@mailfwd = split(/\0/, $in{'mailforward'}); +if (@mailfwd) { + # Add forwarded emails + @mail = &mailbox_list_mails($mailfwd[0], $mailfwd[@mailfwd-1], $folder); + foreach $f (@mailfwd) { + $fwdmail = $mail[$f]; + local $headertext; + foreach $h (@{$fwdmail->{'headers'}}) { + $headertext .= $h->[0].": ".$h->[1]."\n"; + } + push(@attach, { 'data' => $headertext."\n".$fwdmail->{'body'}, + 'headers' => [ [ 'Content-type', 'message/rfc822' ], + [ 'Content-Description', + $fwdmail->{'header'}->{'subject'} ] ] + }); + } + } +$mail->{'attach'} = \@attach; +if ($access{'attach'} >= 0 && $atotal > $access{'attach'}*1024) { + &error(&text('send_eattach', $access{'attach'})); + } + +# Check for text-only email +$textonly = $config{'no_mime'} && !$quoted_printable && + @{$mail->{'attach'}} == 1 && + $mail->{'attach'}->[0] eq $bodyattach && + !$in{'html_edit'}; + +# Send it off +&send_mail($mail, undef, $textonly, $config{'no_crlf'}); +&webmin_log("send", undef, undef, { 'from' => $in{'from'}, 'to' => $in{'to'} }); + +# Tell the user that email as sent +&mail_page_header($text{'send_title'}, undef, undef, + &folder_link($in{'user'}, $folder)); + +@tos = ( split(/,/, $in{'to'}), split(/,/, $in{'cc'}), split(/,/, $in{'bcc'}) ); +$tos = join(" , ", map { "".&html_escape($_)."" } @tos); +print "

",&text($in{'draft'} ? 'send_draft' : 'send_ok', $tos),"

\n"; + +if ($in{'idx'} ne '') { + &mail_page_footer("view_mail.cgi?idx=$in{'idx'}&folder=$in{'folder'}&user=$in{'user'}$subs", + $text{'view_return'}, + "list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", + $text{'mail_return'}, + "", $text{'index_return'}); + } +else { + &mail_page_footer("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", + $text{'mail_return'}, + "", $text{'index_return'}); + } + +# write_attachment(&attach) +sub write_attachment +{ +local ($a) = @_; +local ($enc, $rv); +foreach $h (@{$a->{'headers'}}) { + $rv .= $h->[0].": ".$h->[1]."\r\n"; + $enc = $h->[1] + if (lc($h->[0]) eq 'content-transfer-encoding'); + } +$rv .= "\r\n"; +if (lc($enc) eq 'base64') { + local $encoded = &encode_base64($a->{'data'}); + $encoded =~ s/\r//g; + $encoded =~ s/\n/\r\n/g; + $rv .= $encoded; + } +else { + $a->{'data'} =~ s/\r//g; + $a->{'data'} =~ s/\n/\r\n/g; + $rv .= $a->{'data'}; + if ($a->{'data'} !~ /\n$/) { + $rv .= "\r\n"; + } + } +return $rv; +} + +sub test_max_attach +{ +$attachsize += $_[0]; +if ($access{'attach'} >= 0 && $attachsize > $access{'attach'}) { + &error(&text('send_eattachsize', $access{'attach'})); + } +} + diff --git a/mailboxes/useradmin_update.pl b/mailboxes/useradmin_update.pl new file mode 100644 index 000000000..e1a876fd6 --- /dev/null +++ b/mailboxes/useradmin_update.pl @@ -0,0 +1,94 @@ + +do 'mailboxes-lib.pl'; + +# useradmin_create_user(&details) +# Create a new empty mail file +sub useradmin_create_user +{ +if ($config{'sync_create'}) { + local ($dir, $style, $mailbox, $maildir) = &get_mail_style(); + if ($dir && -d $dir) { + # Create mail file like /var/mail/USERNAME + local $mf = &mail_file_style($_[0]->{'user'}, $dir, $style); + if (!-e $mf) { + &create_mail_file($_[0], $mf); + } + } + if ($mailbox && !-e "$_[0]->{'home'}/$mailbox") { + # Create mail file ~USERNAME/Mailbox + &create_mail_file($_[0], "$_[0]->{'home'}/$mailbox"); + } + if ($maildir && !-e "$_[0]->{'home'}/$maildir") { + # Create mail directory like ~USERNAME/Maildir + &create_mail_dir($_[0], "$_[0]->{'home'}/$maildir"); + } + } +} + +# create_mail_file(&user, file) +sub create_mail_file +{ +open(TOUCH, ">$_[1]"); +close(TOUCH); +if ($config{'sync_perms'}) { + system("chmod ". + quotemeta($config{'sync_perms'})." ". + quotemeta($_[1])); + } +chown($_[0]->{'uid'}, $_[0]->{'gid'}, $_[1]); +} + +# create_mail_dir(&user, dir) +sub create_mail_dir +{ +local $d; +foreach $d ($_[1], "$_[0]/cur", "$_[1]/tmp", "$_[1]/new") { + mkdir($d, 0700); + if ($config{'sync_perms'}) { + system("chmod ". + quotemeta($config{'sync_perms'})." ". + quotemeta($d)); + } + chown($_[0]->{'uid'}, $_[0]->{'gid'}, $d); + } +} + + + +# useradmin_delete_user(&details) +# Delete the user's mail file +sub useradmin_delete_user +{ +if ($config{'sync_delete'}) { + local ($dir, $style, $mailbox, $maildir) = &get_mail_style(); + if ($dir && -d $dir) { + local $mf = &mail_file_style($_[0]->{'user'}, $dir, $style); + unlink($mf); + unlink($mf.".pop"); + } + } +} + +# useradmin_modify_user(&details, &old) +# Rename the user's mail file if necessary, and change it's UID +sub useradmin_modify_user +{ +if ($config{'sync_modify'} && + ($_[0]->{'user'} ne $_[1]->{'user'} || $_[0]->{'uid'} != $_[1]->{'uid'})) { + local ($dir, $style, $mailbox, $maildir) = &get_mail_style(); + if ($dir && -d $dir) { + local $omf = &mail_file_style($_[0]->{'olduser'}, $dir, $style); + local $nmf = &mail_file_style($_[0]->{'user'}, $dir, $style); + local @st = stat($omf); + if ($st[4] != $_[0]->{'uid'}) { + chown($_[0]->{'uid'}, $st[5], $omf); + } + if ($omf ne $nmf && -e $omf) { + &rename_logged($omf, $nmf); + } + } + } +} + +1; + diff --git a/mailboxes/view_mail.cgi b/mailboxes/view_mail.cgi new file mode 100755 index 000000000..ff83e1436 --- /dev/null +++ b/mailboxes/view_mail.cgi @@ -0,0 +1,367 @@ +#!/usr/local/bin/perl +# view_mail.cgi +# View a single email message + +require './mailboxes-lib.pl'; +$force_charset = ''; +&ReadParse(); +&can_user($in{'user'}) || &error($text{'mail_ecannot'}); +if (&is_user($in{'user'})) { + @uinfo = &get_mail_user($in{'user'}); + @uinfo || &error($text{'view_eugone'}); + } + +$uuser = &urlize($in{'user'}); +@folders = &list_user_folders($in{'user'}); +$folder = $folders[$in{'folder'}]; +@mail = &mailbox_list_mails($in{'idx'}, $in{'idx'}, $folder); +$mail = $mail[$in{'idx'}]; +&parse_mail($mail, undef, $in{'raw'}); +@sub = split(/\0/, $in{'sub'}); +$subs = join("", map { "&sub=$_" } @sub); +foreach $s (@sub) { + # We are looking at a mail within a mail .. + local $amail = &extract_mail($mail->{'attach'}->[$s]->{'data'}); + &parse_mail($amail, undef, $in{'raw'}); + $mail = $amail; + } + +dbmopen(%read, "$module_config_directory/$in{'user'}.read", 0600); +eval { $read{$mail->{'header'}->{'message-id'}} = 1 } + if (!$read{$mail->{'header'}->{'message-id'}}); + +if ($in{'raw'}) { + # Special mode - viewing whole raw message + print "Content-type: text/plain\n\n"; + if ($mail->{'fromline'}) { + print $mail->{'fromline'},"\n"; + } + if (defined($mail->{'rawheaders'})) { + #$mail->{'rawheaders'} =~ s/(\S)\t/$1\n\t/g; + print $mail->{'rawheaders'}; + } + else { + foreach $h (@{$mail->{'headers'}}) { + #$h->[1] =~ s/(\S)\t/$1\n\t/g; + print "$h->[0]: $h->[1]\n"; + } + } + print "\n"; + print $mail->{'body'}; + exit; + } + +# Find body attachment and type +($textbody, $htmlbody, $body) = &find_body($mail, $config{'view_html'}); +$body = $htmlbody if ($in{'body'} == 2); +$body = $textbody if ($in{'body'} == 1); +@attach = @{$mail->{'attach'}}; + +# Show pre-body HTML +if ($body && $body eq $htmlbody) { + $headstuff = &head_html($body->{'data'}); + } + +&mail_page_header($text{'view_title'}, $headstuff, undef, + &folder_link($in{'user'}, $folder)); +print &check_clicks_function(); +&show_arrows(); + +print "

\n"; +print "\n"; +print "\n"; +print "\n"; +print "\n"; +foreach $s (@sub) { + print "\n"; + } + +# Find any delivery status attachment +($dstatus) = grep { $_->{'type'} eq 'message/delivery-status' } @attach; + +# Strip out attachments not to display as icons +@attach = grep { $_ ne $body && $_ ne $dstatus } @attach; +@attach = grep { !$_->{'attach'} } @attach; + +if ($config{'top_buttons'} == 2 && &editable_mail($mail)) { + &show_mail_buttons(1, scalar(@sub)); + print "

\n"; + } + +print "\n"; +print "\n"; + +print "
", + "\n"; +print "
$text{'view_headers'} \n"; +if ($in{'headers'}) { + print "$text{'view_noheaders'}\n"; + } +else { + print "$text{'view_allheaders'}\n"; + } +print "  $text{'view_raw'}
\n"; +if ($in{'headers'}) { + # Show all the headers + if ($mail->{'fromline'}) { + print "", + "\n"; + } + foreach $h (@{$mail->{'headers'}}) { + print " ", + "\n"; + } + } +else { + # Just show the most useful headers + print " ", + "\n"; + print " ", + "\n"; + print " ", + "\n" + if ($mail->{'header'}->{'cc'}); + print " ", + "\n"; + print " ", + "\n"; + } +print "
$text{'mail_rfc'}",&eucconv_and_escape($mail->{'fromline'}), + "
$h->[0]:",&eucconv_and_escape(&decode_mimewords($h->[1])), + "
$text{'mail_from'}",&address_link($mail->{'header'}->{'from'}),"
$text{'mail_to'}",&address_link($mail->{'header'}->{'to'}),"
$text{'mail_cc'}",&address_link($mail->{'header'}->{'cc'}),"
$text{'mail_date'}",&eucconv_and_escape($mail->{'header'}->{'date'}), + "
$text{'mail_subject'}",&eucconv_and_escape(&decode_mimewords( + $mail->{'header'}->{'subject'})),"

\n"; + +# Show body attachment, with properly linked URLs +if ($body && $body->{'data'} =~ /\S/) { + if ($body eq $textbody) { + # Show plain text + $bodycontents = "

";
+		foreach $l (&wrap_lines(&eucconv($body->{'data'}),
+					$config{'wrap_width'})) {
+			$bodycontents .= &link_urls_and_escape($l,
+						$config{'link_mode'})."\n";
+			}
+		$bodycontents .= "
"; + if ($htmlbody) { + $bodyright = "$text{'view_ashtml'}"; + } + } + elsif ($body eq $htmlbody) { + # Attempt to show HTML + $bodycontents = &safe_html($body->{'data'}); + $bodycontents = &fix_cids($bodycontents, \@attach, + "detach.cgi?user=$uuser&idx=$in{'idx'}&folder=$in{'folder'}$subs"); + if ($textbody) { + $bodyright = "$text{'view_astext'}"; + } + } + } +if ($bodycontents) { + print "\n"; + print "\n"; + print "
", + " ", + "
$text{'view_body'}$bodyright
\n"; + print $bodycontents; + print "

\n"; + } + +# Show delivery status +if ($dstatus) { + print "\n"; + print "\n"; + print "
$text{'view_dstatus'}
\n"; + + local $ds = &parse_delivery_status($dstatus->{'data'}); + foreach $dsh ('final-recipient', 'diagnostic-code', + 'remote-mta', 'reporting-mta') { + if ($ds->{$dsh}) { + $ds->{$dsh} =~ s/^\S+;//; + print "\n"; + print "\n"; + } + } + + print "
", + $text{'view_'.$dsh},"",&html_escape($ds->{$dsh}),"

\n"; + } + +# Display other attachments +if (@attach) { + print "\n"; + print "\n"; + print "
$text{'view_attach'}
\n"; + foreach $a (@attach) { + local $fn; + $size = (int(length($a->{'data'})/1000)+1)." Kb"; + local $cb; + if ($a->{'type'} eq 'message/rfc822') { + push(@titles, "$text{'view_sub'}
$size"); + } + elsif ($a->{'filename'}) { + push(@titles, &decode_mimewords($a->{'filename'}). + "
$size"); + $fn = &decode_mimewords($a->{'filename'}); + push(@detach, [ $a->{'idx'}, $fn ]); + } + else { + push(@titles, "$a->{'type'}
$size"); + $a->{'type'} =~ /\/(\S+)$/; + $fn = "file.$1"; + push(@detach, [ $a->{'idx'}, $fn ]); + } + if ($a->{'error'}) { + $titles[$#titles] .= "
($a->{'error'})"; + } + $fn =~ s/ /_/g; + $fn =~ s/\#/_/g; + $fn = &html_escape($fn); + if ($a->{'type'} eq 'message/rfc822') { + push(@links, "view_mail.cgi?idx=$in{'idx'}&folder=$in{'folder'}&user=$uuser$subs&sub=$a->{'idx'}"); + } + else { + push(@links, "detach.cgi/$fn?idx=$in{'idx'}&folder=$in{'folder'}&user=$uuser&attach=$a->{'idx'}$subs"); + } + if ($config{'thumbnails'} && + ($a->{'type'} =~ /image\/gif/i && &has_command("giftopnm")&& + &has_command("pnmscale") && &has_command("cjpeg") || + $a->{'type'} =~ /image\/jpeg/i && &has_command("djpeg") && + &has_command("pnmscale") && &has_command("cjpeg"))) { + # Can show an image icon + push(@icons, "detach.cgi?scale=1&idx=$in{'idx'}&folder=$in{'folder'}&attach=$a->{'idx'}$subs"); + $imgicons++; + } + else { + push(@icons, "images/boxes.gif"); + } + } + &icons_table(\@links, \@titles, \@icons, 6, undef, + $imgicons ? ( 0, 0 ) : ( )); + if ($access{'candetach'} && @detach && defined($uinfo[2])) { + print "\n"; + print "\n" if ($body); + print "\n"; + print "$text{'view_dir'}\n"; + print " ", + &file_chooser_button("dir", 1),"\n"; + } + print "

\n"; + } + +&show_mail_buttons(2, scalar(@sub)) if (&editable_mail($mail)); +if ($config{'arrows'} == 2 && !@sub) { + &show_arrows(); + } +print "

\n"; + +dbmclose(%read); + +local @sr = !@sub ? ( ) : + ( "view_mail.cgi?idx=$in{'idx'}", $text{'view_return'} ), +$s = int((@mail - $in{'idx'} - 1) / $config{'perpage'}) * + $config{'perpage'}; +&mail_page_footer(@sub ? ( "view_mail.cgi?idx=$in{'idx'}&folder=$in{'folder'}&user=$uuser", + $text{'view_return'} ) : ( ), + "list_mail.cgi?folder=$in{'folder'}&user=$uuser", $text{'mail_return'}, + "", $text{'index_return'}); + +# show_mail_buttons(pos, submode) +sub show_mail_buttons +{ +local $spacer = " \n"; +if (!$_[1]) { + print ""; + print $spacer; + + if (!$folder->{'sent'} && !$folder->{'drafts'}) { + $m = $read{$mail->{'header'}->{'message-id'}}; + print ""; + print ""; + print $spacer; + } + } +if (&is_user($in{'user'})) { + print ""; + print $spacer; + } + +print ""; +print $spacer; + +if (&is_user($in{'user'})) { + print ""; + print ""; + print $spacer; + } + +print ""; +print $spacer; + +# Show spam report buttons +@modules = &get_available_module_infos(1); +($hasspam) = grep { $_->{'dir'} eq "spam" } @modules; +if (&foreign_installed("spam") && + $config{'spam_buttons'} =~ /mail/ && + &spam_report_cmd($in{'user'})) { + if ($hasspam) { + print ""; + } + if ($config{'spam_del'}) { + print "\n"; + } + else { + print "\n"; + } + } +print "
\n"; +} + +sub show_arrows +{ +print "
\n"; +if (!@sub) { + if ($in{'idx'}) { + print "", + "\n"; + } + print "",&text('view_desc', $in{'idx'}+1, + $folder->{'name'}),"\n"; + if ($in{'idx'} < @mail-1) { + print "", + "\n"; + } + } +else { + print "$text{'view_sub'}\n"; + } +print "

\n"; +} + +# address_link(address) +sub address_link +{ +local @addrs = &split_addresses(&decode_mimewords($_[0])); +local @rv; +foreach $a (@addrs) { + push(@rv, &eucconv_and_escape($a->[2])); + } +return join(" , ", @rv); +} + diff --git a/mailboxes/xinha/Xinha.css b/mailboxes/xinha/Xinha.css new file mode 100644 index 000000000..2b4d7d9a7 --- /dev/null +++ b/mailboxes/xinha/Xinha.css @@ -0,0 +1,257 @@ +.htmlarea { background: #fff; } + +.htmlarea .toolbar { + cursor: default; + background: ButtonFace; + padding: 3px; + border: 1px solid; + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; +} +.htmlarea .toolbar table { margin: 0; font-family: tahoma,verdana,sans-serif; font-size: 11px; } +.htmlarea .toolbar img { border: none; vertical-align: top; } +.htmlarea .toolbar .label { padding: 0px 3px; } + +.htmlarea .toolbar .button { + background: ButtonFace; + color: ButtonText; + border: 1px solid ButtonFace; + padding: 1px; + margin: 0px; + width: 18px; + height: 18px; +} +.htmlarea .toolbar a.button:hover { + border: 1px solid; + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; +} +.htmlarea .toolbar a.buttonDisabled:hover { + border-color: ButtonFace; +} +.htmlarea .toolbar .buttonActive, +.htmlarea .toolbar .buttonPressed +{ + padding: 2px 0px 0px 2px; + border: 1px solid; + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; +} +.htmlarea .toolbar .buttonPressed { + background: ButtonHighlight; +} +.htmlarea .toolbar .indicator { + padding: 0px 3px; + overflow: hidden; + width: 20px; + text-align: center; + cursor: default; + border: 1px solid ButtonShadow; +} + +.htmlarea .toolbar .buttonDisabled img { + filter: gray() alpha(opacity = 25); + -moz-opacity: 0.25; + opacity: 0.25; +} + +.htmlarea .toolbar .separator { + /*position: relative;*/ + margin: 3px; + border-left: 1px solid ButtonShadow; + border-right: 1px solid ButtonHighlight; + width: 0px; + height: 18px; + padding: 0px; +} + +.htmlarea .toolbar .space { width: 5px; } + +.htmlarea .toolbar select, .htmlarea .toolbar option { font: 11px Tahoma,Verdana,sans-serif;} + +.htmlarea .toolbar select, +.htmlarea .toolbar select:hover, +.htmlarea .toolbar select:active { + margin-top: 2px; + margin-bottom: 1px; + color: ButtonText; +} + +.htmlarea iframe.xinha_iframe, .htmlarea textarea.xinha_textarea +{ + border: none; /*1px solid;*/ +} + +.htmlarea .statusBar { + border: 1px solid; + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; + padding: 2px 4px; + background-color: ButtonFace; + color: ButtonText; + font: 11px Tahoma,Verdana,sans-serif; + height:16px; +} + +.htmlarea .statusBar .statusBarTree a { + padding: 2px 5px; + color: #00f; +} + +.htmlarea .statusBar .statusBarTree a:visited { color: #00f; } +.htmlarea .statusBar .statusBarTree a:hover { + background-color: Highlight; + color: HighlightText; + padding: 1px 4px; + border: 1px solid HighlightText; +} + + +/* popup dialogs */ + +.dialog { + color: ButtonText; + background: ButtonFace; +} + +.dialog .content { padding: 2px; } + +.dialog, .dialog button, .dialog input, .dialog select, .dialog textarea, .dialog table { + font: 11px Tahoma,Verdana,sans-serif; +} + +.dialog table { border-collapse: collapse; } + +.dialog .title, .dialog h1 +{ + background: #008; + color: #ff8; + border-bottom: 1px solid #000; + padding: 1px 0px 2px 5px; + font-size: 12px; + font-weight: bold; + cursor: default; +} +.dialog h1 { margin:0px;} +.dialog .title .button { + float: right; + border: 1px solid #66a; + padding: 0px 1px 0px 2px; + margin-right: 1px; + color: #fff; + text-align: center; +} + +.dialog .title .button-hilite { border-color: #88f; background: #44c; } + +.dialog button { + width: 5em; + padding: 0px; +} + +.dialog .buttonColor { + padding: 1px; + cursor: default; + border: 1px solid; + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; +} + +.dialog .buttonColor-hilite { + border-color: #000; +} + +.dialog .buttonColor .chooser, .dialog .buttonColor .nocolor { + height: 0.6em; + border: 1px solid; + padding: 0px 1em; + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; +} + +.dialog .buttonColor .nocolor { padding: 0px; } +.dialog .buttonColor .nocolor-hilite { background-color: #fff; color: #f00; } + +.dialog .label { text-align: right; width: 6em; } +.dialog .value input { width: 100%; } +.dialog .buttons { text-align: right; padding: 2px 4px 0px 4px; } + +.dialog legend { font-weight: bold; } +.dialog fieldset table { margin: 2px 0px; } + +.popupwin { + padding: 0px; + margin: 0px; +} + +.popupwin .title { + background: #fff; + color: #000; + font-weight: bold; + font-size: 120%; + padding: 3px 10px; + margin-bottom: 10px; + border-bottom: 1px solid black; + letter-spacing: 2px; +} + +form { margin: 0px; border: none; } + + +/** Panels **/ +.htmlarea .panels.top +{ + border-bottom : 1px solid; + border-color: ButtonShadow; +} + +.htmlarea .panels.right +{ + border-left : 1px solid; + border-color: ButtonShadow; +} + +.htmlarea .panels.left +{ + border-right : 1px solid; + border-color: ButtonShadow; +} + +.htmlarea .panels.bottom +{ + border-top : 1px solid; + border-color: ButtonShadow; +} + +.htmlarea .panel h1 { + background: ButtonFace; + border: 1px solid; + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; + margin: 0px; + padding: 0px; + font-size:100%; + font-weight:bold; + padding: 2px; + clear:left; + +} + +.htmlarea .panel { overflow:auto; } +.htmlarea .panels.left .panel { border-right:none; border-left:none; } +.htmlarea .panels.left h1 { border-right:none; } +.htmlarea .panels.right .panel { border-right:none; border-left:none; } +.htmlarea .panels.left h1 { border-left:none; } +.htmlarea { border: 1px solid black; } + +.loading +{ + background-color:#666; + position:absolute; + z-index:998; +} +.loading_main +{ + font-size:1.6em; + color:#ff6; + text-align:center; +} +.loading_sub +{ + font-size:1.0em; + color:#fff; + text-align:center; +} diff --git a/mailboxes/xinha/XinhaCore.js b/mailboxes/xinha/XinhaCore.js new file mode 100644 index 000000000..ef37adf99 --- /dev/null +++ b/mailboxes/xinha/XinhaCore.js @@ -0,0 +1,3473 @@ +Xinha.version={"Release":"Trunk","Head":"$HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/XinhaCore.js $".replace(/^[^:]*: (.*) \$$/,"$1"),"Date":"$LastChangedDate: 2007-02-22 02:11:56 +0100 (Do, 22 Feb 2007) $".replace(/^[^:]*: ([0-9-]*) ([0-9:]*) ([+0-9]*) \((.*)\) \$/,"$4 $2 $3"),"Revision":"$LastChangedRevision: 757 $".replace(/^[^:]*: (.*) \$$/,"$1"),"RevisionBy":"$LastChangedBy: ray $".replace(/^[^:]*: (.*) \$$/,"$1")}; +Xinha._resolveRelativeUrl=function(_1,_2){ +if(_2.match(/^([^:]+\:)?\//)){ +return _2; +}else{ +var b=_1.split("/"); +if(b[b.length-1]==""){ +b.pop(); +} +var p=_2.split("/"); +if(p[0]=="."){ +p.shift(); +} +while(p[0]==".."){ +b.pop(); +p.shift(); +} +return b.join("/")+"/"+p.join("/"); +} +}; +if(typeof _editor_url=="string"){ +_editor_url=_editor_url.replace(/\x2f*$/,"/"); +if(!_editor_url.match(/^([^:]+\:)?\//)){ +var path=window.location.toString().split("/"); +path.pop(); +_editor_url=Xinha._resolveRelativeUrl(path.join("/"),_editor_url); +} +}else{ +alert("WARNING: _editor_url is not set! You should set this variable to the editor files path; it should preferably be an absolute path, like in '/htmlarea/', but it can be relative if you prefer. Further we will try to load the editor files correctly but we'll probably fail."); +_editor_url=""; +} +if(typeof _editor_lang=="string"){ +_editor_lang=_editor_lang.toLowerCase(); +}else{ +_editor_lang="en"; +} +if(typeof _editor_skin!=="string"){ +_editor_skin=""; +} +var __xinhas=[]; +Xinha.agt=navigator.userAgent.toLowerCase(); +Xinha.is_ie=((Xinha.agt.indexOf("msie")!=-1)&&(Xinha.agt.indexOf("opera")==-1)); +Xinha.ie_version=parseFloat(Xinha.agt.substring(Xinha.agt.indexOf("msie")+5)); +Xinha.is_opera=(Xinha.agt.indexOf("opera")!=-1); +Xinha.is_mac=(Xinha.agt.indexOf("mac")!=-1); +Xinha.is_mac_ie=(Xinha.is_ie&&Xinha.is_mac); +Xinha.is_win_ie=(Xinha.is_ie&&!Xinha.is_mac); +Xinha.is_gecko=(navigator.product=="Gecko"); +Xinha.isRunLocally=document.URL.toLowerCase().search(/^file:/)!=-1; +if(Xinha.isRunLocally){ +alert("Xinha *must* be installed on a web server. Locally opened files (those that use the \"file://\" protocol) cannot properly function. Xinha will try to initialize but may not be correctly loaded."); +} +function Xinha(_5,_6){ +if(!_5){ +throw ("Tried to create Xinha without textarea specified."); +} +if(Xinha.checkSupportedBrowser()){ +if(typeof _6=="undefined"){ +this.config=new Xinha.Config(); +}else{ +this.config=_6; +} +this._htmlArea=null; +if(typeof _5!="object"){ +_5=Xinha.getElementById("textarea",_5); +} +this._textArea=_5; +this._textArea.spellcheck=false; +this._initial_ta_size={w:_5.style.width?_5.style.width:(_5.offsetWidth?(_5.offsetWidth+"px"):(_5.cols+"em")),h:_5.style.height?_5.style.height:(_5.offsetHeight?(_5.offsetHeight+"px"):(_5.rows+"em"))}; +if(this.config.showLoading){ +var _7=document.createElement("div"); +_7.id="loading_"+_5.name; +_7.className="loading"; +try{ +_7.style.width=_5.offsetWidth+"px"; +} +catch(ex){ +_7.style.width=this._initial_ta_size.w; +} +_7.style.left=Xinha.findPosX(_5)+"px"; +_7.style.top=(Xinha.findPosY(_5)+parseInt(this._initial_ta_size.h,10)/2)+"px"; +var _8=document.createElement("div"); +_8.className="loading_main"; +_8.id="loading_main_"+_5.name; +_8.appendChild(document.createTextNode(Xinha._lc("Loading in progress. Please wait !"))); +var _9=document.createElement("div"); +_9.className="loading_sub"; +_9.id="loading_sub_"+_5.name; +_9.appendChild(document.createTextNode(Xinha._lc("Constructing main object"))); +_7.appendChild(_8); +_7.appendChild(_9); +document.body.appendChild(_7); +this.setLoadingMessage("Constructing object"); +} +this._editMode="wysiwyg"; +this.plugins={}; +this._timerToolbar=null; +this._timerUndo=null; +this._undoQueue=[this.config.undoSteps]; +this._undoPos=-1; +this._customUndo=true; +this._mdoc=document; +this.doctype=""; +this.__htmlarea_id_num=__xinhas.length; +__xinhas[this.__htmlarea_id_num]=this; +this._notifyListeners={}; +var _a={right:{on:true,container:document.createElement("td"),panels:[]},left:{on:true,container:document.createElement("td"),panels:[]},top:{on:true,container:document.createElement("td"),panels:[]},bottom:{on:true,container:document.createElement("td"),panels:[]}}; +for(var i in _a){ +if(!_a[i].container){ +continue; +} +_a[i].div=_a[i].container; +_a[i].container.className="panels "+i; +Xinha.freeLater(_a[i],"container"); +Xinha.freeLater(_a[i],"div"); +} +this._panels=_a; +Xinha.freeLater(this,"_textArea"); +} +} +Xinha.onload=function(){ +}; +Xinha.init=function(){ +Xinha.onload(); +}; +Xinha.RE_tagName=/(<\/|<)\s*([^ \t\n>]+)/ig; +Xinha.RE_doctype=/()\n?/i; +Xinha.RE_head=/((.|\n)*?)<\/head>/i; +Xinha.RE_body=/]*>((.|\n|\r|\t)*?)<\/body>/i; +Xinha.RE_Specials=/([\/\^$*+?.()|{}[\]])/g; +Xinha.RE_email=/[_a-zA-Z\d\-\.]{3,}@[_a-zA-Z\d\-]{2,}(\.[_a-zA-Z\d\-]{2,})+/i; +Xinha.RE_url=/(https?:\/\/)?(([a-z0-9_]+:[a-z0-9_]+@)?[a-z0-9_-]{2,}(\.[a-z0-9_-]{2,}){2,}(:[0-9]+)?(\/\S+)*)/i; +Xinha.Config=function(){ +var _c=this; +this.version=Xinha.version.Revision; +this.width="auto"; +this.height="auto"; +this.sizeIncludesBars=true; +this.sizeIncludesPanels=true; +this.panel_dimensions={left:"200px",right:"200px",top:"100px",bottom:"100px"}; +this.statusBar=true; +this.htmlareaPaste=false; +this.mozParaHandler="best"; +this.getHtmlMethod="DOMwalk"; +this.undoSteps=20; +this.undoTimeout=500; +this.changeJustifyWithDirection=false; +this.fullPage=false; +this.pageStyle=""; +this.pageStyleSheets=[]; +this.baseHref=null; +this.expandRelativeUrl=true; +this.stripBaseHref=true; +this.stripSelfNamedAnchors=true; +this.only7BitPrintablesInURLs=true; +this.sevenBitClean=false; +this.specialReplacements={}; +this.killWordOnPaste=true; +this.makeLinkShowsTarget=true; +this.charSet=Xinha.is_gecko?document.characterSet:document.charset; +this.imgURL="images/"; +this.popupURL="popups/"; +this.htmlRemoveTags=null; +this.flowToolbars=true; +this.showLoading=false; +this.stripScripts=true; +this.convertUrlsToLinks=true; +this.colorPickerCellSize="6px"; +this.colorPickerGranularity=18; +this.colorPickerPosition="bottom,right"; +this.colorPickerWebSafe=false; +this.colorPickerSaveColors=20; +this.fullScreen=false; +this.fullScreenMargins=[0,0,0,0]; +this.toolbar=[["popupeditor"],["separator","formatblock","fontname","fontsize","bold","italic","underline","strikethrough"],["separator","forecolor","hilitecolor","textindicator"],["separator","subscript","superscript"],["linebreak","separator","justifyleft","justifycenter","justifyright","justifyfull"],["separator","insertorderedlist","insertunorderedlist","outdent","indent"],["separator","inserthorizontalrule","createlink","insertimage","inserttable"],["linebreak","separator","undo","redo","selectall","print"],(Xinha.is_gecko?[]:["cut","copy","paste","overwrite","saveas"]),["separator","killword","clearfonts","removeformat","toggleborders","splitblock","lefttoright","righttoleft"],["separator","htmlmode","showhelp","about"]]; +this.fontname={"— font —":"","Arial":"arial,helvetica,sans-serif","Courier New":"courier new,courier,monospace","Georgia":"georgia,times new roman,times,serif","Tahoma":"tahoma,arial,helvetica,sans-serif","Times New Roman":"times new roman,times,serif","Verdana":"verdana,arial,helvetica,sans-serif","impact":"impact","WingDings":"wingdings"}; +this.fontsize={"— size —":"","1 (8 pt)":"1","2 (10 pt)":"2","3 (12 pt)":"3","4 (14 pt)":"4","5 (18 pt)":"5","6 (24 pt)":"6","7 (36 pt)":"7"}; +this.formatblock={"— format —":"","Heading 1":"h1","Heading 2":"h2","Heading 3":"h3","Heading 4":"h4","Heading 5":"h5","Heading 6":"h6","Normal":"p","Address":"address","Formatted":"pre"}; +this.customSelects={}; +function cut_copy_paste(e,_e,_f){ +e.execCommand(_e); +} +this.debug=true; +this.URIs={"blank":"popups/blank.html","link":_editor_url+"modules/CreateLink/link.html","insert_image":_editor_url+"modules/InsertImage/insert_image.html","insert_table":_editor_url+"modules/InsertTable/insert_table.html","select_color":"select_color.html","about":"about.html","help":"editor_help.html"}; +this.btnList={bold:["Bold",Xinha._lc({key:"button_bold",string:["ed_buttons_main.gif",3,2]},"Xinha"),false,function(e){ +e.execCommand("bold"); +}],italic:["Italic",Xinha._lc({key:"button_italic",string:["ed_buttons_main.gif",2,2]},"Xinha"),false,function(e){ +e.execCommand("italic"); +}],underline:["Underline",Xinha._lc({key:"button_underline",string:["ed_buttons_main.gif",2,0]},"Xinha"),false,function(e){ +e.execCommand("underline"); +}],strikethrough:["Strikethrough",Xinha._lc({key:"button_strikethrough",string:["ed_buttons_main.gif",3,0]},"Xinha"),false,function(e){ +e.execCommand("strikethrough"); +}],subscript:["Subscript",Xinha._lc({key:"button_subscript",string:["ed_buttons_main.gif",3,1]},"Xinha"),false,function(e){ +e.execCommand("subscript"); +}],superscript:["Superscript",Xinha._lc({key:"button_superscript",string:["ed_buttons_main.gif",2,1]},"Xinha"),false,function(e){ +e.execCommand("superscript"); +}],justifyleft:["Justify Left",["ed_buttons_main.gif",0,0],false,function(e){ +e.execCommand("justifyleft"); +}],justifycenter:["Justify Center",["ed_buttons_main.gif",1,1],false,function(e){ +e.execCommand("justifycenter"); +}],justifyright:["Justify Right",["ed_buttons_main.gif",1,0],false,function(e){ +e.execCommand("justifyright"); +}],justifyfull:["Justify Full",["ed_buttons_main.gif",0,1],false,function(e){ +e.execCommand("justifyfull"); +}],orderedlist:["Ordered List",["ed_buttons_main.gif",0,3],false,function(e){ +e.execCommand("insertorderedlist"); +}],unorderedlist:["Bulleted List",["ed_buttons_main.gif",1,3],false,function(e){ +e.execCommand("insertunorderedlist"); +}],insertorderedlist:["Ordered List",["ed_buttons_main.gif",0,3],false,function(e){ +e.execCommand("insertorderedlist"); +}],insertunorderedlist:["Bulleted List",["ed_buttons_main.gif",1,3],false,function(e){ +e.execCommand("insertunorderedlist"); +}],outdent:["Decrease Indent",["ed_buttons_main.gif",1,2],false,function(e){ +e.execCommand("outdent"); +}],indent:["Increase Indent",["ed_buttons_main.gif",0,2],false,function(e){ +e.execCommand("indent"); +}],forecolor:["Font Color",["ed_buttons_main.gif",3,3],false,function(e){ +e.execCommand("forecolor"); +}],hilitecolor:["Background Color",["ed_buttons_main.gif",2,3],false,function(e){ +e.execCommand("hilitecolor"); +}],undo:["Undoes your last action",["ed_buttons_main.gif",4,2],false,function(e){ +e.execCommand("undo"); +}],redo:["Redoes your last action",["ed_buttons_main.gif",5,2],false,function(e){ +e.execCommand("redo"); +}],cut:["Cut selection",["ed_buttons_main.gif",5,0],false,cut_copy_paste],copy:["Copy selection",["ed_buttons_main.gif",4,0],false,cut_copy_paste],paste:["Paste from clipboard",["ed_buttons_main.gif",4,1],false,cut_copy_paste],selectall:["Select all","ed_selectall.gif",false,function(e){ +e.execCommand("selectall"); +}],inserthorizontalrule:["Horizontal Rule",["ed_buttons_main.gif",6,0],false,function(e){ +e.execCommand("inserthorizontalrule"); +}],createlink:["Insert Web Link",["ed_buttons_main.gif",6,1],false,function(e){ +e._createLink(); +}],insertimage:["Insert/Modify Image",["ed_buttons_main.gif",6,3],false,function(e){ +e.execCommand("insertimage"); +}],inserttable:["Insert Table",["ed_buttons_main.gif",6,2],false,function(e){ +e.execCommand("inserttable"); +}],htmlmode:["Toggle HTML Source",["ed_buttons_main.gif",7,0],true,function(e){ +e.execCommand("htmlmode"); +}],toggleborders:["Toggle Borders",["ed_buttons_main.gif",7,2],false,function(e){ +e._toggleBorders(); +}],print:["Print document",["ed_buttons_main.gif",8,1],false,function(e){ +if(Xinha.is_gecko){ +e._iframe.contentWindow.print(); +}else{ +e.focusEditor(); +print(); +} +}],saveas:["Save as","ed_saveas.gif",false,function(e){ +e.execCommand("saveas",false,"noname.htm"); +}],about:["About this editor",["ed_buttons_main.gif",8,2],true,function(e){ +e.execCommand("about"); +}],showhelp:["Help using editor",["ed_buttons_main.gif",9,2],true,function(e){ +e.execCommand("showhelp"); +}],splitblock:["Split Block","ed_splitblock.gif",false,function(e){ +e._splitBlock(); +}],lefttoright:["Direction left to right",["ed_buttons_main.gif",0,4],false,function(e){ +e.execCommand("lefttoright"); +}],righttoleft:["Direction right to left",["ed_buttons_main.gif",1,4],false,function(e){ +e.execCommand("righttoleft"); +}],overwrite:["Insert/Overwrite","ed_overwrite.gif",false,function(e){ +e.execCommand("overwrite"); +}],wordclean:["MS Word Cleaner",["ed_buttons_main.gif",5,3],false,function(e){ +e._wordClean(); +}],clearfonts:["Clear Inline Font Specifications",["ed_buttons_main.gif",5,4],true,function(e){ +e._clearFonts(); +}],removeformat:["Remove formatting",["ed_buttons_main.gif",4,4],false,function(e){ +e.execCommand("removeformat"); +}],killword:["Clear MSOffice tags",["ed_buttons_main.gif",4,3],false,function(e){ +e.execCommand("killword"); +}]}; +for(var i in this.btnList){ +var btn=this.btnList[i]; +if(typeof btn!="object"){ +continue; +} +if(typeof btn[1]!="string"){ +btn[1][0]=_editor_url+this.imgURL+btn[1][0]; +}else{ +btn[1]=_editor_url+this.imgURL+btn[1]; +} +btn[0]=Xinha._lc(btn[0]); +} +}; +Xinha.Config.prototype.registerButton=function(id,_3a,_3b,_3c,_3d,_3e){ +var _3f; +if(typeof id=="string"){ +_3f=id; +}else{ +if(typeof id=="object"){ +_3f=id.id; +}else{ +alert("ERROR [Xinha.Config::registerButton]:\ninvalid arguments"); +return false; +} +} +switch(typeof id){ +case "string": +this.btnList[id]=[_3a,_3b,_3c,_3d,_3e]; +break; +case "object": +this.btnList[id.id]=[id.tooltip,id.image,id.textMode,id.action,id.context]; +break; +} +}; +Xinha.prototype.registerPanel=function(_40,_41){ +if(!_40){ +_40="right"; +} +this.setLoadingMessage("Register panel "+_40); +var _42=this.addPanel(_40); +if(_41){ +_41.drawPanelIn(_42); +} +}; +Xinha.Config.prototype.registerDropdown=function(_43){ +this.customSelects[_43.id]=_43; +}; +Xinha.Config.prototype.hideSomeButtons=function(_44){ +var _45=this.toolbar; +for(var i=_45.length;--i>=0;){ +var _47=_45[i]; +for(var j=_47.length;--j>=0;){ +if(_44.indexOf(" "+_47[j]+" ")>=0){ +var len=1; +if(/separator|space/.test(_47[j+1])){ +len=2; +} +_47.splice(j,len); +} +} +} +}; +Xinha.Config.prototype.addToolbarElement=function(id,_4b,_4c){ +var _4d=this.toolbar; +var a,i,j,o,sid; +var _4f=false; +var _50=false; +var _51=0; +var _52=0; +var _53=0; +var _54=false; +var _55=false; +if((id&&typeof id=="object")&&(id.constructor==Array)){ +_4f=true; +} +if((_4b&&typeof _4b=="object")&&(_4b.constructor==Array)){ +_50=true; +_51=_4b.length; +} +if(_4f){ +for(i=0;i=0;){ +a.splice(j,0,id[i]); +} +}else{ +a[j]=id; +} +}else{ +if(_4c<0){ +j=j+_4c+1; +}else{ +if(_4c>0){ +j=j+_4c; +} +} +if(_4f){ +for(i=id.length;--i>=0;){ +a.splice(j,0,id[i]); +} +}else{ +a.splice(j,0,id); +} +} +}else{ +_4d[0].splice(0,0,"separator"); +if(_4f){ +for(i=id.length;--i>=0;){ +_4d[0].splice(0,0,id[i]); +} +}else{ +_4d[0].splice(0,0,id); +} +} +}; +Xinha.Config.prototype.removeToolbarElement=Xinha.Config.prototype.hideSomeButtons; +Xinha.replaceAll=function(_56){ +var tas=document.getElementsByTagName("textarea"); +for(var i=tas.length;i>0;(new Xinha(tas[--i],_56)).generate()){ +} +}; +Xinha.replace=function(id,_5a){ +var ta=Xinha.getElementById("textarea",id); +return ta?(new Xinha(ta,_5a)).generate():null; +}; +Xinha.prototype._createToolbar=function(){ +this.setLoadingMessage("Create Toolbar"); +var _5c=this; +var _5d=document.createElement("div"); +this._toolBar=this._toolbar=_5d; +_5d.className="toolbar"; +_5d.unselectable="1"; +Xinha.freeLater(this,"_toolBar"); +Xinha.freeLater(this,"_toolbar"); +var _5e=null; +var _5f={}; +this._toolbarObjects=_5f; +this._createToolbar1(_5c,_5d,_5f); +this._htmlArea.appendChild(_5d); +return _5d; +}; +Xinha.prototype._setConfig=function(_60){ +this.config=_60; +}; +Xinha.prototype._addToolbar=function(){ +this._createToolbar1(this,this._toolbar,this._toolbarObjects); +}; +Xinha._createToolbarBreakingElement=function(){ +var brk=document.createElement("div"); +brk.style.height="1px"; +brk.style.width="1px"; +brk.style.lineHeight="1px"; +brk.style.fontSize="1px"; +brk.style.clear="both"; +return brk; +}; +Xinha.prototype._createToolbar1=function(_62,_63,_64){ +var _65; +if(_62.config.flowToolbars){ +_63.appendChild(Xinha._createToolbarBreakingElement()); +} +function newLine(){ +if(typeof _65!="undefined"&&_65.childNodes.length===0){ +return; +} +var _66=document.createElement("table"); +_66.border="0px"; +_66.cellSpacing="0px"; +_66.cellPadding="0px"; +if(_62.config.flowToolbars){ +if(Xinha.is_ie){ +_66.style.styleFloat="left"; +}else{ +_66.style.cssFloat="left"; +} +} +_63.appendChild(_66); +var _67=document.createElement("tbody"); +_66.appendChild(_67); +_65=document.createElement("tr"); +_67.appendChild(_65); +_66.className="toolbarRow"; +} +newLine(); +function setButtonStatus(id,_69){ +var _6a=this[id]; +var el=this.element; +if(_6a!=_69){ +switch(id){ +case "enabled": +if(_69){ +Xinha._removeClass(el,"buttonDisabled"); +el.disabled=false; +}else{ +Xinha._addClass(el,"buttonDisabled"); +el.disabled=true; +} +break; +case "active": +if(_69){ +Xinha._addClass(el,"buttonPressed"); +}else{ +Xinha._removeClass(el,"buttonPressed"); +} +break; +} +this[id]=_69; +} +} +function createSelect(txt){ +var _6d=null; +var el=null; +var cmd=null; +var _70=_62.config.customSelects; +var _71=null; +var _72=""; +switch(txt){ +case "fontsize": +case "fontname": +case "formatblock": +_6d=_62.config[txt]; +cmd=txt; +break; +default: +cmd=txt; +var _73=_70[cmd]; +if(typeof _73!="undefined"){ +_6d=_73.options; +_71=_73.context; +if(typeof _73.tooltip!="undefined"){ +_72=_73.tooltip; +} +}else{ +alert("ERROR [createSelect]:\nCan't find the requested dropdown definition"); +} +break; +} +if(_6d){ +el=document.createElement("select"); +el.title=_72; +var obj={name:txt,element:el,enabled:true,text:false,cmd:cmd,state:setButtonStatus,context:_71}; +Xinha.freeLater(obj); +_64[txt]=obj; +for(var i in _6d){ +if(typeof (_6d[i])!="string"){ +continue; +} +var op=document.createElement("option"); +op.innerHTML=Xinha._lc(i); +op.value=_6d[i]; +el.appendChild(op); +} +Xinha._addEvent(el,"change",function(){ +_62._comboSelected(el,txt); +}); +} +return el; +} +function createButton(txt){ +var el,btn,obj=null; +switch(txt){ +case "separator": +if(_62.config.flowToolbars){ +newLine(); +} +el=document.createElement("div"); +el.className="separator"; +break; +case "space": +el=document.createElement("div"); +el.className="space"; +break; +case "linebreak": +newLine(); +return false; +case "textindicator": +el=document.createElement("div"); +el.appendChild(document.createTextNode("A")); +el.className="indicator"; +el.title=Xinha._lc("Current style"); +obj={name:txt,element:el,enabled:true,active:false,text:false,cmd:"textindicator",state:setButtonStatus}; +Xinha.freeLater(obj); +_64[txt]=obj; +break; +default: +btn=_62.config.btnList[txt]; +} +if(!el&&btn){ +el=document.createElement("a"); +el.style.display="block"; +el.href="javascript:void(0)"; +el.style.textDecoration="none"; +el.title=btn[0]; +el.className="button"; +el.style.direction="ltr"; +obj={name:txt,element:el,enabled:true,active:false,text:btn[2],cmd:btn[3],state:setButtonStatus,context:btn[4]||null}; +Xinha.freeLater(el); +Xinha.freeLater(obj); +_64[txt]=obj; +el.ondrag=function(){ +return false; +}; +Xinha._addEvent(el,"mouseout",function(ev){ +if(obj.enabled){ +Xinha._removeClass(el,"buttonActive"); +if(obj.active){ +Xinha._addClass(el,"buttonPressed"); +} +} +}); +Xinha._addEvent(el,"mousedown",function(ev){ +if(obj.enabled){ +Xinha._addClass(el,"buttonActive"); +Xinha._removeClass(el,"buttonPressed"); +Xinha._stopEvent(Xinha.is_ie?window.event:ev); +} +}); +Xinha._addEvent(el,"click",function(ev){ +if(obj.enabled){ +Xinha._removeClass(el,"buttonActive"); +if(Xinha.is_gecko){ +_62.activateEditor(); +} +obj.cmd(_62,obj.name,obj); +Xinha._stopEvent(Xinha.is_ie?window.event:ev); +} +}); +var _7c=Xinha.makeBtnImg(btn[1]); +var img=_7c.firstChild; +el.appendChild(_7c); +obj.imgel=img; +obj.swapImage=function(_7e){ +if(typeof _7e!="string"){ +img.src=_7e[0]; +img.style.position="relative"; +img.style.top=_7e[2]?("-"+(18*(_7e[2]+1))+"px"):"-18px"; +img.style.left=_7e[1]?("-"+(18*(_7e[1]+1))+"px"):"-18px"; +}else{ +obj.imgel.src=_7e; +img.style.top="0px"; +img.style.left="0px"; +} +}; +}else{ +if(!el){ +el=createSelect(txt); +} +} +return el; +} +var _7f=true; +for(var i=0;i] button to switch back to WYSIWYG."); +div.style.display="none"; +this._statusBarTextMode=div; +Xinha.freeLater(this,"_statusBarTextMode"); +this._statusBar.appendChild(div); +if(!this.config.statusBar){ +_8c.style.display="none"; +} +return _8c; +}; +Xinha.prototype.generate=function(){ +var i; +var _8f=this; +if(Xinha.is_ie){ +if(typeof InternetExplorer=="undefined"){ +Xinha.loadPlugin("InternetExplorer",function(){ +_8f.generate(); +},_editor_url+"modules/InternetExplorer/InternetExplorer.js"); +return false; +} +_8f._browserSpecificPlugin=_8f.registerPlugin("InternetExplorer"); +}else{ +if(typeof Gecko=="undefined"){ +Xinha.loadPlugin("Gecko",function(){ +_8f.generate(); +},_editor_url+"modules/Gecko/Gecko.js"); +return false; +} +_8f._browserSpecificPlugin=_8f.registerPlugin("Gecko"); +} +this.setLoadingMessage("Generate Xinha object"); +if(typeof Dialog=="undefined"){ +Xinha._loadback(_editor_url+"modules/Dialogs/dialog.js",this.generate,this); +return false; +} +if(typeof Xinha.Dialog=="undefined"){ +Xinha._loadback(_editor_url+"modules/Dialogs/inline-dialog.js",this.generate,this); +return false; +} +if(typeof FullScreen=="undefined"){ +Xinha.loadPlugin("FullScreen",function(){ +_8f.generate(); +},_editor_url+"modules/FullScreen/full-screen.js"); +return false; +} +var _90=_8f.config.toolbar; +for(i=_90.length;--i>=0;){ +for(var j=_90[i].length;--j>=0;){ +switch(_90[i][j]){ +case "popupeditor": +_8f.registerPlugin("FullScreen"); +break; +case "insertimage": +if(typeof InsertImage=="undefined"&&typeof Xinha.prototype._insertImage=="undefined"){ +Xinha.loadPlugin("InsertImage",function(){ +_8f.generate(); +},_editor_url+"modules/InsertImage/insert_image.js"); +return false; +}else{ +if(typeof InsertImage!="undefined"){ +_8f.registerPlugin("InsertImage"); +} +} +break; +case "createlink": +if(typeof CreateLink=="undefined"&&typeof Xinha.prototype._createLink=="undefined"&&typeof Linker=="undefined"){ +Xinha.loadPlugin("CreateLink",function(){ +_8f.generate(); +},_editor_url+"modules/CreateLink/link.js"); +return false; +}else{ +if(typeof CreateLink!="undefined"){ +_8f.registerPlugin("CreateLink"); +} +} +break; +case "inserttable": +if(typeof InsertTable=="undefined"&&typeof Xinha.prototype._insertTable=="undefined"){ +Xinha.loadPlugin("InsertTable",function(){ +_8f.generate(); +},_editor_url+"modules/InsertTable/insert_table.js"); +return false; +}else{ +if(typeof InsertTable!="undefined"){ +_8f.registerPlugin("InsertTable"); +} +} +break; +case "hilitecolor": +case "forecolor": +if(typeof ColorPicker=="undefined"){ +Xinha.loadPlugin("ColorPicker",function(){ +_8f.generate(); +},_editor_url+"modules/ColorPicker/ColorPicker.js"); +return false; +}else{ +if(typeof ColorPicker!="undefined"){ +_8f.registerPlugin("ColorPicker"); +} +} +break; +} +} +} +if(Xinha.is_gecko&&(_8f.config.mozParaHandler=="best"||_8f.config.mozParaHandler=="dirty")){ +switch(this.config.mozParaHandler){ +case "dirty": +var _92=_editor_url+"modules/Gecko/paraHandlerDirty.js"; +break; +default: +var _92=_editor_url+"modules/Gecko/paraHandlerBest.js"; +break; +} +if(typeof EnterParagraphs=="undefined"){ +Xinha.loadPlugin("EnterParagraphs",function(){ +_8f.generate(); +},_92); +return false; +} +_8f.registerPlugin("EnterParagraphs"); +} +switch(this.config.getHtmlMethod){ +case "TransformInnerHTML": +var _93=_editor_url+"modules/GetHtml/TransformInnerHTML.js"; +break; +default: +var _93=_editor_url+"modules/GetHtml/DOMwalk.js"; +break; +} +if(typeof GetHtmlImplementation=="undefined"){ +Xinha.loadPlugin("GetHtmlImplementation",function(){ +_8f.generate(); +},_93); +return false; +}else{ +_8f.registerPlugin("GetHtmlImplementation"); +} +if(_editor_skin!==""){ +var _94=false; +var _95=document.getElementsByTagName("head")[0]; +var _96=document.getElementsByTagName("link"); +for(i=0;i<_96.length;i++){ +if((_96[i].rel=="stylesheet")&&(_96[i].href==_editor_url+"skins/"+_editor_skin+"/skin.css")){ +_94=true; +} +} +if(!_94){ +var _97=document.createElement("link"); +_97.type="text/css"; +_97.href=_editor_url+"skins/"+_editor_skin+"/skin.css"; +_97.rel="stylesheet"; +_95.appendChild(_97); +} +} +this._framework={"table":document.createElement("table"),"tbody":document.createElement("tbody"),"tb_row":document.createElement("tr"),"tb_cell":document.createElement("td"),"tp_row":document.createElement("tr"),"tp_cell":this._panels.top.container,"ler_row":document.createElement("tr"),"lp_cell":this._panels.left.container,"ed_cell":document.createElement("td"),"rp_cell":this._panels.right.container,"bp_row":document.createElement("tr"),"bp_cell":this._panels.bottom.container,"sb_row":document.createElement("tr"),"sb_cell":document.createElement("td")}; +Xinha.freeLater(this._framework); +var fw=this._framework; +fw.table.border="0"; +fw.table.cellPadding="0"; +fw.table.cellSpacing="0"; +fw.tb_row.style.verticalAlign="top"; +fw.tp_row.style.verticalAlign="top"; +fw.ler_row.style.verticalAlign="top"; +fw.bp_row.style.verticalAlign="top"; +fw.sb_row.style.verticalAlign="top"; +fw.ed_cell.style.position="relative"; +fw.tb_row.appendChild(fw.tb_cell); +fw.tb_cell.colSpan=3; +fw.tp_row.appendChild(fw.tp_cell); +fw.tp_cell.colSpan=3; +fw.ler_row.appendChild(fw.lp_cell); +fw.ler_row.appendChild(fw.ed_cell); +fw.ler_row.appendChild(fw.rp_cell); +fw.bp_row.appendChild(fw.bp_cell); +fw.bp_cell.colSpan=3; +fw.sb_row.appendChild(fw.sb_cell); +fw.sb_cell.colSpan=3; +fw.tbody.appendChild(fw.tb_row); +fw.tbody.appendChild(fw.tp_row); +fw.tbody.appendChild(fw.ler_row); +fw.tbody.appendChild(fw.bp_row); +fw.tbody.appendChild(fw.sb_row); +fw.table.appendChild(fw.tbody); +var _99=this._framework.table; +this._htmlArea=_99; +Xinha.freeLater(this,"_htmlArea"); +_99.className="htmlarea"; +this._framework.tb_cell.appendChild(this._createToolbar()); +var _9a=document.createElement("iframe"); +_9a.src=_editor_url+_8f.config.URIs.blank; +this._framework.ed_cell.appendChild(_9a); +this._iframe=_9a; +this._iframe.className="xinha_iframe"; +Xinha.freeLater(this,"_iframe"); +var _9b=this._createStatusBar(); +this._framework.sb_cell.appendChild(_9b); +var _9c=this._textArea; +_9c.parentNode.insertBefore(_99,_9c); +_9c.className="xinha_textarea"; +Xinha.removeFromParent(_9c); +this._framework.ed_cell.appendChild(_9c); +if(_9c.form){ +Xinha.prependDom0Event(this._textArea.form,"submit",function(){ +_8f._textArea.value=_8f.outwardHtml(_8f.getHTML()); +return true; +}); +var _9d=_9c.value; +Xinha.prependDom0Event(this._textArea.form,"reset",function(){ +_8f.setHTML(_8f.inwardHtml(_9d)); +_8f.updateToolbar(); +return true; +}); +if(!_9c.form.xinha_submit){ +try{ +_9c.form.xinha_submit=_9c.form.submit; +_9c.form.submit=function(){ +this.onsubmit(); +this.xinha_submit(); +}; +} +catch(ex){ +} +} +} +Xinha.prependDom0Event(window,"unload",function(){ +_9c.value=_8f.outwardHtml(_8f.getHTML()); +return true; +}); +_9c.style.display="none"; +_8f.initSize(); +_8f._iframeLoadDone=false; +Xinha._addEvent(this._iframe,"load",function(e){ +if(!_8f._iframeLoadDone){ +_8f._iframeLoadDone=true; +_8f.initIframe(); +} +return true; +}); +}; +Xinha.prototype.initSize=function(){ +this.setLoadingMessage("Init editor size"); +var _9f=this; +var _a0=null; +var _a1=null; +switch(this.config.width){ +case "auto": +_a0=this._initial_ta_size.w; +break; +case "toolbar": +_a0=this._toolBar.offsetWidth+"px"; +break; +default: +_a0=/[^0-9]/.test(this.config.width)?this.config.width:this.config.width+"px"; +break; +} +switch(this.config.height){ +case "auto": +_a1=this._initial_ta_size.h; +break; +default: +_a1=/[^0-9]/.test(this.config.height)?this.config.height:this.config.height+"px"; +break; +} +this.sizeEditor(_a0,_a1,this.config.sizeIncludesBars,this.config.sizeIncludesPanels); +this.notifyOn("panel_change",function(){ +_9f.sizeEditor(); +}); +}; +Xinha.prototype.sizeEditor=function(_a2,_a3,_a4,_a5){ +this._iframe.style.height="100%"; +this._textArea.style.height="100%"; +this._iframe.style.width=""; +this._textArea.style.width=""; +if(_a4!==null){ +this._htmlArea.sizeIncludesToolbars=_a4; +} +if(_a5!==null){ +this._htmlArea.sizeIncludesPanels=_a5; +} +if(_a2){ +this._htmlArea.style.width=_a2; +if(!this._htmlArea.sizeIncludesPanels){ +var _a6=this._panels.right; +if(_a6.on&&_a6.panels.length&&Xinha.hasDisplayedChildren(_a6.div)){ +this._htmlArea.style.width=(this._htmlArea.offsetWidth+parseInt(this.config.panel_dimensions.right,10))+"px"; +} +var _a7=this._panels.left; +if(_a7.on&&_a7.panels.length&&Xinha.hasDisplayedChildren(_a7.div)){ +this._htmlArea.style.width=(this._htmlArea.offsetWidth+parseInt(this.config.panel_dimensions.left,10))+"px"; +} +} +} +if(_a3){ +this._htmlArea.style.height=_a3; +if(!this._htmlArea.sizeIncludesToolbars){ +this._htmlArea.style.height=(this._htmlArea.offsetHeight+this._toolbar.offsetHeight+this._statusBar.offsetHeight)+"px"; +} +if(!this._htmlArea.sizeIncludesPanels){ +var _a8=this._panels.top; +if(_a8.on&&_a8.panels.length&&Xinha.hasDisplayedChildren(_a8.div)){ +this._htmlArea.style.height=(this._htmlArea.offsetHeight+parseInt(this.config.panel_dimensions.top,10))+"px"; +} +var _a9=this._panels.bottom; +if(_a9.on&&_a9.panels.length&&Xinha.hasDisplayedChildren(_a9.div)){ +this._htmlArea.style.height=(this._htmlArea.offsetHeight+parseInt(this.config.panel_dimensions.bottom,10))+"px"; +} +} +} +_a2=this._htmlArea.offsetWidth; +_a3=this._htmlArea.offsetHeight; +var _aa=this._panels; +var _ab=this; +var _ac=1; +function panel_is_alive(pan){ +if(_aa[pan].on&&_aa[pan].panels.length&&Xinha.hasDisplayedChildren(_aa[pan].container)){ +_aa[pan].container.style.display=""; +return true; +}else{ +_aa[pan].container.style.display="none"; +return false; +} +} +if(panel_is_alive("left")){ +_ac+=1; +} +if(panel_is_alive("right")){ +_ac+=1; +} +this._framework.tb_cell.colSpan=_ac; +this._framework.tp_cell.colSpan=_ac; +this._framework.bp_cell.colSpan=_ac; +this._framework.sb_cell.colSpan=_ac; +if(!this._framework.tp_row.childNodes.length){ +Xinha.removeFromParent(this._framework.tp_row); +}else{ +if(!Xinha.hasParentNode(this._framework.tp_row)){ +this._framework.tbody.insertBefore(this._framework.tp_row,this._framework.ler_row); +} +} +if(!this._framework.bp_row.childNodes.length){ +Xinha.removeFromParent(this._framework.bp_row); +}else{ +if(!Xinha.hasParentNode(this._framework.bp_row)){ +this._framework.tbody.insertBefore(this._framework.bp_row,this._framework.ler_row.nextSibling); +} +} +if(!this.config.statusBar){ +Xinha.removeFromParent(this._framework.sb_row); +}else{ +if(!Xinha.hasParentNode(this._framework.sb_row)){ +this._framework.table.appendChild(this._framework.sb_row); +} +} +this._framework.lp_cell.style.width=this.config.panel_dimensions.left; +this._framework.rp_cell.style.width=this.config.panel_dimensions.right; +this._framework.tp_cell.style.height=this.config.panel_dimensions.top; +this._framework.bp_cell.style.height=this.config.panel_dimensions.bottom; +this._framework.tb_cell.style.height=this._toolBar.offsetHeight+"px"; +this._framework.sb_cell.style.height=this._statusBar.offsetHeight+"px"; +var _ae=_a3-this._toolBar.offsetHeight-this._statusBar.offsetHeight; +if(panel_is_alive("top")){ +_ae-=parseInt(this.config.panel_dimensions.top,10); +} +if(panel_is_alive("bottom")){ +_ae-=parseInt(this.config.panel_dimensions.bottom,10); +} +this._iframe.style.height=_ae+"px"; +var _af=_a2; +if(panel_is_alive("left")){ +_af-=parseInt(this.config.panel_dimensions.left,10); +} +if(panel_is_alive("right")){ +_af-=parseInt(this.config.panel_dimensions.right,10); +} +this._iframe.style.width=_af+"px"; +this._textArea.style.height=this._iframe.style.height; +this._textArea.style.width=this._iframe.style.width; +this.notifyOf("resize",{width:this._htmlArea.offsetWidth,height:this._htmlArea.offsetHeight}); +}; +Xinha.prototype.addPanel=function(_b0){ +var div=document.createElement("div"); +div.side=_b0; +if(_b0=="left"||_b0=="right"){ +div.style.width=this.config.panel_dimensions[_b0]; +if(this._iframe){ +div.style.height=this._iframe.style.height; +} +} +Xinha.addClasses(div,"panel"); +this._panels[_b0].panels.push(div); +this._panels[_b0].div.appendChild(div); +this.notifyOf("panel_change",{"action":"add","panel":div}); +return div; +}; +Xinha.prototype.removePanel=function(_b2){ +this._panels[_b2.side].div.removeChild(_b2); +var _b3=[]; +for(var i=0;i\n"; +if(typeof _c4.config.baseHref!="undefined"&&_c4.config.baseHref!==null){ +_c5+="\n"; +} +_c5+=Xinha.addCoreCSS(); +if(_c4.config.pageStyle){ +_c5+=""; +} +if(typeof _c4.config.pageStyleSheets!=="undefined"){ +for(var i=0;i<_c4.config.pageStyleSheets.length;i++){ +if(_c4.config.pageStyleSheets[i].length>0){ +_c5+=""; +} +} +} +_c5+="\n"; +_c5+="\n"; +_c5+=_c4.inwardHtml(_c4._textArea.value); +_c5+="\n"; +_c5+=""; +}else{ +_c5=_c4.inwardHtml(_c4._textArea.value); +if(_c5.match(Xinha.RE_doctype)){ +_c4.setDoctype(RegExp.$1); +_c5=_c5.replace(Xinha.RE_doctype,""); +} +var _c7=_c5.match(//gi); +_c5=_c5.replace(/\s*/gi,""); +_c7?_c5=_c5.replace(/<\/head>/i,_c7.join("\n")+"\n"):null; +} +doc.write(_c5); +doc.close(); +if(this.config.fullScreen){ +this._fullScreen(); +} +this.setEditorEvents(); +}; +Xinha.prototype.whenDocReady=function(F){ +var E=this; +if(this._doc&&this._doc.body){ +F(); +}else{ +setTimeout(function(){ +E.whenDocReady(F); +},50); +} +}; +Xinha.prototype.setMode=function(_ca){ +var _cb; +if(typeof _ca=="undefined"){ +_ca=this._editMode=="textmode"?"wysiwyg":"textmode"; +} +switch(_ca){ +case "textmode": +this.setCC("iframe"); +_cb=this.outwardHtml(this.getHTML()); +this.setHTML(_cb); +this.deactivateEditor(); +this._iframe.style.display="none"; +this._textArea.style.display=""; +if(this.config.statusBar){ +this._statusBarTree.style.display="none"; +this._statusBarTextMode.style.display=""; +} +this.notifyOf("modechange",{"mode":"text"}); +this.findCC("textarea"); +break; +case "wysiwyg": +this.setCC("textarea"); +_cb=this.inwardHtml(this.getHTML()); +this.deactivateEditor(); +this.setHTML(_cb); +this._iframe.style.display=""; +this._textArea.style.display="none"; +this.activateEditor(); +if(this.config.statusBar){ +this._statusBarTree.style.display=""; +this._statusBarTextMode.style.display="none"; +} +this.notifyOf("modechange",{"mode":"wysiwyg"}); +this.findCC("iframe"); +break; +default: +alert("Mode <"+_ca+"> not defined!"); +return false; +} +this._editMode=_ca; +for(var i in this.plugins){ +var _cd=this.plugins[i].instance; +if(_cd&&typeof _cd.onMode=="function"){ +_cd.onMode(_ca); +} +} +}; +Xinha.prototype.setFullHTML=function(_ce){ +var _cf=RegExp.multiline; +RegExp.multiline=true; +if(_ce.match(Xinha.RE_doctype)){ +this.setDoctype(RegExp.$1); +_ce=_ce.replace(Xinha.RE_doctype,""); +} +RegExp.multiline=_cf; +if(0){ +if(_ce.match(Xinha.RE_head)){ +this._doc.getElementsByTagName("head")[0].innerHTML=RegExp.$1; +} +if(_ce.match(Xinha.RE_body)){ +this._doc.getElementsByTagName("body")[0].innerHTML=RegExp.$1; +} +}else{ +var _d0=this.editorIsActivated(); +if(_d0){ +this.deactivateEditor(); +} +var _d1=/((.|\n)*?)<\/html>/i; +_ce=_ce.replace(_d1,"$1"); +this._doc.open("text/html","replace"); +this._doc.write(_ce); +this._doc.close(); +if(_d0){ +this.activateEditor(); +} +this.setEditorEvents(); +return true; +} +}; +Xinha.prototype.setEditorEvents=function(){ +var _d2=this; +var doc=this._doc; +_d2.whenDocReady(function(){ +Xinha._addEvents(doc,["mousedown"],function(){ +_d2.activateEditor(); +return true; +}); +Xinha._addEvents(doc,["keydown","keypress","mousedown","mouseup","drag"],function(_d4){ +return _d2._editorEvent(Xinha.is_ie?_d2._iframe.contentWindow.event:_d4); +}); +for(var i in _d2.plugins){ +var _d6=_d2.plugins[i].instance; +Xinha.refreshPlugin(_d6); +} +if(typeof _d2._onGenerate=="function"){ +_d2._onGenerate(); +} +Xinha.addDom0Event(window,"resize",function(e){ +_d2.sizeEditor(); +}); +_d2.removeLoadingMessage(); +}); +}; +Xinha.prototype.registerPlugin=function(){ +var _d8=arguments[0]; +if(_d8===null||typeof _d8=="undefined"||(typeof _d8=="string"&&eval("typeof "+_d8)=="undefined")){ +return false; +} +var _d9=[]; +for(var i=1;i=0;){ +ta.value+=" "; +} +ta.value+=str+"\n"; +} +function _dt(_fe,_ff){ +var tag=_fe.tagName.toLowerCase(),i; +var ns=Xinha.is_ie?_fe.scopeName:_fe.prefix; +debug(_ff,"- "+tag+" ["+ns+"]"); +for(i=_fe.firstChild;i;i=i.nextSibling){ +if(i.nodeType==1){ +_dt(i,_ff+2); +} +} +} +_dt(this._doc.body,0); +document.body.appendChild(ta); +}; +Xinha.getInnerText=function(el){ +var txt="",i; +for(i=el.firstChild;i;i=i.nextSibling){ +if(i.nodeType==3){ +txt+=i.data; +}else{ +if(i.nodeType==1){ +txt+=Xinha.getInnerText(i); +} +} +} +return txt; +}; +Xinha.prototype._wordClean=function(){ +var _104=this; +var _105={empty_tags:0,mso_class:0,mso_style:0,mso_xmlel:0,orig_len:this._doc.body.innerHTML.length,T:(new Date()).getTime()}; +var _106={empty_tags:"Empty tags removed: ",mso_class:"MSO class names removed: ",mso_style:"MSO inline style removed: ",mso_xmlel:"MSO XML elements stripped: "}; +function showStats(){ +var txt="Xinha word cleaner stats: \n\n"; +for(var i in _105){ +if(_106[i]){ +txt+=_106[i]+_105[i]+"\n"; +} +} +txt+="\nInitial document length: "+_105.orig_len+"\n"; +txt+="Final document length: "+_104._doc.body.innerHTML.length+"\n"; +txt+="Clean-up took "+(((new Date()).getTime()-_105.T)/1000)+" seconds"; +alert(txt); +} +function clearClass(node){ +var newc=node.className.replace(/(^|\s)mso.*?(\s|$)/ig," "); +if(newc!=node.className){ +node.className=newc; +if(!(/\S/.test(node.className))){ +node.removeAttribute("className"); +++_105.mso_class; +} +} +} +function clearStyle(node){ +var _10c=node.style.cssText.split(/\s*;\s*/); +for(var i=_10c.length;--i>=0;){ +if((/^mso|^tab-stops/i.test(_10c[i]))||(/^margin\s*:\s*0..\s+0..\s+0../i.test(_10c[i]))){ +++_105.mso_style; +_10c.splice(i,1); +} +} +node.style.cssText=_10c.join("; "); +} +var _10e=null; +if(Xinha.is_ie){ +_10e=function(el){ +el.outerHTML=Xinha.htmlEncode(el.innerText); +++_105.mso_xmlel; +}; +}else{ +_10e=function(el){ +var txt=document.createTextNode(Xinha.getInnerText(el)); +el.parentNode.insertBefore(txt,el); +Xinha.removeFromParent(el); +++_105.mso_xmlel; +}; +} +function checkEmpty(el){ +if(/^(span|b|strong|i|em|font|div|p)$/i.test(el.tagName)&&!el.firstChild){ +Xinha.removeFromParent(el); +++_105.empty_tags; +} +} +function parseTree(root){ +var tag=root.tagName.toLowerCase(),i,next; +if((Xinha.is_ie&&root.scopeName!="HTML")||(!Xinha.is_ie&&(/:/.test(tag)))){ +_10e(root); +return false; +}else{ +clearClass(root); +clearStyle(root); +for(i=root.firstChild;i;i=next){ +next=i.nextSibling; +if(i.nodeType==1&&parseTree(i)){ +checkEmpty(i); +} +} +} +return true; +} +parseTree(this._doc.body); +this.updateToolbar(); +}; +Xinha.prototype._clearFonts=function(){ +var D=this.getInnerHTML(); +if(confirm(Xinha._lc("Would you like to clear font typefaces?"))){ +D=D.replace(/face="[^"]*"/gi,""); +D=D.replace(/font-family:[^;}"']+;?/gi,""); +} +if(confirm(Xinha._lc("Would you like to clear font sizes?"))){ +D=D.replace(/size="[^"]*"/gi,""); +D=D.replace(/font-size:[^;}"']+;?/gi,""); +} +if(confirm(Xinha._lc("Would you like to clear font colours?"))){ +D=D.replace(/color="[^"]*"/gi,""); +D=D.replace(/([^-])color:[^;}"']+;?/gi,"$1"); +} +D=D.replace(/(style|class)="\s*"/gi,""); +D=D.replace(/<(font|span)\s*>/gi,""); +this.setHTML(D); +this.updateToolbar(); +}; +Xinha.prototype._splitBlock=function(){ +this._doc.execCommand("formatblock",false,"div"); +}; +Xinha.prototype.forceRedraw=function(){ +this._doc.body.style.visibility="hidden"; +this._doc.body.style.visibility=""; +}; +Xinha.prototype.focusEditor=function(){ +switch(this._editMode){ +case "wysiwyg": +try{ +if(Xinha._someEditorHasBeenActivated){ +this.activateEditor(); +this._iframe.contentWindow.focus(); +} +} +catch(ex){ +} +break; +case "textmode": +try{ +this._textArea.focus(); +} +catch(e){ +} +break; +default: +alert("ERROR: mode "+this._editMode+" is not defined"); +} +return this._doc; +}; +Xinha.prototype._undoTakeSnapshot=function(){ +++this._undoPos; +if(this._undoPos>=this.config.undoSteps){ +this._undoQueue.shift(); +--this._undoPos; +} +var take=true; +var txt=this.getInnerHTML(); +if(this._undoPos>0){ +take=(this._undoQueue[this._undoPos-1]!=txt); +} +if(take){ +this._undoQueue[this._undoPos]=txt; +}else{ +this._undoPos--; +} +}; +Xinha.prototype.undo=function(){ +if(this._undoPos>0){ +var txt=this._undoQueue[--this._undoPos]; +if(txt){ +this.setHTML(txt); +}else{ +++this._undoPos; +} +} +}; +Xinha.prototype.redo=function(){ +if(this._undoPos=0;){ +var el=_126[i]; +if(!el){ +continue; +} +var a=document.createElement("a"); +a.href="javascript:void(0)"; +a.el=el; +a.editor=this; +Xinha.addDom0Event(a,"click",function(){ +this.blur(); +this.editor.selectNodeContents(this.el); +this.editor.updateToolbar(true); +return false; +}); +Xinha.addDom0Event(a,"contextmenu",function(){ +this.blur(); +var info="Inline style:\n\n"; +info+=this.el.style.cssText.split(/;\s*/).join(";\n"); +alert(info); +return false; +}); +var txt=el.tagName.toLowerCase(); +if(typeof el.style!="undefined"){ +a.title=el.style.cssText; +} +if(el.id){ +txt+="#"+el.id; +} +if(el.className){ +txt+="."+el.className; +} +a.appendChild(document.createTextNode(txt)); +this._statusBarTree.appendChild(a); +if(i!==0){ +this._statusBarTree.appendChild(document.createTextNode(String.fromCharCode(187))); +} +} +} +} +for(var cmd in this._toolbarObjects){ +var btn=this._toolbarObjects[cmd]; +var _12e=true; +if(typeof (btn.state)!="function"){ +continue; +} +if(btn.context&&!text){ +_12e=false; +var _12f=btn.context; +var _130=[]; +if(/(.*)\[(.*?)\]/.test(_12f)){ +_12f=RegExp.$1; +_130=RegExp.$2.split(","); +} +_12f=_12f.toLowerCase(); +var _131=(_12f=="*"); +for(var k=0;k<_126.length;++k){ +if(!_126[k]){ +continue; +} +if(_131||(_126[k].tagName.toLowerCase()==_12f)){ +_12e=true; +var _133=null; +var att=null; +var comp=null; +var _136=null; +for(var ka=0;ka<_130.length;++ka){ +_133=_130[ka].match(/(.*)(==|!=|===|!==|>|>=|<|<=)(.*)/); +att=_133[1]; +comp=_133[2]; +_136=_133[3]; +if(!eval(_126[k][att]+comp+_136)){ +_12e=false; +break; +} +} +if(_12e){ +break; +} +} +} +} +btn.state("enabled",(!text||btn.text)&&_12e); +if(typeof cmd=="function"){ +continue; +} +var _138=this.config.customSelects[cmd]; +if((!text||btn.text)&&(typeof _138!="undefined")){ +_138.refresh(this); +continue; +} +switch(cmd){ +case "fontname": +case "fontsize": +if(!text){ +try{ +var _139=(""+doc.queryCommandValue(cmd)).toLowerCase(); +if(!_139){ +btn.element.selectedIndex=0; +break; +} +var _13a=this.config[cmd]; +var _13b=0; +for(var j in _13a){ +if((j.toLowerCase()==_139)||(_13a[j].substr(0,_139.length).toLowerCase()==_139)){ +btn.element.selectedIndex=_13b; +throw "ok"; +} +++_13b; +} +btn.element.selectedIndex=0; +} +catch(ex){ +} +} +break; +case "formatblock": +var _13d=[]; +for(var _13e in this.config.formatblock){ +if(typeof this.config.formatblock[_13e]=="string"){ +_13d[_13d.length]=this.config.formatblock[_13e]; +} +} +var _13f=this._getFirstAncestor(this.getSelection(),_13d); +if(_13f){ +for(var x=0;x<_13d.length;x++){ +if(_13d[x].toLowerCase()==_13f.tagName.toLowerCase()){ +btn.element.selectedIndex=x; +} +} +}else{ +btn.element.selectedIndex=0; +} +break; +case "textindicator": +if(!text){ +try{ +var _141=btn.element.style; +_141.backgroundColor=Xinha._makeColor(doc.queryCommandValue(Xinha.is_ie?"backcolor":"hilitecolor")); +if(/transparent/i.test(_141.backgroundColor)){ +_141.backgroundColor=Xinha._makeColor(doc.queryCommandValue("backcolor")); +} +_141.color=Xinha._makeColor(doc.queryCommandValue("forecolor")); +_141.fontFamily=doc.queryCommandValue("fontname"); +_141.fontWeight=doc.queryCommandState("bold")?"bold":"normal"; +_141.fontStyle=doc.queryCommandState("italic")?"italic":"normal"; +} +catch(ex){ +} +} +break; +case "htmlmode": +btn.state("active",text); +break; +case "lefttoright": +case "righttoleft": +var _142=this.getParentElement(); +while(_142&&!Xinha.isBlockElement(_142)){ +_142=_142.parentNode; +} +if(_142){ +btn.state("active",(_142.style.direction==((cmd=="righttoleft")?"rtl":"ltr"))); +} +break; +default: +cmd=cmd.replace(/(un)?orderedlist/i,"insert$1orderedlist"); +try{ +btn.state("active",(!text&&doc.queryCommandState(cmd))); +} +catch(ex){ +} +break; +} +} +if(this._customUndo&&!this._timerUndo){ +this._undoTakeSnapshot(); +var _143=this; +this._timerUndo=setTimeout(function(){ +_143._timerUndo=null; +},this.config.undoTimeout); +} +if(0&&Xinha.is_gecko){ +var s=this.getSelection(); +if(s&&s.isCollapsed&&s.anchorNode&&s.anchorNode.parentNode.tagName.toLowerCase()!="body"&&s.anchorNode.nodeType==3&&s.anchorOffset==s.anchorNode.length&&!(s.anchorNode.parentNode.nextSibling&&s.anchorNode.parentNode.nextSibling.nodeType==3)&&!Xinha.isBlockElement(s.anchorNode.parentNode)){ +try{ +s.anchorNode.parentNode.parentNode.insertBefore(this._doc.createTextNode("\t"),s.anchorNode.parentNode.nextSibling); +} +catch(ex){ +} +} +} +for(var _145 in this.plugins){ +var _146=this.plugins[_145].instance; +if(_146&&typeof _146.onUpdateToolbar=="function"){ +_146.onUpdateToolbar(); +} +} +}; +Xinha.prototype.getAllAncestors=function(){ +var p=this.getParentElement(); +var a=[]; +while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!="body")){ +a.push(p); +p=p.parentNode; +} +a.push(this._doc.body); +return a; +}; +Xinha.prototype._getFirstAncestor=function(sel,_14a){ +var prnt=this.activeElement(sel); +if(prnt===null){ +try{ +prnt=(Xinha.is_ie?this.createRange(sel).parentElement():this.createRange(sel).commonAncestorContainer); +} +catch(ex){ +return null; +} +} +if(typeof _14a=="string"){ +_14a=[_14a]; +} +while(prnt){ +if(prnt.nodeType==1){ +if(_14a===null){ +return prnt; +} +if(_14a.contains(prnt.tagName.toLowerCase())){ +return prnt; +} +if(prnt.tagName.toLowerCase()=="body"){ +break; +} +if(prnt.tagName.toLowerCase()=="table"){ +break; +} +} +prnt=prnt.parentNode; +} +return null; +}; +Xinha.prototype._getAncestorBlock=function(sel){ +var prnt=(Xinha.is_ie?this.createRange(sel).parentElement:this.createRange(sel).commonAncestorContainer); +while(prnt&&(prnt.nodeType==1)){ +switch(prnt.tagName.toLowerCase()){ +case "div": +case "p": +case "address": +case "blockquote": +case "center": +case "del": +case "ins": +case "pre": +case "h1": +case "h2": +case "h3": +case "h4": +case "h5": +case "h6": +case "h7": +return prnt; +case "body": +case "noframes": +case "dd": +case "li": +case "th": +case "td": +case "noscript": +return null; +default: +break; +} +} +return null; +}; +Xinha.prototype._createImplicitBlock=function(type){ +var sel=this.getSelection(); +if(Xinha.is_ie){ +sel.empty(); +}else{ +sel.collapseToStart(); +} +var rng=this.createRange(sel); +}; +Xinha.prototype.surroundHTML=function(_151,_152){ +var html=this.getSelectedHTML(); +this.insertHTML(_151+html+_152); +}; +Xinha.prototype.hasSelectedText=function(){ +return this.getSelectedHTML()!==""; +}; +Xinha.prototype._comboSelected=function(el,txt){ +this.focusEditor(); +var _156=el.options[el.selectedIndex].value; +switch(txt){ +case "fontname": +case "fontsize": +this.execCommand(txt,false,_156); +break; +case "formatblock": +if(!_156){ +this.updateToolbar(); +break; +} +if(!Xinha.is_gecko||_156!=="blockquote"){ +_156="<"+_156+">"; +} +this.execCommand(txt,false,_156); +break; +default: +var _157=this.config.customSelects[txt]; +if(typeof _157!="undefined"){ +_157.action(this); +}else{ +alert("FIXME: combo box "+txt+" not implemented"); +} +break; +} +}; +Xinha.prototype._colorSelector=function(_158){ +var _159=this; +if(Xinha.is_gecko){ +try{ +_159._doc.execCommand("useCSS",false,false); +_159._doc.execCommand("styleWithCSS",false,true); +} +catch(ex){ +} +} +var btn=_159._toolbarObjects[_158].element; +var _15b; +if(_158=="hilitecolor"){ +if(Xinha.is_ie){ +_158="backcolor"; +_15b=Xinha._colorToRgb(_159._doc.queryCommandValue("backcolor")); +}else{ +_15b=Xinha._colorToRgb(_159._doc.queryCommandValue("hilitecolor")); +} +}else{ +_15b=Xinha._colorToRgb(_159._doc.queryCommandValue("forecolor")); +} +var _15c=function(_15d){ +_159._doc.execCommand(_158,false,_15d); +}; +if(Xinha.is_ie){ +var _15e=_159.createRange(_159.getSelection()); +_15c=function(_15f){ +_15e.select(); +_159._doc.execCommand(_158,false,_15f); +}; +} +var _160=new Xinha.colorPicker({cellsize:_159.config.colorPickerCellSize,callback:_15c,granularity:_159.config.colorPickerGranularity,websafe:_159.config.colorPickerWebSafe,savecolors:_159.config.colorPickerSaveColors}); +_160.open(_159.config.colorPickerPosition,btn,_15b); +}; +Xinha.prototype.execCommand=function(_161,UI,_163){ +var _164=this; +this.focusEditor(); +_161=_161.toLowerCase(); +if(this.firePluginEvent("onExecCommand",_161,UI,_163)){ +this.updateToolbar(); +return false; +} +switch(_161){ +case "htmlmode": +this.setMode(); +break; +case "hilitecolor": +case "forecolor": +this._colorSelector(_161); +break; +case "createlink": +this._createLink(); +break; +case "undo": +case "redo": +if(this._customUndo){ +this[_161](); +}else{ +this._doc.execCommand(_161,UI,_163); +} +break; +case "inserttable": +this._insertTable(); +break; +case "insertimage": +this._insertImage(); +break; +case "about": +this._popupDialog(_164.config.URIs.about,null,this); +break; +case "showhelp": +this._popupDialog(_164.config.URIs.help,null,this); +break; +case "killword": +this._wordClean(); +break; +case "cut": +case "copy": +case "paste": +this._doc.execCommand(_161,UI,_163); +if(this.config.killWordOnPaste){ +this._wordClean(); +} +break; +case "lefttoright": +case "righttoleft": +if(this.config.changeJustifyWithDirection){ +this._doc.execCommand((_161=="righttoleft")?"justifyright":"justifyleft",UI,_163); +} +var dir=(_161=="righttoleft")?"rtl":"ltr"; +var el=this.getParentElement(); +while(el&&!Xinha.isBlockElement(el)){ +el=el.parentNode; +} +if(el){ +if(el.style.direction==dir){ +el.style.direction=""; +}else{ +el.style.direction=dir; +} +} +break; +case "justifyleft": +case "justifyright": +_161.match(/^justify(.*)$/); +var ae=this.activeElement(this.getSelection()); +if(ae&&ae.tagName.toLowerCase()=="img"){ +ae.align=ae.align==RegExp.$1?"":RegExp.$1; +}else{ +this._doc.execCommand(_161,UI,_163); +} +break; +default: +try{ +this._doc.execCommand(_161,UI,_163); +} +catch(ex){ +if(this.config.debug){ +alert(ex+"\n\nby execCommand("+_161+");"); +} +} +break; +} +this.updateToolbar(); +return false; +}; +Xinha.prototype._editorEvent=function(ev){ +var _169=this; +if(typeof _169._textArea["on"+ev.type]=="function"){ +_169._textArea["on"+ev.type](); +} +if(this.isKeyEvent(ev)){ +if(_169.firePluginEvent("onKeyPress",ev)){ +return false; +} +if(this.isShortCut(ev)){ +this._shortCuts(ev); +} +} +if(ev.type=="mousedown"){ +if(_169.firePluginEvent("onMouseDown",ev)){ +return false; +} +} +if(_169._timerToolbar){ +clearTimeout(_169._timerToolbar); +} +_169._timerToolbar=setTimeout(function(){ +_169.updateToolbar(); +_169._timerToolbar=null; +},250); +}; +Xinha.prototype._shortCuts=function(ev){ +var key=this.getKey(ev).toLowerCase(); +var cmd=null; +var _16d=null; +switch(key){ +case "b": +cmd="bold"; +break; +case "i": +cmd="italic"; +break; +case "u": +cmd="underline"; +break; +case "s": +cmd="strikethrough"; +break; +case "l": +cmd="justifyleft"; +break; +case "e": +cmd="justifycenter"; +break; +case "r": +cmd="justifyright"; +break; +case "j": +cmd="justifyfull"; +break; +case "z": +cmd="undo"; +break; +case "y": +cmd="redo"; +break; +case "v": +cmd="paste"; +break; +case "n": +cmd="formatblock"; +_16d="p"; +break; +case "0": +cmd="killword"; +break; +case "1": +case "2": +case "3": +case "4": +case "5": +case "6": +cmd="formatblock"; +_16d="h"+key; +break; +} +if(cmd){ +this.execCommand(cmd,false,_16d); +Xinha._stopEvent(ev); +} +}; +Xinha.prototype.convertNode=function(el,_16f){ +var _170=this._doc.createElement(_16f); +while(el.firstChild){ +_170.appendChild(el.firstChild); +} +return _170; +}; +Xinha.prototype.scrollToElement=function(e){ +if(!e){ +e=this.getParentElement(); +if(!e){ +return; +} +} +var _172=Xinha.getElementTopLeft(e); +this._iframe.contentWindow.scrollTo(_172.left,_172.top); +}; +Xinha.prototype.getHTML=function(){ +var html=""; +switch(this._editMode){ +case "wysiwyg": +if(!this.config.fullPage){ +html=Xinha.getHTML(this._doc.body,false,this); +}else{ +html=this.doctype+"\n"+Xinha.getHTML(this._doc.documentElement,true,this); +} +break; +case "textmode": +html=this._textArea.value; +break; +default: +alert("Mode <"+this._editMode+"> not defined!"); +return false; +} +return html; +}; +Xinha.prototype.outwardHtml=function(html){ +for(var i in this.plugins){ +var _176=this.plugins[i].instance; +if(_176&&typeof _176.outwardHtml=="function"){ +html=_176.outwardHtml(html); +} +} +html=html.replace(/<(\/?)b(\s|>|\/)/ig,"<$1strong$2"); +html=html.replace(/<(\/?)i(\s|>|\/)/ig,"<$1em$2"); +html=html.replace(/<(\/?)strike(\s|>|\/)/ig,"<$1del$2"); +html=html.replace("onclick=\"try{if(document.designMode && document.designMode == 'on') return false;}catch(e){} window.open(","onclick=\"window.open("); +var _177=location.href.replace(/(https?:\/\/[^\/]*)\/.*/,"$1")+"/"; +html=html.replace(/https?:\/\/null\//g,_177); +html=html.replace(/((href|src|background)=[\'\"])\/+/ig,"$1"+_177); +html=this.outwardSpecialReplacements(html); +html=this.fixRelativeLinks(html); +if(this.config.sevenBitClean){ +html=html.replace(/[^ -~\r\n\t]/g,function(c){ +return "&#"+c.charCodeAt(0)+";"; +}); +} +html=html.replace(/(]*)(freezescript)/gi,"$1javascript"); +if(this.config.fullPage){ +html=Xinha.stripCoreCSS(html); +} +return html; +}; +Xinha.prototype.inwardHtml=function(html){ +for(var i in this.plugins){ +var _17b=this.plugins[i].instance; +if(_17b&&typeof _17b.inwardHtml=="function"){ +html=_17b.inwardHtml(html); +} +} +html=html.replace(/<(\/?)del(\s|>|\/)/ig,"<$1strike$2"); +html=html.replace("onclick=\"window.open(","onclick=\"try{if(document.designMode && document.designMode == 'on') return false;}catch(e){} window.open("); +html=this.inwardSpecialReplacements(html); +html=html.replace(/(]*)(javascript)/gi,"$1freezescript"); +var _17c=new RegExp("((href|src|background)=['\"])/+","gi"); +html=html.replace(_17c,"$1"+location.href.replace(/(https?:\/\/[^\/]*)\/.*/,"$1")+"/"); +html=this.fixRelativeLinks(html); +if(this.config.fullPage){ +html=Xinha.addCoreCSS(html); +} +return html; +}; +Xinha.prototype.outwardSpecialReplacements=function(html){ +for(var i in this.config.specialReplacements){ +var from=this.config.specialReplacements[i]; +var to=i; +if(typeof from.replace!="function"||typeof to.replace!="function"){ +continue; +} +var reg=new RegExp(from.replace(Xinha.RE_Specials,"\\$1"),"g"); +html=html.replace(reg,to.replace(/\$/g,"$$$$")); +} +return html; +}; +Xinha.prototype.inwardSpecialReplacements=function(html){ +for(var i in this.config.specialReplacements){ +var from=i; +var to=this.config.specialReplacements[i]; +if(typeof from.replace!="function"||typeof to.replace!="function"){ +continue; +} +var reg=new RegExp(from.replace(Xinha.RE_Specials,"\\$1"),"g"); +html=html.replace(reg,to.replace(/\$/g,"$$$$")); +} +return html; +}; +Xinha.prototype.fixRelativeLinks=function(html){ +if(typeof this.config.expandRelativeUrl!="undefined"&&this.config.expandRelativeUrl){ +var src=html.match(/(src|href)="([^"]*)"/gi); +} +var b=document.location.href; +if(src){ +var url,url_m,relPath,base_m,absPath; +for(var i=0;i not defined!"); +return false; +} +return html; +}; +Xinha.prototype.setHTML=function(html){ +if(!this.config.fullPage){ +this._doc.body.innerHTML=html; +}else{ +this.setFullHTML(html); +} +this._textArea.value=html; +}; +Xinha.prototype.setDoctype=function(_190){ +this.doctype=_190; +}; +Xinha._object=null; +Xinha.cloneObject=function(obj){ +if(!obj){ +return null; +} +var _192={}; +if(obj.constructor.toString().match(/\s*function Array\(/)){ +_192=obj.constructor(); +} +if(obj.constructor.toString().match(/\s*function Function\(/)){ +_192=obj; +}else{ +for(var n in obj){ +var node=obj[n]; +if(typeof node=="object"){ +_192[n]=Xinha.cloneObject(node); +}else{ +_192[n]=node; +} +} +} +return _192; +}; +Xinha.checkSupportedBrowser=function(){ +if(Xinha.is_gecko){ +if(navigator.productSub<20021201){ +alert("You need at least Mozilla-1.3 Alpha.\nSorry, your Gecko is not supported."); +return false; +} +if(navigator.productSub<20030210){ +alert("Mozilla < 1.3 Beta is not supported!\nI'll try, though, but it might not work."); +} +} +return Xinha.is_gecko||Xinha.ie_version>=5.5; +}; +Xinha._eventFlushers=[]; +Xinha.flushEvents=function(){ +var x=0; +var e=Xinha._eventFlushers.pop(); +while(e){ +try{ +if(e.length==3){ +Xinha._removeEvent(e[0],e[1],e[2]); +x++; +}else{ +if(e.length==2){ +e[0]["on"+e[1]]=null; +e[0]._xinha_dom0Events[e[1]]=null; +x++; +} +} +} +catch(ex){ +} +e=Xinha._eventFlushers.pop(); +} +}; +if(document.addEventListener){ +Xinha._addEvent=function(el,_198,func){ +el.addEventListener(_198,func,true); +Xinha._eventFlushers.push([el,_198,func]); +}; +Xinha._removeEvent=function(el,_19b,func){ +el.removeEventListener(_19b,func,true); +}; +Xinha._stopEvent=function(ev){ +ev.preventDefault(); +ev.stopPropagation(); +}; +}else{ +if(document.attachEvent){ +Xinha._addEvent=function(el,_19f,func){ +el.attachEvent("on"+_19f,func); +Xinha._eventFlushers.push([el,_19f,func]); +}; +Xinha._removeEvent=function(el,_1a2,func){ +el.detachEvent("on"+_1a2,func); +}; +Xinha._stopEvent=function(ev){ +try{ +ev.cancelBubble=true; +ev.returnValue=false; +} +catch(ex){ +} +}; +}else{ +Xinha._addEvent=function(el,_1a6,func){ +alert("_addEvent is not supported"); +}; +Xinha._removeEvent=function(el,_1a9,func){ +alert("_removeEvent is not supported"); +}; +Xinha._stopEvent=function(ev){ +alert("_stopEvent is not supported"); +}; +} +} +Xinha._addEvents=function(el,evs,func){ +for(var i=evs.length;--i>=0;){ +Xinha._addEvent(el,evs[i],func); +} +}; +Xinha._removeEvents=function(el,evs,func){ +for(var i=evs.length;--i>=0;){ +Xinha._removeEvent(el,evs[i],func); +} +}; +Xinha.addDom0Event=function(el,ev,fn){ +Xinha._prepareForDom0Events(el,ev); +el._xinha_dom0Events[ev].unshift(fn); +}; +Xinha.prependDom0Event=function(el,ev,fn){ +Xinha._prepareForDom0Events(el,ev); +el._xinha_dom0Events[ev].push(fn); +}; +Xinha._prepareForDom0Events=function(el,ev){ +if(typeof el._xinha_dom0Events=="undefined"){ +el._xinha_dom0Events={}; +Xinha.freeLater(el,"_xinha_dom0Events"); +} +if(typeof el._xinha_dom0Events[ev]=="undefined"){ +el._xinha_dom0Events[ev]=[]; +if(typeof el["on"+ev]=="function"){ +el._xinha_dom0Events[ev].push(el["on"+ev]); +} +el["on"+ev]=function(_1bc){ +var a=el._xinha_dom0Events[ev]; +var _1be=true; +for(var i=a.length;--i>=0;){ +el._xinha_tempEventHandler=a[i]; +if(el._xinha_tempEventHandler(_1bc)===false){ +el._xinha_tempEventHandler=null; +_1be=false; +break; +} +el._xinha_tempEventHandler=null; +} +return _1be; +}; +Xinha._eventFlushers.push([el,ev]); +} +}; +Xinha.prototype.notifyOn=function(ev,fn){ +if(typeof this._notifyListeners[ev]=="undefined"){ +this._notifyListeners[ev]=[]; +Xinha.freeLater(this,"_notifyListeners"); +} +this._notifyListeners[ev].push(fn); +}; +Xinha.prototype.notifyOf=function(ev,args){ +if(this._notifyListeners[ev]){ +for(var i=0;i0;){ +if(cls[--i]!=_1c6){ +ar[ar.length]=cls[i]; +} +} +el.className=ar.join(" "); +}; +Xinha._addClass=function(el,_1cb){ +Xinha._removeClass(el,_1cb); +el.className+=" "+_1cb; +}; +Xinha._hasClass=function(el,_1cd){ +if(!(el&&el.className)){ +return false; +} +var cls=el.className.split(" "); +for(var i=cls.length;i>0;){ +if(cls[--i]==_1cd){ +return true; +} +} +return false; +}; +Xinha._blockTags=" body form textarea fieldset ul ol dl li div "+"p h1 h2 h3 h4 h5 h6 quote pre table thead "+"tbody tfoot tr td th iframe address blockquote "; +Xinha.isBlockElement=function(el){ +return el&&el.nodeType==1&&(Xinha._blockTags.indexOf(" "+el.tagName.toLowerCase()+" ")!=-1); +}; +Xinha._paraContainerTags=" body td th caption fieldset div"; +Xinha.isParaContainer=function(el){ +return el&&el.nodeType==1&&(Xinha._paraContainerTags.indexOf(" "+el.tagName.toLowerCase()+" ")!=-1); +}; +Xinha._closingTags=" a abbr acronym address applet b bdo big blockquote button caption center cite code del dfn dir div dl em fieldset font form frameset h1 h2 h3 h4 h5 h6 i iframe ins kbd label legend map menu noframes noscript object ol optgroup pre q s samp script select small span strike strong style sub sup table textarea title tt u ul var "; +Xinha.needsClosingTag=function(el){ +return el&&el.nodeType==1&&(Xinha._closingTags.indexOf(" "+el.tagName.toLowerCase()+" ")!=-1); +}; +Xinha.htmlEncode=function(str){ +if(typeof str.replace=="undefined"){ +str=str.toString(); +} +str=str.replace(/&/ig,"&"); +str=str.replace(//ig,">"); +str=str.replace(/\xA0/g," "); +str=str.replace(/\x22/g,"""); +return str; +}; +Xinha.prototype.stripBaseURL=function(_1d4){ +if(this.config.baseHref===null||!this.config.stripBaseHref){ +return _1d4; +} +var _1d5=this.config.baseHref.replace(/^(https?:\/\/[^\/]+)(.*)$/,"$1"); +var _1d6=new RegExp(_1d5); +return _1d4.replace(_1d6,""); +}; +String.prototype.trim=function(){ +return this.replace(/^\s+/,"").replace(/\s+$/,""); +}; +Xinha._makeColor=function(v){ +if(typeof v!="number"){ +return v; +} +var r=v&255; +var g=(v>>8)&255; +var b=(v>>16)&255; +return "rgb("+r+","+g+","+b+")"; +}; +Xinha._colorToRgb=function(v){ +if(!v){ +return ""; +} +var r,g,b; +function hex(d){ +return (d<16)?("0"+d.toString(16)):d.toString(16); +} +if(typeof v=="number"){ +r=v&255; +g=(v>>8)&255; +b=(v>>16)&255; +return "#"+hex(r)+hex(g)+hex(b); +} +if(v.substr(0,3)=="rgb"){ +var re=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/; +if(v.match(re)){ +r=parseInt(RegExp.$1,10); +g=parseInt(RegExp.$2,10); +b=parseInt(RegExp.$3,10); +return "#"+hex(r)+hex(g)+hex(b); +} +return null; +} +if(v.substr(0,1)=="#"){ +return v; +} +return null; +}; +Xinha.prototype._popupDialog=function(url,_1e0,init){ +Dialog(this.popupURL(url),_1e0,init); +}; +Xinha.prototype.imgURL=function(file,_1e3){ +if(typeof _1e3=="undefined"){ +return _editor_url+file; +}else{ +return _editor_url+"plugins/"+_1e3+"/img/"+file; +} +}; +Xinha.prototype.popupURL=function(file){ +var url=""; +if(file.match(/^plugin:\/\/(.*?)\/(.*)/)){ +var _1e6=RegExp.$1; +var _1e7=RegExp.$2; +if(!(/\.html$/.test(_1e7))){ +_1e7+=".html"; +} +url=_editor_url+"plugins/"+_1e6+"/popups/"+_1e7; +}else{ +if(file.match(/^\/.*?/)){ +url=file; +}else{ +url=_editor_url+this.config.popupURL+file; +} +} +return url; +}; +Xinha.getElementById=function(tag,id){ +var el,i,objs=document.getElementsByTagName(tag); +for(i=objs.length;--i>=0&&(el=objs[i]);){ +if(el.id==id){ +return el; +} +} +return null; +}; +Xinha.prototype._toggleBorders=function(){ +var _1eb=this._doc.getElementsByTagName("TABLE"); +if(_1eb.length!==0){ +if(!this.borders){ +this.borders=true; +}else{ +this.borders=false; +} +for(var i=0;i<_1eb.length;i++){ +if(this.borders){ +Xinha._addClass(_1eb[i],"htmtableborders"); +}else{ +Xinha._removeClass(_1eb[i],"htmtableborders"); +} +} +} +return true; +}; +Xinha.addCoreCSS=function(html){ +var _1ee="\n"; +if(html&&//i.test(html)){ +return html.replace(//i,""+_1ee); +}else{ +if(html){ +return _1ee+html; +}else{ +return _1ee; +} +} +}; +Xinha.stripCoreCSS=function(html){ +return html.replace(/]+title="Xinha Internal CSS"(.|\n)*?<\/style>/i,""); +}; +Xinha.addClasses=function(el,_1f1){ +if(el!==null){ +var _1f2=el.className.trim().split(" "); +var ours=_1f1.split(" "); +for(var x=0;x"+s+""); +} +} +Xinha.arrayContainsArray=function(a1,a2){ +var _210=true; +for(var x=0;x>2; +enc2=((chr1&3)<<4)|(chr2>>4); +enc3=((chr2&15)<<2)|(chr3>>6); +enc4=chr3&63; +if(isNaN(chr2)){ +enc3=enc4=64; +}else{ +if(isNaN(chr3)){ +enc4=64; +} +} +_23f=_23f+_23e.charAt(enc1)+_23e.charAt(enc2)+_23e.charAt(enc3)+_23e.charAt(enc4); +}while(i<_23d.length); +return _23f; +}; +Xinha.base64_decode=function(_243){ +var _244="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; +var _245=""; +var chr1,chr2,chr3; +var enc1,enc2,enc3,enc4; +var i=0; +_243=_243.replace(/[^A-Za-z0-9\+\/\=]/g,""); +do{ +enc1=_244.indexOf(_243.charAt(i++)); +enc2=_244.indexOf(_243.charAt(i++)); +enc3=_244.indexOf(_243.charAt(i++)); +enc4=_244.indexOf(_243.charAt(i++)); +chr1=(enc1<<2)|(enc2>>4); +chr2=((enc2&15)<<4)|(enc3>>2); +chr3=((enc3&3)<<6)|enc4; +_245=_245+String.fromCharCode(chr1); +if(enc3!=64){ +_245=_245+String.fromCharCode(chr2); +} +if(enc4!=64){ +_245=_245+String.fromCharCode(chr3); +} +}while(i<_243.length); +return _245; +}; +Xinha.removeFromParent=function(el){ +if(!el.parentNode){ +return; +} +var pN=el.parentNode; +pN.removeChild(el); +return el; +}; +Xinha.hasParentNode=function(el){ +if(el.parentNode){ +if(el.parentNode.nodeType==11){ +return false; +} +return true; +} +return false; +}; +Xinha.viewportSize=function(_24c){ +_24c=(_24c)?_24c:window; +var x,y; +if(_24c.innerHeight){ +x=_24c.innerWidth; +y=_24c.innerHeight; +}else{ +if(_24c.document.documentElement&&_24c.document.documentElement.clientHeight){ +x=_24c.document.documentElement.clientWidth; +y=_24c.document.documentElement.clientHeight; +}else{ +if(_24c.document.body){ +x=_24c.document.body.clientWidth; +y=_24c.document.body.clientHeight; +} +} +} +return {"x":x,"y":y}; +}; +Xinha.prototype.scrollPos=function(_24e){ +_24e=(_24e)?_24e:window; +var x,y; +if(_24e.pageYOffset){ +x=_24e.pageXOffset; +y=_24e.pageYOffset; +}else{ +if(_24e.document.documentElement&&document.documentElement.scrollTop){ +x=_24e.document.documentElement.scrollLeft; +y=_24e.document.documentElement.scrollTop; +}else{ +if(_24e.document.body){ +x=_24e.document.body.scrollLeft; +y=_24e.document.body.scrollTop; +} +} +} +return {"x":x,"y":y}; +}; +Xinha.getElementTopLeft=function(_250){ +var _251={top:0,left:0}; +while(_250){ +_251.top+=_250.offsetTop; +_251.left+=_250.offsetLeft; +if(_250.offsetParent&&_250.offsetParent.tagName.toLowerCase()!="body"){ +_250=_250.offsetParent; +}else{ +_250=null; +} +} +return _251; +}; +Xinha.findPosX=function(obj){ +var _253=0; +if(obj.offsetParent){ +return Xinha.getElementTopLeft(obj).left; +}else{ +if(obj.x){ +_253+=obj.x; +} +} +return _253; +}; +Xinha.findPosY=function(obj){ +var _255=0; +if(obj.offsetParent){ +return Xinha.getElementTopLeft(obj).top; +}else{ +if(obj.y){ +_255+=obj.y; +} +} +return _255; +}; +Xinha.prototype.setLoadingMessage=function(_256,_257,_258){ +if(!this.config.showLoading||!document.getElementById("loading_sub_"+this._textArea.name)){ +return; +} +var elt=document.getElementById("loading_sub_"+this._textArea.name); +elt.innerHTML=Xinha._lc(_256,_257,_258); +}; +Xinha.prototype.removeLoadingMessage=function(){ +if(!this.config.showLoading||!document.getElementById("loading_"+this._textArea.name)){ +return; +} +document.body.removeChild(document.getElementById("loading_"+this._textArea.name)); +}; +Xinha.toFree=[]; +Xinha.freeLater=function(obj,prop){ +Xinha.toFree.push({o:obj,p:prop}); +}; +Xinha.free=function(obj,prop){ +if(obj&&!prop){ +for(var p in obj){ +Xinha.free(obj,p); +} +}else{ +if(obj){ +try{ +obj[prop]=null; +} +catch(x){ +} +} +} +}; +Xinha.collectGarbageForIE=function(){ +Xinha.flushEvents(); +for(var x=0;x"; + while(!feof($fp)) { + $data .= fread($fp, 1024); + } + preg_match_all('#_lc\("([^"]+)"|_lc\(\'([^\']+)\'#', $data, $m); + foreach($m[1] as $i) { + if(trim(strip_tags($i))=="") continue; + $ret[] = $i; + } + foreach($m[2] as $i) { + if(trim(strip_tags($i))=="") continue; + $ret[] = $i; + } + } + } + + if($plugin=="TableOperations") + { + preg_match_all('#options = \\[([^\\]]+)\\];#', $data, $m); + foreach($m[1] as $i) { + preg_match_all('#"([^"]+)"#', $i, $m1); + foreach($m1[1] as $i) { + $ret[] = $i; + } + } + + //["cell-delete", "td", "Delete cell"], + preg_match_all('#\\["[^"]+",[ \t]*"[^"]+",[ \t]*"([^"]+)"\\]#', $data, $m); + foreach($m[1] as $i) { + $ret[] = $i; + } + } + + + $files = getFiles("$pluginDir/", "html$"); + $files = array_merge($files, getFiles("$pluginDir/", "php$")); + foreach($files as $file) + { + $ret = array_merge($ret, parseHtmlFile($file, $plugin)); + } + + $files = getFiles("$pluginDir/popups/", "html$"); + foreach($files as $file) + { + $ret = array_merge($ret, parseHtmlFile($file, $plugin)); + } + $ret = array_unique($ret); + + $langData[$plugin] = $ret; +} + +foreach($langData as $plugin=>$strings) +{ + if(sizeof($strings)==0) continue; + + + $data = "// I18N constants\n"; + $data .= "//\n"; + $data .= "//LANG: \"base\", ENCODING: UTF-8\n"; + $data .= "//Author: Translator-Name, \n"; + $data .= "// FOR TRANSLATORS:\n"; + $data .= "//\n"; + $data .= "// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\n"; + $data .= "// (at least a valid email address)\n"; + $data .= "//\n"; + $data .= "// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\n"; + $data .= "// (if this is not possible, please include a comment\n"; + $data .= "// that states what encoding is necessary.)\n"; + $data .= "\n"; + $data .= "{\n"; + sort($strings); + foreach($strings as $string) { + $string = str_replace(array('\\', '"'), array('\\\\', '\\"'), $string); + $data .= " \"".$string."\": \"\",\n"; + } + $data = substr($data, 0, -2); + $data .= "\n"; + $data .= "}\n"; + + if($plugin=="HTMLArea") + $file = "../lang/base.js"; + else + $file = "../plugins/$plugin/lang/base.js"; + + $fp = fopen($file, "w"); + if(!$fp) continue; + fwrite($fp, $data); + fclose($fp); + echo "$file written...
"; +} + + + + +function parseHtmlFile($file, $plugin="") +{ + $ret = array(); + + $fp = fopen($file, "r"); + if(!$fp) { + die("invalid fp"); + } + $data = ""; + while(!feof($fp)) { + $data .= fread($fp, 1024); + } + + if($plugin=="FormOperations" || $plugin=="SuperClean" || $plugin=="Linker") { + //-tags for inline-dialog or panel-dialog based dialogs + $elems = array("l10n"); + } else { + $elems = array("title", "input", "select", "legend", "span", "option", "td", "button", "div", "label"); + } + foreach($elems as $elem) { + preg_match_all("#<{$elem}[^>]*>([^<^\"]+)#i", $data, $m); + foreach($m[1] as $i) { + if(trim(strip_tags($i))=="") continue; + if($i=="/") continue; + if($plugin=="ImageManager" && preg_match('#^--+$#', $i)) continue; //skip those ------ + if($plugin=="CharacterMap" && preg_match('#&[a-z0-9]+;#i', trim($i)) || $i=="@") continue; + if($plugin=="SpellChecker" && preg_match('#^\'\\.\\$[a-z]+\\.\'$#', $i)) continue; + $ret[] = trim($i); + } + } + + if($plugin=="FormOperations" || $plugin=="SuperClean" || $plugin=="Linker") + { + //_( for inline-dialog or panel-dialog based dialogs + preg_match_all('#"_\(([^"]+)\)"#i', $data, $m); + foreach($m[1] as $i) { + if(trim($i)=="") continue; + $ret[] = $i; + } + } + else + { + preg_match_all('#title="([^"]+)"#i', $data, $m); + foreach($m[1] as $i) { + if(trim(strip_tags($i))=="") continue; + if(strip_tags($i)==" - ") continue; //skip those - (ImageManager) + $ret[] = $i; + } + } + return($ret); +} + + +function getFiles($rootdirpath, $eregi_match='') { + $array = array(); + if ($dir = @opendir($rootdirpath)) { + $array = array(); + while (($file = readdir($dir)) !== false) { + if($file=="." || $file==".." || $file==".svn") continue; + if($eregi_match=="") + $array[] = $rootdirpath."/".$file; + else if(eregi($eregi_match,$file)) + $array[] = $rootdirpath."/".$file; + + } + closedir($dir); + } + return $array; +} + + + + + +?> diff --git a/mailboxes/xinha/contrib/php-xinha.php b/mailboxes/xinha/contrib/php-xinha.php new file mode 100644 index 000000000..2fac5d225 --- /dev/null +++ b/mailboxes/xinha/contrib/php-xinha.php @@ -0,0 +1,202 @@ + + * with (xinha_config.ImageManager) + * { + * '/home/your/directory', + * 'images_url' => '/directory' + * ) + * ) + * ?> + * } + * + * + */ + + function xinha_pass_to_php_backend($Data, $KeyLocation = 'Xinha:BackendKey') + { + + $bk = array(); + $bk['data'] = serialize($Data); + + @session_start(); + if(!isset($_SESSION[$KeyLocation])) + { + $_SESSION[$KeyLocation] = uniqid('Key_'); + } + + $bk['session_name'] = session_name(); + $bk['key_location'] = $KeyLocation; + $bk['hash'] = + function_exists('sha1') ? + sha1($_SESSION[$KeyLocation] . $bk['data']) + : md5($_SESSION[$KeyLocation] . $bk['data']); + + + // The data will be passed via a postback to the + // backend, we want to make sure these are going to come + // out from the PHP as an array like $bk above, so + // we need to adjust the keys. + $backend_data = array(); + foreach($bk as $k => $v) + { + $backend_data["backend_data[$k]"] = $v; + } + + // The session_start() above may have been after data was sent, so cookies + // wouldn't have worked. + $backend_data[session_name()] = session_id(); + + echo 'backend_data = ' . xinha_to_js($backend_data) . "; \n"; + + } + + /** Convert PHP data structure to Javascript */ + + function xinha_to_js($var, $tabs = 0) + { + if(is_numeric($var)) + { + return $var; + } + + if(is_string($var)) + { + return "'" . xinha_js_encode($var) . "'"; + } + + if(is_array($var)) + { + $useObject = false; + foreach(array_keys($var) as $k) { + if(!is_numeric($k)) $useObject = true; + } + $js = array(); + foreach($var as $k => $v) + { + $i = ""; + if($useObject) { + if(preg_match('#^[a-zA-Z]+[a-zA-Z0-9]*$#', $k)) { + $i .= "$k: "; + } else { + $i .= "'$k': "; + } + } + $i .= xinha_to_js($v, $tabs + 1); + $js[] = $i; + } + if($useObject) { + $ret = "{\n" . xinha_tabify(implode(",\n", $js), $tabs) . "\n}"; + } else { + $ret = "[\n" . xinha_tabify(implode(",\n", $js), $tabs) . "\n]"; + } + return $ret; + } + + return 'null'; + } + + /** Like htmlspecialchars() except for javascript strings. */ + + function xinha_js_encode($string) + { + static $strings = "\\,\",',%,&,<,>,{,},@,\n,\r"; + + if(!is_array($strings)) + { + $tr = array(); + foreach(explode(',', $strings) as $chr) + { + $tr[$chr] = sprintf('\x%02X', ord($chr)); + } + $strings = $tr; + } + + return strtr($string, $strings); + } + + + /** Used by plugins to get the config passed via + * xinha_pass_to_backend() + * returns either the structure given, or NULL + * if none was passed or a security error was encountered. + */ + + function xinha_read_passed_data() + { + if(isset($_REQUEST['backend_data']) && is_array($_REQUEST['backend_data'])) + { + $bk = $_REQUEST['backend_data']; + session_name($bk['session_name']); + @session_start(); + if(!isset($_SESSION[$bk['key_location']])) return NULL; + + if($bk['hash'] === + function_exists('sha1') ? + sha1($_SESSION[$bk['key_location']] . $bk['data']) + : md5($_SESSION[$bk['key_location']] . $bk['data'])) + { + return unserialize(ini_get('magic_quotes_gpc') ? stripslashes($bk['data']) : $bk['data']); + } + } + + return NULL; + } + + /** Used by plugins to get a query string that can be sent to the backend + * (or another part of the backend) to send the same data. + */ + + function xinha_passed_data_querystring() + { + $qs = array(); + if(isset($_REQUEST['backend_data']) && is_array($_REQUEST['backend_data'])) + { + foreach($_REQUEST['backend_data'] as $k => $v) + { + $v = ini_get('magic_quotes_gpc') ? stripslashes($v) : $v; + $qs[] = "backend_data[" . rawurlencode($k) . "]=" . rawurlencode($v); + } + } + + $qs[] = session_name() . '=' . session_id(); + return implode('&', $qs); + } + + + /** Just space-tab indent some text */ + function xinha_tabify($text, $tabs) + { + if($text) + { + return str_repeat(" ", $tabs) . preg_replace('/\n(.)/', "\n" . str_repeat(" ", $tabs) . "\$1", $text); + } + } + + /** Return upload_max_filesize value from php.ini in kilobytes (function adapted from php.net)**/ + function upload_max_filesize_kb() + { + $val = ini_get('upload_max_filesize'); + $val = trim($val); + $last = strtolower($val{strlen($val)-1}); + switch($last) + { + // The 'G' modifier is available since PHP 5.1.0 + case 'g': + $val *= 1024; + case 'm': + $val *= 1024; + } + return $val; +} +?> \ No newline at end of file diff --git a/mailboxes/xinha/examples/Extended.html b/mailboxes/xinha/examples/Extended.html new file mode 100644 index 000000000..69aeddad3 --- /dev/null +++ b/mailboxes/xinha/examples/Extended.html @@ -0,0 +1,299 @@ + + + + Settings + + + + + + + + +
Settings
+
+
Editor width:
+ +

+

Editor height:
+ +

+

Size includes bars
+ +

+

Status Bar
+ +

+

Mozilla Parameter Handler:
+ +
+
Undo steps:
+ +

+

Base href:
+ +

+

Strip base href
+ +

+

Strip self named anchors
+ +

+

only 7bit printables in URLs
+ +

+

7bit Clean
+ +

+

kill Word on paste
+ +

+

flow toolbars
+ +

+

show loading
+ +

+ +

+
+
CharacterMap mode :
+ +
+

+ +

+
+
ListType mode :
+ +
+

+ +

+
+
CharCounter (showChar) :

+
CharCounter (showWord) :

+
CharCounter (showHtml) :
+
+

+ +

+ + +
+
+ + diff --git a/mailboxes/xinha/examples/custom.css b/mailboxes/xinha/examples/custom.css new file mode 100644 index 000000000..15530d58d --- /dev/null +++ b/mailboxes/xinha/examples/custom.css @@ -0,0 +1,40 @@ + /*--------------------------------------:noTabs=true:tabSize=2:indentSize=2:-- + -- CSS plugin example CSS file. This file is used by full_example.js + -- when the CSS plugin is included in an auto-generated example. + -- @TODO Make this CSS more useful. + -- + -- $HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/examples/custom.css $ + -- $LastChangedDate: 2007-01-19 23:24:36 +0100 (Fr, 19 Jan 2007) $ + -- $LastChangedRevision: 677 $ + -- $LastChangedBy: ray $ + --------------------------------------------------------------------------*/ + +body { background-color: #234; color: #dd8; font-family: tahoma; font-size: 12px; } + +a:link, a:visited { color: #8cf; } +a:hover { color: #ff8; } + +h1 { background-color: #456; color: #ff8; padding: 2px 5px; border: 1px solid; border-color: #678 #012 #012 #678; } + +/* syntax highlighting (used by the first combo defined for the CSS plugin) */ + +pre { margin: 0px 1em; padding: 5px 1em; background-color: #000; border: 1px dotted #02d; border-left: 2px solid #04f; } +.code { color: #f5deb3; } +.string { color: #00ffff; } +.comment { color: #8fbc8f; } +.variable-name { color: #fa8072; } +.type { color: #90ee90; font-weight: bold; } +.reference { color: #ee82ee; } +.preprocessor { color: #faf; } +.keyword { color: #ffffff; font-weight: bold; } +.function-name { color: #ace; } +.html-tag { font-weight: bold; } +.html-helper-italic { font-style: italic; } +.warning { color: #ffa500; font-weight: bold; } +.html-helper-bold { font-weight: bold; } + +/* info combo */ + +.quote { font-style: italic; color: #ee9; } +.highlight { background-color: yellow; color: #000; } +.deprecated { text-decoration: line-through; color: #aaa; } diff --git a/mailboxes/xinha/examples/dynamic.css b/mailboxes/xinha/examples/dynamic.css new file mode 100644 index 000000000..58bd14b29 --- /dev/null +++ b/mailboxes/xinha/examples/dynamic.css @@ -0,0 +1,56 @@ + /*--------------------------------------:noTabs=true:tabSize=2:indentSize=2:-- + -- DynamicCSS plugin example CSS file. Used by full_example.js + -- when the DynamicCSS plugin is included in an auto-generated example. + -- @TODO Make this CSS more useful. + -- + -- $HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/examples/dynamic.css $ + -- $LastChangedDate: 2007-01-19 23:24:36 +0100 (Fr, 19 Jan 2007) $ + -- $LastChangedRevision: 677 $ + -- $LastChangedBy: ray $ + --------------------------------------------------------------------------*/ + +p { + FONT-FAMILY: Arial, Helvetica; + FONT-SIZE: 9pt; + FONT-WEIGHT: normal; + COLOR: #000000; +} + +p.p1 { + FONT-FAMILY: Arial, Helvetica; + FONT-SIZE: 11pt; + FONT-WEIGHT: normal; + COLOR: #000000; +} + +p.p2 { + FONT-FAMILY: Arial, Helvetica; + FONT-SIZE: 13pt; + FONT-WEIGHT: normal; + COLOR: #000000; +} + +div { + FONT-FAMILY: Arial, Helvetica; + FONT-SIZE: 9pt; + FONT-WEIGHT: bold; + COLOR: #000000; +} + +div.div1 { + FONT-FAMILY: Arial, Helvetica; + FONT-SIZE: 11pt; + FONT-WEIGHT: bold; + COLOR: #000000; +} + +div.div2 { + FONT-FAMILY: Arial, Helvetica; + FONT-SIZE: 13pt; + FONT-WEIGHT: bold; + COLOR: #000000; +} + +.quote { font-style: italic; color: #ee9; } +.highlight { background-color: yellow; color: #000; } +.deprecated { text-decoration: line-through; color: #aaa; } diff --git a/mailboxes/xinha/examples/ext_example-body.html b/mailboxes/xinha/examples/ext_example-body.html new file mode 100644 index 000000000..129aa38c8 --- /dev/null +++ b/mailboxes/xinha/examples/ext_example-body.html @@ -0,0 +1,202 @@ + + + + + + + + Example of Xinha + + + + + + + + + + + +
+
+ + +
+ + diff --git a/mailboxes/xinha/examples/ext_example-dest.php b/mailboxes/xinha/examples/ext_example-dest.php new file mode 100644 index 000000000..5a226e4f8 --- /dev/null +++ b/mailboxes/xinha/examples/ext_example-dest.php @@ -0,0 +1,23 @@ + + + + Example of Xinha + + + +$value){ + if(substr($key,0,10) == 'myTextarea') { + echo '

'.$key.'(source):

'.$value.'
'; + echo '

'.$key.'(preview):

'.$value; + } + } +?> + + diff --git a/mailboxes/xinha/examples/ext_example-menu.php b/mailboxes/xinha/examples/ext_example-menu.php new file mode 100644 index 000000000..1ce111548 --- /dev/null +++ b/mailboxes/xinha/examples/ext_example-menu.php @@ -0,0 +1,331 @@ + + + + + + + + Example of Xinha + + + + + + +
+

Xinha Example

+
+ Settings + + + +
+ +
+
+ Plugins +
+read())) //not a dot file or directory + { if(substr($entry,0,1) != '.') + { + $dir_array[] = $entry; + } + } + $d->close(); + sort($dir_array); + foreach ($dir_array as $entry) + { + echo ''."\n"; + } + +?> +
+
+
+ + + +
+ + + + diff --git a/mailboxes/xinha/examples/ext_example.html b/mailboxes/xinha/examples/ext_example.html new file mode 100644 index 000000000..ae3e15748 --- /dev/null +++ b/mailboxes/xinha/examples/ext_example.html @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/mailboxes/xinha/examples/full_example.css b/mailboxes/xinha/examples/full_example.css new file mode 100644 index 000000000..56bf25403 --- /dev/null +++ b/mailboxes/xinha/examples/full_example.css @@ -0,0 +1,48 @@ + /*--------------------------------------:noTabs=true:tabSize=2:indentSize=2:-- + -- Xinha example CSS file. This is ripped from Trac ;) + -- + -- $HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/examples/full_example.css $ + -- $LastChangedDate: 2007-01-19 23:24:36 +0100 (Fr, 19 Jan 2007) $ + -- $LastChangedRevision: 677 $ + -- $LastChangedBy: ray $ + --------------------------------------------------------------------------*/ + + body { + background: #fff; + color: #000; + margin: 10px; + } + body, th, td { + font: normal 13px verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif; + } + h1, h2, h3, h4 { + font-family: arial,verdana,'Bitstream Vera Sans',helvetica,sans-serif; + font-weight: bold; + letter-spacing: -0.018em; + } + h1 { font-size: 21px; margin: .15em 1em 0 0 } + h2 { font-size: 16px; margin: 2em 0 .5em; } + h3 { font-size: 14px; margin: 1.5em 0 .5em; } + hr { border: none; border-top: 1px solid #ccb; margin: 2em 0; } + address { font-style: normal } + img { border: none } + + :link, :visited { + text-decoration: none; + color: #b00; + border-bottom: 1px dotted #bbb; + } + :link:hover, :visited:hover { + background-color: #eee; + color: #555; + } + h1 :link, h1 :visited ,h2 :link, h2 :visited, h3 :link, h3 :visited, + h4 :link, h4 :visited, h5 :link, h5 :visited, h6 :link, h6 :visited { + color: inherit; + } + + .area_holder + { + margin:10px; + } + label {font-size: 11px;} \ No newline at end of file diff --git a/mailboxes/xinha/examples/full_example.js b/mailboxes/xinha/examples/full_example.js new file mode 100644 index 000000000..64e4735b4 --- /dev/null +++ b/mailboxes/xinha/examples/full_example.js @@ -0,0 +1,97 @@ +var num=1; +if(window.parent&&window.parent!=window){ +var f=window.parent.menu.document.forms[0]; +_editor_lang=f.lang[f.lang.selectedIndex].value; +_editor_skin=f.skin[f.skin.selectedIndex].value; +num=parseInt(f.num.value); +if(isNaN(num)){ +num=1; +f.num.value=1; +} +xinha_plugins=[]; +for(var x=0;x + + + +Simple example of Xinha + + + + + + + + + + + + + + +
+ + + +
+ + + \ No newline at end of file diff --git a/mailboxes/xinha/examples/stylist.css b/mailboxes/xinha/examples/stylist.css new file mode 100644 index 000000000..f64878777 --- /dev/null +++ b/mailboxes/xinha/examples/stylist.css @@ -0,0 +1,31 @@ + /*--------------------------------------:noTabs=true:tabSize=2:indentSize=2:-- + -- Stylist plugin example CSS file. Used by full_example.js + -- when the Stylist plugin is included in an auto-generated example. + -- + -- $HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/examples/stylist.css $ + -- $LastChangedDate: 2007-01-19 23:24:36 +0100 (Fr, 19 Jan 2007) $ + -- $LastChangedRevision: 677 $ + -- $LastChangedBy: ray $ + --------------------------------------------------------------------------*/ + +.bluetext +{ + color:blue; +} + +p.blue_paragraph +{ + color:darkblue; +} + +li.green_list_item +{ + color:green; +} + +h1.webdings_lvl_1 +{ + font-family:webdings; +} + +img.polaroid { border:1px solid black; background-color:white; padding:10px; padding-bottom:30px; } \ No newline at end of file diff --git a/mailboxes/xinha/examples/testbed.html b/mailboxes/xinha/examples/testbed.html new file mode 100644 index 000000000..c58d4d327 --- /dev/null +++ b/mailboxes/xinha/examples/testbed.html @@ -0,0 +1,191 @@ + + + + + + + + + Example of Xinha + + + + + + + + + + + + +
+ + + +
+ + Hide + Show + + \ No newline at end of file diff --git a/mailboxes/xinha/htmlarea.js b/mailboxes/xinha/htmlarea.js new file mode 100644 index 000000000..014c4dbd9 --- /dev/null +++ b/mailboxes/xinha/htmlarea.js @@ -0,0 +1,23 @@ + + /*--------------------------------------:noTabs=true:tabSize=2:indentSize=2:-- + -- COMPATABILITY FILE + -- htmlarea.js is now XinhaCore.js + -- + -- $HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/htmlarea.js $ + -- $LastChangedDate: 2007-01-15 15:28:57 +0100 (Mo, 15 Jan 2007) $ + -- $LastChangedRevision: 659 $ + -- $LastChangedBy: gogo $ + --------------------------------------------------------------------------*/ + +if ( typeof _editor_url == "string" ) +{ + // Leave exactly one backslash at the end of _editor_url + _editor_url = _editor_url.replace(/\x2f*$/, '/'); +} +else +{ + alert("WARNING: _editor_url is not set! You should set this variable to the editor files path; it should preferably be an absolute path, like in '/htmlarea/', but it can be relative if you prefer. Further we will try to load the editor files correctly but we'll probably fail."); + _editor_url = ''; +} + +document.write(''); \ No newline at end of file diff --git a/mailboxes/xinha/images/de/bold.gif b/mailboxes/xinha/images/de/bold.gif new file mode 100644 index 0000000000000000000000000000000000000000..21d286fc435846c595e069eee75ea12d8d5e5e8d GIT binary patch literal 57 zcmZ?wbhEHb6k-r!=wM{{|Np<2ub1La7Dfgj&|zg@Vc=lkWME(t=*cfQu<)c*3BPAo LV$AJLObpflp)C(L literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/de/italic.gif b/mailboxes/xinha/images/de/italic.gif new file mode 100644 index 0000000000000000000000000000000000000000..0bf794722ee66fdcaf7a4db33d892aa17ff059f1 GIT binary patch literal 63 zcmZ?wbhEHb6k-r!=wM{{|Npij|0Dt%rKmY&$ literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_about.gif b/mailboxes/xinha/images/ed_about.gif new file mode 100644 index 0000000000000000000000000000000000000000..0f28d405d55bda68a5eed33a6c747f04cb94b926 GIT binary patch literal 76 zcmZ?wbhEHb6k-r!=wM{{|NlP&1B2pE7Dgb&pu@<($RGfO3{1*B{h0^e?wgk)$QBvB eto+fs+y;-PhwXN$SsRyURn6hi-WJHfU=08kofpdh literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_align.gif b/mailboxes/xinha/images/ed_align.gif new file mode 100644 index 0000000000000000000000000000000000000000..6c60d50ffea9dcf11e2efa5fa05f47a8c59427de GIT binary patch literal 3388 zcmV-C4a4$BNk%w1Va5Q)0NpkK|NsC0|Nj600001hfPjGB9v;lh%z%IZdwY8T0E8w) zjQ}&5goK2^z`z|mi2wlq|LDyG0)&770NmW%|Nj60|Ns900A^-ps;a7)nVA5905dZ) zO-)VQ;_dtU{n*~>{{a8^`TT;DzPiNP0DAxcga8XIf7ILUS#YQwJiGu7?yX7*o z-ex!n26xBCa`}rsnvK?LKro~)wRUm+i*?fTN`PB~MS^L2frwRdf`&+rZiP{hl9YXu zjCYccn?rF_jeeq+go$%{m{*pkq=&5mpHrczQmdV&wx@5JsTQO+fnUfDLGJpth(UZ9zC!Tya zVZ4mdm*&{%HtFkY$8RsweMt8Khp|_cPd@y0%gZIkT4cLH2a9xXxu%(0@L9LucHa3G zKydgWr5^wrWT@eW9Oh>KA!w>?_8M~Q9mgIi?vcmeXV^89MSa{MHGlvW8kNC~IOeEh zWehe)Vu`U4=h*oOkpewEb;>Jq=rpvmBM_=f=kp%%0m;{iq({20UQW8k; zCIR>M6)(O?-D{W{>%RF2zv-e2utjkdtFTo9z{?iH5Fd4KbdjMfK*bY~ z;Zd`Vaf@(0S8^|I1q9qL0b-P*q|bw5FR%%k=HxQqZ|^YTs*l%o_(^dckn7 zdU{oEt}Jxx6jH7{=ew!B^6#NfO=;s%A&MpvycWCs?YlE3`&-p-b5h%UY8iJ}uv?SX z0vN5%7-a&vOP~U!wgh)MkXRFlpadrv!EQb9g2l2R1~-@@4RY{|o zl@rJs;_yA*{HBwNvd=Xs(lpF8XF8v`&S=KzS5R@s;y^{rGjVe+8ciuA)#)F0){%<; zJ+k6K@?g?g<;SKgv=Bf6Do|R6N}AF1QO{)RGMdOUr)g;+qxyHyIXy*$bwR4GENMh0 zNcE~pt!e|W%2lzbu&eNlLQcQRK@6DntZ0pt0vy2Bwz}1=3OFhUp9RRJbaHd?dFW6u zfCLP1pezdLfCmOk*uoCh1rCtw1`81wEb=jKcl{roz!OyLJU{@K%`9f^z}LT8A+Ssc zL1I^@z|xZNEbQnQ0P3ogyE^4HzA{sbknjK@aNxFo4M1Q;z*`vvfVU#>0B}VR*PswU z0tY~@a+Ay4(~{*Gdt~iutRMge;A^4)(5!X^0Dw0jDQkH)MqA6afyS{-vI2FyWIWmcf;F(5v-L3 z4oI*AYQWYJi1t7ao3M~8yfgWFm9eMV;`O4tWaLDrx)z8s0xCe|6XON}QMSO8tNfhJ z`u70<4zqv*Yhwk(Ai)WyfdW(zfFBz-!V_NCkTD!B4P(}M`#*Tpaf^BlS>=Fiqx0SHF3jy=%k2M2kPizGk=))nD8Ym&(<6iSKzMNH}ukGO6l zCUL2|++RCbUsLcy%#Thm3Sf}q#Om788v9zNj~i^T412X6PD-A?)g&f04*|%%Zl@sN0XRnh2zEa2pxiv? zI|spuGY)H5%X+|}wX_5@!1Sg&{ou_~R?W%60GvO70YUFM0IH7vbFA~6C>UV0*u_3( z6@1|AXixjuPXO-ax;?q&b{4L3HR@7}7%6o(_1*W%0Ri;g?_l`*XC+Pe!XM~`p0+Aj zn<9m=&VBJqDS+fBPx;DE-tmfuyizXDlmcLWtC~*=TYD|6rQm^~nd)_+FFQF@DACw3j zA4DdnqC0L%wK^u^D6*Np#z(+9rwj}NA7g=hU^^8OrF&wB9_<@K{V|6Gr# ze)xasLzA(7+y^T12Y%safA`0GjiY~y#eb*ge;lP3d;x*~1c-a{cYp}U8Iwmu42VGq zH&WY2MX}`<*7q2x2TKOX7|~Z68(0P%ctJ5|R7Ej>17#_UL4#=FPqBo7x;GvhC=@UF zKz7y`BRDKN=t}b8d0O&%LFhn32p&bKE2*aj^;Z;12r1?&iRclF$cS-x8ZrlogJ^oZx44V{YG^7n<%?HUGlwXQ`{#(pn2U;- zj7X)3#mJ1dD0`C#jUZ%+)JKgTI8&#GjnN1X!N`pbs89+8j>o7_*GP`M7;~$Lj$GJ_ z>{uS%okMj5!^jMD}@{u5^DlBl(kEID5;`I5pG zlQJoHnOBo)F+;$Ilh5UVkI0iVDUQhilsT!5KS`8aAt^hFlr||1Nyd~%rU>TGRq2yj>6K4~Wa}uFSkaGJW|>e)kd|M0lWb`fX!(|L$(D1OmO8nO zZy8cxnU`mom3(;>UHO+|DU{zRn0hIdg=v^FM3#xEn0mO7j`^4Z5t)P84V1Z5o{1De0027!Nn`y0 literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_align_center.gif b/mailboxes/xinha/images/ed_align_center.gif new file mode 100644 index 0000000000000000000000000000000000000000..75845b7a3d9330ce2a01ec273c5e00f786787c1f GIT binary patch literal 61 zcmZ?wbhEHb6k-r!=wM{{|NlP&1B2pE7Dgb&pu@z#%)rOM&A`AU($mjz`t5{EvvqDc Qyfm%MyJ>kph=IWx0MhLda{vGU literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_align_justify.gif b/mailboxes/xinha/images/ed_align_justify.gif new file mode 100644 index 0000000000000000000000000000000000000000..568c5953050baa69f102176ff3af9f85062dbdaf GIT binary patch literal 60 zcmZ?wbhEHb6k-r!=wM{{|NlP&1B2pE7Dgb&pu@z#%)rOM&A`AU+|$o-`YvbxY#lc* O-6O&3?#1g8%>k literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_blank.gif b/mailboxes/xinha/images/ed_blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..1ea396b81d150892e1c3b0238ca5a95ce873fd15 GIT binary patch literal 56 zcmZ?wbhEHb6k-r!XkcLY|NlP&1B2pE7Dgb&paUX6G7L=oE&VG`zvW*%XUnbb&G+Vr HGgt!vg8mRB literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_buttons_main.gif b/mailboxes/xinha/images/ed_buttons_main.gif new file mode 100644 index 0000000000000000000000000000000000000000..bc1962ba1f41ffc0530bf84f6b021f914a947689 GIT binary patch literal 6629 zcmW-jd0b5W`~TnP%$YOOOif1%?Y*Z(i_~bjQL57-Npi$Z%5o$LrHLC6?$c^Y7$o%( z4&p{)B!tqm*t=_NMea0ZYoSKS66Wjod;NJmuE*o`cwE=@xL(g`(?cdrUV01M0$KpH z|6c%rbJZ>40Or8)^IyJbf7d(T4wjTDH5zSOTigDF3P~uf(P$c*|C_cjdE$)aXKFQ+ zOue_fzq(~mt8K#2EC&aNOSeB!35@bqle9=veY-;{Q@ri}f>dE;wH?75UXTe2ZBx^s zO9P&<=d+J>{67z%EiNvm*5B-U^BNQbR-q~`Zi?C5+}8Ql!^5McO{3$JC6%kv($b1A ztHt5}lTdpKPhOXw(!{0|PFwarwMMHmqk<`7X}P-Pd8gB?opaZoq-2`r4=q^-YL2mm zUq-Z7ZnrT-ir+R`508ZXgGp)Gs!om1g8igaSzdXixH!K3)t8suFR0&QRQvYGir8uo zk9bl7wb|L~9xWB6X!_k0AMfawG^*NY`R4MgH=48rAwSnjCops>t59fk_wifWI^}Xr zR8*9u5=v85X~hp#X5PI}ezK_;$WN(hnM$eBwsd~6u&{`aZ(4zELBnpjk36@SW-kWQd(P9re;CJ zh3MM0FFYPk_R5{m0xFfB$6Seg;4UFaX#!cPq03IPQmHghUhwM25h<%+`=X_%7^Q-# z|Hx29w76)UM{)6rcJqzt1<_CJ$pmTsYA3Qt_3TTTqKIM{sFIURm7G?P;%^w&==UkQ zpa2C8pdJ9e7I63$p$fJxlW*v}@Q&hW!*;?ptR$2GQ!`L^zsFU3Y#Z{e%yYu|264Cd z;4=z;$cEVInWNosLLz??xbu&xtv_TB#Q&BE($`o-QwjGD1?-tu;Plur@E_M5Az9A* zSGAlDPY&C9Z9N^HH*;%VO_*nI_@OAbXx|yb3D3b2hn%V7Qj+Fh+|Y94@tMMNPp&S$ zc*EYQZN-c$iOFv&M?NYR6y~oM?2P#`@Uo)ls-S7d*WT{REr$CV7s%av{$1u#w&wn` zwJRP>2|6AzUga6AtXMY2s=Q)o`O{jjaZeV-Xf*1qk%xux8)Psqp)1=Y{!~|vcGJzS?J&o&TZTr4cIP^-jZ)^hRG0*1 zV2zG1^W6<5DR)kKBRih!G|VUYVs%eFDsq)%GxIEpmm*vzisXAk1|q^y^vgg_;>63qJ)!9O(Wxr}Hwm-} zy#a;jt=Ei5BPOkbt!$K~{A*%H4-t%8#VmM{A~4d8Qzz;eQ5u_!<)`SIIAIYZ-e(X> zJC`7i>YHcq8}0R1--?XJRd6@C%Q&1T?N8Wr*U(dd*A4-WiVo5tjkqIoSx2`Npr%A6 z$5o#yt2dfOD#ZKj{~FOL89$nG4Ol&eQ*YL{c(UAfZJKber+{A1p#~#1B@nO#0(b?Y-xthB&apHfFCwn}-D#%T;xTob z#37X~+&adjL1b70IJztTqF6!WnB*THWIW|vN2KxT6lAym`2L;9q=%CwaD^*%c7lj; zr}&bDS~`q+Z+9XgJv zpPIPLW65{XU$U?7S7mD>)5nac>$%Uw;Ma)tXlWFy(?}yhS#_uZ%;E0s-gG~WH9!;& zJkL?$*}?O#`Gpqx=c=ZSlQ6>3y&0Hd4`~>s1UY~)%V!aH#Y@XWV{GjPQsyBhU}vly zJOAd4X^+R<3$2VY`1GWVjQJrq8qUd#Ze67C-omNZ5RFnyK(@USd|*@`#lMRl0JI+PlpgauN;= zc0F&$+P?`z0$w2!K_uv^La;PZ88apHH!_XBiL5+tABEIX(h9GLUcya23*c$ zt}5ri^qu1qx7r^}e>e*N3ri5q@8N)XDo&VztojWXY<}W1<WV}pe$*^`^< zjL|!R86gY14gYycE`YsDeMWWIgF4O>HIieXL_{)MtB#`W+Qy~%4si)cc0#GJQh`~l z{{8A`VB<-3&FBe$Z8w)Veq!>T)W@CwB1k@(voU+z9raB?WI%Dt*;o_nVeJ`DE7^aZ z$xF<~Q|ScI^9Lvc zf+xGo&B6F}KwzRQSg#pKH80&qBHi*M-*>Y8AwpQKRy4mpZPu35h~B9kpYv zjH5FM@733(lH=T2R#l8zD$NqI79LE!;iF?oCS7i(7w| zL-r%+Sw{DQ;MdRr9{;I^BW+{~=AR-Elhi_8b++kT@HRUYxY^Ie@zgrtcPb6HV_ehC zH}&v3IoQ1qSv>!AWBEpJna@4gR=)wsVY6NTs^eNo#$98Ruivw#_`wMQ#?7I=SomOu zz4Fh%n5|^biWUZ!h3WsBljU(zeo}8CGIaJSy0~Rs@8Fu6_HFi~(mGZ{J!#iB)%F|N z{5`LDS+tI-{MTnM5X~RYG|!q>rByC<>_B|g56VORom+S34lg^l>qqGnpNRllW}W+M zcyPs!*Dcyz1GQSv6QLc$VEmcdja!Bz8G%g9sbVmc+hK!vu+T%2O39&*Jl*UL^3xDA zgeY```hR3hpfcweB5PUb`pmjLf1uP{wd=?X^IjPWB!{(@^x)qQ(EfprKa`GflOd%T;!m9-MM=tz_ z2G`XtI<)m-LwNH}&}2!lATnPfL1(KE5H>DM6?88i^~ezhP}qSU#Kn>8Z(4xaL47r{ zP_~QHy+-?V;iT@+**ZC|hmmy3hhnjX&-SCJC{rbhHO*W;*=rY#?Uuk48dNKU_Xyz) zD6sfV>@-gx$6qcDMJj-=oa3u@dg}pQH0WKYvHyN^LqUk(n4A5Fm2x|DsuBs1j0dpT zKubdd3QM1wXQV`?LNrSUaF^}=P_ch8*pJ%mM;L!(vYflgHW&IXo320Mln$CAobwU? zjgy?UA@|fmU1vcA4U9FyS^~_5mH~VaM~tQMeSqcWtMe_Kq1!X)?&Q+%0pX+>W7P*- zAa^Q-;E~8w8vSO6UbN#+mIndN9~zyB93nN9Jc3lL`;xmqy4abcL9A)PLtA#3)%l-X zfKKpIuVXnGTtp$PaS}`=fPqHn4|I$KDF;rv=S)8~WVllt4b34M!N47|WSx2ts4lME zuqsdh=9+@}-{|NC+*En#No6S-C<=kPr>Vj@&Ic>C#VoEwjuEGQ2;fhh9;XJ@f>?3R zmOG*AOWOCwE;}R`avX2#(y4}x6eebVFBxl8I(dk*xW183_Xko*%{A z@9ndHGs;&Z)qmtKF zauw%)cteHye2AK#tkvMVB>YPLcB~t9P;(|ST!TFBLDw(SkrLcL{#k;p{VoSDMo z{K&Kkb1%&^Ki^$&33I>LcrRzoor~D9g=+~^6S>AxT511q<^V^$`d(#ADSx-bYq#Po zKO-)f;O0wLR~KH^?Yg|p$6N2~m5l4+bf2o6)#B_JhK!7OV+Uit^5nv+8#F$=O7xv$ zRkIQ2RUfp3Jc|)1WR^KChk?oz9L+W&cmW!pi*W##gS0WwLdx5yc4;<9&u^Gyq$og! z&>JJDH_MqO#jMoGN;w`(V&7L-mDxc<1!}(P0&2rElslY{gH|-xgq$JJfMZPY)>3*7Qgm|T@u-vFUm*CYmELrf)^`?IP!kb}1}*8oN<6%Y)&T-w zA_^hY*f@FZok09|aBVfMKnyU1#BE93lSX3+uyzX`wwbe`MB+f=*7Dmy6e6bd&afcM z1xAxTG1K{X<+>cHz)gMUMXCMc(a=(Qcv@&p>x``1#W?2zAX#q22&xCUsu&mt$7bHG z;h-Eudc~CFc*^Y)IhAQEcvJS>7ek&63D!e22w?RkL2ed6zaQ~nc$H~_e^_pFB2$0i zv@ug#a=%tT5aT|$I}tQDLatRf{0*d=?(=6$uvn>!4FS%d1)dTVkpe6Q7$`PMlpbCr zo}yK@j3e%xAvpE_3DKc?{ev4AHQKv@Q^2aCn-*~@wm4LP*<|Txy=EaqGst_`T5RdD zc|!QG#{xc~2^U|&Wh;=3M{vm7r)&uXoFDo8Ff-m1OK7Eev~nUKq_!x9&LBC{cA6Y- zcpRvCe3=JqAs_aZ1W$%DAimxcj)mn%HBXn+JVeERssYzk`XF5oWYE`;hc|mtb?`d2&|Z&6ZjdyrX)cJ-ofPAF0z|v$PPj&8%%$T5>KaVpsAsnCgQZs*t8hc&;l_|>&Kv&(GTD=e~Zt>4>qRxs`2L^;s8 z^jNsX_02&3)m3R#8NbB2K0P_-V77K!Pu`7L={I_GyLpRL*s4d^A~i2#z;ugaPYk6~ z@}hS?4Z~^tkwR~qnisCZ;+5ETbK_U<{oWQDJBD<7$MJ|;x8R zqW-&nu)FzP<*#>DBK)eKBOZXxqy)GMOEPEHAOqbu-i^M0^rtHv@$>$-c|bKV@bHD( zOeJwV$&TIAt&2=h0EVbZuCPi3>g4Pb z_|`C~dhXc;OXj^!{j-0*LOe$lY}Wd2L9W%-U%}5?%fol4bT&^lpYOV;ddd6Nrswnf zUhLe)_26!iYPybQ*Vx48Kk8|}WNkic*WF9w=H4q_fX+Mp?Bew19sawUtFE}Ld^~!l zc|?bIdB>x3%O_^n|GRnkeb%L% zNU{R(UL{v|=ziMar!lf4ym|W1UF*5xQbpiv*LSM}^?JJ%4OdLUiNg+CVe&>K3%)y;_5ImFfs@*@G&qj zdvoj(I2T~)7(eIH3#kZ+sbwrvE_f=q2OYk!HuvN%#)}-Tibrx2ELueQo_+Y+w8P0^ id$B~F>B9{#S literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_clearfonts.gif b/mailboxes/xinha/images/ed_clearfonts.gif new file mode 100644 index 0000000000000000000000000000000000000000..38c52a875c0ef27e25ad1647a59bf05ffa0dd9aa GIT binary patch literal 134 zcmZ?wbhEHblwgoxn90QO|NsAca&in{p!k!8kqgMuVPs%r5CcL6rtqHrl^k#RW4pdc z7G&+6k*&Zn_lawg#U#ekMXB5Elq~jdxU)cWO5@IdT%3GXv0fR59MhGPi&}Fu($$o< jK0YEi`Q{ug&%-CHj%%n~*<5S%%Ji{wS_iChL)BVAp8G+AQMOcA(+|1zyOj&0L7myj3Ay4 zBLgFY00Tb*152cUhr*FPGlFIp-o2YDc<4Z>GAGMb&7~m*CmdrBUzzZR@zG|MLrb=J z^VD=SxCPC&%xu1X%0wfAo%^WM&!n|$S{uR+PW7An!tcNVKAC$@PdDUB?BW0D`Ps6Y Hfx#L8Ig&v> literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_color_fg.gif b/mailboxes/xinha/images/ed_color_fg.gif new file mode 100644 index 0000000000000000000000000000000000000000..292ab8775fea244f6e21247bcac49caeb4ca2727 GIT binary patch literal 164 zcmZ?wbhEHb6k-r!*v-Z8|NsB$>S_iChL)C=|NntBi1-hJ{~1~s7(g;8K=CIFBS=7p zk%5sxfPtTZfh92DglFSkru5zVFNB`;#=G}D^lWo{y-P0p3}X^|q1c&Y3Cb3{3I-Be xdfdDlj1(-`yIPbixGXpsGn-y1D(zqHkSJp@W9RgPI}8luFL>z}$}uun0|3kxGI9U_ literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_copy.gif b/mailboxes/xinha/images/ed_copy.gif new file mode 100644 index 0000000000000000000000000000000000000000..0e440eb43eedcfcb3406cd5ddd2fc604c0781375 GIT binary patch literal 97 zcmZ?wbhEHb6k-r!n90oW9}E~kph58`3nPf3!^FVEz|X+Tz`$fQg@2{i!^CS@>p5qx uk=?WTIgi40$Mzo`%nnP_F7VE3Y$}kRb-eaMS%=_PDQ(YOk)ESm4AubS8zG+n literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_custom.gif b/mailboxes/xinha/images/ed_custom.gif new file mode 100644 index 0000000000000000000000000000000000000000..1444030ff711280446d70707b90ef7484a2bb734 GIT binary patch literal 50 zcmZ?wbhEHb6k-r!=wM{{|NlP&1B2pE7Dgb&pu^6<%D}?F$-uzG>5{a(n)6>$F)M>L E02ql1rT_o{ literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_cut.gif b/mailboxes/xinha/images/ed_cut.gif new file mode 100644 index 0000000000000000000000000000000000000000..23fbf80119ee8ec704159701936e398db1a8ba52 GIT binary patch literal 78 zcmZ?wbhEHb6k-r!n90QO|Nnmmh6V;OQ2fcl2x924GB7c4GVn1lFv+u|OwXEePD*IQ dQTOYY)jAF|9=tJ8!C{eBRaffwO)-oN)&S-l7QX-h literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_delete.gif b/mailboxes/xinha/images/ed_delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..aff568e32264977584c0123440a2dec8b4aa1509 GIT binary patch literal 80 zcmZ?wbhEHb6k-r!n90QO|Nnmm1}LfclZ6q;VbEb_U}oTB;ALQ7QuJY2nVGbgVG937 e;niCvzN$-HV4fNvS@d*yhurm5A3X9|8LR=31{p&D literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_format_bold.gif b/mailboxes/xinha/images/ed_format_bold.gif new file mode 100644 index 0000000000000000000000000000000000000000..78686d1f2db5a42689361a3e157717ccbce8c855 GIT binary patch literal 57 zcmZ?wbhEHb6k-r!=wM{{|NlP&1B2pE7Dgb&pu@_*!oUfH3`_z&`3%d?%%11W*(UaS K&$LZU4AuaAwho2> literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_format_italic.gif b/mailboxes/xinha/images/ed_format_italic.gif new file mode 100644 index 0000000000000000000000000000000000000000..2d3baf2044edf1a793cc4ea90d3581b93857d5ea GIT binary patch literal 67 zcmZ?wbhEHb6k-r!n90oW|Nnmm28QbD>Xw!k#h)yUKn{Zr3j+%SClE3)iL?mLOt<7Y U(&XtNslYWYG1joFNQA)}07+^Png9R* literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_format_strike.gif b/mailboxes/xinha/images/ed_format_strike.gif new file mode 100644 index 0000000000000000000000000000000000000000..a5b14295020e799d3c16603e5bab36dc7fa19cd5 GIT binary patch literal 66 zcmZ?wbhEHb6k-r!=wM{{|NlP&1B2pE7Dgb&pu^0-%)rCI&A`AU*&--eG3|R)3Gdm^ V(6Bk--JTa*dS`1^xiKn)fv(hA}W$0|4hX52OG9 literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_format_sup.gif b/mailboxes/xinha/images/ed_format_sup.gif new file mode 100644 index 0000000000000000000000000000000000000000..4ecb9a16c9297d2d517a5e46f3ef0d0ac8846d23 GIT binary patch literal 67 zcmZ?wbhEHb6k-r!n90QO|Nnmm28IS8W?)eK$-)Stbyygf7`T9tfk~u=U+KinZE;hy SSdwR+?S1_>@p>QwgEavD4iSz3 literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_format_underline.gif b/mailboxes/xinha/images/ed_format_underline.gif new file mode 100644 index 0000000000000000000000000000000000000000..4bc47a17255670cf344f0bb5c61272fe4be48bc8 GIT binary patch literal 69 zcmZ?wbhEHb6k-r!n90QO|Nnmm28QbDY9OijlZ6pTG3c-|urP2ka5FG4iS;nIvz_gX WsR`KDWmxORuu=26g;p9PgEas+eh}FJ literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_help.gif b/mailboxes/xinha/images/ed_help.gif new file mode 100644 index 0000000000000000000000000000000000000000..d5f7d63f34bbb1ddce2c87428a1e22eabbbf491b GIT binary patch literal 55 zcmZ?wbhEHb6k-r!=wM{{|NlP&1B2pE7Dgb&pu@(%!obGB#lXPC=OQ<)YQejx7=Evg J*CnhB)&N;f4E_KB literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_hr.gif b/mailboxes/xinha/images/ed_hr.gif new file mode 100644 index 0000000000000000000000000000000000000000..ec5c7786a7821473bd34080b68c2f3a1345ad671 GIT binary patch literal 53 zcmZ?wbhEHb6k-r!n90QO|NsA)GiMqb8#6F4DE?$&1X2t-j0_wM{0vMC3`}fO`Xx`l IWo57i0CCw2Y5)KL literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_html.gif b/mailboxes/xinha/images/ed_html.gif new file mode 100644 index 0000000000000000000000000000000000000000..026da4eda42e31bfa29648f9a1244119417d11d8 GIT binary patch literal 64 zcmZ?wbhEHb6k-r!=wM{{|NlP&1B2pE7Dgb&pu@z#!obJC$-uxQ-XfS-dG`B)tc)-% T{c{tK?Tc8boHi?vfx#L8`PC7# literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_image.gif b/mailboxes/xinha/images/ed_image.gif new file mode 100644 index 0000000000000000000000000000000000000000..1af79c3306501b9968a6317aab68b8f0d349f68c GIT binary patch literal 125 zcmZ?wbhEHb6k-r!SjEop|NsAnh6V-(1|SB}Km-)}&!G5|g%K#qpu@z##J~rH49rd% z8}F=cKBBo=N$Iui0tPk?8I=ash!uSd7g*;?bUd8N^f~EFzRh;-IldPUJrvt}e`BIH X!<-B1JV7g>)|+*OZF*TH%wP=w$O|kI literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_indent_less.gif b/mailboxes/xinha/images/ed_indent_less.gif new file mode 100644 index 0000000000000000000000000000000000000000..7dda02a9fa084c75ce7cc05109c3acdfea761d46 GIT binary patch literal 84 zcmZ?wbhEHb6k-r!n90QO|Nnmm5NH8n#h)yUAhr%810#a~13v=;lWGfp literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_indent_more.gif b/mailboxes/xinha/images/ed_indent_more.gif new file mode 100644 index 0000000000000000000000000000000000000000..c34b47e3d5c4f11bed404684e4bb2c70989089df GIT binary patch literal 84 zcmZ?wbhEHb6k-r!n90QO|Nnmm5NH8n#h)yUAhr%810#a~13v=;lWGfph&otUAqs6_BQ)5GFSruUFsM< literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_killword.gif b/mailboxes/xinha/images/ed_killword.gif new file mode 100644 index 0000000000000000000000000000000000000000..fd934a784d34e3c7dff6f42890f82a656e3b25ae GIT binary patch literal 151 zcmZ?wbhEHb6k-r!SjEQh9}E~682-OF3nW&pTIK8O`=5b9@h1x-7Xu@M4kM5d073@l z7>TGm>kLF3v~}GCH(HB}PiPEt4RFheB$r6Mm{)2fSLh6SL z6gahc|Bh9OO-+{I;-E$-)Sv7<8B!SQvO1*clj@L|U2{PakiH UsPR_S()T-Po5v{;%)np`056yi{{R30 literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_right_to_left.gif b/mailboxes/xinha/images/ed_right_to_left.gif new file mode 100644 index 0000000000000000000000000000000000000000..9b255bd2caebef576c390e71c0c197210289c672 GIT binary patch literal 75 zcmZ?wbhEHb6k-r!n90QO|Nnmm1_l-mqh%NO7Ml5}^L=BK@v4>4ByXmB!E0|1`| BA({XH literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_save.gif b/mailboxes/xinha/images/ed_save.gif new file mode 100644 index 0000000000000000000000000000000000000000..82262d03b6d2aa86eaefd2e088cadd8e23b863d6 GIT binary patch literal 128 zcmZ?wbhEHb6k-r!SjEcl|Nnmm1`yfMz|hdpaOch)AQuP}f3h%wXdNa7CI)^WWMFoc z*tLftk;QQ}#{`GW*GjG?rPEouQY7cdXl@D;p7}80zJ=}St~_m)qmM(4*BZYVY$u4aHhh7>s{PqGpz_UV*3HmP6+mnkX$u65&n zi_v1KSl1ExS|j2#T7moh5nZ7yt$XQ+zlEyvmT8wg|J5oaU}l}v?|Dk-SMrdfjL`69 zv#F4ZwGEgSBKe67(}W-uNChMVz)+BkecwYWuy%|{M{L`cbMR(eSGX@`y?IpsPZsyZ gy3g;voOk32Pp!sk?4;WN{r~^~07*qoM6N<$g5pnSV*mgE literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_saveas.gif b/mailboxes/xinha/images/ed_saveas.gif new file mode 100644 index 0000000000000000000000000000000000000000..4edd9882856879891fddac0dfcdff07fde48213f GIT binary patch literal 104 zcmZ?wbhEHb6k-r!n90EK|Nnmm28NavhU#ht#h)yUKn{ZrBLgD?KM*=FS+)qSoGp}o zh~wPG*=kogZx9tvXULYeSde~y4M875fb1@SU H1_o;YKqMhg literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_selectall.gif b/mailboxes/xinha/images/ed_selectall.gif new file mode 100644 index 0000000000000000000000000000000000000000..9acf0a038973ccaa3715ae0015960d1c2a35d5dd GIT binary patch literal 150 zcmZ?wbhEHb6k-r!Sj7MWX=!Qy|NlR8<_rUn`u`s+#-R9&AXya<+S5`F5UYXj*W$4@*! w^Dn5Cbp1K#WHftGg_Bm~owr6;ZvIm{D8g9d#u@Gt9l8DT&n literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_show_border.gif b/mailboxes/xinha/images/ed_show_border.gif new file mode 100644 index 0000000000000000000000000000000000000000..42849b71c42467b3cb13d458f05bbed77d240b11 GIT binary patch literal 88 zcmZ?wbhEHb6k-r!n90QO|NnmmATXW@Bou$LFoHNbj0~&{0t~zi3{09m{h5c}?wgmw o#?p{~Y+KgpT8@gTPZ;yE($^_v9m|=0t)L@)dyH0H5CelX02AFCp#T5? literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_splitblock.gif b/mailboxes/xinha/images/ed_splitblock.gif new file mode 100644 index 0000000000000000000000000000000000000000..1f1582b9fce824da228b9eec72415916ff4b16d8 GIT binary patch literal 82 zcmZ?wbhEHb6k-r!n8^SI|Ns97vJ`)^FoFbhm>8HCcp3N@9GH|_`ZN!`m7Bsd@s@VR eK8ro)U4j<%b{s2x`Kq$vcAL)jwX-Y57_0$1t{MRV literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_splitcel.gif b/mailboxes/xinha/images/ed_splitcel.gif new file mode 100644 index 0000000000000000000000000000000000000000..a6e5ab582b3ae4caecf8c810c67dcf23e0fc2611 GIT binary patch literal 111 zcmZ?wbhEHb6lV})SjEEd|Nnmm1_;>zq=0M)Q2fcl2x93lGO#iTFz_-kFq=s1x}&9Z zKr?;K)LXBAH8Cm*G<(eQH{m*bt1HvsOo^>Y9$#{r<*$|*xe~7>-3?{4pJu8tFjxZs D7)Bz_ literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/ed_undo.gif b/mailboxes/xinha/images/ed_undo.gif new file mode 100644 index 0000000000000000000000000000000000000000..319242fde2107c8fce1ccb6c29f19c9353c47c57 GIT binary patch literal 67 zcmZ?wbhEHb6k-r!n90QO|Nnmmh6W&DU|>-E$-)Sv7<5<|SQ&U2*clj@L|Wt}nHu|C UvX*N_oIP6hd}^pr00V=*MN~u7K-5As&a!I2!<`)WiKvjMg5#!%)KO870Ucm)I^9Ham&;|d z{SFDa59onGqI!mrt*-|O!n`1C00MBE6m{f8J&A&~)tPy_?s z+Xl26+e}80$lPfXd3kkowF~H$_4c=ln2|@r7Ez{ngb|NPSl@kq(*54LsAz_!MvVcX zA%V5$OOEHy(A+%Jr)ij8o*5A@*%uHj&sCmDYrb)8er4`jAFBK#(o+YZ#L{75U}4~7;9_84(G_SA%(CE?(bigcP{H@`v7TgiA1CV)PKSt= ZAjwHt5zY@8+xk=kBqX_5TU3}BtO0-RBaQ$7 literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/fr/strikethrough.gif b/mailboxes/xinha/images/fr/strikethrough.gif new file mode 100644 index 0000000000000000000000000000000000000000..5707aefca484ab93127d0502d7776a76f050ca12 GIT binary patch literal 131 zcmV-}0DS*PNk%w1VG;lm0J{$W|Ns90001W^C%pgwdwYBTLP9+~J@D}GtE;Qm*VkBB zSY~Es2L}h&8X6D~5ZxdkA^8LW00000ECT=p01E&K000Cq5G+BdK_DL!TtY#BWkeuk lLO^6dc>>`96vZ>#cSDnAru4j5BE(t%e+*P;88FBq06WIMDGdMs literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/fr/underline.gif b/mailboxes/xinha/images/fr/underline.gif new file mode 100644 index 0000000000000000000000000000000000000000..4ecaf22126f2e855ded3b733284b0d875a473821 GIT binary patch literal 134 zcmZ?wbhEHb6k-r!*v-rE|Nnmm28Qd`uOB>kP(VOHU0vPQ*0#F3`oo70X=!PzSFdJg zXP-H9W<*2;P#F*?{$ybU(K;*)EDT%>JPZsh#sUo@hpgC6ik;(Y3aL!u2njRF5Hb*% jda8{lMl#i#rB#AQ$k{+yX6Vso&&CcpIdVWwKwu_~h$DNVE8UXWF8SVf8 literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/fullscreen_minimize.gif b/mailboxes/xinha/images/fullscreen_minimize.gif new file mode 100644 index 0000000000000000000000000000000000000000..f679e5a937350bcbc0c7f77549c6cabd499ca261 GIT binary patch literal 87 zcmZ?wbhEHb6k-r!=wM{{|NlP&1B2pE7Dgb&pu@<($RGfO3`}}0@++%v$jWsX=(Sy1 qa!%uXrNZ*e%VN`(%*6fU%6mvCejDDef| z;PtWr0vW?V=SmtU1;XLLy!aLbsh}`5J(VQtN&qo7*GOWI1OPh} C&^P-4 literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/insertmacro.png b/mailboxes/xinha/images/insertmacro.png new file mode 100644 index 0000000000000000000000000000000000000000..3c874be5404a01ace3af766211b22a683d7d2554 GIT binary patch literal 638 zcmV-^0)hRBP)i-TIFv5MK`50txY&S-0Ywt+BBDrQuemdAS{g9cm|S~j9c+$9Q(S!D z`zV8lEB2i2Efkr^fa<8qbLfxuG45V&~=?!twu7LL=;7JV`IbN^?J8@ zdwZX0nl=k8+M75o&h-sP_hGA7xQ&Us@d&sT;mo!aF+L{BVY2tJ`twop1g(OLq zNoQv#s;aWKw#LA~0P%R-28>$-rBVq|6p>{ahr>a=UPn^od;}f8I0e!%-a`F5c~m5V;cay zQRm(3=OnJ(WPX00Xf*m4nO#{bQ~mn=H@2}&ZL``!aAfE-iNwrk~fH(O#lD@07*qoM6N<$f~;d5Bme*a literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/tidy.gif b/mailboxes/xinha/images/tidy.gif new file mode 100644 index 0000000000000000000000000000000000000000..a881c640a665683fc6ee1902c3ee1a8b919eae24 GIT binary patch literal 375 zcmZ?wbh9u|6k-r!xO z_u934@3W`uG~e@~$^?@D#^$Cl>jJe&Jd8yR3Nu(^U%i|pBEi7rp|Yu92_v`n zZ`}w5Taj{R(Q1Y=1|Ak>-*5>f2L3$WZZWR-9uE~x0VZB44sQ;2KL%k=jwBu-Zx+cV z49ZOM9s=AVxr@Uma7lVdi%Re^uygJ7R8aL46zAhm6p}sW$?wg^s>UKSBfx+C9WS?s IZjKDr0AD|CumAu6 literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/toggle_borders.gif b/mailboxes/xinha/images/toggle_borders.gif new file mode 100644 index 0000000000000000000000000000000000000000..95bc5be812cbd79f0ca5e29346a1ff15fb0f3125 GIT binary patch literal 73 zcmZ?wbhEHb6k-r!=wM>_|NsA)GiMZkvM@3LfesS`69XR*GB7Fh^m9tT&U;Wj(RYT? bB=L~@mAzMMAE#!qx6gZ?(zYs$fx#L8Lpm7# literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/images/xinha_logo.gif b/mailboxes/xinha/images/xinha_logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..346e313a44e14f64f6c8db2867c00c3f16a1f632 GIT binary patch literal 3006 zcmV;v3qkZpNk%w1VaotA0PcSP|Ns9000960|M40C=^6m~`S|?%`r{e^-{0T)8UXb4 z^!NAo+8O})`1a}P={q|+{{H>%@9)9DzxEmc{QUd<{r&s;`Tzg@)YQ}@BqaR*|NZ^^ zTwGlK{{G+H+)`3f|Ns6+M@J404*mT6`1kex{rtPTyUoqbadC0&8UXXEp#T5;g@uLk z5CHi9|Nj2`F)=Y38XCz80K69i{QLW8XlVHM^#A_+)CmBgp`pYX1-1?Vs0IM<+}P1u zQ2PJ>oSdBEn2`4G?BS}S)0dC<`1tYh@%#Ds=H})8|Np6}sr>!>v$L~%dwc)>`}+F& zi;Ii3C>ZSA*QOQ>|Nj2l+uP#e;=f!{;3yc~t)&s$in^p`;rU?@4vYJ{{QE~yUcuWA^8LW00000ECB!j z0K)(<000O7fE741ejEqG^T>z4kl$Dm3n3$jQo{MsxyBE72Fz7tz+&)YBl_+XCL) z+}YJD;@Qz4D;Ue`?CrD>U+L7##6Kfb%GBnm8XI#&6(~at=pILjxZ% zSn})7FQ$M0AsRffMFrJ)bHpE0M4{k<3{F8rTos5%9z^D$ryhG5ya!)SAQbSK1sbS; z!yGNNpvH+OwxMDhIOqT%NYfQ4#1%a3u)_>C=E%bpXHX|VR^xpY0(&)FcwUC^O~Rr7 zhbaA^!WzKuZA*Ab3I#1BjpJJlT>TjY$OAJDmal^qjNj{o1O# z4R5rs)6Ky9CTHPm?Y38k`zE?4Z@4ADvloI9mmr?;DlrBOAua|@&_VnhZcoc$5v@^a8$d;)CZ2fy5-iIR61Lh!(nH1&302rVE2u#qz z2^P!P`~@JasGB5N*%#EaZd9!XAW&P`_*PCJV3(2O9ZG3=*OhjHuUG9O{{~tKIEo+# zmdk_>&jZ=ijrFILH7i9d;P$BryG{bHdd&oC{fZ&g zR${A^a6tJYm_yn|GP1XAU2aK+R<&AS1Hu(e61>re-`bD3n=rxy0B1S?z)_XWO(|4O z+fvrnvbun^DkZ$Y9ua_n6Z7@%Sc(u7FyeNM}A+GwvVPyq|W zWdkD+KpCbm1r8%cX4AayHzVNH$EsMrrDacaF)`i$##pN_1^^b%qXkVAA;Ajv0FRd? zs0UjzR+sfmzC=?33M8Qnaj;R71werkWUE|))3HB6Th2-k019dl0=Ygw2?+fzaYg{5Ctc~;y7e?> zi(DPjn0f{XPxu<9aEA`VrBiZBWejk+34BBFa9Okj7y!5BLM9KU?r}7w?@PKGD4+@- zmrnskuz~uB2nR5aIm~51bDF1B1Lw6}7N+p6p7UT0KwrZi8vgJ&B{2jKNcsbY%?U0j zJ?VOFg3`Hg2_zsr>1a@@(hEI_6DU2Qr``JHK0w$b)nM3GxH<}ea{1gBy@@YP$wg+0&9l@w4ekaAl8DKXnP4DumLt`;0Ks@ zf#x-j`5$ON18JZD8)8&H(|rE)pI@&4JQ<-NCI0p9Q2ATj)P=z zBboJ4687SH*c)FNkip7aJbaR%I6o*z!TU!kzmT(JlKOi_=7+gghD8U5nu$9W`jsL34s6rJF;GX AU;qFB literal 0 HcmV?d00001 diff --git a/mailboxes/xinha/lang/b5.js b/mailboxes/xinha/lang/b5.js new file mode 100644 index 000000000..f0006990c --- /dev/null +++ b/mailboxes/xinha/lang/b5.js @@ -0,0 +1,29 @@ +// I18N constants -- UTF-8 +// by Dave Lo -- dlo@interactivetools.com +{ + "Bold": "ç²—é«”", + "Italic": "斜體", + "Underline": "底線", + "Strikethrough": "刪除線", + "Subscript": "下標", + "Superscript": "上標", + "Justify Left": "ä½ç½®é å·¦", + "Justify Center": "ä½ç½®å±…中", + "Justify Right": "ä½ç½®é å³", + "Justify Full": "ä½ç½®å·¦å³å¹³ç­‰", + "Ordered List": "é †åºæ¸…å–®", + "Bulleted List": "ç„¡åºæ¸…å–®", + "Decrease Indent": "減å°è¡Œå‰ç©ºç™½", + "Increase Indent": "加寬行å‰ç©ºç™½", + "Font Color": "文字é¡è‰²", + "Background Color": "背景é¡è‰²", + "Horizontal Rule": "水平線", + "Insert Web Link": "æ’入連çµ", + "Insert/Modify Image": "æ’入圖形", + "Insert Table": "æ’入表格", + "Toggle HTML Source": "切æ›HTML原始碼", + "Enlarge Editor": "放大", + "About this editor": "關於 HTMLArea", + "Help using editor": "說明", + "Current style": "字體例å­" +} diff --git a/mailboxes/xinha/lang/ch.js b/mailboxes/xinha/lang/ch.js new file mode 100644 index 000000000..4227fa45e --- /dev/null +++ b/mailboxes/xinha/lang/ch.js @@ -0,0 +1,56 @@ +// I18N constants + +// LANG: "ch", ENCODING: UTF-8 +// Samuel Stone, http://stonemicro.com/ + +{ + "Bold": "ç²—é«”", + "Italic": "斜體", + "Underline": "底線", + "Strikethrough": "刪線", + "Subscript": "下標", + "Superscript": "上標", + "Justify Left": "é å·¦", + "Justify Center": "居中", + "Justify Right": "é å³", + "Justify Full": "整齊", + "Ordered List": "é †åºæ¸…å–®", + "Bulleted List": "ç„¡åºæ¸…å–®", + "Decrease Indent": "伸排", + "Increase Indent": "縮排", + "Font Color": "文字é¡è‰²", + "Background Color": "背景é¡è‰²", + "Horizontal Rule": "水平線", + "Insert Web Link": "æ’入連çµ", + "Insert/Modify Image": "æ’入圖åƒ", + "Insert Table": "æ’入表格", + "Toggle HTML Source": "切æ›HTML原始碼", + "Enlarge Editor": "伸出編輯系統", + "About this editor": "關於 HTMLArea", + "Help using editor": "說明", + "Current style": "字體例å­", + "Undoes your last action": "回原", + "Redoes your last action": "釿¥", + "Cut selection": "剪制选项", + "Copy selection": "å¤åˆ¶é€‰é¡¹", + "Paste from clipboard": "贴上", + "Direction left to right": "从左到å³", + "Direction right to left": "从å³åˆ°å·¦", + "OK": "好", + "Cancel": "å–æ¶ˆ", + "Path": "途徑", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "你在用純字編輯方å¼. 用 [<>] 按鈕轉回 æ‰€è¦‹å³æ‰€å¾— 編輯方å¼.", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "æ•´é å¼åœ¨Internet Explorer 上常出å•題, 因為這是 Internet Explorer 的無åå•題,我們無法解決。你å¯èƒ½çœ‹è¦‹ä¸€äº›åžƒåœ¾ï¼Œæˆ–é‡åˆ°å…¶ä»–å•題。我們已警告了你. 如果è¦è½‰åˆ° æ­£é å¼ 請按 好.", + "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.", + "Cancel": "å–æ¶ˆ", + "Insert/Modify Link": "æ’å…¥/改寫連çµ", + "New window (_blank)": "新窗户(_blank)", + "None (use implicit)": "ç„¡(use implicit)", + "Other": "å…¶ä»–", + "Same frame (_self)": "本匡 (_self)", + "Target:": "目標匡:", + "Title (tooltip):": "主題 (tooltip):", + "Top frame (_top)": "上匡 (_top)", + "URL:": "ç¶²å€:", + "You must enter the URL where this link points to": "你必須輸入你è¦è¿žç»“的網å€" +} diff --git a/mailboxes/xinha/lang/cz.js b/mailboxes/xinha/lang/cz.js new file mode 100644 index 000000000..87faec80b --- /dev/null +++ b/mailboxes/xinha/lang/cz.js @@ -0,0 +1,50 @@ +// I18N constants + +// LANG: "cz", ENCODING: UTF-8 +// Author: Jiri Löw, + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "TuÄnÄ›", + "Italic": "Kurzíva", + "Underline": "Podtržení", + "Strikethrough": "PÅ™eÅ¡krtnutí", + "Subscript": "Dolní index", + "Superscript": "Horní index", + "Justify Left": "Zarovnat doleva", + "Justify Center": "Na stÅ™ed", + "Justify Right": "Zarovnat doprava", + "Justify Full": "Zarovnat do stran", + "Ordered List": "Seznam", + "Bulleted List": "Odrážky", + "Decrease Indent": "PÅ™edsadit", + "Increase Indent": "Odsadit", + "Font Color": "Barva písma", + "Background Color": "Barva pozadí", + "Horizontal Rule": "Vodorovná Äára", + "Insert Web Link": "Vložit odkaz", + "Insert/Modify Image": "Vložit obrázek", + "Insert Table": "Vložit tabulku", + "Toggle HTML Source": "PÅ™epnout HTML", + "Enlarge Editor": "Nové okno editoru", + "About this editor": "O této aplikaci", + "Help using editor": "NápovÄ›da aplikace", + "Current style": "Zvolený styl", + "Undoes your last action": "Vrátí poslední akci", + "Redoes your last action": "Opakuje poslední akci", + "Cut selection": "Vyjmout", + "Copy selection": "Kopírovat", + "Paste from clipboard": "Vložit", + "OK": "OK", + "Cancel": "ZruÅ¡it", + "Path": "Cesta", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Jste v TEXTOVÉM REŽIMU. Použijte tlaÄítko [<>] pro pÅ™epnutí do WYSIWIG." +} diff --git a/mailboxes/xinha/lang/da.js b/mailboxes/xinha/lang/da.js new file mode 100644 index 000000000..5a14e2b3d --- /dev/null +++ b/mailboxes/xinha/lang/da.js @@ -0,0 +1,30 @@ +// LANG: "da", ENCODING: UTF-8 +// Author: rene, + +{ + "Bold": "Fed", + "Italic": "Kursiv", + "Underline": "Understregning", + "Strikethrough": "Overstregning ", + "Subscript": "Sænket skrift", + "Superscript": "Hævet skrift", + "Justify Left": "Venstrejuster", + "Justify Center": "Centrer", + "Justify Right": "Højrejuster", + "Justify Full": "Lige margener", + "Ordered List": "Opstilling med tal", + "Bulleted List": "Opstilling med punkttegn", + "Decrease Indent": "Formindsk indrykning", + "Increase Indent": "Forøg indrykning", + "Font Color": "Skriftfarve", + "Background Color": "Baggrundsfarve", + "Horizontal Rule": "Horisontal linie", + "Insert Web Link": "Indsæt hyperlink", + "Insert/Modify Image": "Indsæt billede", + "Insert Table": "Indsæt tabel", + "Toggle HTML Source": "HTML visning", + "Enlarge Editor": "Vis editor i popup", + "About this editor": "Om htmlarea", + "Help using editor": "Hjælp", + "Current style": "Anvendt stil" +} diff --git a/mailboxes/xinha/lang/de.js b/mailboxes/xinha/lang/de.js new file mode 100644 index 000000000..b85f4a73a --- /dev/null +++ b/mailboxes/xinha/lang/de.js @@ -0,0 +1,163 @@ +// I18N constants +// LANG: "de", ENCODING: UTF-8 +{ + "Bold": "Fett", + "Italic": "Kursiv", + "Underline": "Unterstrichen", + "Strikethrough": "Durchgestrichen", + "Subscript": "Tiefgestellt", + "Superscript": "Hochgestellt", + "Justify Left": "Linksbündig", + "Justify Center": "Zentriert", + "Justify Right": "Rechtsbündig", + "Justify Full": "Blocksatz", + "Ordered List": "Nummerierte Liste", + "Bulleted List": "Aufzählungsliste", + "Decrease Indent": "Einzug verkleinern", + "Increase Indent": "Einzug vergrößern", + "Font Color": "Schriftfarbe", + "Background Color": "Hindergrundfarbe", + "Horizontal Rule": "Horizontale Linie", + "Insert Web Link": "Hyperlink einfügen", + "Insert/Modify Image": "Bild einfügen/verändern", + "Insert Table": "Tabelle einfügen", + "Toggle HTML Source": "HTML Quelltext ein/ausschalten", + "Enlarge Editor": "Editor vergrößern", + "About this editor": "Über diesen Editor", + "Help using editor": "Hilfe", + "Current style": "Derzeitiger Stil", + "Undoes your last action": "Rückgängig", + "Redoes your last action": "Wiederholen", + "Cut selection": "Ausschneiden", + "Copy selection": "Kopieren", + "Paste from clipboard": "Einfügen aus der Zwischenablage", + "Direction left to right": "Textrichtung von Links nach Rechts", + "Direction right to left": "Textrichtung von Rechts nach Links", + "Remove formatting": "Formatierung entfernen", + "Select all": "Alles markieren", + "Print document": "Dokument ausdrucken", + "Clear MSOffice tags": "MSOffice filter", + "Clear Inline Font Specifications": "Zeichensatz Formatierungen entfernen", + "Would you like to clear font typefaces?": "Wollen Sie Zeichensatztypen entfernen", + "Would you like to clear font sizes?": "Wollen Sie Zeichensatzgrößen entfernen", + "Would you like to clear font colours?": "Wollen sie Zeichensatzfarben entfernen", + "Split Block": "Block teilen", + "Toggle Borders": "Tabellenränder ein/ausblenden", + "Save as": "speichern unter", + "Insert/Overwrite": "Einfügen/Überschreiben", + "— format —": "— Format —", + "Heading 1": "Überschrift 1", + "Heading 2": "Überschrift 2", + "Heading 3": "Überschrift 3", + "Heading 4": "Überschrift 4", + "Heading 5": "Überschrift 5", + "Heading 6": "Überschrift 6", + "Normal": "Normal (Absatz)", + "Address": "Adresse", + "Formatted": "Formatiert", + + //dialogs + "OK": "OK", + "Cancel": "Abbrechen", + "Path": "Pfad", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Sie sind im Text-Modus. Benutzen Sie den [<>] Button, um in den visuellen Modus (WYSIWIG) zu gelangen.", + "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "Aus Sicherheitsgründen dürfen Skripte normalerweise nicht auf Ausschneiden/Kopieren/Einfügen zugreifen. Benutzen Sie bitte die entsprechenden Tastatur-Kommandos (Strg + x/c/v).", + + "You need to select some text before create a link": "Sie müssen einen Text markieren, um einen Link zu erstellen", + "Your Document is not well formed. Check JavaScript console for details.": "Ihr Dokument ist in keinem sauberen Format. Benutzen Sie die Javascript Console für weitere Informationen.", + + "Alignment:": "Ausrichtung:", + "Not set": "nicht eingestellt", + "Left": "links", + "Right": "rechts", + "Texttop": "oben bündig", + "Absmiddle": "mittig", + "Baseline": "Grundlinie", + "Absbottom": "unten bündig", + "Bottom": "unten", + "Middle": "zentriert", + "Top": "oben", + + "Layout": "Layout", + "Spacing": "Abstand", + "Horizontal:": "horizontal:", + "Horizontal padding": "horizontaler Inhaltsabstand", + "Vertical:": "vertikal:", + "Vertical padding": "vertikaler Inhaltsabstand", + "Border thickness:": "Randstärke:", + "Leave empty for no border": "leer lassen für keinen Rand", + + //Insert Link + "Insert/Modify Link": "Verknüpfung hinzufügen/ändern", + "None (use implicit)": "k.A. (implizit)", + "New window (_blank)": "Neues Fenster (_blank)", + "Same frame (_self)": "Selber Rahmen (_self)", + "Top frame (_top)": "Oberster Rahmen (_top)", + "Other": "Anderes", + "Target:": "Ziel:", + "Title (tooltip):": "Titel (Tooltip):", + "URL:": "URL:", + "You must enter the URL where this link points to": "Sie müssen eine Ziel-URL angeben für die Verknüpfung angeben", + + // Insert Table + "Insert Table": "Table einfügen", + "Rows:": "Zeilen:", + "Number of rows": "Zeilenanzahl", + "Cols:": "Spalten:", + "Number of columns": "Spaltenanzahl", + "Width:": "Breite:", + "Width of the table": "Tabellenbreite", + "Percent": "Prozent", + "Pixels": "Pixel", + "Em": "Geviert", + "Width unit": "Größeneinheit", + "Fixed width columns": "Spalten mit fester Breite", + "Positioning of this table": "Positionierung der Tabelle", + "Cell spacing:": "Zellenabstand:", + "Space between adjacent cells": "Raum zwischen angrenzenden Zellen", + "Cell padding:": "Innenabstand:", + "Space between content and border in cell": "Raum zwischen Inhalt und Rand der Zelle", + "You must enter a number of rows": "Bitte geben Sie die Anzahl der Zeilen an", + "You must enter a number of columns": "Bitte geben Sie die Anzahl der Spalten an", + + // Insert Image + "Insert Image": "Bild einfügen", + "Image URL:": "Bild URL:", + "Enter the image URL here": "Bitte geben sie hier die Bild URL ein", + "Preview": "Voransicht", + "Preview the image in a new window": "Voransicht des Bildes in einem neuen Fenster", + "Alternate text:": "Alternativer Text:", + "For browsers that don't support images": "für Browser, die keine Bilder unterstützen", + "Positioning of this image": "Positionierung dieses Bildes", + "Image Preview:": "Bild Voransicht:", + "You must enter the URL": "Bitte geben Sie die URL ein", + + "button_bold": "de/bold.gif", + "button_italic": "de/italic.gif", + "button_underline": "de/underline.gif", + + // Editor Help + "Keyboard shortcuts": "Tastaturkürzel", + "The editor provides the following key combinations:": "Der Editor unterstützt die folgenden kombinationen:", + "new paragraph": "Neuer Absatz(Paragraph)", + "insert linebreak": "Harter Umbruch einfügen", + "Set format to paragraph": "Setze Formatierung auf Absatz", + "Clean content pasted from Word": "Von Word eingefügter Text bereinigen", + "Headings": "Überschrift Typ 1 bis 6", + "Close": "Schließen", + + // Loading messages + "Loading in progress. Please wait !": "Editor wird geladen. Bitte warten !", + "Constructing main object": "Hauptteil wird erzeugt", + "Create Toolbar": "Bearbeitungswerkzeuge werden angelegt", + "Register panel right": "Erzeugt rechte Leiste", + "Register panel left": "Erzeugt linke Leiste", + "Register panel top": "Erzeugt obere Leiste", + "Register panel bottom": "Erzeugt untere Leiste", + + // ColorPicker + "Click a color..." : "Farbe wählen", + "Sample" : "Beispiel", + "Web Safe: " : "Web Safe: ", + "Color: " : "Farbe: " +}; \ No newline at end of file diff --git a/mailboxes/xinha/lang/ee.js b/mailboxes/xinha/lang/ee.js new file mode 100644 index 000000000..2c961e514 --- /dev/null +++ b/mailboxes/xinha/lang/ee.js @@ -0,0 +1,50 @@ +// I18N constants + +// LANG: "ee", ENCODING: UTF-8 +// Author: Martin Raie, + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "Paks", + "Italic": "Kursiiv", + "Underline": "Allakriipsutatud", + "Strikethrough": "Läbikriipsutatud", + "Subscript": "Allindeks", + "Superscript": "Ülaindeks", + "Justify Left": "Joonda vasakule", + "Justify Center": "Joonda keskele", + "Justify Right": "Joonda paremale", + "Justify Full": "Rööpjoonda", + "Ordered List": "Nummerdus", + "Bulleted List": "Täpploend", + "Decrease Indent": "Vähenda taanet", + "Increase Indent": "Suurenda taanet", + "Font Color": "Fondi värv", + "Background Color": "Tausta värv", + "Horizontal Rule": "Horisontaaljoon", + "Insert Web Link": "Lisa viit", + "Insert/Modify Image": "Lisa pilt", + "Insert Table": "Lisa tabel", + "Toggle HTML Source": "HTML/tavaline vaade", + "Enlarge Editor": "Suurenda toimeti aken", + "About this editor": "Teave toimeti kohta", + "Help using editor": "Spikker", + "Current style": "Kirjastiil", + "Undoes your last action": "Võta tagasi", + "Redoes your last action": "Tee uuesti", + "Cut selection": "Lõika", + "Copy selection": "Kopeeri", + "Paste from clipboard": "Kleebi", + "OK": "OK", + "Cancel": "Loobu", + "Path": "Path", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Sa oled tekstireziimis. Kasuta nuppu [<>] lülitamaks tagasi WYSIWIG reziimi." +} diff --git a/mailboxes/xinha/lang/el.js b/mailboxes/xinha/lang/el.js new file mode 100644 index 000000000..8476a4d06 --- /dev/null +++ b/mailboxes/xinha/lang/el.js @@ -0,0 +1,55 @@ +// I18N constants + +// LANG: "el", ENCODING: UTF-8 +// Author: Dimitris Glezos, dimitris@glezos.com + +{ + "Bold": "ΞˆΞ½Ο„ΞÎΞ½Ξ±", + "Italic": "Πλάγια", + "Underline": "Ξ�Ο€ΞÎΞ³ΟÂαμμισμένα", + "Strikethrough": "ΔιαγΟÂΞ±ΞΌΞΌΞ­Ξ½Ξ±", + "Subscript": "ΔΡίκτης", + "Superscript": "ΔΡίκτης", + "Justify Left": "ΣτΞÎίχιση Ξ‘ΟÂιστΡΟÂΞ¬", + "Justify Center": "ΣτΞÎίχιση ΞšΞ­Ξ½Ο„ΟÂΞÎ", + "Justify Right": "ΣτΞÎίχιση ΔΡξιά", + "Justify Full": "Ξ Ξ»Ξ�ΟÂΞ·Ο‚ ΣτΞÎίχιση", + "Ordered List": "Ξ‘ΟÂίθμηση", + "Bulleted List": "ΚΞÎυκκίδΡς", + "Decrease Indent": "ΞœΞ΅Ξ―Ο‰ΟƒΞ· ΕσΞÎχ�ς", + "Increase Indent": "Ξ‘ΟÂξηση ΕσΞÎχ�ς", + "Font Color": "Ξ§ΟÂώμα Ξ“ΟÂΞ±ΞΌΞΌΞ±Ο„ΞÎσΡιΟÂάς", + "Background Color": "Ξ§ΟÂώμα Ξ¦ΟŒΞ½Ο„ΞÎΟ…", + "Horizontal Rule": "ΟΟÂΞΉΞΆΟŒΞ½Ο„ΞΉΞ± Ξ“ΟÂΞ±ΞΌΞΌΞ�", + "Insert Web Link": "ΕισαγωγΞ� ΣυνδέσμΞÎΟ…", + "Insert/Modify Image": "ΕισαγωγΞ�/Ξ�ΟÂΞÎΟ€ΞÎΟ€ΞÎίηση Ξ•ΞΉΞΊΟŒΞ½Ξ±Ο‚", + "Insert Table": "ΕισαγωγΞ� Ξ Ξ―Ξ½Ξ±ΞΊΞ±", + "Toggle HTML Source": "ΕναλλαγΞ� σΡ/Ξ±Ο€ΟŒ HTML", + "Enlarge Editor": "ΞœΞ΅Ξ³Ξ­Ξ½ΞΈΟ…Ξ½ΟƒΞ· ΡπΡξΡΟÂγαστΞ�", + "About this editor": "ΠληΟÂΞÎΟ†ΞÎΟÂίΡς", + "Help using editor": "Ξ’ΞÎ�θΡια", + "Current style": "Ξ Ξ±ΟÂών στυλ", + "Undoes your last action": "ΑναίΟÂΡση τΡλΡυταίας ΡνέΟÂγΡιας", + "Redoes your last action": "ΕπαναφΞÎΟÂΞ¬ Ξ±Ο€ΟŒ Ξ±Ξ½Ξ±Ξ―ΟÂΡση", + "Cut selection": "ΑπΞÎΞΊΞÎπ�", + "Copy selection": "ΑντιγΟÂαφ�", + "Paste from clipboard": "Ξ•Ο€ΞΉΞΊΟŒΞ»Ξ»Ξ·ΟƒΞ·", + "Direction left to right": "ΞšΞ±Ο„Ξ΅ΟÂθυνση Ξ±ΟÂιστΡΟÂΞ¬ Ο€ΟÂΞÎΟ‚ δΡξιά", + "Direction right to left": "ΞšΞ±Ο„Ξ΅ΟÂθυνση Ξ±Ο€ΟŒ δΡξιά Ο€ΟÂΞÎΟ‚ τα Ξ±ΟÂιστΡΟÂΞ¬", + "OK": "OK", + "Cancel": "ΑκΟÂΟÂωση", + "Path": "ΔιαδΟÂΞÎΞΌΞ�", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "ΕίστΡ σΡ TEXT MODE. Ξ§ΟÂησιμΞÎΟ€ΞÎΞΉΞ�στΡ Ο„ΞΠΞΊΞÎυμπί [<>] Ξ³ΞΉΞ± Ξ½Ξ± ΡπανέΟÂθΡτΡ στΞΠWYSIWIG.", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "Ξ— κατάσταση πλΞ�ΟÂΞ·Ο‚ ΞÎΞΈΟŒΞ½Ξ·Ο‚ έχΡι Ο€ΟÂΞÎΞ²Ξ»Ξ�ματα ΞΌΞ΅ Ο„ΞÎΞ½ Internet Explorer, Ξ»ΟŒΞ³Ο‰ σφαλμάτων στΞÎΞ½ ίδιΞΠΟ„ΞÎΞ½ browser. Αν Ο„ΞΠΟƒΟÂστημα σας Ρίναι Windows 9x ΞΌΟ€ΞÎΟÂΡί ΞΊΞ±ΞΉ Ξ½Ξ± Ο‡ΟÂΡιαστΡίτΡ reboot. Αν ΡίστΡ σίγΞÎΟ…ΟÂΞÎΞΉ, πατΞ�στΡ ΟΚ.", + "Cancel": "ΑκΟÂΟÂωση", + "Insert/Modify Link": "ΕισαγωγΞ�/Ξ�ΟÂΞÎΟ€ΞÎΟ€ΞÎίηση ΟƒΟÂνδΡσμΞÎΟ…", + "New window (_blank)": "ΞÂΞ­ΞΠπαΟÂάθυΟÂΞΠ(_blank)", + "None (use implicit)": "Κανένα (Ο‡ΟÂΞ�ση Ξ±Ο€ΟŒΞ»Ο…Ο„ΞÎΟ…)", + "Other": "ΑλλΞÎ", + "Same frame (_self)": "ΊδιΞΠframe (_self)", + "Target:": "Target:", + "Title (tooltip):": "Ξ�ίτλΞÎΟ‚ (tooltip):", + "Top frame (_top)": "Πάνω frame (_top)", + "URL:": "URL:", + "You must enter the URL where this link points to": "Ξ ΟÂέπΡι Ξ½Ξ± ΡισάγΡτΡ Ο„ΞΠURL Ο€ΞÎΟ… ΞÎδηγΡί Ξ±Ο…Ο„ΟŒΟ‚ ΞΠΟƒΟÂνδΡσμΞÎΟ‚" +} diff --git a/mailboxes/xinha/lang/es.js b/mailboxes/xinha/lang/es.js new file mode 100644 index 000000000..e1ea5c11e --- /dev/null +++ b/mailboxes/xinha/lang/es.js @@ -0,0 +1,40 @@ +// I18N constants + +// LANG: "es", ENCODING: UTF-8 + +{ + "Bold": "Negrita", + "Italic": "Cursiva", + "Underline": "Subrayado", + "Strikethrough": "Tachado", + "Subscript": "Sub?ndice", + "Superscript": "Super?ndice", + "Justify Left": "Alinear a la Izquierda", + "Justify Center": "Centrar", + "Justify Right": "Alinear a la Derecha", + "Justify Full": "Justificar", + "Ordered List": "Lista Ordenada", + "Bulleted List": "Lista No Ordenada", + "Decrease Indent": "Aumentar Sangr?a", + "Increase Indent": "Disminuir Sangr?a", + "Font Color": "Color del Texto", + "Background Color": "Color del Fondo", + "Horizontal Rule": "L?nea Horizontal", + "Insert Web Link": "Insertar Enlace", + "Insert/Modify Image": "Insertar Imagen", + "Insert Table": "Insertar Tabla", + "Toggle HTML Source": "Ver Documento en HTML", + "Enlarge Editor": "Ampliar Editor", + "About this editor": "Acerca del Editor", + "Help using editor": "Ayuda", + "Current style": "Estilo Actual", + "Undoes your last action": "Deshacer", + "Redoes your last action": "Rehacer", + "Cut selection": "Cortar selecci?n", + "Copy selection": "Copiar selecci?n", + "Paste from clipboard": "Pegar desde el portapapeles", + "OK": "Aceptar", + "Cancel": "Cancelar", + "Path": "Ruta", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Esta en modo TEXTO. Use el boton [<>] para cambiar a WYSIWIG" +} diff --git a/mailboxes/xinha/lang/fa.js b/mailboxes/xinha/lang/fa.js new file mode 100644 index 000000000..106e83127 --- /dev/null +++ b/mailboxes/xinha/lang/fa.js @@ -0,0 +1,167 @@ +// I18N constants +// LANG: "fa", ENCODING: UTF-8 +{ + "Bold": "ضخیم", + "Italic": "مورب", + "Underline": "زیر خط", + "Strikethrough": "رو خط", + "Subscript": "زیروند", + "Superscript": "بالاوند", + "Justify Left": "تراز از Ú†Ù¾", + "Justify Center": "تراز در وسط", + "Justify Right": "تراز در راست", + "Justify Full": "تراز از Ú†Ù¾ Ùˆ راست", + "Ordered List": "Ùهرست مرتب", + "Bulleted List": "Ùهرست گلوله ای", + "Decrease Indent": "کاهش سر خط", + "Increase Indent": "Ø§ÙØ²Ø§ÛŒØ´ سر خط", + "Font Color": "رنگ Ùلم", + "Background Color": "رنگ پس زمینه", + "Horizontal Rule": "خط اÙÙ‚ÛŒ", + "Insert Web Link": "Ø§ÙØ²ÙˆØ¯Ù† لینک وب", + "Insert/Modify Image": "Ø§ÙØ²ÙˆØ¯Ù† یا ویرایش تصویر", + "Insert Table": "Ø§ÙØ²ÙˆØ¯Ù† جدول", + "Toggle HTML Source": "مشاهده یا عدم مشاهده متن در قالب HTML", + "Enlarge Editor": "بزرگ کردن ویرایش گر", + "About this editor": "درباره این ویرایش گر", + "Help using editor": "راهنمای Ø§Ø³ØªÙØ§Ø¯Ù‡ ویرایش گر", + "Current style": "شیوه کنونی", + "Undoes your last action": "برگرداندن آخرین عمل", + "Redoes your last action": "انجام مجدد آخرین عمل", + "Cut selection": "بریدن انتخاب شده", + "Copy selection": "Ú©Ù¾ÛŒ انتخاب شده", + "Paste from clipboard": "چسباندن از تخته کار", + "Direction left to right": "جهت از Ú†Ù¾ به راست", + "Direction right to left": "جهت از راست به Ú†Ù¾", + "Remove formatting": "Ø­Ø°Ù ÙØ±Ù…ت بندی", + "Select all": "انتخاب همه", + "Print document": "چاپ سند", + "Clear MSOffice tags": "پاک کردن متن از برچسب های MSOffice", + "Clear Inline Font Specifications": "پاک کردن متن از مشخصات Ùونت", + "Would you like to clear font typefaces?": "آیا تمایل دارید ظاهر Ùلم را پاک کنید؟", + "Would you like to clear font sizes?": "آیا تمایل دارید اندازه قلم را پاک کنید", + "Would you like to clear font colours?": "آیا تمایل دارید رنگ قلم را پاک کنید؟", + "Split Block": "بلاک جداسازی", + "Toggle Borders": "ÙØ¹Ø§Ù„/غیر ÙØ¹Ø§Ù„ کردن لبه ها", + "Save as": "ذخیره مانند...", + "Insert/Overwrite": "Ø§ÙØ²ÙˆØ¯Ù†/جانویسی", + "— format —": "— قالب —", + "Heading 1": "تیتر 1", + "Heading 2": "تیتر 2", + "Heading 3": "تیتر 3", + "Heading 4": "تیتر 4", + "Heading 5": "تیتر 5", + "Heading 6": "تیتر 6", + "Normal": "معمولی", + "Address": "آدرس", + "Formatted": "قالب بندی شده", + + //dialogs + "OK": "بله", + "Cancel": "انصراÙ", + "Path": "مسیر", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "در مد متنی هستید. از دکمه [<>] Ø§Ø³ØªÙØ§Ø¯Ù‡ نمایید تا به مد WYSIWYG برگردید.", + "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "دکمه چسباندن در مرورگرهای سری Mozilla کار نمی کند (به دلایل ÙÙ†ÛŒ امنیتی).برای چسباندن مستقیم ØŒ دکمه CTRL-V را در ØµÙØ­Ù‡ کلید بزنید.", + "Your Document is not well formed. Check JavaScript console for details.": "سند شما بدرستی قالب بندی نشده است. برای اطلاعات بیشتر پایانه نمایش جاوااسکریپت را بررسی کنید.", + + "Alignment:": "تراز بندی", + "Not set": "تنظیم نشده", + "Left": "Ú†Ù¾", + "Right": "راست", + "Texttop": "بالای متن", + "Absmiddle": "دقیقا وسط", + "Baseline": "ابتدای خط", + "Absbottom": "دقیقا پایین", + "Bottom": "پایین", + "Middle": "وسط", + "Top": "بالا", + + "Layout": "لایه", + "Spacing": "ÙØ§ØµÙ„Ù‡ گذاری", + "Horizontal:": "اÙÙ‚ÛŒ", + "Horizontal padding": "پرکننده اÙÙ‚ÛŒ", + "Vertical:": "عمودی", + "Vertical padding": "پرکننده عمودی", + "Border thickness:": "ضخامت لبه", + "Leave empty for no border": "برای بدون لبه خالی رها Ú©Ù†", + + //Insert Link + "Insert/Modify Link": "Ø§ÙØ²ÙˆØ¯Ù† / ویرایش لینک", + "None (use implicit)": "هیچکدام (Ø§Ø³ØªÙØ§Ø¯Ù‡ از بدون شرط)", + "New window (_blank)": "پنجره جدید (_blank)", + "Same frame (_self)": "ÙØ±ÛŒÙ… یکسان (_self)", + "Top frame (_top)": "ÙØ±ÛŒÙ… بالایی (_top)", + "Other": "سایر", + "Target:": "هدÙ", + "Title (tooltip):": "عنوان (راهنمای یک خطی)", + "URL:": "URL:", + "You must enter the URL where this link points to": "باید URLÛŒ Ú©Ù‡ این لینک به آن اشاره دارد را وارد کنید", + "You need to select some text before creating a link": "باید قبل از ساخت لینک ØŒ متنی را انتخاب نمایید", + + // Insert Table + "Insert Table": "Ø§ÙØ²ÙˆØ¯Ù† جدول", + "Rows:": "ردی٠ها", + "Number of rows": "تعداد ردی٠ها", + "Cols:": "ستون ها", + "Number of columns": "تعداد ستون ها", + "Width:": "طول", + "Width of the table": "طول جدول", + "Percent": "درصد", + "Pixels": "پیکسل ها", + "Em": "Em", + "Width unit": "واحد طول", + "Fixed width columns": "ستون های طول ثابت", + "Positioning of this table": "موقعیت یابی این جدول", + "Cell spacing:": "ÙØ§ØµÙ„Ù‡ سلول ها", + "Space between adjacent cells": "ÙØ§ØµÙ„Ù‡ بین سلول های همجوار", + "Cell padding:": "پر کننده سلول", + "Space between content and border in cell": "ÙØ§ØµÙ„Ù‡ بین محتوا Ùˆ لبه در سلول", + "You must enter a number of rows": "باید تعداد ردی٠ها را وارد کنید", + "You must enter a number of columns": "باید تعداد ستون ها را وارد کنید", + + // Insert Image + "Insert Image": "Ø§ÙØ²ÙˆØ¯Ù† تصویر", + "Image URL:": "URL تصویر", + "Enter the image URL here": "URL تصویر را اینجا وارد کنید", + "Preview": "پیش نمایش", + "Preview the image in a new window": "پیش نمایش تصویر در پنجره ای جدید", + "Alternate text:": "متن جایگزین", + "For browsers that don't support images": "برای مرورگرهایی Ú©Ù‡ از تصاویر پشتیبانی نمی کنند", + "Positioning of this image": "موقعیت یابی تصویر", + "Image Preview:": "پیش نمایش تصویر", + "You must enter the URL": "شما باید URL را وارد کنید", + + // toolbar + "button_bold": "fr/bold.gif", + "button_underline": "fr/underline.gif", + "button_strikethrough": "fr/strikethrough.gif", + + // Editor Help + "Xinha Help": "راهنمای Xinha", + "Editor Help": "راهنمای ویرایشگر", + "Keyboard shortcuts": "میانبرهای ØµÙØ­Ù‡ کلید", + "The editor provides the following key combinations:": "ویرایشگر Ø§Ø³ØªÙØ§Ø¯Ù‡ از کلید های گروهی زیر را مسیر Ù…ÛŒ سازد :", + "ENTER": "ENTREE", + "new paragraph": "پاراگرا٠جدید", + "SHIFT-ENTER": "SHIFT+ENTREE", + "insert linebreak": "Ø§ÙØ²ÙˆØ¯Ù† جدا کننده خط", + "Set format to paragraph": "تغییر قالب به پاراگراÙ", + "Clean content pasted from Word": "تمیز کردن محتوای چسبانده شده از Word", + "Headings": "عنوان گذاری", + "Close": "بستن", + + // Loading messages + "Loading in progress. Please wait !": "بارگذاری در حال انجام است. Ù„Ø·ÙØ§ صبر کنید !", + "Constructing main object": "ساختن شیء اصلی", + "Constructing object": "ساختن شیء", + "Register panel right": "ثبت قاب راست", + "Register panel left": "ثبت قاب Ú†Ù¾", + "Register panel top": "ثبت قاب بالا", + "Register panel bottom": "ثبت قاب پایین", + "Create Toolbar": "ساخت نوار ابزار", + "Create StatusBar": "ساخت نوار وضعیت", + "Generate Xinha object": "تولید شیء Xinha", + "Init editor size": "مقدار دهی اندازه ویرایشگر", + "Init IFrame": "مقدار دهی IFrame", + "Register plugin $plugin": "ثبت پلاگین $plugin" +}; \ No newline at end of file diff --git a/mailboxes/xinha/lang/fi.js b/mailboxes/xinha/lang/fi.js new file mode 100644 index 000000000..0297c7849 --- /dev/null +++ b/mailboxes/xinha/lang/fi.js @@ -0,0 +1,38 @@ +// I18N constants + +// LANG: "en", ENCODING: UTF-8 + +{ + "Bold": "Lihavoitu", + "Italic": "Kursivoitu", + "Underline": "Alleviivattu", + "Strikethrough": "Yliviivattu", + "Subscript": "Alaindeksi", + "Superscript": "Yläindeksi", + "Justify Left": "Tasaa vasemmat reunat", + "Justify Center": "Keskitä", + "Justify Right": "Tasaa oikeat reunat", + "Justify Full": "Tasaa molemmat reunat", + "Ordered List": "Numerointi", + "Bulleted List": "Luettelomerkit", + "Decrease Indent": "Pienennä sisennystä", + "Increase Indent": "Lisää sisennystä", + "Font Color": "Fontin väri", + "Background Color": "Taustaväri", + "Horizontal Rule": "Vaakaviiva", + "Insert Web Link": "Lisää linkki", + "Insert/Modify Image": "Lisää kuva", + "Insert Table": "Lisää taulukko", + "Toggle HTML Source": "HTML-lähdekoodi vs WYSIWYG", + "Enlarge Editor": "Suurenna editori", + "About this editor": "Tietoja editorista", + "Help using editor": "Näytä ohje", + "Current style": "Nykyinen tyyli", + "Undoes your last action": "Peruuta viimeinen toiminto", + "Redoes your last action": "Palauta viimeinen toiminto", + "Cut selection": "Leikkaa maalattu", + "Copy selection": "Kopioi maalattu", + "Paste from clipboard": "Liitä leikepyödältä", + "OK": "Hyväksy", + "Cancel": "Peruuta" +} diff --git a/mailboxes/xinha/lang/fr.js b/mailboxes/xinha/lang/fr.js new file mode 100644 index 000000000..c338846fb --- /dev/null +++ b/mailboxes/xinha/lang/fr.js @@ -0,0 +1,167 @@ +// I18N constants +// LANG: "fr", ENCODING: UTF-8 +{ + "Bold": "Gras", + "Italic": "Italique", + "Underline": "Souligné", + "Strikethrough": "Barré", + "Subscript": "Indice", + "Superscript": "Exposant", + "Justify Left": "Aligner à gauche", + "Justify Center": "Centrer", + "Justify Right": "Aligner à droite", + "Justify Full": "Justifier", + "Ordered List": "Liste numérotée", + "Bulleted List": "Liste à puces", + "Decrease Indent": "Diminuer le retrait", + "Increase Indent": "Augmenter le retrait", + "Font Color": "Couleur de police", + "Background Color": "Surlignage", + "Horizontal Rule": "Ligne horizontale", + "Insert Web Link": "Insérer un lien", + "Insert/Modify Image": "Insérer / Modifier une image", + "Insert Table": "Insérer un tableau", + "Toggle HTML Source": "Afficher / Masquer code source", + "Enlarge Editor": "Agrandir l'éditeur", + "About this editor": "A propos", + "Help using editor": "Aide", + "Current style": "Style courant", + "Undoes your last action": "Annuler la dernière action", + "Redoes your last action": "Répéter la dernière action", + "Cut selection": "Couper la sélection", + "Copy selection": "Copier la sélection", + "Paste from clipboard": "Coller depuis le presse-papier", + "Direction left to right": "Direction de gauche à droite", + "Direction right to left": "Direction de droite à gauche", + "Remove formatting": "Supprimer mise en forme", + "Select all": "Tout sélectionner", + "Print document": "Imprimer document", + "Clear MSOffice tags": "Supprimer tags MSOffice", + "Clear Inline Font Specifications": "Supprimer paramètres inline de la police", + "Would you like to clear font typefaces?": "Voulez-vous supprimer les types ?", + "Would you like to clear font sizes?": "Voulez-vous supprimer les tailles ?", + "Would you like to clear font colours?": "Voulez-vous supprimer les couleurs ?", + "Split Block": "Séparer les blocs", + "Toggle Borders": "Afficher / Masquer les bordures", + "Save as": "Enregistrer sous", + "Insert/Overwrite": "Insertion / Remplacement", + "— format —": "— Format —", + "Heading 1": "Titre 1", + "Heading 2": "Titre 2", + "Heading 3": "Titre 3", + "Heading 4": "Titre 4", + "Heading 5": "Titre 5", + "Heading 6": "Titre 6", + "Normal": "Normal", + "Address": "Adresse", + "Formatted": "Formaté", + + //dialogs + "OK": "OK", + "Cancel": "Annuler", + "Path": "Chemin", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Vous êtes en MODE TEXTE. Appuyez sur le bouton [<>] pour retourner au mode WYSIWYG.", + "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "Le bouton Coller ne fonctionne pas sur les navigateurs basés sur Mozilla (pour des raisons de sécurité). Pressez CTRL-V au clavier pour coller directement.", + "Your Document is not well formed. Check JavaScript console for details.": "Le document est mal formé. Vérifiez la console JavaScript pour plus de détails.", + + "Alignment:": "Alignement", + "Not set": "Indéfini", + "Left": "Gauche", + "Right": "Droite", + "Texttop": "Texttop", + "Absmiddle": "Absmiddle", + "Baseline": "Baseline", + "Absbottom": "Absbottom", + "Bottom": "Bas", + "Middle": "Milieu", + "Top": "Haut", + + "Layout": "Mise en page", + "Spacing": "Espacement", + "Horizontal:": "Horizontal", + "Horizontal padding": "Marge horizontale interne", + "Vertical:": "Vertical", + "Vertical padding": "Marge verticale interne", + "Border thickness:": "Epaisseur de bordure", + "Leave empty for no border": "Laisser vide pour pas de bordure", + + //Insert Link + "Insert/Modify Link": "Insérer / Modifier un lien", + "None (use implicit)": "Aucune (implicite)", + "New window (_blank)": "Nouvelle fenêtre (_blank)", + "Same frame (_self)": "Même frame (_self)", + "Top frame (_top)": "Frame principale (_top)", + "Other": "Autre", + "Target:": "Cible", + "Title (tooltip):": "Texte alternatif", + "URL:": "URL:", + "You must enter the URL where this link points to": "Vous devez entrer l'URL de ce lien", + "You need to select some text before creating a link": "Vous devez sélectionner du texte avant de créer un lien", + + // Insert Table + "Insert Table": "Insérer un tableau", + "Rows:": "Lignes", + "Number of rows": "Nombre de lignes", + "Cols:": "Colonnes", + "Number of columns": "Nombre de colonnes", + "Width:": "Largeur", + "Width of the table": "Largeur du tableau", + "Percent": "Pourcent", + "Pixels": "Pixels", + "Em": "Em", + "Width unit": "Unités de largeur", + "Fixed width columns": "Colonnes à taille fixe", + "Positioning of this table": "Position du tableau", + "Cell spacing:": "Espacement", + "Space between adjacent cells": "Espace entre les cellules adjacentes", + "Cell padding:": "Marge interne", + "Space between content and border in cell": "Espace entre le contenu et la bordure d'une cellule", + "You must enter a number of rows": "Vous devez entrer le nombre de lignes", + "You must enter a number of columns": "Vous devez entrer le nombre de colonnes", + + // Insert Image + "Insert Image": "Insérer une image", + "Image URL:": "URL image", + "Enter the image URL here": "Entrer l'URL de l'image ici", + "Preview": "Prévisualiser", + "Preview the image in a new window": "Prévisualiser l'image dans une nouvelle fenêtre", + "Alternate text:": "Texte alternatif", + "For browsers that don't support images": "Pour les navigateurs qui ne supportent pas les images", + "Positioning of this image": "Position de l'image", + "Image Preview:": "Prévisualisation", + "You must enter the URL": "Vous devez entrer l'URL", + + // toolbar + "button_bold": "fr/bold.gif", + "button_underline": "fr/underline.gif", + "button_strikethrough": "fr/strikethrough.gif", + + // Editor Help + "Xinha Help": "Aide Xinha", + "Editor Help": "Aide de l'éditeur", + "Keyboard shortcuts": "Raccourcis clavier", + "The editor provides the following key combinations:": "L'éditeur fournit les combinaisons de touches suivantes :", + "ENTER": "ENTREE", + "new paragraph": "Nouveau paragraphe", + "SHIFT-ENTER": "SHIFT+ENTREE", + "insert linebreak": "Insère un saut de ligne", + "Set format to paragraph": "Applique le format paragraphe", + "Clean content pasted from Word": "Nettoyage du contenu copié depuis Word", + "Headings": "Titres", + "Close": "Fermer", + + // Loading messages + "Loading in progress. Please wait !": "Chargement en cours. Veuillez patienter !", + "Constructing main object": "Construction de l'objet principal", + "Constructing object": "Construction de l'objet", + "Register panel right": "Enregistrement du panneau droit", + "Register panel left": "Enregistrement du panneau gauche", + "Register panel top": "Enregistrement du panneau supérieur", + "Register panel bottom": "Enregistrement du panneau inférieur", + "Create Toolbar": "Construction de la barre d'icones", + "Create StatusBar": "Construction de la barre de status", + "Generate Xinha object": "Génération de l'objet Xinha", + "Init editor size": "Initialisation de la taille d'édition", + "Init IFrame": "Initialisation de l'iframe", + "Register plugin $plugin": "Enregistrement du plugin $plugin" +}; \ No newline at end of file diff --git a/mailboxes/xinha/lang/gb.js b/mailboxes/xinha/lang/gb.js new file mode 100644 index 000000000..d3c8df83b --- /dev/null +++ b/mailboxes/xinha/lang/gb.js @@ -0,0 +1,29 @@ +// I18N constants -- Chinese GB +// by Dave Lo -- dlo@interactivetools.com +{ + "Bold": "粗体", + "Italic": "斜体", + "Underline": "底线", + "Strikethrough": "删除线", + "Subscript": "下标", + "Superscript": "上标", + "Justify Left": "ä½ç½®é å·¦", + "Justify Center": "ä½ç½®å±…中", + "Justify Right": "ä½ç½®é å³", + "Justify Full": "ä½ç½®å·¦å³å¹³ç­‰", + "Ordered List": "é¡ºåºæ¸…å•", + "Bulleted List": "æ— åºæ¸…å•", + "Decrease Indent": "å‡å°è¡Œå‰ç©ºç™½", + "Increase Indent": "加宽行å‰ç©ºç™½", + "Font Color": "文字颜色", + "Background Color": "背景颜色", + "Horizontal Rule": "水平线", + "Insert Web Link": "æ’入连结", + "Insert/Modify Image": "æ’入图形", + "Insert Table": "æ’入表格", + "Toggle HTML Source": "切æ¢HTML原始ç ", + "Enlarge Editor": "放大", + "About this editor": "关於 HTMLArea", + "Help using editor": "说明", + "Current style": "字体例å­" +} diff --git a/mailboxes/xinha/lang/he.js b/mailboxes/xinha/lang/he.js new file mode 100644 index 000000000..60dbd7658 --- /dev/null +++ b/mailboxes/xinha/lang/he.js @@ -0,0 +1,64 @@ +// I18N constants + +// LANG: "he", ENCODING: UTF-8 +// Author: Liron Newman, http://www.eesh.net, + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "מודגש", + "Italic": "נטוי", + "Underline": "קו תחתי", + "Strikethrough": "קו ×מצע", + "Subscript": "כתב עילי", + "Superscript": "כתב תחתי", + "Justify Left": " ישור לשמ×ל", + "Justify Center": "ישור למרכז", + "Justify Right": "ישור לימין", + "Justify Full": "ישור לשורה מל××”", + "Ordered List": "רשימה ממוספרת", + "Bulleted List": "רשימה ×œ× ×ž×ž×•×¡×¤×¨×ª", + "Decrease Indent": "הקטן כניסה", + "Increase Indent": "הגדל כניסה", + "Font Color": "צבע גופן", + "Background Color": "צבע רקע", + "Horizontal Rule": "קו ×× ×›×™", + "Insert Web Link": "הכנס היפר-קישור", + "Insert/Modify Image": "הכנס/שנה תמונה", + "Insert Table": "הכנס טבלה", + "Toggle HTML Source": "שנה מצב קוד HTML", + "Enlarge Editor": "הגדל ×ת העורך", + "About this editor": "×ודות עורך ×–×”", + "Help using editor": "עזרה לשימוש בעורך", + "Current style": "סגנון נוכחי", + "Undoes your last action": "מבטל ×ת פעולתך ×”×חרונה", + "Redoes your last action": "מבצע מחדש ×ת הפעולה ×”×חרונה שביטלת", + "Cut selection": "גזור בחירה", + "Copy selection": "העתק בחירה", + "Paste from clipboard": "הדבק מהלוח", + "Direction left to right": "כיוון משמ×ל לימין", + "Direction right to left": "כיוון מימין לשמ×ל", + "OK": "×ישור", + "Cancel": "ביטול", + "Path": "נתיב עיצוב", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "×תה במצב טקסט × ×§×™ (קוד). השתמש בכפתור [<>] כדי לחזור למצב WYSIWYG (תצוגת עיצוב).", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "מצב מסך ×ž×œ× ×™×•×¦×¨ בעיות בדפדפן Internet Explorer, עקב ב××’×™× ×‘×“×¤×“×¤×Ÿ ×œ× ×™×›×•×œ× ×• לפתור ×ת ×–×”. ×ת/×” עלול/×” לחוות תצוגת זבל, בעיות בתפקוד העורך ו/×ו קריסה של הדפדפן. ×× ×”×ž×¢×¨×›×ª שלך ×”×™× Windows 9x סביר להניח שתקבל/×™ ", + "Cancel": "ביטול", + "Insert/Modify Link": "הוסף/שנה קישור", + "New window (_blank)": "חלון חדש (_blank)", + "None (use implicit)": "×œ×œ× (השתמש ב-frame ×”×§×™×™×)", + "Other": "×חר", + "Same frame (_self)": "×ותו frame (_self)", + "Target:": "יעד:", + "Title (tooltip):": "כותרת (tooltip):", + "Top frame (_top)": "Frame עליון (_top)", + "URL:": "URL:", + "You must enter the URL where this link points to": "חובה לכתוב URL ש×ליו קישור ×–×” מצביע" +} diff --git a/mailboxes/xinha/lang/hu.js b/mailboxes/xinha/lang/hu.js new file mode 100644 index 000000000..75c541c06 --- /dev/null +++ b/mailboxes/xinha/lang/hu.js @@ -0,0 +1,64 @@ +// I18N constants + +// LANG: "hu", ENCODING: UTF-8 +// Author: Miklós Somogyi, + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "Félkövér", + "Italic": "DÅ‘lt", + "Underline": "Aláhúzott", + "Strikethrough": "Ãthúzott", + "Subscript": "Alsó index", + "Superscript": "FelsÅ‘ index", + "Justify Left": "Balra zárt", + "Justify Center": "Középre zárt", + "Justify Right": "Jobbra zárt", + "Justify Full": "Sorkizárt", + "Ordered List": "Számozott lista", + "Bulleted List": "Számozatlan lista", + "Decrease Indent": "Behúzás csökkentése", + "Increase Indent": "Behúzás növelése", + "Font Color": "Karakterszín", + "Background Color": "Háttérszín", + "Horizontal Rule": "Elválasztó vonal", + "Insert Web Link": "Hiperhivatkozás beszúrása", + "Insert/Modify Image": "Kép beszúrása", + "Insert Table": "Táblázat beszúrása", + "Toggle HTML Source": "HTML forrás be/ki", + "Enlarge Editor": "SzerkesztÅ‘ külön ablakban", + "About this editor": "Névjegy", + "Help using editor": "Súgó", + "Current style": "Aktuális stílus", + "Undoes your last action": "Visszavonás", + "Redoes your last action": "Újra végrehajtás", + "Cut selection": "Kivágás", + "Copy selection": "Másolás", + "Paste from clipboard": "Beillesztés", + "Direction left to right": "Irány balról jobbra", + "Direction right to left": "Irány jobbról balra", + "OK": "Rendben", + "Cancel": "Mégsem", + "Path": "Hierarchia", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Forrás mód. Visszaváltás [<>] gomb", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "A teljesképrenyÅ‘s szerkesztés hibát okozhat Internet Explorer használata esetén, ez a böngészÅ‘ a hibája, amit nem tudunk kikerülni. Szemetet észlelhet a képrenyÅ‘n, illetve néhány funkció hiányozhat és/vagy véletlenszerűen lefagyhat a böngészÅ‘. Windows 9x operaciós futtatása esetén elég valószínű, hogy ", + "Cancel": "Mégsem", + "Insert/Modify Link": "Hivatkozás Beszúrása/Módosítása", + "New window (_blank)": "Új ablak (_blank)", + "None (use implicit)": "Nincs (use implicit)", + "Other": "Más", + "Same frame (_self)": "Ugyanabba a keretbe (_self)", + "Target:": "Cél:", + "Title (tooltip):": "Cím (tooltip):", + "Top frame (_top)": "FelsÅ‘ keret (_top)", + "URL:": "URL:", + "You must enter the URL where this link points to": "Be kell írnia az URL-t, ahova a hivatkozás mutasson" +} diff --git a/mailboxes/xinha/lang/it.js b/mailboxes/xinha/lang/it.js new file mode 100644 index 000000000..426e74c92 --- /dev/null +++ b/mailboxes/xinha/lang/it.js @@ -0,0 +1,55 @@ +// I18N constants + +// LANG: "it", ENCODING: UTF-8 +// Author: Mattia Landoni, http://www.webpresident.org/ + +{ + "Bold": "Grassetto", + "Italic": "Corsivo", + "Underline": "Sottolineato", + "Strikethrough": "Barrato", + "Subscript": "Pedice", + "Superscript": "Apice", + "Justify Left": "Sinistra", + "Justify Center": "Centrato", + "Justify Right": "Destra", + "Justify Full": "Giustificato", + "Ordered List": "Lista numerata", + "Bulleted List": "Lista non numerata", + "Decrease Indent": "Diminuisci indentazione", + "Increase Indent": "Aumenta indentazione", + "Font Color": "Colore font", + "Background Color": "Colore sfondo", + "Horizontal Rule": "Righello orizzontale", + "Insert Web Link": "Inserisci link", + "Insert/Modify Image": "Inserisci/modifica Immagine", + "Insert Table": "Inserisci tabella", + "Toggle HTML Source": "Visualizza/nascondi sorgente HTML", + "Enlarge Editor": "Allarga editor", + "About this editor": "Informazioni su HTMLArea", + "Help using editor": "Aiuto", + "Current style": "Stile corrente", + "Undoes your last action": "Annulla ultima azione", + "Redoes your last action": "Ripeti ultima azione", + "Cut selection": "Taglia", + "Copy selection": "Copia", + "Paste from clipboard": "Incolla", + "Direction left to right": "Testo da sx a dx", + "Direction right to left": "Testo da dx a sx", + "OK": "OK", + "Cancel": "Annulla", + "Path": "Percorso", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Sei in MODALITA", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "E", + "Cancel": "Annulla", + "Insert/Modify Link": "Inserisci/modifica link", + "New window (_blank)": "Nuova finestra (_blank)", + "None (use implicit)": "Niente (usa implicito)", + "Other": "Altro", + "Same frame (_self)": "Stessa frame (_self)", + "Target:": "Target:", + "Title (tooltip):": "Title (suggerimento):", + "Top frame (_top)": "Pagina intera (_top)", + "URL:": "URL:", + "You must enter the URL where this link points to": "Devi inserire l'indirizzo a cui punta il link" +} diff --git a/mailboxes/xinha/lang/ja.js b/mailboxes/xinha/lang/ja.js new file mode 100644 index 000000000..b2d927da2 --- /dev/null +++ b/mailboxes/xinha/lang/ja.js @@ -0,0 +1,169 @@ +// I18N constants +// LANG: "ja", ENCODING: UTF-8N + +{ + "Bold": "太字", + "Italic": "斜体", + "Underline": "下線", + "Strikethrough": "æ‰“ã¡æ¶ˆã—ç·š", + "Subscript": "ä¸‹ä»˜ãæ·»ãˆå­—", + "Superscript": "ä¸Šä»˜ãæ·»ãˆå­—", + "Justify Left": "左寄ã›", + "Justify Center": "中央寄ã›", + "Justify Right": "å³å¯„ã›", + "Justify Full": "å‡ç­‰å‰²ä»˜", + "Ordered List": "番å·ä»˜ãç®‡æ¡æ›¸ã", + "Bulleted List": "記å·ä»˜ãç®‡æ¡æ›¸ã", + "Decrease Indent": "インデント解除", + "Increase Indent": "インデント設定", + "Font Color": "文字色", + "Background Color": "背景色", + "Horizontal Rule": "水平線", + "Insert Web Link": "ãƒªãƒ³ã‚¯ã®æŒ¿å…¥", + "Insert/Modify Image": "ç”»åƒã®æŒ¿å…¥/修正", + "Insert Table": "テーブルを挿入", + "Toggle HTML Source": "HTML編集モードを切替", + "Enlarge Editor": "エディタを最大化", + "About this editor": "ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…å ±", + "Help using editor": "ヘルプ", + "Current style": "ç¾åœ¨ã®ã‚¹ã‚¿ã‚¤ãƒ«", + "Undoes your last action": "å…ƒã«æˆ»ã™", + "Redoes your last action": "やり直ã—", + "Cut selection": "切りå–り", + "Copy selection": "コピー", + "Paste from clipboard": "貼り付ã‘", + "Direction left to right": "å·¦ã‹ã‚‰å³ã¸", + "Direction right to left": "å³ã‹ã‚‰å·¦ã¸", + "Remove formatting": "書å¼å‰Šé™¤", + "Select all": "ã™ã¹ã¦é¸æŠž", + "Print document": "å°åˆ·", + "Clear MSOffice tags": "MSOfficeタグをクリア", + "Clear Inline Font Specifications": "インラインフォント指定をクリア", + "Would you like to clear font typefaces?": "フォントåをクリアã—ã¾ã™ã‹?", + "Would you like to clear font sizes?": "サイズをクリアã—ã¾ã™ã‹?", + "Would you like to clear font colours?": "色をクリアã—ã¾ã™ã‹?", + "Split Block": "領域分割", + "Toggle Borders": "境界線ã®åˆ‡æ›¿", + "Save as": "åå‰ã‚’ã¤ã‘ã¦ä¿å­˜", + "Insert/Overwrite": "挿入/上書ã", + "— format —": "— æ›¸å¼ —", + "Heading 1": "見出ã—1", + "Heading 2": "見出ã—2", + "Heading 3": "見出ã—3", + "Heading 4": "見出ã—4", + "Heading 5": "見出ã—5", + "Heading 6": "見出ã—6", + "Normal": "標準", + "Address": "アドレス", + "Formatted": "整形済ã¿", + "— font —": "— フォント —", + "— size —": "— サイズ —", + + //dialogs + "OK": "OK", + "Cancel": "中止", + "Path": "パス", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "ãƒ†ã‚­ã‚¹ãƒˆãƒ¢ãƒ¼ãƒ‰ã§æ“作ã—ã¦ã„ã¾ã™ã€‚WYSIWYGç·¨é›†ã«æˆ»ã‚‹ã«ã¯[<>]ボタンを使ã£ã¦ãã ã•ã„。", + "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "Mozillaベースã®Webブラウザã§ã¯ã€è²¼ã‚Šä»˜ã‘ãƒœã‚¿ãƒ³ã¯æ©Ÿèƒ½ã—ã¾ã›ã‚“(技術的ãªã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ä¸Šã®ç†ç”±ã§ï¼‰ã€‚Ctrl+Vキーを押ã—ã¦ç›´æŽ¥è²¼ã‚Šä»˜ã‘ã¦ãã ã•ã„。", + "Your Document is not well formed. Check JavaScript console for details.": "ã“ã®æ–‡æ›¸ã«ã¯æ§‹æ–‡çš„ãªå•題ãŒã‚りã¾ã™ã€‚詳細ã¯JavaScriptコンソールをå‚ç…§ã—ã¦ãã ã•ã„。", + "You need to select some text before creating a link": "リンクを作æˆã™ã‚‹ã«ã¯ãƒ†ã‚­ã‚¹ãƒˆã‚’é¸æŠžã™ã‚‹å¿…è¦ãŒã‚りã¾ã™", + + "Alignment:": "行æƒãˆ:", + "Not set": "ãªã—", + "Left": "å·¦", + "Right": "å³", + "Texttop": "テキスト上部", + "Absmiddle": "中央(絶対的)", + "Baseline": "ベースライン", + "Absbottom": "下(絶対的)", + "Bottom": "下", + "Middle": "中央", + "Top": "上", + + "Layout": "レイアウト", + "Spacing": "é–“éš”", + "Horizontal:": "æ°´å¹³:", + "Horizontal padding": "水平余白", + "Vertical:": "垂直:", + "Vertical padding": "垂直余白", + "Border thickness:": "境界線ã®å¤ªã•:", + "Leave empty for no border": "境界線ãŒãªã„å ´åˆã¯ç©ºã®ã¾ã¾ã«ã™ã‚‹", + + //Insert Link + "Insert/Modify Link": "ãƒªãƒ³ã‚¯ã®æŒ¿å…¥/修正", + "None (use implicit)": "ãªã— (デフォルトã«ä»»ã›ã‚‹)", + "New window (_blank)": "æ–°ã—ã„ウィンドウ (_blank)", + "Same frame (_self)": "自己フレーム内 (_self)", + "Top frame (_top)": "最上ä½ãƒ•レーム (_top)", + "Other": "ãã®ä»–", + "Target:": "ターゲット:", + "Title (tooltip):": "タイトル:", + "URL:": "URL:", + "You must enter the URL where this link points to": "ã“ã®ãƒªãƒ³ã‚¯ãŒæŒ‡ã—示ã™URLを入力ã—ã¦ãã ã•ã„", + + // Insert Table + "Insert Table": "ãƒ†ãƒ¼ãƒ–ãƒ«ã®æŒ¿å…¥", + "Rows:": "行:", + "Number of rows": "行数", + "Cols:": "列:", + "Number of columns": "列数", + "Width:": "å¹…:", + "Width of the table": "テーブルã®å¹…", + "Percent": "パーセント(%)", + "Pixels": "ピクセル(px)", + "Em": "相対値(em)", + "Width unit": "å¹…ã®å˜ä½", + "Fixed width columns": "列ã®å¹…を固定", + "Positioning of this table": "ã“ã®ãƒ†ãƒ¼ãƒ–ルã®é…ç½®", + "Cell spacing:": "セル間隔:", + "Space between adjacent cells": "隣接ã™ã‚‹ã‚»ãƒ«é–“ã®è·é›¢", + "Cell padding:": "セル余白:", + "Space between content and border in cell": "セル内ã«ãŠã‘る内容ã¨å¢ƒç•Œç·šã¨ã®è·é›¢", + "You must enter a number of rows": "行数を入力ã—ã¦ãã ã•ã„", + "You must enter a number of columns": "列数を入力ã—ã¦ãã ã•ã„", + + // Insert Image + "Insert Image": "ç”»åƒã®æŒ¿å…¥", + "Image URL:": "ç”»åƒURL:", + "Enter the image URL here": "ç”»åƒã®URLã‚’ã“ã“ã«å…¥åŠ›ã—ã¾ã™", + "Preview": "表示", + "Preview the image in a new window": "ウィンドウã§ç”»åƒã‚’表示", + "Alternate text:": "代替テキスト:", + "For browsers that don't support images": "ç”»åƒè¡¨ç¤ºã‚’サãƒãƒ¼ãƒˆã—ãªã„ブラウザã«å¿…è¦ã§ã™", + "Positioning of this image": "ç”»åƒã®é…ç½®", + "Image Preview:": "ç”»åƒè¡¨ç¤º:", + "You must enter the URL": "URLを入力ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™", + + //"button_bold": "fr/bold.gif", + //"button_underline": "fr/underline.gif", + //"button_strikethrough": "fr/strikethrough.gif", + + // Editor Help + "Xinha Help": "ヘルプ", + "Editor Help": "エディタã®ãƒ˜ãƒ«ãƒ—", + "Keyboard shortcuts": "キーボードショートカット", + "The editor provides the following key combinations:": "エディタã¯ä»¥ä¸‹ã®ã‚­ãƒ¼æ“作をæä¾›ã—ã¦ã„ã¾ã™:", + "ENTER": "ENTER", + "new paragraph": "æ–°è¦æ®µè½", + "SHIFT-ENTER": "SHIFT+ENTER", + "insert linebreak": "段è½å†…æ”¹è¡Œã®æŒ¿å…¥", + "Set format to paragraph": "æ®µè½æ›¸å¼ã®è¨­å®š", + "Clean content pasted from Word": "Wordã‹ã‚‰è²¼ã‚Šä»˜ã‘られãŸå†…å®¹ã®æ¸…書", + "Headings": "見出ã—", + "Close": "é–‰ã˜ã‚‹", + + // Loading messages + "Loading in progress. Please wait !": "ロード中ã§ã™ã€‚ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„", + "Constructing main object": "æ§‹æˆä¸­ main object", + "Constructing object": "æ§‹æˆä¸­ object", + "Register panel right": "登録 å³ãƒ‘ãƒãƒ«", + "Register panel left": "登録 左パãƒãƒ«", + "Register panel top": "登録 上パãƒãƒ«", + "Register panel bottom": "登録 下パãƒãƒ«", + "Create Toolbar": "ä½œæˆ ãƒ„ãƒ¼ãƒ«ãƒãƒ¼", + "Create StatusBar": "ä½œæˆ ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãƒãƒ¼", + "Generate Xinha object": "ç”Ÿæˆ Xinha object", + "Init editor size": "åˆæœŸåŒ– エディタã®ã‚µã‚¤ã‚º", + "Init IFrame": "åˆæœŸåŒ– IFrame", + "Register plugin $plugin": "プラグインã®ç™»éŒ² $plugin" +}; \ No newline at end of file diff --git a/mailboxes/xinha/lang/lt.js b/mailboxes/xinha/lang/lt.js new file mode 100644 index 000000000..12356762e --- /dev/null +++ b/mailboxes/xinha/lang/lt.js @@ -0,0 +1,53 @@ +// I18N constants + +// LANG: "lt", ENCODING: UTF-8 +// Author: Jaroslav Å atkeviÄ, + +{ + "Bold": "ParyÅ¡kinti", + "Italic": "Kursyvas", + "Underline": "Pabraukti", + "Strikethrough": "Perbraukti", + "Subscript": "Apatinis indeksas", + "Superscript": "VirÅ¡utinis indeksas", + "Justify Left": "Lygiavimas pagal kairÄ™", + "Justify Center": "Lygiavimas pagal centrÄ…", + "Justify Right": "Lygiavimas pagal deÅ¡inÄ™", + "Justify Full": "Lygiuoti pastraipÄ…", + "Ordered List": "Numeruotas sÄ…raÅ¡as", + "Bulleted List": "Suženklintas sÄ…raÅ¡as", + "Decrease Indent": "Sumažinti paraÅ¡tÄ™", + "Increase Indent": "Padidinti paraÅ¡tÄ™", + "Font Color": "Å rifto spalva", + "Background Color": "Fono spalva", + "Horizontal Rule": "Horizontali linija", + "Insert Web Link": "Ä®terpti nuorodÄ…", + "Insert/Modify Image": "Ä®terpti paveiksliukÄ…", + "Insert Table": "Ä®terpti lentelÄ™", + "Toggle HTML Source": "Perjungti į HTML/WYSIWYG", + "Enlarge Editor": "IÅ¡plÄ—stas redagavimo ekranas/Enlarge Editor", + "About this editor": "Apie redaktorių", + "Help using editor": "Pagalba naudojant redaktorių", + "Current style": "Dabartinis stilius", + "Undoes your last action": "AtÅ¡aukia paskutini jÅ«sų veiksmÄ…", + "Redoes your last action": "Pakartoja paskutinį atÅ¡auktÄ… jÅ«sų veiksmÄ…", + "Cut selection": "IÅ¡kirpti", + "Copy selection": "Kopijuoti", + "Paste from clipboard": "Ä®terpti", + "OK": "OK", + "Cancel": "AtÅ¡aukti", + "Path": "Kelias", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "JÅ«s esete teksto režime. Naudokite [<>] mygtukÄ… grįžimui į WYSIWYG.", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren", + "Cancel": "AtÅ¡aukti", + "Insert/Modify Link": "IdÄ—ti/Modifikuoti", + "New window (_blank)": "Naujas langas (_blank)", + "None (use implicit)": "None (use implicit)", + "Other": "Kitas", + "Same frame (_self)": "Same frame (_self)", + "Target:": "Target:", + "Title (tooltip):": "Pavadinimas (tooltip):", + "Top frame (_top)": "Top frame (_top)", + "URL:": "URL:", + "You must enter the URL where this link points to": "Jus privalote nurodyti URL į kuri rodo Å¡itÄ… nuoroda" +} diff --git a/mailboxes/xinha/lang/lv.js b/mailboxes/xinha/lang/lv.js new file mode 100644 index 000000000..b24593d95 --- /dev/null +++ b/mailboxes/xinha/lang/lv.js @@ -0,0 +1,42 @@ +// I18N constants + +// LANG: "lv", ENCODING: UTF-8 +// Author: Mihai Bazon, http://dynarch.com/mishoo +// Translated by: Janis Klavins, + +{ + "Bold": "Trekniem burtiem", + "Italic": "Kursîvâ", + "Underline": "Pasvîtrots", + "Strikethrough": "Pârsvîtrots", + "Subscript": "Novietot zem rindas", + "Superscript": "Novietot virs rindas", + "Justify Left": "Izlîdzinât pa kreisi", + "Justify Center": "Izlîdzinât centrâ", + "Justify Right": "Izlîdzinât pa labi", + "Justify Full": "Izlîdzinât pa visu lapu", + "Ordered List": "Numurçts saraksts", + "Bulleted List": "Saraksts", + "Decrease Indent": "Samazinât atkâpi", + "Increase Indent": "Palielinât atkâpi", + "Font Color": "Burtu krâsa", + "Background Color": "Fona krâsa", + "Horizontal Rule": "Horizontâla atdalîtâjsvîtra", + "Insert Web Link": "Ievietot hipersaiti", + "Insert/Modify Image": "Ievietot attçlu", + "Insert Table": "Ievietot tabulu", + "Toggle HTML Source": "Skatît HTML kodu", + "Enlarge Editor": "Palielinât Rediìçtâju", + "About this editor": "Par ðo rediìçtâju", + "Help using editor": "Rediìçtâja palîgs", + "Current style": "Patreizçjais stils", + "Undoes your last action": "Atcelt pçdçjo darbîbu", + "Redoes your last action": "Atkârtot pçdçjo darbîbu", + "Cut selection": "Izgriezt iezîmçto", + "Copy selection": "Kopçt iezîmçto", + "Paste from clipboard": "Ievietot iezîmçto", + "OK": "Labi", + "Cancel": "Atcelt", + "Path": "Ceïð", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Jûs patlaban darbojaties TEKSTA REÞÎMÂ. Lai pârietu atpakaï uz GRAFISKO REÞÎMU (WYSIWIG), lietojiet [<>] pogu." +} diff --git a/mailboxes/xinha/lang/nb.js b/mailboxes/xinha/lang/nb.js new file mode 100644 index 000000000..6ae045151 --- /dev/null +++ b/mailboxes/xinha/lang/nb.js @@ -0,0 +1,78 @@ +// I18N constants + +// LANG: "nb", ENCODING: UTF-8 + +// - translated by ses +// Additional translations by HÃ¥vard Wigtil +// Additional translations by Kim Steinhaug + +{ + "Bold": "Fet", + "Italic": "Kursiv", + "Underline": "Understreket", + "Strikethrough": "Gjennomstreket", + "Subscript": "Nedsenket", + "Superscript": "Opphøyet", + "Justify Left": "Venstrejuster", + "Justify Center": "Midtjuster", + "Justify Right": "Høyrejuster", + "Justify Full": "Blokkjuster", + "Ordered List": "Nummerert liste", + "Bulleted List": "Punktliste", + "Decrease Indent": "Reduser innrykk", + "Increase Indent": "Øke innrykk", + "Font Color": "Tekstfarge", + "Background Color": "Bakgrundsfarge", + "Horizontal Rule": "Vannrett linje", + "Insert Web Link": "Lag lenke", + "Insert/Modify Image": "Sett inn bilde", + "Insert Table": "Sett inn tabell", + "Toggle HTML Source": "Vis kildekode", + "Enlarge Editor": "Vis i eget vindu", + "About this editor": "Om denne editor", + "Help using editor": "Hjelp", + "Current style": "NÃ¥værende stil", + "Undoes your last action": "Angrer siste redigering", + "Redoes your last action": "Gjør om siste angring", + "Cut selection": "Klipp ut omrÃ¥de", + "Copy selection": "Kopier omrÃ¥de", + "Save as": "Lagre som", + "Paste from clipboard": "Lim inn", + "Remove formatting": "Fjern formattering", + "Direction left to right": "Fra venstre mot høyre", + "Direction right to left": "Fra høyre mot venstre", + "Insert/Overwrite": "Sett inn/Overskriv", + "OK": "OK", + "Cancel": "Avbryt", + "Path": "Tekstvelger", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Du er i tekstmodus Klikk pÃ¥ [<>] for Ã¥ gÃ¥ tilbake til WYSIWIG.", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "Visning i eget vindu har kjente problemer med Internet Explorer, pÃ¥ grunn av problemer med denne nettleseren. Mulige problemer er et uryddig skjermbilde, manglende editorfunksjoner og/eller at nettleseren crasher. Hvis du bruker Windows 95 eller Windows 98 er det ogsÃ¥ muligheter for at Windows will crashe.\n\nTrykk ", + "Cancel": "Avbryt", + "Insert/Modify Link": "Rediger lenke", + "New window (_blank)": "Eget vindu (_blank)", + "None (use implicit)": "Ingen (bruk standardinnstilling)", + "Other": "Annen", + "Same frame (_self)": "Samme ramme (_self)", + "Target:": "MÃ¥l:", + "Title (tooltip):": "Tittel (tooltip):", + "Top frame (_top)": "Toppramme (_top)", + "URL:": "Adresse:", + "You must enter the URL where this link points to": "Du mÃ¥ skrive inn en adresse som denne lenken skal peke til", + "Clear Inline Font Specifications": "Fjerne inline font spesifikasjoner", + "Would you like to clear font typefaces?": "Ønsker du Ã¥ fjerne skrifttyper", + "Would you like to clear font sizes?": "Ønsker du Ã¥ fjerne skrift størrelser", + "Would you like to clear font colours?": "Ønsker du Ã¥ fjerne farger pÃ¥ skriften", + "Print document": "Skriv ut dokumentet", + "Split Block": "Seperasjonsblokk", + "Toggle Borders": "Skru av/pÃ¥ hjelpelinjer pÃ¥ tabeller", + "Select all": "Merk alt", + // Loading messages + "Loading in progress. Please wait !": "WYSIWYG laster, vennligst vent!", + "Constructing main object": "Vennligst vent", + "Create Toolbar": "Lag verktøylinje", + "Register panel right": "Registrer høyrepanel", + "Register panel left": "Registrer venstrepanel", + "Register panel top": "Registrer toppanel", + "Register panel bottom": "Registrer bunnpanel" + +}; diff --git a/mailboxes/xinha/lang/nl.js b/mailboxes/xinha/lang/nl.js new file mode 100644 index 000000000..3fe6b8c2e --- /dev/null +++ b/mailboxes/xinha/lang/nl.js @@ -0,0 +1,64 @@ +// I18N constants + +// LANG: "nl", ENCODING: UTF-8 +// Author: Michel Weegeerink (info@mmc-shop.nl), http://mmc-shop.nl + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "Vet", + "Italic": "Cursief", + "Underline": "Onderstrepen", + "Strikethrough": "Doorhalen", + "Subscript": "Subscript", + "Superscript": "Superscript", + "Justify Left": "Links uitlijnen", + "Justify Center": "Centreren", + "Justify Right": "Rechts uitlijnen", + "Justify Full": "Uitvullen", + "Ordered List": "Nummering", + "Bulleted List": "Opsommingstekens", + "Decrease Indent": "Inspringing verkleinen", + "Increase Indent": "Inspringing vergroten", + "Font Color": "Tekstkleur", + "Background Color": "Achtergrondkleur", + "Horizontal Rule": "Horizontale lijn", + "Insert Web Link": "Hyperlink invoegen/aanpassen", + "Insert/Modify Image": "Afbeelding invoegen/aanpassen", + "Insert Table": "Tabel invoegen", + "Toggle HTML Source": "HTML broncode", + "Enlarge Editor": "Vergroot Editor", + "About this editor": "Over deze editor", + "Help using editor": "HTMLArea help", + "Current style": "Huidige stijl", + "Undoes your last action": "Ongedaan maken", + "Redoes your last action": "Herhalen", + "Cut selection": "Knippen", + "Copy selection": "Kopi?ren", + "Paste from clipboard": "Plakken", + "Direction left to right": "Tekstrichting links naar rechts", + "Direction right to left": "Tekstrichting rechts naar links", + "OK": "OK", + "Cancel": "Annuleren", + "Path": "Pad", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Je bent in TEKST-mode. Gebruik de [<>] knop om terug te keren naar WYSIWYG-mode.", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "Fullscreen-mode veroorzaakt problemen met Internet Explorer door bugs in de webbrowser die we niet kunnen omzeilen. Hierdoor kunnen de volgende effecten optreden: verknoeide teksten, een verlies aan editor-functionaliteit en/of willekeurig vastlopen van de webbrowser. Als u Windows 95 of 98 gebruikt, is het zeer waarschijnlijk dat u een algemene beschermingsfout (", + "Cancel": "Annuleren", + "Insert/Modify Link": "Hyperlink invoegen/aanpassen", + "New window (_blank)": "Nieuw venster (_blank)", + "None (use implicit)": "Geen", + "Other": "Ander", + "Same frame (_self)": "Zelfde frame (_self)", + "Target:": "Doel:", + "Title (tooltip):": "Titel (tooltip):", + "Top frame (_top)": "Bovenste frame (_top)", + "URL:": "URL:", + "You must enter the URL where this link points to": "Geef de URL in waar de link naar verwijst" +} diff --git a/mailboxes/xinha/lang/pl.js b/mailboxes/xinha/lang/pl.js new file mode 100644 index 000000000..b5bd5ce1d --- /dev/null +++ b/mailboxes/xinha/lang/pl.js @@ -0,0 +1,125 @@ +// I18N constants +// LANG: "pl", ENCODING: UTF-8 +// translated: Krzysztof Kotowicz, http://www.eskot.krakow.pl/portfolio/, koto@webworkers.pl +{ + "Bold": "Pogrubienie", + "Italic": "Pochylenie", + "Underline": "PodkreÅ›lenie", + "Strikethrough": "PrzekreÅ›lenie", + "Subscript": "Indeks dolny", + "Superscript": "Indeks górny", + "Justify Left": "Wyrównaj do lewej", + "Justify Center": "WyÅ›rodkuj", + "Justify Right": "Wyrównaj do prawej", + "Justify Full": "Wyjustuj", + "Ordered List": "Numerowanie", + "Bulleted List": "Wypunktowanie", + "Decrease Indent": "Zmniejsz wciÄ™cie", + "Increase Indent": "ZwiÄ™ksz wciÄ™cie", + "Font Color": "Kolor czcionki", + "Background Color": "Kolor tÅ‚a", + "Horizontal Rule": "Linia pozioma", + "Insert Web Link": "Wstaw adres sieci Web", + "Insert/Modify Image": "Wstaw obraz", + "Insert Table": "Wstaw tabelÄ™", + "Toggle HTML Source": "Edycja WYSIWYG/w źródle strony", + "Enlarge Editor": "PeÅ‚ny ekran", + "About this editor": "Informacje o tym edytorze", + "Help using editor": "Pomoc", + "Current style": "Obecny styl", + "Undoes your last action": "Cofa ostatnio wykonane polecenie", + "Redoes your last action": "Ponawia ostatnio wykonane polecenie", + "Cut selection": "Wycina zaznaczenie do schowka", + "Copy selection": "Kopiuje zaznaczenie do schowka", + "Paste from clipboard": "Wkleja zawartość schowka", + "Direction left to right": "Kierunek tekstu lewo-prawo", + "Direction right to left": "Kierunek tekstu prawo-lewo", + "Remove formatting": "UsuÅ„ formatowanie", + "Select all": "Zaznacz wszystko", + "Print document": "Drukuj dokument", + "Clear MSOffice tags": "Wyczyść tagi MSOffice", + "Clear Inline Font Specifications": "Wycisz bezpoÅ›rednie przypisania czcionek", + "Split Block": "Podziel blok", + "Toggle Borders": "Włącz / wyłącz ramki", + + "— format —": "— Format —", + "Heading 1": "Nagłówek 1", + "Heading 2": "Nagłówek 2", + "Heading 3": "Nagłówek 3", + "Heading 4": "Nagłówek 4", + "Heading 5": "Nagłówek 5", + "Heading 6": "Nagłówek 6", + "Normal": "Normalny", + "Address": "Adres", + "Formatted": "Preformatowany", + + //dialogs + "OK": "OK", + "Cancel": "Anuluj", + "Path": "Åšcieżka", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "JesteÅ› w TRYBIE TEKSTOWYM. Użyj przycisku [<>], aby przełączyć siÄ™ na tryb WYSIWYG.", + "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "Przycisk Wklej nie dziaÅ‚a w przeglÄ…darkach Mozilla z uwagi na ustawienia bezpieczeÅ„stwa. NaciÅ›nij CRTL-V, aby wkleić zawartość schowka.", + + "Alignment:": "Wyrównanie:", + "Not set": "Nie ustawione", + "Left": "Do lewej", + "Right": "Do prawej", + "Texttop": "Góra tekstu", + "Absmiddle": "Abs. Å›rodek", + "Baseline": "Linia bazowa", + "Absbottom": "Abs. dół", + "Bottom": "Dół", + "Middle": "Åšrodek", + "Top": "Góra", + + "Layout": "Layout", + "Spacing": "Spacjowanie", + "Horizontal:": "Poziome:", + "Horizontal padding": "WciÄ™cie poziome", + "Vertical:": "Pionowe:", + "Vertical padding": "WciÄ™cie pionowe", + "Border thickness:": "Grubość obramowania:", + "Leave empty for no border": "Bez ramek - zostaw puste", + + //Insert Link + "Insert/Modify Link": "Wstaw/edytuj odnoÅ›nik", + "None (use implicit)": "Brak", + "New window (_blank)": "Nowe okno (_blank)", + "Same frame (_self)": "Ta sama ramka (_self)", + "Top frame (_top)": "Główna ramka (_top)", + "Other": "Inne", + "Target:": "Okno docelowe:", + "Title (tooltip):": "TytuÅ‚ (tooltip):", + "URL:": "URL:", + "You must enter the URL where this link points to": "Musisz podać URL, na jaki bÄ™dzie wskazywaÅ‚ odnoÅ›nik", + + // Insert Table + "Insert Table": "Wstaw tabelÄ™", + "Rows:": "Wierszy:", + "Number of rows": "Liczba wierszy", + "Cols:": "Kolumn:", + "Number of columns": "Liczba kolumn", + "Width:": "Szerokość:", + "Width of the table": "Szerokość tabeli", + "Percent": "Procent", + "Pixels": "Pikseli", + "Em": "Em", + "Width unit": "Jednostka", + "Fixed width columns": "Kolumny o staÅ‚ej szerokoÅ›ci", + "Positioning of this table": "Pozycjonowanie tabeli", + "Cell spacing:": "OdstÄ™p komórek:", + "Space between adjacent cells": "PrzestrzeÅ„ pomiÄ™dzy komórkami", + "Cell padding:": "WciÄ™cie komórek:", + "Space between content and border in cell": "PrzestrzeÅ„ miÄ™dzy krawÄ™dziÄ… a zawartoÅ›ciÄ… komórki", + + // Insert Image + "Insert Image": "Wstaw obrazek", + "Image URL:": "URL obrazka:", + "Enter the image URL here": "Podaj URL obrazka", + "Preview": "PodglÄ…d", + "Preview the image in a new window": "PodglÄ…d obrazka w nowym oknie", + "Alternate text:": "Tekst alternatywny:", + "For browsers that don't support images": "Dla przeglÄ…darek, które nie obsÅ‚ugujÄ… obrazków", + "Positioning of this image": "Pozycjonowanie obrazka", + "Image Preview:": "PodglÄ…d obrazka:" +} diff --git a/mailboxes/xinha/lang/pt_br.js b/mailboxes/xinha/lang/pt_br.js new file mode 100644 index 000000000..156216d97 --- /dev/null +++ b/mailboxes/xinha/lang/pt_br.js @@ -0,0 +1,32 @@ +// I18N constants + +// LANG: "bt_br", ENCODING: UTF-8 +// Brazilian Portuguese Translation by Alex Piaz + +{ + "Bold": "Negrito", + "Italic": "Itálico", + "Underline": "Sublinhado", + "Strikethrough": "Tachado", + "Subscript": "Subescrito", + "Superscript": "Sobrescrito", + "Justify Left": "Alinhar à Esquerda", + "Justify Center": "Centralizar", + "Justify Right": "Alinhar à Direita", + "Justify Full": "Justificar", + "Ordered List": "Lista Numerada", + "Bulleted List": "Lista Marcadores", + "Decrease Indent": "Diminuir Indentação", + "Increase Indent": "Aumentar Indentação", + "Font Color": "Cor da Fonte", + "Background Color": "Cor do Fundo", + "Horizontal Rule": "Linha Horizontal", + "Insert Web Link": "Inserir Link", + "Insert/Modify Image": "Inserir Imagem", + "Insert Table": "Inserir Tabela", + "Toggle HTML Source": "Ver Código-Fonte", + "Enlarge Editor": "Expandir Editor", + "About this editor": "Sobre", + "Help using editor": "Ajuda", + "Current style": "Estilo Atual" +} diff --git a/mailboxes/xinha/lang/ro.js b/mailboxes/xinha/lang/ro.js new file mode 100644 index 000000000..6565bd202 --- /dev/null +++ b/mailboxes/xinha/lang/ro.js @@ -0,0 +1,63 @@ +// I18N constants + +// LANG: "ro", ENCODING: UTF-8 +// Author: Mihai Bazon, http://dynarch.com/mishoo + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "ÃŽngroÅŸat", + "Italic": "Italic", + "Underline": "Subliniat", + "Strikethrough": "Tăiat", + "Subscript": "Indice jos", + "Superscript": "Indice sus", + "Justify Left": "Aliniere la stânga", + "Justify Center": "Aliniere pe centru", + "Justify Right": "Aliniere la dreapta", + "Justify Full": "Aliniere în ambele părÅ£i", + "Ordered List": "Listă ordonată", + "Bulleted List": "Listă marcată", + "Decrease Indent": "MicÅŸorează alineatul", + "Increase Indent": "MăreÅŸte alineatul", + "Font Color": "Culoarea textului", + "Background Color": "Culoare de fundal", + "Horizontal Rule": "Linie orizontală", + "Insert Web Link": "Inserează/modifică link", + "Insert/Modify Image": "Inserează/modifică imagine", + "Insert Table": "Inserează un tabel", + "Toggle HTML Source": "Sursa HTML / WYSIWYG", + "Enlarge Editor": "Maximizează editorul", + "About this editor": "Despre editor", + "Help using editor": "DocumentaÅ£ie (devel)", + "Current style": "Stilul curent", + "Undoes your last action": "Anulează ultima acÅ£iune", + "Redoes your last action": "Reface ultima acÅ£iune anulată", + "Cut selection": "Taie în clipboard", + "Copy selection": "Copie în clipboard", + "Paste from clipboard": "Aduce din clipboard", + "Direction left to right": "DirecÅ£ia de scriere: stânga - dreapta", + "Direction right to left": "DirecÅ£ia de scriere: dreapta - stânga", + "OK": "OK", + "Cancel": "Anulează", + "Path": "Calea", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "EÅŸti în modul TEXT. Apasă butonul [<>] pentru a te întoarce în modul WYSIWYG.", + "Cancel": "Renunţă", + "Insert/Modify Link": "Inserează/modifcă link", + "New window (_blank)": "Fereastră nouă (_blank)", + "None (use implicit)": "Nimic (foloseÅŸte ce-i implicit)", + "Other": "Alt target", + "Same frame (_self)": "AceeaÅŸi fereastră (_self)", + "Target:": "Å¢inta:", + "Title (tooltip):": "Titlul (tooltip):", + "Top frame (_top)": "Fereastra principală (_top)", + "URL:": "URL:", + "You must enter the URL where this link points to": "Trebuie să introduceÅ£i un URL" +} diff --git a/mailboxes/xinha/lang/ru.js b/mailboxes/xinha/lang/ru.js new file mode 100644 index 000000000..5290b7f01 --- /dev/null +++ b/mailboxes/xinha/lang/ru.js @@ -0,0 +1,185 @@ +// I18N constants + +// LANG: "ru", ENCODING: UTF-8 +// Author: Yulya Shtyryakova, + +// Some additions by: Alexey Kirpichnikov, +// I took French version as a source of English phrases because French version was the most comprehensive +// (fr.js was the largest file, actually) %) + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "Полужирный", + "Italic": "Ðаклонный", + "Underline": "Подчеркнутый", + "Strikethrough": "Перечеркнутый", + "Subscript": "Ðижний индекÑ", + "Superscript": "Верхний индекÑ", + "Justify Left": "По левому краю", + "Justify Center": "По центру", + "Justify Right": "По правому краю", + "Justify Full": "По ширине", + "Ordered List": "Ðумерованный ÑпиÑок", + "Bulleted List": "Маркированный ÑпиÑок", + "Decrease Indent": "Уменьшить отÑтуп", + "Increase Indent": "Увеличить отÑтуп", + "Font Color": "Цвет шрифта", + "Background Color": "Цвет фона", + "Horizontal Rule": "Горизонтальный разделитель", + "Insert Web Link": "Ð’Ñтавить гиперÑÑылку", + "Insert/Modify Image": "Ð’Ñтавить изображение", + "Insert Table": "Ð’Ñтавить таблицу", + "Toggle HTML Source": "Показать Html-код", + "Enlarge Editor": "Увеличить редактор", + "About this editor": "О редакторе", + "Help using editor": "Помощь", + "Current style": "Текущий Ñтиль", + "Undoes your last action": "Отменить", + "Redoes your last action": "Повторить", + "Cut selection": "Вырезать", + "Copy selection": "Копировать", + "Paste from clipboard": "Ð’Ñтавить", + "Direction left to right": "Ðаправление Ñлева направо", + "Direction right to left": "Ðаправление Ñправа налево", + "Remove formatting": "Убрать форматирование", + "Select all": "Выделить вÑе", + "Print document": "Печать", + "Clear MSOffice tags": "Удалить разметку MSOffice", + "Clear Inline Font Specifications": "Удалить непоÑредÑтвенное задание шрифтов", + "Would you like to clear font typefaces?": "Удалить типы шрифтов?", + "Would you like to clear font sizes?": "Удалить размеры шрифтов ?", + "Would you like to clear font colours?": "Удалить цвета шрифтов ?", + "Split Block": "Разделить блок", + "Toggle Borders": "Включить/выключить отображение границ", + "Save as": "Сохранить как", + "Insert/Overwrite": "Ð’Ñтавка/замена", + "— format —": "— форматирование —", + "Heading 1": "Заголовок 1", + "Heading 2": "Заголовок 2", + "Heading 3": "Заголовок 3", + "Heading 4": "Заголовок 4", + "Heading 5": "Заголовок 5", + "Heading 6": "Заголовок 6", + "Normal": "Обычный текÑÑ‚", + "Address": "ÐдреÑ", + "Formatted": "Отформатированный текÑÑ‚", + + "— font —": "— шрифт —", + "— size —": "— размер —", + + +// Диалоги + + "OK": "OK", + "Cancel": "Отмена", + "Path": "Путь", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Ð’Ñ‹ в режиме Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Html-кода. нажмите кнопку [<>], чтобы переключитьÑÑ Ð² визуальный режим.", + +"The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "Кнопка Ð’Ñтавить не работает в браузерах на оÑнове Mozilla (по техничеÑким причинам, ÑвÑзанным Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑноÑтью). Ðажмите Ctrl-V на клавиатуре, чтобы вÑтавить.", + + "Your Document is not well formed. Check JavaScript console for details.": "Ваш документ неправильно Ñформирован. ПоÑмотрите КонÑоль JavaScript, чтобы узнать подробноÑти.", + + "Alignment:": "Выравнивание", + "Not set": "Ðе уÑтановлено", + "Left": "По левому краю", + "Right": "По правому краю", + "Texttop": "По верхней границе текÑта", + "Absmiddle": "По Ñередине текÑта", + "Baseline": "По нижней границе текÑта", + "Absbottom": "По нижней границе", + "Bottom": "По нижнему краю", + "Middle": "ПоÑредине", + "Top": "По верхнему краю", + + "Layout": "РаÑположение", + "Spacing": "ПолÑ", + "Horizontal:": "По горизонтали", + "Horizontal padding": "Горизонтальные полÑ", + "Vertical:": "По вертикали", + "Vertical padding": "Вертикальные полÑ", + "Border thickness:": "Толщина рамки", + "Leave empty for no border": "ОÑтавьте пуÑтым, чтобы убрать рамку", + + //Insert Link + "Insert/Modify Link": "Ð’Ñтавка/изменение ÑÑылки", + "None (use implicit)": "По умолчанию", + "New window (_blank)": "Ðовое окно (_blank)", + "Same frame (_self)": "То же окно (_self)", + "Top frame (_top)": "РодительÑкое окно (_top)", + "Other": "Другое", + "Target:": "Открывать в окне:", + "Title (tooltip):": "Ð’ÑÐ¿Ð»Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ Ð¿Ð¾Ð´Ñказка", + "URL:": "URL:", + "You must enter the URL where this link points to": "Ð’Ñ‹ должны указать URL, на который будет указывать ÑÑылка", + "You need to select some text before creating a link": "Ð’Ñ‹ должны выделить текÑÑ‚, который будет преобразован в ÑÑылку", + + // Insert Table + "Insert Table": "Ð’Ñтавка таблицы", + "Rows:": "Строки", + "Number of rows": "КоличеÑтво Ñтрок", + "Cols:": "Столбцы", + "Number of columns": "КоличеÑтво Ñтолбцов", + "Width:": "Ширина", + "Width of the table": "Ширина таблицы", + "Percent": "проценты", + "Pixels": "пикÑелы", + "Em": "em", + "Width unit": "Единицы измерениÑ", + "Fixed width columns": "Столбцы фикÑированной ширины", + "Positioning of this table": "РаÑположение таблицы", + "Cell spacing:": "РаÑÑтоÑние между Ñчейками", + "Space between adjacent cells": "РаÑÑтоÑние между ÑоÑедними Ñчейками", + "Cell padding:": "ÐŸÐ¾Ð»Ñ Ð² Ñчейках", + "Space between content and border in cell": "РаÑÑтоÑние между границей Ñчейки и текÑтом", + "You must enter a number of rows": "Ð’Ñ‹ должны ввеÑти количеÑтво Ñтрок", + "You must enter a number of columns": "Ð’Ñ‹ должны ввеÑти количеÑтво Ñтолбцов", + + // Insert Image + "Insert Image": "Ð’Ñтавка изображениÑ", + "Image URL:": "URL изображениÑ", + "Enter the image URL here": "Ð’Ñтавьте Ð°Ð´Ñ€ÐµÑ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ", + "Preview": "Предварительный проÑмотр", + "Preview the image in a new window": "Предварительный проÑмотр в отдельном окне", + "Alternate text:": "Ðльтернативный текÑÑ‚", + "For browsers that don't support images": "Ð”Ð»Ñ Ð±Ñ€Ð°ÑƒÐ·ÐµÑ€Ð¾Ð², которые не отображают картинки", + "Positioning of this image": "РаÑположение изображениÑ", + "Image Preview:": "Предварительный проÑмотр", + "You must enter the URL": "Ð’Ñ‹ должны ввеÑти URL", + + // Editor Help + "Xinha Help": "Помощь", + "Editor Help": "Помощь", + "Keyboard shortcuts": "ГорÑчие клавиши", + "The editor provides the following key combinations:": "Редактор поддерживает Ñледующие комбинации клавиш:", + "ENTER": "ENTER", + "new paragraph": "новый абзац", + "SHIFT-ENTER": "SHIFT+ENTER", + "insert linebreak": "Ð¿ÐµÑ€ÐµÐ½Ð¾Ñ Ñтроки", + "Set format to paragraph": "Отформатировать абзац", + "Clean content pasted from Word": "ОчиÑтить текÑÑ‚, вÑтавленный из Word", + "Headings": "Заголовки", + "Close": "Закрыть", + + // Loading messages + "Loading in progress. Please wait !": "Загрузка... ПожалуйÑта, подождите.", + "Constructing main object": "Создание главного объекта", + "Constructing object": "Создание объекта", + "Register panel right": "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¾Ð¹ панели", + "Register panel left": "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð»ÐµÐ²Ð¾Ð¹ панели", + "Register panel top": "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð²ÐµÑ€Ñ…Ð½ÐµÐ¹ панели", + "Register panel bottom": "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð¸Ð¶Ð½ÐµÐ¹ панели", + "Create Toolbar": "Создание панели инÑтрументов", + "Create StatusBar": "Создание панели ÑоÑтоÑниÑ", + "Generate Xinha object": "Создание объекта Xinha", + "Init editor size": "Ð˜Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° редактора", + "Init IFrame": "Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ iframe", + "Register plugin $plugin": "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ $plugin" +}; diff --git a/mailboxes/xinha/lang/sh.js b/mailboxes/xinha/lang/sh.js new file mode 100644 index 000000000..270630464 --- /dev/null +++ b/mailboxes/xinha/lang/sh.js @@ -0,0 +1,140 @@ +// I18N constants + +// LANG: "sh", ENCODING: UTF-8 | ISO-8859-2 +// Author: Ljuba Ranković, http://www.rankovic.net/ljubar + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "Masno", + "Italic": "Kurziv", + "Underline": "PodvuÄeno", + "Strikethrough": "Precrtano", + "Subscript": "Indeks-tekst", + "Superscript": "Eksponent-tekst", + "Justify Left":"Ravnanje ulevo", + "Justify Center": "Ravnanje po simetrali", + "Justify Right": "Ravnanje udesno", + "Justify Full": "Puno ravnanje", + "Ordered List": "Lista sa rednim brojevima", + "Bulleted List": "Lista sa simbolima", + "Decrease Indent": "smanji uvlaÄenje", + "Increase Indent": "Povećaj uvlaÄenje", + "Font Color": "Boja slova", + "Background Color": "Boja pozadine", + "Horizontal Rule": "Horizontalna linija", + "Insert Web Link": "Dodaj web link", + "Insert/Modify Image": "Dodaj/promeni sliku", + "Insert Table": "Ubaci tabelu", + "Toggle HTML Source": "Prebaci na HTML kod", + "Enlarge Editor": "Povećaj editor", + "About this editor": "O ovom editoru", + "Help using editor": "Pomoć pri korišćenju editora", + "Current style": "Važeći stil", + "Undoes your last action": "PoniÅ¡tava poslednju radnju", + "Redoes your last action": "Vraća poslednju radnju", + "Cut selection": "Iseci izabrano", + "Copy selection": "Kopiraj izabrano", + "Paste from clipboard": "Zalepi iz klipborda", + "Direction left to right": "Pravac s leva na desno", + "Direction right to left": "Pravac s desna na levo", + "Remove formatting": "Ukoni formatiranje", + "Select all": "Izaberi sve", + "Print document": "Å tampaj dokument", + "Clear MSOffice tags": "ObriÅ¡i MSOffice tagove", + "Clear Inline Font Specifications": "ObriÅ¡i dodeljene osobine fonta", + "Split Block": "Podeli blok", + "Toggle Borders": "Izmeni okvire", + + "— format —": "— Format —", + "Heading 1": "Zaglavlje 1", + "Heading 2": "Zaglavlje 2", + "Heading 3": "Zaglavlje 3", + "Heading 4": "Zaglavlje 4", + "Heading 5": "Zaglavlje 5", + "Heading 6": "Zaglavlje 6", + "Normal": "ObiÄan", + "Address": "Adresa", + "Formatted": "Formatiran", + + // dialogs + "OK": "OK", + "Cancel": "PoniÅ¡ti", + "Path": "Putanja", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Nalazite se u TEXT režimu. Koristite [<>] dugme za povratak na WYSIWYG.", + + "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "", + + "Alignment:": "Ravnanje", + "Not set": "Nije postavljeno", + "Left": "Levo", + "Right": "Desno", + "Texttop": "Vrh teksta", + "Absmiddle": "Apsolutna sredina", + "Baseline": "Donja linija", + "Absbottom": "Apsolutno dno", + "Bottom": "Dno", + "Middle": "Sredina", + "Top": "Vrh", + + "Layout": "Prelom", + "Spacing": "Razmak", + "Horizontal:": "Po horizontali", + "Horizontal padding": "Horizontalno odstojanje", + "Vertical:": "Po vertikali", + "Vertical padding": "Vertikalno odstojanje", + "Border thickness:": "Debljina okvira", + "Leave empty for no border": "Ostavi prazno kad nema okvira", + + // Insert Link + "Insert/Modify Link": "Dodaj/promeni Link", + "None (use implicit)": "koristi podrazumevano", + "New window (_blank)": "Novom prozoru (_blank)", + "Same frame (_self)": "Isti frejm (_self)", + "Top frame (_top)": "Glavni frejm (_top)", + "Other": "Drugo", + "Target:": "Otvori u:", + "Title (tooltip):": "Naziv (tooltip):", + "URL:": "URL:", + "You must enter the URL where this link points to": "Morate uneti URL na koji vodi ovaj link", + + // Insert Table + "Insert Table": "Ubaci tabelu", + "Rows:": "Redovi", + "Number of rows": "Broj redova", + "Cols:": "Kolone", + "Number of columns": "Broj kolona", + "Width:": "Å irina", + "Width of the table": "Å irina tabele", + "Percent": "Procenat", + "Pixels": "Pikseli", + "Em": "Em", + "Width unit": "Jedinica Å¡irine", + "Fixed width columns": "Fiksirana Å¡irina kolona", + "Positioning of this table": "Postavljanje ove tabele", + "Cell spacing:": "Rastojanje ćelija", + "Space between adjacent cells": "Rastojanje naspramnih ćelija", + "Cell padding:": "UnutraÅ¡nja odstojanja u ćeliji", + "Space between content and border in cell": "Rastojanje izmeÄ‘u sadržaja i okvira ćelije", + + // Insert Image + "Insert Image": "Ubaci sliku", + "Image URL:": "URL slike", + "Enter the image URL here": "Unesite URL slike ovde", + "Preview": "Pregled", + "Preview the image in a new window": "Pregledaj sliku u novom prozoru", + "Alternate text:": "Alternativni tekst", + "For browsers that don't support images": "Za pretraživaÄe koji ne podržavaju slike", + "Positioning of this image": "Postavljanje ove slike", + "Image Preview:": "Pregled slike", + + // Select Color popup + "Select Color": "Izaberite boju" +}; diff --git a/mailboxes/xinha/lang/si.js b/mailboxes/xinha/lang/si.js new file mode 100644 index 000000000..90a69b53d --- /dev/null +++ b/mailboxes/xinha/lang/si.js @@ -0,0 +1,50 @@ +// I18N constants + +// LANG: "si", ENCODING: UTF-8 +// Author: Tomaz Kregar, x_tomo_x@email.si + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "Krepko", + "Italic": "LežeÄe", + "Underline": "PodÄrtano", + "Strikethrough": "PreÄrtano", + "Subscript": "Podpisano", + "Superscript": "Nadpisano", + "Justify Left": "Poravnaj levo", + "Justify Center": "Na sredino", + "Justify Right": "Poravnaj desno", + "Justify Full": "Porazdeli vsebino", + "Ordered List": "OÅ¡tevilÄevanje", + "Bulleted List": "OznaÄevanje", + "Decrease Indent": "ZmanjÅ¡aj zamik", + "Increase Indent": "PoveÄaj zamik", + "Font Color": "Barva pisave", + "Background Color": "Barva ozadja", + "Horizontal Rule": "Vodoravna Ärta", + "Insert Web Link": "Vstavi hiperpovezavo", + "Insert/Modify Image": "Vstavi sliko", + "Insert Table": "Vstavi tabelo", + "Toggle HTML Source": "Preklopi na HTML kodo", + "Enlarge Editor": "PoveÄaj urejevalnik", + "About this editor": "Vizitka za urejevalnik", + "Help using editor": "PomoÄ za urejevalnik", + "Current style": "Trenutni slog", + "Undoes your last action": "Razveljavi zadnjo akcijo", + "Redoes your last action": "Uveljavi zadnjo akcijo", + "Cut selection": "Izreži", + "Copy selection": "Kopiraj", + "Paste from clipboard": "Prilepi", + "OK": "V redu", + "Cancel": "PrekliÄi", + "Path": "Pot", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Si v tekstovnem naÄinu. Uporabi [<>] gumb za prklop nazaj na WYSIWYG." +} diff --git a/mailboxes/xinha/lang/sr.js b/mailboxes/xinha/lang/sr.js new file mode 100644 index 000000000..06f78c469 --- /dev/null +++ b/mailboxes/xinha/lang/sr.js @@ -0,0 +1,140 @@ +// I18N constants + +// LANG: "sh", ENCODING: UTF-8 | ISO-8859-5 +// Author: Ljuba Ranković, http://www.rankovic.net/ljubar + +// FOR TRANSLATORS: +// +// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE +// (at least a valid email address) +// +// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING; +// (if this is not possible, please include a comment +// that states what encoding is necessary.) + +{ + "Bold": "МаÑно", + "Italic": "Курзив", + "Underline": "Подвучено", + "Strikethrough": "Прецртано", + "Subscript": "ИндекÑ-текÑÑ‚", + "Superscript": "ЕкÑпонент-текÑÑ‚", + "Justify Left": "Равнање улево", + "Justify Center": "Равнање по Ñиметрали", + "Justify Right": "Равнање удеÑно", + "Justify Full": "Пуно равнање", + "Ordered List": "ЛиÑта Ñа редним бројевима", + "Bulleted List": "ЛиÑта Ñа Ñимболима", + "Decrease Indent": "Смањи увлачење", + "Increase Indent": "Повећај увлачење", + "Font Color": "Боја Ñлова", + "Background Color": "Боја позадине", + "Horizontal Rule": "Хоризонтална линија", + "Insert Web Link": "додај веб линк", + "Insert/Modify Image": "додај/промени Ñлику", + "Insert Table": "Убаци табелу", + "Toggle HTML Source": "Пребаци на приказ ХТМЛ кода", + "Enlarge Editor": "Повећај едитор", + "About this editor": "О овом едитору", + "Help using editor": "Помоћ при коришћењу едитора", + "Current style": "Важећи Ñтил", + "Undoes your last action": "Поништава поÑледњу радњу", + "Redoes your last action": "Враћа поÑледњу радњу", + "Cut selection": "ИÑеци изабрано", + "Copy selection": "Копирај изабрано", + "Paste from clipboard": "Залепи из клипборда", + "Direction left to right": "Правац Ñ Ð»ÐµÐ²Ð° на деÑно", + "Direction right to left": "Правац Ñ Ð´ÐµÑна на лево", + "Remove formatting": "Уклони форматирање", + "Select all": "Изабери Ñве", + "Print document": "Штампај документ", + "Clear MSOffice tags": "Обриши MSOffice тагове", + "Clear Inline Font Specifications": "Обриши примењене оÑобине фонта", + "Split Block": "Подели блок", + "Toggle Borders": "Пребаци оквирне линије", + + "— format —": "— Format —", + "Heading 1": "Заглавље 1", + "Heading 2": "Заглавље 2", + "Heading 3": "Заглавље 3", + "Heading 4": "Заглавље 4", + "Heading 5": "Заглавље 5", + "Heading 6": "Заглавље 6", + "Normal": "обичан", + "Address": "адреÑа", + "Formatted": "форматиран", + + // dialogs + "OK": "OK", + "Cancel": "Поништи", + "Path": "Путања", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Ðалазите Ñе у ТЕКСТ режиму. КориÑтите [<>] дугме за повратак на ШВТИД (WYSIWYG).", + + "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "Дугме 'залепи' не ради у претраживачима породице Mozilla (из разлога ÑигурноÑти). ПритиÑните CTRL-V на таÑтатури да директно залепите.", + + "Alignment:": "Равнање", + "Not set": "Ðије поÑтављено", + "Left": "Лево", + "Right": "ДеÑно", + "Texttop": "Врх текÑта", + "Absmiddle": "ÐпÑолутна Ñредина", + "Baseline": "Доња линија", + "Absbottom": "ÐпÑолутно дно", + "Bottom": "Дно", + "Middle": "Средина", + "Top": "Врх", + + "Layout": "Прелом", + "Spacing": "Размак", + "Horizontal:": "По хоризонтали", + "Horizontal padding": "Хортизонтално одÑтојање", + "Vertical:": "По вертикали", + "Vertical padding": "Вертикално одÑтојање", + "Border thickness:": "Дебљина оквира", + "Leave empty for no border": "ОÑтави празно кад нема оквира", + + // Insert Link + "Insert/Modify Link": "додај/промени линк", + "None (use implicit)": "кориÑти подразумевано", + "New window (_blank)": "Ðовом прозору (_blank)", + "Same frame (_self)": "ИÑти фрејм (_self)", + "Top frame (_top)": "Главни фрејм (_top)", + "Other": "Друго", + "Target:": "Отвори у:", + "Title (tooltip):": "Ðазив (tooltip):", + "URL:": "УРЛ:", + "You must enter the URL where this link points to": "Морате унети УРЛ на који води овај линк", + + // Insert Table + "Insert Table": "Убаци табелу", + "Rows:": "Редови", + "Number of rows": "Број редова", + "Cols:": "Колоне", + "Number of columns": "Број колона", + "Width:": "Ширина", + "Width of the table": "Ширина табеле", + "Percent": "Процената", + "Pixels": "ПикÑела", + "Em": "Ем", + "Width unit": "Јединица ширине", + "Fixed width columns": "ФикÑирана ширина колоне", + "Positioning of this table": "ПоÑтављање ове табеле", + "Cell spacing:": "Размак између ћелија", + "Space between adjacent cells": "Размак између наÑпрамних ћелија", + "Cell padding:": "Унутрашња одÑтојања од ивица ћелије", + "Space between content and border in cell": "РаÑтојање између Ñадржаја у ћелији и њеног оквира", + + // Insert Image + "Insert Image": "Убаци Ñлику", + "Image URL:": "УРЛ Ñлике", + "Enter the image URL here": "УнеÑите УРЛ Ñлике овде", + "Preview": "Преглед", + "Preview the image in a new window": "Прегледај Ñлику у новом прозору", + "Alternate text:": "алтернативни текÑÑ‚", + "For browsers that don't support images": "За претраживаче који не подржавају Ñлике", + "Positioning of this image": "ПоÑтављање ове Ñлике", + "Image Preview:": "Преглед Ñлике", + + // Select Color popup + "Select Color": "Изабери боју" +}; diff --git a/mailboxes/xinha/lang/sv.js b/mailboxes/xinha/lang/sv.js new file mode 100644 index 000000000..61af49e3e --- /dev/null +++ b/mailboxes/xinha/lang/sv.js @@ -0,0 +1,116 @@ +// I18N constants +// LANG: "sv", ENCODING: UTF-8 + +// Swedish version for htmlArea v3.0 +// Initital translation by pat +// Synced with additional contants in rev. 477 (Mar 2006) by Thomas Loo + +{ + "Bold": "Fet", + "Italic": "Kursiv", + "Underline": "Understruken", + "Strikethrough": "Genomstruken", + "Subscript": "Nedsänkt", + "Superscript": "Upphöjd", + "Justify Left": "Vänsterjustera", + "Justify Center": "Centrera", + "Justify Right": "Högerjustera", + "Justify Full": "Marginaljustera", + "Ordered List": "Numrerad lista", + "Bulleted List": "Punktlista", + "Decrease Indent": "Minska indrag", + "Increase Indent": "Öka indrag", + "Font Color": "Textfärg", + "Background Color": "Bakgrundsfärg", + "Horizontal Rule": "VÃ¥grät linje", + "Insert Web Link": "Infoga länk", + "Insert/Modify Image": "Infoga bild", + "Toggle HTML Source": "Visa källkod", + "Enlarge Editor": "Visa i eget fönster", + "About this editor": "Om denna editor", + "Help using editor": "Hjälp", + "Current style": "Nuvarande stil", + + "Undoes your last action": "Ã…ngra kommando", + "Redoes your last action": "Upprepa kommando", + "Select all": "Markera allt", + "Print document": "Skriv ut", + "Clear MSOffice tags": "Städa bort MS Office taggar", + "Clear Inline Font Specifications": "Rensa inbäddad typsnittsinformation", + "Remove formatting": "Rensa formattering", + "Toggle Borders": "Objektramar", + "Split Block": "Dela block", + "Direction left to right": "Vänster till höger", + "Direction right to left": "Höger till vänster", + + "Insert/Overwrite": "Infoga/Skriv över", + "OK": "OK", + "Cancel": "Avbryt", + "Path": "Objekt", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Du befinner dig i texläge. Klicka pÃ¥ ikonen [<>] ovan för att växla tillbaka till WYSIWIG läge", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "Visning i fullskärmsläga fungerar dÃ¥ligt i din webläsare. Möjliga problem resulterar i en ryckig editor, saknade editorfunktioner och/eller att webläsaren kraschar. Om du använder Windows 95/98 finns ocksÃ¥ möjligheten att Windows kraschar.\n\nTryck ", + "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "Denna knapp fungerar ej i Mozillabaserad webläsare, använd istället snabbtangenterna CTRL-V pÃ¥ tangentbordet för att klistra in.", + + "Insert/Modify Link": "Redigera länk", + "New window (_blank)": "Nytt fönster (_blank)", + "None (use implicit)": "Ingen (använd standardinställing)", + "Other": "Annan", + "Same frame (_self)": "Samma ram (_self)", + "Target:": "MÃ¥l:", + "Title (tooltip):": "Titel (tooltip):", + "Top frame (_top)": "Toppram (_top)", + "URL:": "Sökväg:", + "You must enter the URL where this link points to": "Du mÃ¥sta ange en adress till vilken länken skall peka pÃ¥", + "Would you like to clear font typefaces?": "Radera alla typsnittsinformation ?", + "Would you like to clear font sizes?": "Radera alla fontstorlekar ?", + "Would you like to clear font colours?": "Ta bort all textfärger ?", + + "You need to select some text before creating a link": "Du mÃ¥sta markera ett objekt att applicera länken pÃ¥!", + + // Insert Table + "Insert Table": "Infoga tabell", + "Rows:": "Rader:", + "Number of rows": "Antal rader", + "Cols:": "Kolumner:", + "Number of columns": "Antal kolumner", + "Width:": "Bredd:", + "Width of the table": "Tabellbredd", + "Percent": "Procent", + "Pixels": "Pixlar", + "Em": "", + "Width unit": "Breddenheter", + "Fixed width columns": "Fixerad bredd", + "Alignment:": "Marginaljustering", + "Positioning of this table": "Tabellposition", + "Border thickness:": "Ramtjocklek", + "Leave empty for no border": "Lämna fältet tomt för att undvika ramar", + "Spacing": "Cellegenskaper", + "Cell spacing:": "Cellmarginaler:", + "Space between adjacent cells": "Utrymme mellan celler", + "Cell padding:": "Cellindrag:", + "Space between content and border in cell": "Utrymme mellan ram och cellinnehÃ¥ll", + "You must enter a number of rows": "Ange ental rader", + "You must enter a number of columns": "Ange antal kolumner", + + // Editor Help + "Keyboard shortcuts": "Snabbtangenter", + "The editor provides the following key combinations:": "Editorn nyttjar följande kombinationer:", + "new paragraph": "Ny paragraf ", + "insert linebreak": "Infoga radbrytning ", + "Set format to paragraph": "Aktivera paragrafläge", + "Clean content pasted from Word": "Rensa innehÃ¥ll inklistrat frÃ¥n MS Word", + "Headings": "Skapa standardrubrik", + "Cut selection": "Klipp ut markering", + "Copy selection": "Kopiera markering", + "Paste from clipboard": "Klistra in", + "Close": "Stäng", + + // Loading messages + "Loading in progress. Please wait !": "Editorn laddas. Vänta...", + "Constructing main object": "Skapar huvudobjekt", + "Create Toolbar": "Skapar verktygspanel", + "Register panel right": "Registerar panel höger", + "Register panel left": "Registerar panel vänster", + "Register panel top": "Registerar toppanel", + "Register panel bottom": "Registerar fotpanel" +} diff --git a/mailboxes/xinha/lang/vn.js b/mailboxes/xinha/lang/vn.js new file mode 100644 index 000000000..4bdd0d319 --- /dev/null +++ b/mailboxes/xinha/lang/vn.js @@ -0,0 +1,56 @@ +// I18N constants : Vietnamese +// LANG: "en", ENCODING: UTF-8 +// Author: Nguyá»…n Äình Nam, +// Modified 21/07/2004 by Phạm Mai Quân + +{ + "Bold": "Äậm", + "Italic": "Nghiêng", + "Underline": "Gạch Chân", + "Strikethrough": "Gạch Xóa", + "Subscript": "Viết Xuống Dưới", + "Superscript": "Viết Lên Trên", + "Justify Left": "Căn Trái", + "Justify Center": "Căn Giữa", + "Justify Right": "Căn Phải", + "Justify Full": "Căn Äá»u", + "Ordered List": "Danh Sách Có Thứ Tá»± (1, 2, 3)", + "Bulleted List": "Danh Sách Phi Thứ Tá»± (Chấm đầu dòng)", + "Decrease Indent": "Lùi Ra Ngoài", + "Increase Indent": "Thụt Vào Trong", + "Font Color": "Màu Chữ", + "Background Color": "Màu Ná»n", + "Horizontal Rule": "Dòng Kẻ Ngang", + "Insert Web Link": "Tạo Liên Kết", + "Insert/Modify Image": "Chèn Ảnh", + "Insert Table": "Chèn Bảng", + "Toggle HTML Source": "Chế Äá»™ Mã HTML", + "Enlarge Editor": "Phóng To Ô Soạn Thảo", + "About this editor": "Tá»± Giá»›i Thiệu", + "Help using editor": "Giúp Äỡ", + "Current style": "Äịnh Dạng Hiện Thá»i", + "Undoes your last action": "Há»§y thao tác trước", + "Redoes your last action": "Lấy lại thao tác vừa bá»", + "Cut selection": "Cắt", + "Copy selection": "Sao chép", + "Paste from clipboard": "Dán", + "Direction left to right": "Viết từ trái sang phải", + "Direction right to left": "Viết từ phải sang trái", + "OK": "Äồng ý", + "Cancel": "Há»§y", + "The full screen mode is known to cause problems with Internet Explorer, due to browser bugs that we weren": "Chế độ phóng to ô soạn thảo có thể gây lá»—i vá»›i Internet Explorer vì má»™t số lá»—i cá»§a trình duyệt này, vì thế chế độ này có thể sẽ không chạy. Hiển thị không đúng, lá»™n xá»™n, không có đầy đủ chức năng, và cÅ©ng có thể làm trình duyệt cá»§a bạn bị tắt ngang. Nếu bạn Ä‘ang sá»­ dụng Windows 9x bạn có thể bị báo lá»—i ", + "Path": "ÄÆ°á»ng Dẫn", + "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.": "Bạn Ä‘ang ở chế độ text. Sá»­ dụng nút [<>] để chuyển lại chế độ WYSIWIG.", + "Cancel": "Há»§y", + "Insert/Modify Link": "Thêm/Chỉnh sá»­a đưá»ng dẫn", + "New window (_blank)": "Cá»­a sổ má»›i (_blank)", + "None (use implicit)": "Không (sá»­ dụng implicit)", + "OK": "Äồng ý", + "Other": "Khác", + "Same frame (_self)": "Trên cùng khung (_self)", + "Target:": "NÆ¡i hiện thị:", + "Title (tooltip):": "Tiêu đỠ(cá»§a hướng dẫn):", + "Top frame (_top)": "Khung trên cùng (_top)", + "URL:": "URL:", + "You must enter the URL where this link points to": "Bạn phải Ä‘iá»n địa chỉ (URL) mà đưá»ng dẫn sẽ liên kết tá»›i" +} diff --git a/mailboxes/xinha/license.txt b/mailboxes/xinha/license.txt new file mode 100644 index 000000000..e7798cf0b --- /dev/null +++ b/mailboxes/xinha/license.txt @@ -0,0 +1,30 @@ +htmlArea License (based on BSD license) +Copyright (c) 2002-2004, interactivetools.com, inc. +Copyright (c) 2003-2004 dynarch.com +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1) Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2) Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3) Neither the name of interactivetools.com, inc. nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/mailboxes/xinha/modules/ColorPicker/ColorPicker.js b/mailboxes/xinha/modules/ColorPicker/ColorPicker.js new file mode 100644 index 000000000..dfdeb8576 --- /dev/null +++ b/mailboxes/xinha/modules/ColorPicker/ColorPicker.js @@ -0,0 +1,522 @@ +ColorPicker._pluginInfo={name:"colorPicker",version:"1.0",developer:"James Sleeman",developer_url:"http://www.gogo.co.nz/",c_owner:"Gogo Internet Services",license:"htmlArea",sponsor:"Gogo Internet Services",sponsor_url:"http://www.gogo.co.nz/"}; +function ColorPicker(){ +} +Xinha.colorPicker=function(_1){ +if(Xinha.colorPicker.savedColors.length===0){ +Xinha.colorPicker.loadColors(); +} +var _2=this; +var _3=false; +var _4=false; +var _5=0; +var _6=0; +this.callback=_1.callback?_1.callback:function(_7){ +alert("You picked "+_7); +}; +this.websafe=_1.websafe?_1.websafe:false; +this.savecolors=_1.savecolors?_1.savecolors:20; +this.cellsize=parseInt(_1.cellsize?_1.cellsize:"10px",10); +this.side=_1.granularity?_1.granularity:18; +var _8=this.side+1; +var _9=this.side-1; +this.value=1; +this.saved_cells=null; +this.table=document.createElement("table"); +this.table.className="dialog"; +this.table.cellSpacing=this.table.cellPadding=0; +this.table.onmouseup=function(){ +_3=false; +_4=false; +}; +this.tbody=document.createElement("tbody"); +this.table.appendChild(this.tbody); +this.table.style.border="1px solid WindowFrame"; +this.table.style.zIndex="1000"; +var tr=document.createElement("tr"); +var td=document.createElement("td"); +td.colSpan=this.side; +td.className="title"; +td.style.fontFamily="small-caption,caption,sans-serif"; +td.style.fontSize="x-small"; +td.appendChild(document.createTextNode(Xinha._lc("Click a color..."))); +td.style.borderBottom="1px solid WindowFrame"; +tr.appendChild(td); +td=null; +var td=document.createElement("td"); +td.className="title"; +td.colSpan=2; +td.style.fontFamily="Tahoma,Verdana,sans-serif"; +td.style.borderBottom="1px solid WindowFrame"; +td.style.paddingRight="0"; +tr.appendChild(td); +var _c=document.createElement("div"); +_c.title=Xinha._lc("Close"); +_c.className="buttonColor"; +_c.style.height="11px"; +_c.style.width="11px"; +_c.style.cursor="pointer"; +_c.onclick=function(){ +_2.close(); +}; +_c.appendChild(document.createTextNode("\xd7")); +_c.align="center"; +_c.style.verticalAlign="top"; +_c.style.position="relative"; +_c.style.cssFloat="right"; +_c.style.styleFloat="right"; +_c.style.padding="0"; +_c.style.margin="2px"; +_c.style.backgroundColor="transparent"; +_c.style.fontSize="11px"; +if(!Xinha.is_ie){ +_c.style.lineHeight="9px"; +} +_c.style.letterSpacing="0"; +td.appendChild(_c); +this.tbody.appendChild(tr); +_c=tr=td=null; +this.constrain_cb=document.createElement("input"); +this.constrain_cb.type="checkbox"; +this.chosenColor=document.createElement("input"); +this.chosenColor.type="text"; +this.chosenColor.maxLength=7; +this.chosenColor.style.width="50px"; +this.chosenColor.style.fontSize="11px"; +this.chosenColor.onchange=function(){ +if(/#[0-9a-f]{6,6}/i.test(this.value)){ +_2.backSample.style.backgroundColor=this.value; +_2.foreSample.style.color=this.value; +} +}; +this.backSample=document.createElement("div"); +this.backSample.appendChild(document.createTextNode("\xa0")); +this.backSample.style.fontWeight="bold"; +this.backSample.style.fontFamily="small-caption,caption,sans-serif"; +this.backSample.fontSize="x-small"; +this.foreSample=document.createElement("div"); +this.foreSample.appendChild(document.createTextNode(Xinha._lc("Sample"))); +this.foreSample.style.fontWeight="bold"; +this.foreSample.style.fontFamily="small-caption,caption,sans-serif"; +this.foreSample.fontSize="x-small"; +function toHex(_d){ +var h=_d.toString(16); +if(h.length<2){ +h="0"+h; +} +return h; +} +function tupleToColor(_f){ +return "#"+toHex(_f.red)+toHex(_f.green)+toHex(_f.blue); +} +function nearestPowerOf(num,_11){ +return Math.round(Math.round(num/_11)*_11); +} +function doubleHexDec(dec){ +return parseInt(dec.toString(16)+dec.toString(16),16); +} +function rgbToWebsafe(_13){ +_13.red=doubleHexDec(nearestPowerOf(parseInt(toHex(_13.red).charAt(0),16),3)); +_13.blue=doubleHexDec(nearestPowerOf(parseInt(toHex(_13.blue).charAt(0),16),3)); +_13.green=doubleHexDec(nearestPowerOf(parseInt(toHex(_13.green).charAt(0),16),3)); +return _13; +} +function hsvToRGB(h,s,v){ +var _17; +if(s===0){ +_17={red:v,green:v,blue:v}; +}else{ +h/=60; +var i=Math.floor(h); +var f=h-i; +var p=v*(1-s); +var q=v*(1-s*f); +var t=v*(1-s*(1-f)); +switch(i){ +case 0: +_17={red:v,green:t,blue:p}; +break; +case 1: +_17={red:q,green:v,blue:p}; +break; +case 2: +_17={red:p,green:v,blue:t}; +break; +case 3: +_17={red:p,green:q,blue:v}; +break; +case 4: +_17={red:t,green:p,blue:v}; +break; +default: +_17={red:v,green:p,blue:q}; +break; +} +} +_17.red=Math.ceil(_17.red*255); +_17.green=Math.ceil(_17.green*255); +_17.blue=Math.ceil(_17.blue*255); +return _17; +} +this.open=function(_1d,_1e,_1f){ +this.table.style.display=""; +this.pick_color(); +if(_1f&&/#[0-9a-f]{6,6}/i.test(_1f)){ +this.chosenColor.value=_1f; +this.backSample.style.backgroundColor=_1f; +this.foreSample.style.color=_1f; +} +this.table.style.position="absolute"; +var e=_1e; +var top=0; +var _22=0; +do{ +top+=e.offsetTop; +_22+=e.offsetLeft; +e=e.offsetParent; +}while(e); +var x,y; +if(/top/.test(_1d)){ +if(top-this.table.offsetHeight>0){ +this.table.style.top=(top-this.table.offsetHeight)+"px"; +}else{ +this.table.style.top=0; +} +}else{ +this.table.style.top=(top+_1e.offsetHeight)+"px"; +} +if(/left/.test(_1d)){ +this.table.style.left=_22+"px"; +}else{ +if(_22-(this.table.offsetWidth-_1e.offsetWidth)>0){ +this.table.style.left=(_22-(this.table.offsetWidth-_1e.offsetWidth))+"px"; +}else{ +this.table.style.left=0; +} +} +}; +function pickCell(_24){ +_2.chosenColor.value=_24.colorCode; +_2.backSample.style.backgroundColor=_24.colorCode; +_2.foreSample.style.color=_24.colorCode; +if((_24.hue>=195&&_24.saturation>0.5)||(_24.hue===0&&_24.saturation===0&&_24.value<0.5)||(_24.hue!==0&&_2.value<0.75)){ +_24.style.borderColor="#fff"; +}else{ +_24.style.borderColor="#000"; +} +_5=_24.thisrow; +_6=_24.thiscol; +} +function pickValue(_25){ +if(_2.value<0.5){ +_25.style.borderColor="#fff"; +}else{ +_25.style.borderColor="#000"; +} +_9=_25.thisrow; +_8=_25.thiscol; +_2.chosenColor.value=_2.saved_cells[_5][_6].colorCode; +_2.backSample.style.backgroundColor=_2.saved_cells[_5][_6].colorCode; +_2.foreSample.style.color=_2.saved_cells[_5][_6].colorCode; +} +function unpickCell(row,col){ +_2.saved_cells[row][col].style.borderColor=_2.saved_cells[row][col].colorCode; +} +this.pick_color=function(){ +var _28,cols; +var _29=this; +var _2a=359/(this.side); +var _2b=1/(this.side-1); +var _2c=1/(this.side-1); +var _2d=this.constrain_cb.checked; +if(this.saved_cells===null){ +this.saved_cells=[]; +for(var row=0;row=195&&_3f.saturation>0.5)||(_3f.hue===0&&_3f.saturation===0&&_3f.value<0.5)||(_3f.hue!==0&&_29.value<0.75)){ +_3f.style.borderColor="#fff"; +}else{ +_3f.style.borderColor="#000"; +} +} +}; +this.close=function(){ +this.table.style.display="none"; +}; +}; +Xinha.colorPicker.savedColors=[]; +Xinha.colorPicker.remember=function(_40,_41){ +for(var i=Xinha.colorPicker.savedColors.length;i--;){ +if(Xinha.colorPicker.savedColors[i]==_40){ +return false; +} +} +Xinha.colorPicker.savedColors.splice(0,0,_40); +Xinha.colorPicker.savedColors=Xinha.colorPicker.savedColors.slice(0,_41); +var _43=new Date(); +_43.setMonth(_43.getMonth()+1); +document.cookie="XinhaColorPicker="+escape(Xinha.colorPicker.savedColors.join("-"))+";expires="+_43.toGMTString(); +return true; +}; +Xinha.colorPicker.loadColors=function(){ +var _44=document.cookie.indexOf("XinhaColorPicker"); +if(_44!=-1){ +var _45=(document.cookie.indexOf("=",_44)+1); +var end=document.cookie.indexOf(";",_44); +if(end==-1){ +end=document.cookie.length; +} +Xinha.colorPicker.savedColors=unescape(document.cookie.substring(_45,end)).split("-"); +} +}; +Xinha.colorPicker._lc=function(_47){ +return Xinha._lc(_47); +}; + diff --git a/mailboxes/xinha/modules/CreateLink/link.html b/mailboxes/xinha/modules/CreateLink/link.html new file mode 100644 index 000000000..adad40058 --- /dev/null +++ b/mailboxes/xinha/modules/CreateLink/link.html @@ -0,0 +1,136 @@ + + + + Insert/Modify Link + + + + + + + + +
Insert/Modify Link
+
+ + + + + + + + + + + + + +
URL:
Title (tooltip):
Target: + +
+ +
+ + +
+
+ + \ No newline at end of file diff --git a/mailboxes/xinha/modules/CreateLink/link.js b/mailboxes/xinha/modules/CreateLink/link.js new file mode 100644 index 000000000..57d8c1b9a --- /dev/null +++ b/mailboxes/xinha/modules/CreateLink/link.js @@ -0,0 +1,84 @@ +CreateLink._pluginInfo={name:"CreateLink",origin:"Xinha Core",version:"$LastChangedRevision: 694 $".replace(/^[^:]*: (.*) \$$/,"$1"),developer:"The Xinha Core Developer Team",developer_url:"$HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/modules/CreateLink/link.js $".replace(/^[^:]*: (.*) \$$/,"$1"),sponsor:"",sponsor_url:"",license:"htmlArea"}; +function CreateLink(_1){ +} +Xinha.prototype._createLink=function(_2){ +var _3=this; +var _4=null; +if(typeof _2=="undefined"){ +_2=this.getParentElement(); +if(_2){ +while(_2&&!/^a$/i.test(_2.tagName)){ +_2=_2.parentNode; +} +} +} +if(!_2){ +var _5=_3.getSelection(); +var _6=_3.createRange(_5); +var _7=0; +if(Xinha.is_ie){ +if(_5.type=="Control"){ +_7=_6.length; +}else{ +_7=_6.compareEndPoints("StartToEnd",_6); +} +}else{ +_7=_6.compareBoundaryPoints(_6.START_TO_END,_6); +} +if(_7===0){ +alert(Xinha._lc("You need to select some text before creating a link")); +return; +} +_4={f_href:"",f_title:"",f_target:"",f_usetarget:_3.config.makeLinkShowsTarget}; +}else{ +_4={f_href:Xinha.is_ie?_3.stripBaseURL(_2.href):_2.getAttribute("href"),f_title:_2.title,f_target:_2.target,f_usetarget:_3.config.makeLinkShowsTarget}; +} +Dialog(_3.config.URIs.link,function(_8){ +if(!_8){ +return false; +} +var a=_2; +if(!a){ +try{ +var _a=Xinha.uniq("http://www.example.com/Link"); +_3._doc.execCommand("createlink",false,_a); +var _b=_3._doc.getElementsByTagName("a"); +for(var i=0;i<_b.length;i++){ +var _d=_b[i]; +if(_d.href==_a){ +if(!a){ +a=_d; +} +_d.href=_8.f_href; +if(_8.f_target){ +_d.target=_8.f_target; +} +if(_8.f_title){ +_d.title=_8.f_title; +} +} +} +} +catch(ex){ +} +}else{ +var _e=_8.f_href.trim(); +_3.selectNodeContents(a); +if(_e===""){ +_3._doc.execCommand("unlink",false,null); +_3.updateToolbar(); +return false; +}else{ +a.href=_e; +} +} +if(!(a&&a.tagName.toLowerCase()=="a")){ +return false; +} +a.target=_8.f_target.trim(); +a.title=_8.f_title.trim(); +_3.selectNodeContents(a); +_3.updateToolbar(); +},_4); +}; + diff --git a/mailboxes/xinha/modules/Dialogs/dialog.js b/mailboxes/xinha/modules/Dialogs/dialog.js new file mode 100644 index 000000000..fcb57d550 --- /dev/null +++ b/mailboxes/xinha/modules/Dialogs/dialog.js @@ -0,0 +1,62 @@ +function Dialog(_1,_2,_3){ +if(typeof _3=="undefined"){ +_3=window; +} +Dialog._geckoOpenModal(_1,_2,_3); +} +Dialog._parentEvent=function(ev){ +setTimeout(function(){ +if(Dialog._modal&&!Dialog._modal.closed){ +Dialog._modal.focus(); +} +},50); +try{ +if(Dialog._modal&&!Dialog._modal.closed){ +Xinha._stopEvent(ev); +} +} +catch(e){ +} +}; +Dialog._return=null; +Dialog._modal=null; +Dialog._arguments=null; +Dialog._geckoOpenModal=function(_5,_6,_7){ +var _8=window.open(_5,"hadialog","toolbar=no,menubar=no,personalbar=no,width=10,height=10,"+"scrollbars=no,resizable=yes,modal=yes,dependable=yes"); +Dialog._modal=_8; +Dialog._arguments=_7; +function capwin(w){ +Xinha._addEvent(w,"click",Dialog._parentEvent); +Xinha._addEvent(w,"mousedown",Dialog._parentEvent); +Xinha._addEvent(w,"focus",Dialog._parentEvent); +} +function relwin(w){ +Xinha._removeEvent(w,"click",Dialog._parentEvent); +Xinha._removeEvent(w,"mousedown",Dialog._parentEvent); +Xinha._removeEvent(w,"focus",Dialog._parentEvent); +} +capwin(window); +for(var i=0;i(.*?)<\/l10n>/ig,function(_9,_a){ +return _4._lc(_a); +}).replace(/="_\((.*?)\)"/g,function(_b,_c){ +return "=\""+_4._lc(_c)+"\""; +}); +this.rootElem.innerHTML=_2; +this.editor.notifyOn("resize",function(e,_e){ +_4.rootElem.style.width=_4.width=_4.editor._framework.ed_cell.offsetWidth+"px"; +_4.rootElem.style.height=_4.height=_4.editor._framework.ed_cell.offsetHeight+"px"; +_4.onresize(); +}); +}; +Xinha.Dialog.prototype.onresize=function(){ +return true; +}; +Xinha.Dialog.prototype.show=function(_f){ +if(Xinha.is_ie){ +this._lastRange=this.editor._createRange(this.editor._getSelection()); +} +if(typeof _f!="undefined"){ +this.setValues(_f); +} +this._restoreTo=[this.editor._textArea.style.display,this.editor._iframe.style.visibility,this.editor.hidePanels()]; +this.editor._textArea.style.display="none"; +this.editor._iframe.style.visibility="hidden"; +this.rootElem.style.display=""; +}; +Xinha.Dialog.prototype.hide=function(){ +this.rootElem.style.display="none"; +this.editor._textArea.style.display=this._restoreTo[0]; +this.editor._iframe.style.visibility=this._restoreTo[1]; +this.editor.showPanels(this._restoreTo[2]); +if(Xinha.is_ie){ +this._lastRange.select(); +} +this.editor.updateToolbar(); +return this.getValues(); +}; +Xinha.Dialog.prototype.toggle=function(){ +if(this.rootElem.style.display=="none"){ +this.show(); +}else{ +this.hide(); +} +}; +Xinha.Dialog.prototype.setValues=function(_10){ +for(var i in _10){ +var _12=this.getElementsByName(i); +if(!_12){ +continue; +} +for(var x=0;x<_12.length;x++){ +var e=_12[x]; +switch(e.tagName.toLowerCase()){ +case "select": +for(var j=0;j=0){ +v=i.options[i.selectedIndex]; +} +} +break; +case "textarea": +case "input": +default: +switch(i.type.toLowerCase()){ +case "radio": +if(i.checked){ +v=i.value; +break; +} +case "checkbox": +if(v==null){ +if(this.getElementsByName(this.r_id[i.name]).length>1){ +v=new Array(); +} +} +if(i.checked){ +if(v!=null&&typeof v=="object"&&v.push){ +v.push(i.value); +}else{ +v=i.value; +} +} +break; +default: +v=i.value; +break; +} +} +_17[this.r_id[i.name]]=v; +} +return _17; +}; +Xinha.Dialog.prototype.getElementById=function(id){ +return this.document.getElementById(this.id[id]?this.id[id]:id); +}; +Xinha.Dialog.prototype.getElementsByName=function(_1e){ +return this.document.getElementsByName(this.id[_1e]?this.id[_1e]:_1e); +}; + diff --git a/mailboxes/xinha/modules/Dialogs/panel-dialog.js b/mailboxes/xinha/modules/Dialogs/panel-dialog.js new file mode 100644 index 000000000..321dac04e --- /dev/null +++ b/mailboxes/xinha/modules/Dialogs/panel-dialog.js @@ -0,0 +1,76 @@ + +Xinha.PanelDialog = function(editor, side, html, localizer) +{ + this.id = { }; + this.r_id = { }; // reverse lookup id + this.editor = editor; + this.document = document; + this.rootElem = editor.addPanel(side); + + var dialog = this; + if(typeof localizer == 'function') + { + this._lc = localizer; + } + else if(localizer) + { + this._lc = function(string) + { + return Xinha._lc(string,localizer); + }; + } + else + { + this._lc = function(string) + { + return string; + }; + } + + html = html.replace(/\[([a-z0-9_]+)\]/ig, + function(fullString, id) + { + if(typeof dialog.id[id] == 'undefined') + { + dialog.id[id] = Xinha.uniq('Dialog'); + dialog.r_id[dialog.id[id]] = id; + } + return dialog.id[id]; + } + ).replace(/(.*?)<\/l10n>/ig, + function(fullString,translate) + { + return dialog._lc(translate) ; + } + ).replace(/="_\((.*?)\)"/g, + function(fullString, translate) + { + return '="' + dialog._lc(translate) + '"'; + } + ); + + this.rootElem.innerHTML = html; +}; + +Xinha.PanelDialog.prototype.show = function(values) +{ + this.editor.showPanel(this.rootElem); +}; + +Xinha.PanelDialog.prototype.hide = function() +{ + this.editor.hidePanel(this.rootElem); + return this.getValues(); +}; + +Xinha.PanelDialog.prototype.onresize = Xinha.Dialog.prototype.onresize; + +Xinha.PanelDialog.prototype.toggle = Xinha.Dialog.prototype.toggle; + +Xinha.PanelDialog.prototype.setValues = Xinha.Dialog.prototype.setValues; + +Xinha.PanelDialog.prototype.getValues = Xinha.Dialog.prototype.getValues; + +Xinha.PanelDialog.prototype.getElementById = Xinha.Dialog.prototype.getElementById; + +Xinha.PanelDialog.prototype.getElementsByName = Xinha.Dialog.prototype.getElementsByName; \ No newline at end of file diff --git a/mailboxes/xinha/modules/Dialogs/popupwin.js b/mailboxes/xinha/modules/Dialogs/popupwin.js new file mode 100644 index 000000000..6fcffe412 --- /dev/null +++ b/mailboxes/xinha/modules/Dialogs/popupwin.js @@ -0,0 +1,120 @@ +function PopupWin(_1,_2,_3,_4){ +this.editor=_1; +this.handler=_3; +var _5=window.open("","__ha_dialog","toolbar=no,menubar=no,personalbar=no,width=600,height=600,left=20,top=40,scrollbars=no,resizable=yes"); +this.window=_5; +var _6=_5.document; +this.doc=_6; +var _7=this; +var _8=document.baseURI||document.URL; +if(_8&&_8.match(/(.*)\/([^\/]+)/)){ +_8=RegExp.$1+"/"; +} +if(typeof _editor_url!="undefined"&&!(/^\//.test(_editor_url))&&!(/http:\/\//.test(_editor_url))){ +_8+=_editor_url; +}else{ +_8=_editor_url; +} +if(!(/\/$/.test(_8))){ +_8+="/"; +} +this.baseURL=_8; +_6.open(); +var _9=""+_2+"\n"; +_9+="\n"; +if(_editor_skin!=""){ +_9+="\n"; +} +_9+="\n"; +_9+=""; +_6.write(_9); +_6.close(); +function init2(){ +var _a=_6.body; +if(!_a){ +setTimeout(init2,25); +return false; +} +_5.title=_2; +_6.documentElement.style.padding="0px"; +_6.documentElement.style.margin="0px"; +var _b=_6.createElement("div"); +_b.className="content"; +_7.content=_b; +_a.appendChild(_b); +_7.element=_a; +_4(_7); +_5.focus(); +} +init2(); +} +PopupWin.prototype.callHandler=function(){ +var _c=["input","textarea","select"]; +var _d={}; +for(var ti=_c.length;--ti>=0;){ +var _f=_c[ti]; +var els=this.content.getElementsByTagName(_f); +for(var j=0;j +{ + "Maximize/Minimize Editor": "Maximera/Minimera WYSIWYG fönster" +}; diff --git a/mailboxes/xinha/modules/Gecko/Gecko.js b/mailboxes/xinha/modules/Gecko/Gecko.js new file mode 100644 index 000000000..1f03ef4e3 --- /dev/null +++ b/mailboxes/xinha/modules/Gecko/Gecko.js @@ -0,0 +1,386 @@ +Gecko._pluginInfo={name:"Gecko",origin:"Xinha Core",version:"$LastChangedRevision: 716 $".replace(/^[^:]*: (.*) \$$/,"$1"),developer:"The Xinha Core Developer Team",developer_url:"$HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/modules/Gecko/Gecko.js $".replace(/^[^:]*: (.*) \$$/,"$1"),sponsor:"",sponsor_url:"",license:"htmlArea"}; +function Gecko(_1){ +this.editor=_1; +_1.Gecko=this; +} +Gecko.prototype.onKeyPress=function(ev){ +var _3=this.editor; +var s=_3.getSelection(); +if(_3.isShortCut(ev)){ +switch(_3.getKey(ev).toLowerCase()){ +case "z": +if(_3._unLink&&_3._unlinkOnUndo){ +Xinha._stopEvent(ev); +_3._unLink(); +_3.updateToolbar(); +return true; +} +break; +case "a": +sel=_3.getSelection(); +sel.removeAllRanges(); +range=_3.createRange(); +range.selectNodeContents(_3._doc.body); +sel.addRange(range); +Xinha._stopEvent(ev); +return true; +break; +case "v": +if(!_3.config.htmlareaPaste){ +return true; +} +break; +} +} +switch(_3.getKey(ev)){ +case " ": +var _5=function(_6,_7){ +var _8=_6.nextSibling; +if(typeof _7=="string"){ +_7=_3._doc.createElement(_7); +} +var a=_6.parentNode.insertBefore(_7,_8); +Xinha.removeFromParent(_6); +a.appendChild(_6); +_8.data=" "+_8.data; +s.collapse(_8,1); +_3._unLink=function(){ +var t=a.firstChild; +a.removeChild(t); +a.parentNode.insertBefore(t,a); +Xinha.removeFromParent(a); +_3._unLink=null; +_3._unlinkOnUndo=false; +}; +_3._unlinkOnUndo=true; +return a; +}; +if(_3.config.convertUrlsToLinks&&s&&s.isCollapsed&&s.anchorNode.nodeType==3&&s.anchorNode.data.length>3&&s.anchorNode.data.indexOf(".")>=0){ +var _b=s.anchorNode.data.substring(0,s.anchorOffset).search(/\S{4,}$/); +if(_b==-1){ +break; +} +if(_3._getFirstAncestor(s,"a")){ +break; +} +var _c=s.anchorNode.data.substring(0,s.anchorOffset).replace(/^.*?(\S*)$/,"$1"); +var _d=_c.match(Xinha.RE_email); +if(_d){ +var _e=s.anchorNode; +var _f=_e.splitText(s.anchorOffset); +var _10=_e.splitText(_b); +_5(_10,"a").href="mailto:"+_d[0]; +break; +} +RE_date=/([0-9]+\.)+/; +RE_ip=/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/; +var _11=_c.match(Xinha.RE_url); +if(_11){ +if(RE_date.test(_c)){ +if(!RE_ip.test(_c)){ +break; +} +} +var _12=s.anchorNode; +var _13=_12.splitText(s.anchorOffset); +var _14=_12.splitText(_b); +_5(_14,"a").href=(_11[1]?_11[1]:"http://")+_11[2]; +break; +} +} +break; +} +switch(ev.keyCode){ +case 27: +if(_3._unLink){ +_3._unLink(); +Xinha._stopEvent(ev); +} +break; +break; +case 8: +case 46: +if(!ev.shiftKey&&this.handleBackspace()){ +Xinha._stopEvent(ev); +} +default: +_3._unlinkOnUndo=false; +if(s.anchorNode&&s.anchorNode.nodeType==3){ +var a=_3._getFirstAncestor(s,"a"); +if(!a){ +break; +} +if(!a._updateAnchTimeout){ +if(s.anchorNode.data.match(Xinha.RE_email)&&a.href.match("mailto:"+s.anchorNode.data.trim())){ +var _16=s.anchorNode; +var _17=function(){ +a.href="mailto:"+_16.data.trim(); +a._updateAnchTimeout=setTimeout(_17,250); +}; +a._updateAnchTimeout=setTimeout(_17,1000); +break; +} +var m=s.anchorNode.data.match(Xinha.RE_url); +if(m&&a.href.match(s.anchorNode.data.trim())){ +var _19=s.anchorNode; +var _1a=function(){ +m=_19.data.match(Xinha.RE_url); +if(m){ +a.href=(m[1]?m[1]:"http://")+m[2]; +} +a._updateAnchTimeout=setTimeout(_1a,250); +}; +a._updateAnchTimeout=setTimeout(_1a,1000); +} +} +} +break; +} +return false; +}; +Gecko.prototype.handleBackspace=function(){ +var _1b=this.editor; +setTimeout(function(){ +var sel=_1b.getSelection(); +var _1d=_1b.createRange(sel); +var SC=_1d.startContainer; +var SO=_1d.startOffset; +var EC=_1d.endContainer; +var EO=_1d.endOffset; +var _22=SC.nextSibling; +if(SC.nodeType==3){ +SC=SC.parentNode; +} +if(!(/\S/.test(SC.tagName))){ +var p=document.createElement("p"); +while(SC.firstChild){ +p.appendChild(SC.firstChild); +} +SC.parentNode.insertBefore(p,SC); +Xinha.removeFromParent(SC); +var r=_1d.cloneRange(); +r.setStartBefore(_22); +r.setEndAfter(_22); +r.extractContents(); +sel.removeAllRanges(); +sel.addRange(r); +} +},10); +}; +Gecko.prototype.inwardHtml=function(_25){ +_25=_25.replace(/<(\/?)strong(\s|>|\/)/ig,"<$1b$2"); +_25=_25.replace(/<(\/?)em(\s|>|\/)/ig,"<$1i$2"); +_25=_25.replace(/<(\/?)del(\s|>|\/)/ig,"<$1strike$2"); +return _25; +}; +Gecko.prototype.outwardHtml=function(_26){ +_26=_26.replace(/[\s]*<\/script>/ig,""); +return _26; +}; +Gecko.prototype.onExecCommand=function(_27,UI,_29){ +try{ +this.editor._doc.execCommand("useCSS",false,true); +this.editor._doc.execCommand("styleWithCSS",false,false); +} +catch(ex){ +} +switch(_27){ +case "paste": +alert(Xinha._lc("The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.")); +return true; +} +return false; +}; +Gecko.prototype.onMouseDown=function(ev){ +if(ev.target.tagName.toLowerCase()=="hr"){ +var sel=this.editor.getSelection(); +var _2c=this.editor.createRange(sel); +_2c.selectNode(ev.target); +} +}; +Xinha.prototype.insertNodeAtSelection=function(_2d){ +var sel=this.getSelection(); +var _2f=this.createRange(sel); +sel.removeAllRanges(); +_2f.deleteContents(); +var _30=_2f.startContainer; +var pos=_2f.startOffset; +var _32=_2d; +switch(_30.nodeType){ +case 3: +if(_2d.nodeType==3){ +_30.insertData(pos,_2d.data); +_2f=this.createRange(); +_2f.setEnd(_30,pos+_2d.length); +_2f.setStart(_30,pos+_2d.length); +sel.addRange(_2f); +}else{ +_30=_30.splitText(pos); +if(_2d.nodeType==11){ +_32=_32.firstChild; +} +_30.parentNode.insertBefore(_2d,_30); +this.selectNodeContents(_32); +this.updateToolbar(); +} +break; +case 1: +if(_2d.nodeType==11){ +_32=_32.firstChild; +} +_30.insertBefore(_2d,_30.childNodes[pos]); +this.selectNodeContents(_32); +this.updateToolbar(); +break; +} +}; +Xinha.prototype.getParentElement=function(sel){ +if(typeof sel=="undefined"){ +sel=this.getSelection(); +} +var _34=this.createRange(sel); +try{ +var p=_34.commonAncestorContainer; +if(!_34.collapsed&&_34.startContainer==_34.endContainer&&_34.startOffset-_34.endOffset<=1&&_34.startContainer.hasChildNodes()){ +p=_34.startContainer.childNodes[_34.startOffset]; +} +while(p.nodeType==3){ +p=p.parentNode; +} +return p; +} +catch(ex){ +return null; +} +}; +Xinha.prototype.activeElement=function(sel){ +if((sel===null)||this.selectionEmpty(sel)){ +return null; +} +if(!sel.isCollapsed){ +if(sel.anchorNode.childNodes.length>sel.anchorOffset&&sel.anchorNode.childNodes[sel.anchorOffset].nodeType==1){ +return sel.anchorNode.childNodes[sel.anchorOffset]; +}else{ +if(sel.anchorNode.nodeType==1){ +return sel.anchorNode; +}else{ +return null; +} +} +} +return null; +}; +Xinha.prototype.selectionEmpty=function(sel){ +if(!sel){ +return true; +} +if(typeof sel.isCollapsed!="undefined"){ +return sel.isCollapsed; +} +return true; +}; +Xinha.prototype.selectNodeContents=function(_38,pos){ +this.focusEditor(); +this.forceRedraw(); +var _3a; +var _3b=typeof pos=="undefined"?true:false; +var sel=this.getSelection(); +_3a=this._doc.createRange(); +if(_3b&&_38.tagName&&_38.tagName.toLowerCase().match(/table|img|input|textarea|select/)){ +_3a.selectNode(_38); +}else{ +_3a.selectNodeContents(_38); +} +sel.removeAllRanges(); +sel.addRange(_3a); +}; +Xinha.prototype.insertHTML=function(_3d){ +var sel=this.getSelection(); +var _3f=this.createRange(sel); +this.focusEditor(); +var _40=this._doc.createDocumentFragment(); +var div=this._doc.createElement("div"); +div.innerHTML=_3d; +while(div.firstChild){ +_40.appendChild(div.firstChild); +} +var _42=this.insertNodeAtSelection(_40); +}; +Xinha.prototype.getSelectedHTML=function(){ +var sel=this.getSelection(); +var _44=this.createRange(sel); +return Xinha.getHTML(_44.cloneContents(),false,this); +}; +Xinha.prototype.getSelection=function(){ +return this._iframe.contentWindow.getSelection(); +}; +Xinha.prototype.createRange=function(sel){ +this.activateEditor(); +if(typeof sel!="undefined"){ +try{ +return sel.getRangeAt(0); +} +catch(ex){ +return this._doc.createRange(); +} +}else{ +return this._doc.createRange(); +} +}; +Xinha.prototype.isKeyEvent=function(_46){ +return _46.type=="keypress"; +}; +Xinha.prototype.getKey=function(_47){ +return String.fromCharCode(_47.charCode); +}; +Xinha.getOuterHTML=function(_48){ +return (new XMLSerializer()).serializeToString(_48); +}; +Xinha.prototype.cc=String.fromCharCode(173); +Xinha.prototype.setCC=function(_49){ +if(_49=="textarea"){ +var ta=this._textArea; +var _4b=ta.selectionStart; +var _4c=ta.value.substring(0,_4b); +var _4d=ta.value.substring(_4b,ta.value.length); +if(_4d.match(/^[^<]*>/)){ +var _4e=_4d.indexOf(">")+1; +ta.value=_4c+_4d.substring(0,_4e)+this.cc+_4d.substring(_4e,_4d.length); +}else{ +ta.value=_4c+this.cc+_4d; +} +}else{ +var sel=this.getSelection(); +sel.getRangeAt(0).insertNode(document.createTextNode(this.cc)); +} +}; +Xinha.prototype.findCC=function(_50){ +var _51=(_50=="textarea")?window:this._iframe.contentWindow; +if(_51.find(this.cc)){ +if(_50=="textarea"){ +var ta=this._textArea; +var _53=pos=ta.selectionStart; +var end=ta.selectionEnd; +var _55=ta.scrollTop; +ta.value=ta.value.substring(0,_53)+ta.value.substring(end,ta.value.length); +ta.selectionStart=pos; +ta.selectionEnd=pos; +ta.scrollTop=_55; +ta.focus(); +}else{ +var sel=this.getSelection(); +sel.getRangeAt(0).deleteContents(); +} +} +}; +Xinha.prototype._standardToggleBorders=Xinha.prototype._toggleBorders; +Xinha.prototype._toggleBorders=function(){ +var _57=this._standardToggleBorders(); +var _58=this._doc.getElementsByTagName("TABLE"); +for(var i=0;i<_58.length;i++){ +_58[i].style.display="none"; +_58[i].style.display="table"; +} +return _57; +}; + diff --git a/mailboxes/xinha/modules/Gecko/paraHandlerBest.js b/mailboxes/xinha/modules/Gecko/paraHandlerBest.js new file mode 100644 index 000000000..317fead3c --- /dev/null +++ b/mailboxes/xinha/modules/Gecko/paraHandlerBest.js @@ -0,0 +1,293 @@ +EnterParagraphs._pluginInfo={name:"EnterParagraphs",version:"1.0",developer:"Adam Wright",developer_url:"http://www.hipikat.org/",sponsor:"The University of Western Australia",sponsor_url:"http://www.uwa.edu.au/",license:"htmlArea"}; +EnterParagraphs.prototype._whiteSpace=/^\s*$/; +EnterParagraphs.prototype._pExclusions=/^(address|blockquote|body|dd|div|dl|dt|fieldset|form|h1|h2|h3|h4|h5|h6|hr|li|noscript|ol|p|pre|table|ul)$/i; +EnterParagraphs.prototype._pContainers=/^(body|del|div|fieldset|form|ins|map|noscript|object|td|th)$/i; +EnterParagraphs.prototype._pBreak=/^(address|pre|blockquote)$/i; +EnterParagraphs.prototype._permEmpty=/^(area|base|basefont|br|col|frame|hr|img|input|isindex|link|meta|param)$/i; +EnterParagraphs.prototype._elemSolid=/^(applet|br|button|hr|img|input|table)$/i; +EnterParagraphs.prototype._pifySibling=/^(address|blockquote|del|div|dl|fieldset|form|h1|h2|h3|h4|h5|h6|hr|ins|map|noscript|object|ol|p|pre|table|ul|)$/i; +EnterParagraphs.prototype._pifyForced=/^(ul|ol|dl|table)$/i; +EnterParagraphs.prototype._pifyParent=/^(dd|dt|li|td|th|tr)$/i; +function EnterParagraphs(_1){ +this.editor=_1; +if(Xinha.is_gecko){ +this.onKeyPress=this.__onKeyPress; +} +} +EnterParagraphs.prototype.name="EnterParagraphs"; +EnterParagraphs.prototype.insertAdjacentElement=function(_2,_3,el){ +if(_3=="BeforeBegin"){ +_2.parentNode.insertBefore(el,_2); +}else{ +if(_3=="AfterEnd"){ +_2.nextSibling?_2.parentNode.insertBefore(el,_2.nextSibling):_2.parentNode.appendChild(el); +}else{ +if(_3=="AfterBegin"&&_2.firstChild){ +_2.insertBefore(el,_2.firstChild); +}else{ +if(_3=="BeforeEnd"||_3=="AfterBegin"){ +_2.appendChild(el); +} +} +} +} +}; +EnterParagraphs.prototype.forEachNodeUnder=function(_5,_6,_7,_8){ +var _9,end; +if(_5.nodeType==11&&_5.firstChild){ +_9=_5.firstChild; +end=_5.lastChild; +}else{ +_9=end=_5; +} +while(end.lastChild){ +end=end.lastChild; +} +return this.forEachNode(_9,end,_6,_7,_8); +}; +EnterParagraphs.prototype.forEachNode=function(_a,_b,_c,_d,_e){ +var _f=function(_10,_11){ +return (_11=="ltr"?_10.nextSibling:_10.previousSibling); +}; +var _12=function(_13,_14){ +return (_14=="ltr"?_13.firstChild:_13.lastChild); +}; +var _15,lookup,fnReturnVal; +var _16=_e; +var _17=false; +while(_15!=_d=="ltr"?_b:_a){ +if(!_15){ +_15=_d=="ltr"?_a:_b; +}else{ +if(_12(_15,_d)){ +_15=_12(_15,_d); +}else{ +if(_f(_15,_d)){ +_15=_f(_15,_d); +}else{ +lookup=_15; +while(!_f(lookup,_d)&&lookup!=(_d=="ltr"?_b:_a)){ +lookup=lookup.parentNode; +} +_15=(_f(lookup,_d)?_f(lookup,_d):lookup); +} +} +} +_17=(_15==(_d=="ltr"?_b:_a)); +switch(_c){ +case "cullids": +fnReturnVal=this._fenCullIds(_15,_16); +break; +case "find_fill": +fnReturnVal=this._fenEmptySet(_15,_16,_c,_17); +break; +case "find_cursorpoint": +fnReturnVal=this._fenEmptySet(_15,_16,_c,_17); +break; +} +if(fnReturnVal[0]){ +return fnReturnVal[1]; +} +if(_17){ +break; +} +if(fnReturnVal[1]){ +_16=fnReturnVal[1]; +} +} +return false; +}; +EnterParagraphs.prototype._fenEmptySet=function(_18,_19,_1a,_1b){ +if(!_19&&!_18.firstChild){ +_19=_18; +} +if((_18.nodeType==1&&this._elemSolid.test(_18.nodeName))||(_18.nodeType==3&&!this._whiteSpace.test(_18.nodeValue))||(_18.nodeType!=1&&_18.nodeType!=3)){ +switch(_1a){ +case "find_fill": +return new Array(true,false); +break; +case "find_cursorpoint": +return new Array(true,_18); +break; +} +} +if(_1b){ +return new Array(true,_19); +} +return new Array(false,_19); +}; +EnterParagraphs.prototype._fenCullIds=function(_1c,_1d,_1e){ +if(_1d.id){ +_1e[_1d.id]?_1d.id="":_1e[_1d.id]=true; +} +return new Array(false,_1e); +}; +EnterParagraphs.prototype.processSide=function(rng,_20){ +var _21=function(_22,_23){ +return (_23=="left"?_22.previousSibling:_22.nextSibling); +}; +var _24=_20=="left"?rng.startContainer:rng.endContainer; +var _25=_20=="left"?rng.startOffset:rng.endOffset; +var _26,start=_24; +while(start.nodeType==1&&!this._permEmpty.test(start.nodeName)){ +start=(_25?start.lastChild:start.firstChild); +} +while(_26=_26?(_21(_26,_20)?_21(_26,_20):_26.parentNode):start){ +if(_21(_26,_20)){ +if(this._pExclusions.test(_21(_26,_20).nodeName)){ +return this.processRng(rng,_20,_26,_21(_26,_20),(_20=="left"?"AfterEnd":"BeforeBegin"),true,false); +} +}else{ +if(this._pContainers.test(_26.parentNode.nodeName)){ +return this.processRng(rng,_20,_26,_26.parentNode,(_20=="left"?"AfterBegin":"BeforeEnd"),true,false); +}else{ +if(this._pExclusions.test(_26.parentNode.nodeName)){ +if(this._pBreak.test(_26.parentNode.nodeName)){ +return this.processRng(rng,_20,_26,_26.parentNode,(_20=="left"?"AfterBegin":"BeforeEnd"),false,(_20=="left"?true:false)); +}else{ +return this.processRng(rng,_20,(_26=_26.parentNode),(_21(_26,_20)?_21(_26,_20):_26.parentNode),(_21(_26,_20)?(_20=="left"?"AfterEnd":"BeforeBegin"):(_20=="left"?"AfterBegin":"BeforeEnd")),false,false); +} +} +} +} +} +}; +EnterParagraphs.prototype.processRng=function(rng,_28,_29,_2a,_2b,_2c,_2d){ +var _2e=_28=="left"?rng.startContainer:rng.endContainer; +var _2f=_28=="left"?rng.startOffset:rng.endOffset; +var _30=this.editor; +var _31=_30._doc.createRange(); +_31.selectNode(_29); +if(_28=="left"){ +_31.setEnd(_2e,_2f); +rng.setStart(_31.startContainer,_31.startOffset); +}else{ +if(_28=="right"){ +_31.setStart(_2e,_2f); +rng.setEnd(_31.endContainer,_31.endOffset); +} +} +var cnt=_31.cloneContents(); +this.forEachNodeUnder(cnt,"cullids","ltr",this.takenIds,false,false); +var _33,pifyOffset,fill; +_33=_28=="left"?(_31.endContainer.nodeType==3?true:false):(_31.startContainer.nodeType==3?false:true); +pifyOffset=_33?_31.startOffset:_31.endOffset; +_33=_33?_31.startContainer:_31.endContainer; +if(this._pifyParent.test(_33.nodeName)&&_33.parentNode.childNodes.item(0)==_33){ +while(!this._pifySibling.test(_33.nodeName)){ +_33=_33.parentNode; +} +} +if(cnt.nodeType==11&&!cnt.firstChild){ +if(_33.nodeName!="BODY"||(_33.nodeName=="BODY"&&pifyOffset!=0)){ +cnt.appendChild(_30._doc.createElement(_33.nodeName)); +} +} +fill=this.forEachNodeUnder(cnt,"find_fill","ltr",false); +if(fill&&this._pifySibling.test(_33.nodeName)&&((pifyOffset==0)||(pifyOffset==1&&this._pifyForced.test(_33.nodeName)))){ +_29=_30._doc.createElement("p"); +_29.innerHTML=" "; +if((_28=="left")&&_33.previousSibling){ +return new Array(_33.previousSibling,"AfterEnd",_29); +}else{ +if((_28=="right")&&_33.nextSibling){ +return new Array(_33.nextSibling,"BeforeBegin",_29); +}else{ +return new Array(_33.parentNode,(_28=="left"?"AfterBegin":"BeforeEnd"),_29); +} +} +} +if(fill){ +if(fill.nodeType==3){ +fill=_30._doc.createDocumentFragment(); +} +if((fill.nodeType==1&&!this._elemSolid.test())||fill.nodeType==11){ +var _34=_30._doc.createElement("p"); +_34.innerHTML=" "; +fill.appendChild(_34); +}else{ +var _34=_30._doc.createElement("p"); +_34.innerHTML=" "; +fill.parentNode.insertBefore(parentNode,fill); +} +} +if(fill){ +_29=fill; +}else{ +_29=(_2c||(cnt.nodeType==11&&!cnt.firstChild))?_30._doc.createElement("p"):_30._doc.createDocumentFragment(); +_29.appendChild(cnt); +} +if(_2d){ +_29.appendChild(_30._doc.createElement("br")); +} +return new Array(_2a,_2b,_29); +}; +EnterParagraphs.prototype.isNormalListItem=function(rng){ +var _36,listNode; +_36=rng.startContainer; +if((typeof _36.nodeName!="undefined")&&(_36.nodeName.toLowerCase()=="li")){ +listNode=_36; +}else{ +if((typeof _36.parentNode!="undefined")&&(typeof _36.parentNode.nodeName!="undefined")&&(_36.parentNode.nodeName.toLowerCase()=="li")){ +listNode=_36.parentNode; +}else{ +return false; +} +} +if(!listNode.previousSibling){ +if(rng.startOffset==0){ +return false; +} +} +return true; +}; +EnterParagraphs.prototype.__onKeyPress=function(ev){ +if(ev.keyCode==13&&!ev.shiftKey&&this.editor._iframe.contentWindow.getSelection){ +return this.handleEnter(ev); +} +}; +EnterParagraphs.prototype.handleEnter=function(ev){ +var _39; +var sel=this.editor.getSelection(); +var rng=this.editor.createRange(sel); +if(this.isNormalListItem(rng)){ +return true; +} +this.takenIds=new Object(); +var _3c=this.processSide(rng,"left"); +var _3d=this.processSide(rng,"right"); +_39=_3d[2]; +sel.removeAllRanges(); +rng.deleteContents(); +var _3e=this.forEachNodeUnder(_39,"find_cursorpoint","ltr",false,true); +if(!_3e){ +alert("INTERNAL ERROR - could not find place to put cursor after ENTER"); +} +if(_3c){ +this.insertAdjacentElement(_3c[0],_3c[1],_3c[2]); +} +if(_3d&&_3d.nodeType!=1){ +this.insertAdjacentElement(_3d[0],_3d[1],_3d[2]); +} +if((_3e)&&(this._permEmpty.test(_3e.nodeName))){ +var _3f=0; +while(_3e.parentNode.childNodes.item(_3f)!=_3e){ +_3f++; +} +sel.collapse(_3e.parentNode,_3f); +}else{ +try{ +sel.collapse(_3e,0); +if(_3e.nodeType==3){ +_3e=_3e.parentNode; +} +this.editor.scrollToElement(_3e); +} +catch(e){ +} +} +this.editor.updateToolbar(); +Xinha._stopEvent(ev); +return true; +}; + diff --git a/mailboxes/xinha/modules/Gecko/paraHandlerDirty.js b/mailboxes/xinha/modules/Gecko/paraHandlerDirty.js new file mode 100644 index 000000000..aef572238 --- /dev/null +++ b/mailboxes/xinha/modules/Gecko/paraHandlerDirty.js @@ -0,0 +1,116 @@ +EnterParagraphs._pluginInfo={name:"EnterParagraphs",origin:"Xinha Core",version:"$LastChangedRevision: 688 $".replace(/^[^:]*: (.*) \$$/,"$1"),developer:"The Xinha Core Developer Team",developer_url:"$HeadURL: http://svn.xinha.python-hosting.com/trunk/modules/Gecko/paraHandlerDirty.js $".replace(/^[^:]*: (.*) \$$/,"$1"),sponsor:"",sponsor_url:"",license:"htmlArea"}; +function EnterParagraphs(_1){ +this.editor=_1; +} +EnterParagraphs.prototype.onKeyPress=function(ev){ +if(ev.keyCode==13&&!ev.shiftKey){ +this.dom_checkInsertP(); +Xinha._stopEvent(ev); +} +}; +EnterParagraphs.prototype.dom_checkInsertP=function(){ +var _3=this.editor; +var p,body; +var _5=_3.getSelection(); +var _6=_3.createRange(_5); +if(!_6.collapsed){ +_6.deleteContents(); +} +_3.deactivateEditor(); +var SC=_6.startContainer; +var SO=_6.startOffset; +var EC=_6.endContainer; +var EO=_6.endOffset; +if(SC==EC&&SC==body&&!SO&&!EO){ +p=_3._doc.createTextNode(" "); +body.insertBefore(p,body.firstChild); +_6.selectNodeContents(p); +SC=_6.startContainer; +SO=_6.startOffset; +EC=_6.endContainer; +EO=_6.endOffset; +} +p=_3.getAllAncestors(); +var _b=null; +body=_3._doc.body; +for(var i=0;i1){ +var nb=_3._doc.createElement("p"); +while(df.firstChild){ +var s=df.firstChild; +df.removeChild(s); +nb.appendChild(s); +} +df.appendChild(nb); +} +if(!(/\S/.test(_b.innerHTML))){ +_b.innerHTML=" "; +} +p=df.firstChild; +if(!(/\S/.test(p.innerHTML))){ +p.innerHTML="
"; +} +if((/^\s*\s*$/.test(p.innerHTML))&&(/^h[1-6]$/i.test(p.tagName))){ +df.appendChild(_3.convertNode(p,"p")); +df.removeChild(p); +} +var _14=_b.parentNode.insertBefore(df.firstChild,_b.nextSibling); +_3.activateEditor(); +_5=_3.getSelection(); +_5.removeAllRanges(); +_5.collapse(_14,0); +_3.scrollToElement(_14); +}; + diff --git a/mailboxes/xinha/modules/GetHtml/DOMwalk.js b/mailboxes/xinha/modules/GetHtml/DOMwalk.js new file mode 100644 index 000000000..ee47633b4 --- /dev/null +++ b/mailboxes/xinha/modules/GetHtml/DOMwalk.js @@ -0,0 +1,168 @@ +function GetHtmlImplementation(_1){ +this.editor=_1; +} +GetHtmlImplementation._pluginInfo={name:"GetHtmlImplementation DOMwalk",origin:"Xinha Core",version:"$LastChangedRevision: 742 $".replace(/^[^:]*: (.*) \$$/,"$1"),developer:"The Xinha Core Developer Team",developer_url:"$HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/modules/GetHtml/DOMwalk.js $".replace(/^[^:]*: (.*) \$$/,"$1"),sponsor:"",sponsor_url:"",license:"htmlArea"}; +Xinha.getHTML=function(_2,_3,_4){ +try{ +return Xinha.getHTMLWrapper(_2,_3,_4); +} +catch(ex){ +alert(Xinha._lc("Your Document is not well formed. Check JavaScript console for details.")); +return _4._iframe.contentWindow.document.body.innerHTML; +} +}; +Xinha.emptyAttributes=" checked disabled ismap readonly nowrap compact declare selected defer multiple noresize noshade "; +Xinha.getHTMLWrapper=function(_5,_6,_7,_8){ +var _9=""; +if(!_8){ +_8=""; +} +switch(_5.nodeType){ +case 10: +case 6: +case 12: +break; +case 2: +break; +case 4: +_9+=(Xinha.is_ie?("\n"+_8):"")+""; +break; +case 5: +_9+="&"+_5.nodeValue+";"; +break; +case 7: +_9+=(Xinha.is_ie?("\n"+_8):"")+""; +break; +case 1: +case 11: +case 9: +var _a; +var i; +var _c=(_5.nodeType==1)?_5.tagName.toLowerCase():""; +if((_c=="script"||_c=="noscript")&&_7.config.stripScripts){ +break; +} +if(_6){ +_6=!(_7.config.htmlRemoveTags&&_7.config.htmlRemoveTags.test(_c)); +} +if(Xinha.is_ie&&_c=="head"){ +if(_6){ +_9+=(Xinha.is_ie?("\n"+_8):"")+""; +} +var _d=RegExp.multiline; +RegExp.multiline=true; +var _e=_5.innerHTML.replace(Xinha.RE_tagName,function(_f,p1,p2){ +return p1+p2.toLowerCase(); +}); +RegExp.multiline=_d; +_9+=_e+"\n"; +if(_6){ +_9+=(Xinha.is_ie?("\n"+_8):"")+""; +} +break; +}else{ +if(_6){ +_a=(!(_5.hasChildNodes()||Xinha.needsClosingTag(_5))); +_9+=(Xinha.is_ie&&Xinha.isBlockElement(_5)?("\n"+_8):"")+"<"+_5.tagName.toLowerCase(); +var _12=_5.attributes; +for(i=0;i<_12.length;++i){ +var a=_12.item(i); +if(typeof a.nodeValue=="object"){ +continue; +} +if(_5.tagName.toLowerCase()=="input"&&_5.type.toLowerCase()=="checkbox"&&a.nodeName.toLowerCase()=="value"&&a.nodeValue.toLowerCase()=="on"){ +continue; +} +if(!a.specified&&!(_5.tagName.toLowerCase().match(/input|option/)&&a.nodeName=="value")&&!(_5.tagName.toLowerCase().match(/area/)&&a.nodeName.match(/shape|coords/i))){ +continue; +} +var _14=a.nodeName.toLowerCase(); +if(/_moz_editor_bogus_node/.test(_14)){ +_9=""; +break; +} +if(/(_moz)|(contenteditable)|(_msh)/.test(_14)){ +continue; +} +var _15; +if(Xinha.emptyAttributes.indexOf(" "+_14+" ")!=-1){ +_15=_14; +}else{ +if(_14!="style"){ +if(typeof _5[a.nodeName]!="undefined"&&_14!="href"&&_14!="src"&&!(/^on/.test(_14))){ +_15=_5[a.nodeName]; +}else{ +_15=a.nodeValue; +if(Xinha.is_ie&&(_14=="href"||_14=="src")){ +_15=_7.stripBaseURL(_15); +} +if(_7.config.only7BitPrintablesInURLs&&(_14=="href"||_14=="src")){ +_15=_15.replace(/([^!-~]+)/g,function(_16){ +return escape(_16); +}); +} +} +}else{ +if(!Xinha.is_ie){ +_15=_5.style.cssText.replace(/rgb\(.*?\)/ig,function(rgb){ +return Xinha._colorToRgb(rgb); +}); +} +} +} +if(/^(_moz)?$/.test(_15)){ +continue; +} +_9+=" "+_14+"=\""+Xinha.htmlEncode(_15)+"\""; +} +if(Xinha.is_ie&&_5.style.cssText){ +_9+=" style=\""+_5.style.cssText.toLowerCase()+"\""; +} +if(Xinha.is_ie&&_5.tagName.toLowerCase()=="option"&&_5.selected){ +_9+=" selected=\"selected\""; +} +if(_9!==""){ +if(_a&&_c=="p"){ +_9+="> 

"; +}else{ +if(_a){ +_9+=" />"; +}else{ +_9+=">"; +} +} +} +} +} +var _18=false; +if(_c=="script"||_c=="noscript"){ +if(!_7.config.stripScripts){ +if(Xinha.is_ie){ +var _19="\n"+_5.innerHTML.replace(/^[\n\r]*/,"").replace(/\s+$/,"")+"\n"+_8; +}else{ +var _19=(_5.hasChildNodes())?_5.firstChild.nodeValue:""; +} +_9+=_19+""+((Xinha.is_ie)?"\n":""); +} +}else{ +for(i=_5.firstChild;i;i=i.nextSibling){ +if(!_18&&i.nodeType==1&&Xinha.isBlockElement(i)){ +_18=true; +} +_9+=Xinha.getHTMLWrapper(i,true,_7,_8+" "); +} +if(_6&&!_a){ +_9+=(Xinha.is_ie&&Xinha.isBlockElement(_5)&&_18?("\n"+_8):"")+""; +} +} +break; +case 3: +_9=/^script|noscript|style$/i.test(_5.parentNode.tagName)?_5.data:Xinha.htmlEncode(_5.data); +break; +case 8: +_9=""; +break; +} +return _9; +}; + diff --git a/mailboxes/xinha/modules/GetHtml/TransformInnerHTML.js b/mailboxes/xinha/modules/GetHtml/TransformInnerHTML.js new file mode 100644 index 000000000..4043edb89 --- /dev/null +++ b/mailboxes/xinha/modules/GetHtml/TransformInnerHTML.js @@ -0,0 +1,143 @@ +function GetHtmlImplementation(_1){ +this.editor=_1; +} +GetHtmlImplementation._pluginInfo={name:"GetHtmlImplementation TransformInnerHTML",version:"1.0",developer:"Nelson Bright",developer_url:"http://www.brightworkweb.com/",sponsor:"",sponsor_url:"",license:"htmlArea"}; +HTMLArea.RegExpCache=[new RegExp().compile(/<\s*\/?([^\s\/>]+)[\s*\/>]/gi),new RegExp().compile(/(\s+)_moz[^=>]*=[^\s>]*/gi),new RegExp().compile(/\s*=\s*(([^'"][^>\s]*)([>\s])|"([^"]+)"|'([^']+)')/g),new RegExp().compile(/\/>/g),new RegExp().compile(/<(br|hr|img|input|link|meta|param|embed|area)((\s*\S*="[^"]*")*)>/g),new RegExp().compile(/(checked|compact|declare|defer|disabled|ismap|multiple|no(href|resize|shade|wrap)|readonly|selected)([\s>])/gi),new RegExp().compile(/(="[^']*)'([^'"]*")/),new RegExp().compile(/&(?=[^<]*>)/g),new RegExp().compile(/<\s+/g),new RegExp().compile(/\s+(\/)?>/g),new RegExp().compile(/\s{2,}/g),new RegExp().compile(/\s+([^=\s]+)((="[^"]+")|([\s>]))/g),new RegExp().compile(/\s+contenteditable(=[^>\s\/]*)?/gi),new RegExp().compile(/((href|src)=")([^\s]*)"/g),new RegExp().compile(/<\/?(div|p|h[1-6]|table|tr|td|th|ul|ol|li|blockquote|object|br|hr|img|embed|param|pre|script|html|head|body|meta|link|title|area|input|form|textarea|select|option)[^>]*>/g),new RegExp().compile(/<\/(div|p|h[1-6]|table|tr|ul|ol|blockquote|object|html|head|body|script|form|select)( [^>]*)?>/g),new RegExp().compile(/<(div|p|h[1-6]|table|tr|ul|ol|blockquote|object|html|head|body|script|form|select)( [^>]*)?>/g),new RegExp().compile(/<(td|th|li|option|br|hr|embed|param|pre|meta|link|title|area|input|textarea)[^>]*>/g),new RegExp().compile(/(^|<\/(pre|script)>)(\s|[^\s])*?(<(pre|script)[^>]*>|$)/g),new RegExp().compile(/(]*>)([\s\S])*?(<\/pre>)/g),new RegExp().compile(/(^|)([\s\S]*?)(?=|$)/g),new RegExp().compile(/\S*=""/g),new RegExp().compile(/|<\?[\s\S]*?\?>|<\/?\w[^>]*>/g),new RegExp().compile(/(^|<\/script>)[\s\S]*?(]*>|$)/g)]; +HTMLArea.prototype.cleanHTML=function(_2){ +var c=HTMLArea.RegExpCache; +_2=_2.replace(c[0],function(_4){ +return _4.toLowerCase(); +}).replace(c[1]," ").replace(c[12]," ").replace(c[2],"=\"$2$4$5\"$3").replace(c[21]," ").replace(c[11],function(_5,p1,p2){ +return " "+p1.toLowerCase()+p2; +}).replace(c[3],">").replace(c[9],"$1>").replace(c[5],"$1=\"$1\"$3").replace(c[4],"<$1$2 />").replace(c[6],"$1$2").replace(c[8],"<").replace(c[10]," "); +if(HTMLArea.is_ie&&c[13].test(_2)){ +_2=_2.replace(c[13],"$1"+this.stripBaseURL(RegExp.$3)+"\""); +} +if(this.config.only7BitPrintablesInURLs){ +if(HTMLArea.is_ie){ +c[13].test(_2); +} +if(c[13].test(_2)){ +try{ +_2=_2.replace(c[13],"$1"+decodeURIComponent(RegExp.$3).replace(/([^!-~]+)/g,function(_8){ +return escape(_8); +})+"\""); +} +catch(e){ +_2=_2.replace(c[13],"$1"+RegExp.$3.replace(/([^!-~]+)/g,function(_9){ +return escape(_9); +})+"\""); +} +} +} +return _2; +}; +HTMLArea.indent=function(s,_b){ +HTMLArea.__nindent=0; +HTMLArea.__sindent=""; +HTMLArea.__sindentChar=(typeof _b=="undefined")?" ":_b; +var c=HTMLArea.RegExpCache; +if(HTMLArea.is_gecko){ +s=s.replace(c[19],function(_d){ +return _d.replace(/
/g,"\n"); +}); +} +s=s.replace(c[18],function(_e){ +_e=_e.replace(c[20],function(st,$1,$2){ +string=$2.replace(/[\n\r]/gi," ").replace(/\s+/gi," ").replace(c[14],function(str){ +if(str.match(c[16])){ +var s="\n"+HTMLArea.__sindent+str; +HTMLArea.__sindent+=HTMLArea.__sindentChar; +++HTMLArea.__nindent; +return s; +}else{ +if(str.match(c[15])){ +--HTMLArea.__nindent; +HTMLArea.__sindent=""; +for(var i=HTMLArea.__nindent;i>0;--i){ +HTMLArea.__sindent+=HTMLArea.__sindentChar; +} +return "\n"+HTMLArea.__sindent+str; +}else{ +if(str.match(c[17])){ +return "\n"+HTMLArea.__sindent+str; +} +} +} +return str; +}); +return $1+string; +}); +return _e; +}); +s=s.replace(/^\s*/,"").replace(/ +\n/g,"\n").replace(/[\r\n]+<\/script>/g,"\n"); +return s; +}; +HTMLArea.getHTML=function(_15,_16,_17){ +var _18=""; +var c=HTMLArea.RegExpCache; +if(_15.nodeType==11){ +var div=document.createElement("div"); +var _1b=_15.insertBefore(div,_15.firstChild); +for(j=_1b.nextSibling;j;j=j.nextSibling){ +_1b.appendChild(j.cloneNode(true)); +} +_18+=_1b.innerHTML.replace(c[23],function(_1c){ +_1c=_1c.replace(c[22],function(tag){ +if(/^<[!\?]/.test(tag)){ +return tag; +}else{ +return _17.cleanHTML(tag); +} +}); +return _1c; +}); +}else{ +var _1e=(_15.nodeType==1)?_15.tagName.toLowerCase():""; +if(_16){ +_18+="<"+_1e; +var _1f=_15.attributes; +for(i=0;i<_1f.length;++i){ +var a=_1f.item(i); +if(!a.specified){ +continue; +} +var _21=a.nodeName.toLowerCase(); +var _22=a.nodeValue; +_18+=" "+_21+"=\""+_22+"\""; +} +_18+=">"; +} +if(_1e=="html"){ +innerhtml=_17._doc.documentElement.innerHTML; +}else{ +innerhtml=_15.innerHTML; +} +_18+=innerhtml.replace(c[23],function(_23){ +_23=_23.replace(c[22],function(tag){ +if(/^<[!\?]/.test(tag)){ +return tag; +}else{ +if(!(_17.config.htmlRemoveTags&&_17.config.htmlRemoveTags.test(tag.replace(/<([^\s>\/]+)/,"$1")))){ +return _17.cleanHTML(tag); +}else{ +return ""; +} +} +}); +return _23; +}); +if(HTMLArea.is_ie){ +_18=_18.replace(/]*)?>/g,"").replace(/(<(ul|ol)[^>]*>)[\s\n]*<\/li>/g,"$1").replace(/<\/li>([\s\n]*<\/li>)+/g,""); +} +if(HTMLArea.is_gecko){ +_18=_18.replace(/
\n$/,""); +} +if(_16){ +_18+=""; +} +_18=HTMLArea.indent(_18); +} +return _18; +}; + diff --git a/mailboxes/xinha/modules/InsertImage/insert_image.html b/mailboxes/xinha/modules/InsertImage/insert_image.html new file mode 100644 index 000000000..f4f81af9f --- /dev/null +++ b/mailboxes/xinha/modules/InsertImage/insert_image.html @@ -0,0 +1,174 @@ + + + Insert Image + + + + + + + + + + +
Insert Image
+ +
+ + + + + + + + + + + + + + +
Image URL: + +
Alternate text:
+ +
+ +
+Layout + +
+ +
Alignment:
+ + +
+ +
Border thickness:
+ + +
+ +
+ +
+Spacing + +
+ +
Horizontal:
+ + +
+ +
Vertical:
+ + +
+ +
+
+
+Image Preview:
+ +
+
+ + +
+
+ + \ No newline at end of file diff --git a/mailboxes/xinha/modules/InsertImage/insert_image.js b/mailboxes/xinha/modules/InsertImage/insert_image.js new file mode 100644 index 000000000..2af77df35 --- /dev/null +++ b/mailboxes/xinha/modules/InsertImage/insert_image.js @@ -0,0 +1,107 @@ +InsertImage._pluginInfo={name:"InsertImage",origin:"Xinha Core",version:"$LastChangedRevision: 733 $".replace(/^[^:]*: (.*) \$$/,"$1"),developer:"The Xinha Core Developer Team",developer_url:"$HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/modules/InsertImage/insert_image.js $".replace(/^[^:]*: (.*) \$$/,"$1"),sponsor:"",sponsor_url:"",license:"htmlArea"}; +function InsertImage(_1){ +} +Xinha.prototype._insertImage=function(_2){ +var _3=this; +var _4; +if(typeof _2=="undefined"){ +_2=this.getParentElement(); +if(_2&&_2.tagName.toLowerCase()!="img"){ +_2=null; +} +} +var _5; +if(typeof _3.config.baseHref!="undefined"&&_3.config.baseHref!==null){ +_5=_3.config.baseHref; +}else{ +var _6=window.location.toString().split("/"); +_6.pop(); +_5=_6.join("/"); +} +if(_2){ +_4={f_base:_5,f_url:Xinha.is_ie?_3.stripBaseURL(_2.src):_2.getAttribute("src"),f_alt:_2.alt,f_border:_2.border,f_align:_2.align,f_vert:(_2.vspace!=-1?_2.vspace:""),f_horiz:(_2.hspace!=-1?_2.hspace:""),f_width:_2.width,f_height:_2.height}; +}else{ +_4={f_base:_5,f_url:""}; +} +Dialog(_3.config.URIs.insert_image,function(_7){ +if(!_7){ +return false; +} +var _8=_2; +if(!_8){ +if(Xinha.is_ie){ +var _9=_3.getSelection(); +var _a=_3.createRange(_9); +_3._doc.execCommand("insertimage",false,_7.f_url); +_8=_a.parentElement(); +if(_8.tagName.toLowerCase()!="img"){ +_8=_8.previousSibling; +} +}else{ +_8=document.createElement("img"); +_8.src=_7.f_url; +_3.insertNodeAtSelection(_8); +if(!_8.tagName){ +_8=_a.startContainer.firstChild; +} +} +}else{ +_8.src=_7.f_url; +} +for(var _b in _7){ +var _c=_7[_b]; +switch(_b){ +case "f_alt": +if(_c){ +_8.alt=_c; +}else{ +_8.removeAttribute("alt"); +} +break; +case "f_border": +if(_c){ +_8.border=parseInt(_c||"0"); +}else{ +_8.removeAttribute("border"); +} +break; +case "f_align": +if(_c){ +_8.align=_c; +}else{ +_8.removeAttribute("align"); +} +break; +case "f_vert": +if(_c){ +_8.vspace=parseInt(_c||"0"); +}else{ +_8.removeAttribute("vspace"); +} +break; +case "f_horiz": +if(_c){ +_8.hspace=parseInt(_c||"0"); +}else{ +_8.removeAttribute("hspace"); +} +break; +case "f_width": +if(_c){ +_8.width=parseInt(_c||"0"); +}else{ +_8.removeAttribute("width"); +} +break; +case "f_height": +if(_c){ +_8.height=parseInt(_c||"0"); +}else{ +_8.removeAttribute("height"); +} +break; +} +} +},_4); +}; + diff --git a/mailboxes/xinha/modules/InsertTable/insert_table.html b/mailboxes/xinha/modules/InsertTable/insert_table.html new file mode 100644 index 000000000..351a0a26d --- /dev/null +++ b/mailboxes/xinha/modules/InsertTable/insert_table.html @@ -0,0 +1,157 @@ + + + + Insert Table + + + + + + + + + + +
Insert Table
+ +
+ + + + + + + + + + + + + + + + + +
Rows:Width:
Cols:
+ +

+ +

+Layout + +
+ +
Alignment:
+ + +

+ +

Border thickness:
+ + +
+ +
+ +
+Spacing + +
+ +
Cell spacing:
+ + +

+ +

Cell padding:
+ + +
+ +
+ +
+ + +
+ +
+ + + \ No newline at end of file diff --git a/mailboxes/xinha/modules/InsertTable/insert_table.js b/mailboxes/xinha/modules/InsertTable/insert_table.js new file mode 100644 index 000000000..74183b248 --- /dev/null +++ b/mailboxes/xinha/modules/InsertTable/insert_table.js @@ -0,0 +1,63 @@ +InsertTable._pluginInfo={name:"InsertTable",origin:"Xinha Core",version:"$LastChangedRevision: 688 $".replace(/^[^:]*: (.*) \$$/,"$1"),developer:"The Xinha Core Developer Team",developer_url:"$HeadURL: http://svn.xinha.python-hosting.com/trunk/modules/InsertTable/insert_table.js $".replace(/^[^:]*: (.*) \$$/,"$1"),sponsor:"",sponsor_url:"",license:"htmlArea"}; +function InsertTable(_1){ +} +Xinha.prototype._insertTable=function(){ +var _2=this.getSelection(); +var _3=this.createRange(_2); +var _4=this; +Dialog(_4.config.URIs.insert_table,function(_5){ +if(!_5){ +return false; +} +var _6=_4._doc; +var _7=_6.createElement("table"); +for(var _8 in _5){ +var _9=_5[_8]; +if(!_9){ +continue; +} +switch(_8){ +case "f_width": +_7.style.width=_9+_5.f_unit; +break; +case "f_align": +_7.align=_9; +break; +case "f_border": +_7.border=parseInt(_9,10); +break; +case "f_spacing": +_7.cellSpacing=parseInt(_9,10); +break; +case "f_padding": +_7.cellPadding=parseInt(_9,10); +break; +} +} +var _a=0; +if(_5.f_fixed){ +_a=Math.floor(100/parseInt(_5.f_cols,10)); +} +var _b=_6.createElement("tbody"); +_7.appendChild(_b); +for(var i=0;i<_5.f_rows;++i){ +var tr=_6.createElement("tr"); +_b.appendChild(tr); +for(var j=0;j<_5.f_cols;++j){ +var td=_6.createElement("td"); +if(_a){ +td.style.width=_a+"%"; +} +tr.appendChild(td); +td.appendChild(_6.createTextNode("\xa0")); +} +} +if(Xinha.is_ie){ +_3.pasteHTML(_7.outerHTML); +}else{ +_4.insertNodeAtSelection(_7); +} +return true; +},null); +}; + diff --git a/mailboxes/xinha/modules/InternetExplorer/InternetExplorer.js b/mailboxes/xinha/modules/InternetExplorer/InternetExplorer.js new file mode 100644 index 000000000..a1d965e92 --- /dev/null +++ b/mailboxes/xinha/modules/InternetExplorer/InternetExplorer.js @@ -0,0 +1,203 @@ +InternetExplorer._pluginInfo={name:"Internet Explorer",origin:"Xinha Core",version:"$LastChangedRevision: 737 $".replace(/^[^:]*: (.*) \$$/,"$1"),developer:"The Xinha Core Developer Team",developer_url:"$HeadURL: http://svn.xinha.python-hosting.com/tags/0.92beta/modules/InternetExplorer/InternetExplorer.js $".replace(/^[^:]*: (.*) \$$/,"$1"),sponsor:"",sponsor_url:"",license:"htmlArea"}; +function InternetExplorer(_1){ +this.editor=_1; +_1.InternetExplorer=this; +} +InternetExplorer.prototype.onKeyPress=function(ev){ +if(this.editor.isShortCut(ev)){ +switch(this.editor.getKey(ev).toLowerCase()){ +case "n": +this.editor.execCommand("formatblock",false,"

"); +Xinha._stopEvent(ev); +return true; +break; +case "1": +case "2": +case "3": +case "4": +case "5": +case "6": +this.editor.execCommand("formatblock",false,""); +Xinha._stopEvent(ev); +return true; +break; +} +} +switch(ev.keyCode){ +case 8: +case 46: +if(this.handleBackspace()){ +Xinha._stopEvent(ev); +return true; +} +break; +} +return false; +}; +InternetExplorer.prototype.handleBackspace=function(){ +var _3=this.editor; +var _4=_3.getSelection(); +if(_4.type=="Control"){ +var _5=_3.activeElement(_4); +Xinha.removeFromParent(_5); +return true; +} +var _6=_3.createRange(_4); +var r2=_6.duplicate(); +r2.moveStart("character",-1); +var a=r2.parentElement(); +if(a!=_6.parentElement()&&(/^a$/i.test(a.tagName))){ +r2.collapse(true); +r2.moveEnd("character",1); +r2.pasteHTML(""); +r2.select(); +return true; +} +}; +InternetExplorer.prototype.inwardHtml=function(_9){ +_9=_9.replace(/<(\/?)del(\s|>|\/)/ig,"<$1strike$2"); +return _9; +}; +Xinha.prototype.insertNodeAtSelection=function(_a){ +this.insertHTML(_a.outerHTML); +}; +Xinha.prototype.getParentElement=function(_b){ +if(typeof _b=="undefined"){ +_b=this.getSelection(); +} +var _c=this.createRange(_b); +switch(_b.type){ +case "Text": +var _d=_c.parentElement(); +while(true){ +var _e=_c.duplicate(); +_e.moveToElementText(_d); +if(_e.inRange(_c)){ +break; +} +if((_d.nodeType!=1)||(_d.tagName.toLowerCase()=="body")){ +break; +} +_d=_d.parentElement; +} +return _d; +case "None": +return _c.parentElement(); +case "Control": +return _c.item(0); +default: +return this._doc.body; +} +}; +Xinha.prototype.activeElement=function(_f){ +if((_f===null)||this.selectionEmpty(_f)){ +return null; +} +if(_f.type.toLowerCase()=="control"){ +return _f.createRange().item(0); +}else{ +var _10=_f.createRange(); +var _11=this.getParentElement(_f); +if(_11.innerHTML==_10.htmlText){ +return _11; +} +return null; +} +}; +Xinha.prototype.selectionEmpty=function(sel){ +if(!sel){ +return true; +} +return this.createRange(sel).htmlText===""; +}; +Xinha.prototype.selectNodeContents=function(_13,pos){ +this.focusEditor(); +this.forceRedraw(); +var _15; +var _16=typeof pos=="undefined"?true:false; +if(_16&&_13.tagName&&_13.tagName.toLowerCase().match(/table|img|input|select|textarea/)){ +_15=this._doc.body.createControlRange(); +_15.add(_13); +}else{ +_15=this._doc.body.createTextRange(); +_15.moveToElementText(_13); +} +_15.select(); +}; +Xinha.prototype.insertHTML=function(_17){ +this.focusEditor(); +var sel=this.getSelection(); +var _19=this.createRange(sel); +_19.pasteHTML(_17); +}; +Xinha.prototype.getSelectedHTML=function(){ +var sel=this.getSelection(); +var _1b=this.createRange(sel); +if(_1b.htmlText){ +return _1b.htmlText; +}else{ +if(_1b.length>=1){ +return _1b.item(0).outerHTML; +} +} +return ""; +}; +Xinha.prototype.getSelection=function(){ +return this._doc.selection; +}; +Xinha.prototype.createRange=function(sel){ +return sel.createRange(); +}; +Xinha.prototype.isKeyEvent=function(_1d){ +return _1d.type=="keydown"; +}; +Xinha.prototype.getKey=function(_1e){ +return String.fromCharCode(_1e.keyCode); +}; +Xinha.getOuterHTML=function(_1f){ +return _1f.outerHTML; +}; +Xinha.prototype.cc=String.fromCharCode(8201); +Xinha.prototype.setCC=function(_20){ +if(_20=="textarea"){ +var ta=this._textArea; +var pos=document.selection.createRange(); +pos.collapse(); +pos.text=this.cc; +var _23=ta.value.indexOf(this.cc); +var _24=ta.value.substring(0,_23); +var _25=ta.value.substring(_23+this.cc.length,ta.value.length); +if(_25.match(/^[^<]*>/)){ +var _26=_25.indexOf(">")+1; +ta.value=_24+_25.substring(0,_26)+this.cc+_25.substring(_26,_25.length); +}else{ +ta.value=_24+this.cc+_25; +} +}else{ +var sel=this.getSelection(); +var r=sel.createRange(); +if(sel.type=="Control"){ +var _29=r.item(0); +_29.outerHTML+=this.cc; +}else{ +r.collapse(); +r.text=this.cc; +} +} +}; +Xinha.prototype.findCC=function(_2a){ +var _2b=(_2a=="textarea")?this._textArea:this._doc.body; +range=_2b.createTextRange(); +if(range.findText(escape(this.cc))){ +range.select(); +range.text=""; +} +if(range.findText(this.cc)){ +range.select(); +range.text=""; +} +if(_2a=="textarea"){ +this._textArea.focus(); +} +}; + diff --git a/mailboxes/xinha/popups/about.html b/mailboxes/xinha/popups/about.html new file mode 100644 index 000000000..2091075e9 --- /dev/null +++ b/mailboxes/xinha/popups/about.html @@ -0,0 +1,296 @@ + + + + + +About Xinha + + + + + + + +
+ +

Xinha

+ +
+ +
+
+ +
+ +

A free WYSIWYG editor replacement for <textarea> fields.

+

Visit the Xinha Website for more information.

+ +

+ Use of Xinha is granted by the terms of the htmlArea License (based on BSD license) +

+

+ Xinha was originally based on work by Mihai Bazon which is: +

+
Copyright (c) 2003-2004 dynarch.com.
+    Copyright (c) 2002-2003 interactivetools.com, inc.
+    This copyright notice MUST stay intact for use.
+ +
+ +
+ +

+ The development of Xinha would not have been possible without the original work of Mihai Bazon, InteractiveTools.com, and the many sponsors and contributors from around the world. +

+ +
+ +
+
htmlArea License (based on BSD license)
+Copyright (c) 2002-2004, interactivetools.com, inc.
+Copyright (c) 2003-2004 dynarch.com
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1) Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+2) Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3) Neither the name of interactivetools.com, inc. nor the names of its
+   contributors may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+ +
+
+
+
+ + +
+ +
+ +
+ + +
+ + +
+
About
Thanks
License
Plugins
Version
+ +
+ +
+ + diff --git a/mailboxes/xinha/popups/blank.html b/mailboxes/xinha/popups/blank.html new file mode 100644 index 000000000..5b1b16d1f --- /dev/null +++ b/mailboxes/xinha/popups/blank.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/mailboxes/xinha/popups/editor_help.html b/mailboxes/xinha/popups/editor_help.html new file mode 100644 index 000000000..ac4fb1af5 --- /dev/null +++ b/mailboxes/xinha/popups/editor_help.html @@ -0,0 +1,62 @@ + + + Editor Help + + + + + + + +

Xinha Help
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Keyboard shortcuts
+ The editor provides the following key combinations: +
ENTERnew paragraph(<P>)
SHIFT-ENTERinsert linebreak(<BR>)
CTRL-ASelect all
CTRL-BBold
CTRL-IItalic
CTRL-UUnderline
CTRL-SStrikethrough
CTRL-LJustify Left
CTRL-EJustify Center
CTRL-RJustify Right
CTRL-JJustify Full
CTRL-ZUndoes your last action
CTRL-YRedoes your last action
CTRL-NSet format to paragraph
CTRL-0 (zero)Clean content pasted from Word
CTRL-1 .. CTRL-6Headings (<h1> .. <h6>)
CTRL-XCut selection
CTRL-CCopy selection
CTRL-VPaste from clipboard
+
+ +
+ + \ No newline at end of file diff --git a/mailboxes/xinha/popups/popup.css b/mailboxes/xinha/popups/popup.css new file mode 100644 index 000000000..7bf935893 --- /dev/null +++ b/mailboxes/xinha/popups/popup.css @@ -0,0 +1,39 @@ +html, body, .dialog { + background: ButtonFace; + color: ButtonText; + font: 11px Tahoma,Verdana,sans-serif; + margin: 0px; + padding: 0px; +} +body { padding: 5px; } +form { padding: 0px; margin: 0px; } +form p { + margin-top: 5px; + margin-bottom: 5px; +} +table { + font: 11px Tahoma,Verdana,sans-serif; +} +select, input, button { font: 11px Tahoma,Verdana,sans-serif; } +button { width: 70px; } +table .label { text-align: right; width: 8em; } + +.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; } +.fr { width: 7em; float: left; padding: 2px 5px; text-align: right; } +fieldset { padding: 0px 10px 5px 5px; } +.space { padding: 2px; } +.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px; +border-bottom: 1px solid black; letter-spacing: 2px; +} +.buttonColor { + padding: 1px; + cursor: default; + border: 1px solid; + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; +} +#buttons { + margin-top: 1em; + border-top: 1px solid #999; + padding: 1em; + text-align: right; +} \ No newline at end of file diff --git a/mailboxes/xinha/popups/popup.js b/mailboxes/xinha/popups/popup.js new file mode 100644 index 000000000..9cb5210ab --- /dev/null +++ b/mailboxes/xinha/popups/popup.js @@ -0,0 +1,102 @@ +Xinha=window.opener.Xinha; +HTMLArea=window.opener.Xinha; +function getAbsolutePos(el){ +var r={x:el.offsetLeft,y:el.offsetTop}; +if(el.offsetParent){ +var _3=getAbsolutePos(el.offsetParent); +r.x+=_3.x; +r.y+=_3.y; +} +return r; +} +function comboSelectValue(c,_5){ +var _6=c.getElementsByTagName("option"); +for(var i=_6.length;--i>=0;){ +var op=_6[i]; +op.selected=(op.value==_5); +} +c.value=_5; +} +function __dlg_onclose(){ +opener.Dialog._return(null); +} +function __dlg_init(_9,_a){ +__xinha_dlg_init(_a); +} +function __xinha_dlg_init(_b){ +if(window.__dlg_init_done){ +return true; +} +if(window.opener._editor_skin!=""){ +var _c=document.getElementsByTagName("head")[0]; +var _d=document.createElement("link"); +_d.type="text/css"; +_d.href=window.opener._editor_url+"skins/"+window.opener._editor_skin+"/skin.css"; +_d.rel="stylesheet"; +_c.appendChild(_d); +} +window.dialogArguments=opener.Dialog._arguments; +var _e=document.body; +if(!_b){ +var _f=Xinha.viewportSize(window); +_b={width:_f.x,height:_e.scrollHeight}; +} +window.resizeTo(_b.width,_b.height); +var _f=Xinha.viewportSize(window); +window.resizeBy(0,_e.scrollHeight-_f.y); +if(_b.top&&_b.left){ +window.moveTo(_b.left,_b.top); +}else{ +if(!Xinha.is_ie){ +var x=opener.screenX+(opener.outerWidth-_b.width)/2; +var y=opener.screenY+(opener.outerHeight-_b.height)/2; +}else{ +var x=(self.screen.availWidth-_b.width)/2; +var y=(self.screen.availHeight-_b.height)/2; +} +window.moveTo(x,y); +} +Xinha.addDom0Event(document.body,"keypress",__dlg_close_on_esc); +window.__dlg_init_done=true; +} +function __dlg_translate(_12){ +var _13=["input","select","legend","span","option","td","th","button","div","label","a","img"]; +for(var _14=0;_14<_13.length;++_14){ +var _15=document.getElementsByTagName(_13[_14]); +for(var i=_15.length;--i>=0;){ +var _17=_15[i]; +if(_17.firstChild&&_17.firstChild.data){ +var txt=Xinha._lc(_17.firstChild.data,_12); +if(txt){ +_17.firstChild.data=txt; +} +} +if(_17.title){ +var txt=Xinha._lc(_17.title,_12); +if(txt){ +_17.title=txt; +} +} +if(_17.tagName.toLowerCase()=="input"&&(/^(button|submit|reset)$/i.test(_17.type))){ +var txt=Xinha._lc(_17.value,_12); +if(txt){ +_17.value=txt; +} +} +} +} +document.title=Xinha._lc(document.title,_12); +} +function __dlg_close(val){ +opener.Dialog._return(val); +window.close(); +} +function __dlg_close_on_esc(ev){ +ev||(ev=window.event); +if(ev.keyCode==27){ +__dlg_close(null); +return false; +} +return true; +} + diff --git a/mailboxes/xinha/popups/select_color.html b/mailboxes/xinha/popups/select_color.html new file mode 100644 index 000000000..b64a4844b --- /dev/null +++ b/mailboxes/xinha/popups/select_color.html @@ -0,0 +1,359 @@ + +Select Color + + + + + + + +
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/mailboxes/xinha/release-notes.txt b/mailboxes/xinha/release-notes.txt new file mode 100644 index 000000000..30611b382 --- /dev/null +++ b/mailboxes/xinha/release-notes.txt @@ -0,0 +1,63 @@ +Xinha - The Community-Built Online HTML Editor + +For bug reports, forum, and updates go to +http://xinha.org + +Release History + +Xinha 0.92beta + - fixed Ticket #831 stop empty anchors from being removed + - Make htmlarea.js just load XinhaCore.js instead of being a copy of it. + - fixed Ticket #445 Toggle TableBorder doesn't work if this.fullpage=true or using FullPage plugin + - fixed Ticket #551 shape and coord attributes of area element are ignored by IE + - fixed Ticket #650 SpellChecker is not compatible with FullPage plugin + - fixed Ticket #816 CharacterMap and ListType panel modes make editor jump to top in IE + - fixed Ticket #570 change behaviour of justify when an image is selected to make the image float left/right, + click the justify button again to undo it + - fixed Ticket #891 noscript content got escaped + - fixed Ticket #857 Firefox fails to load in fullpage mode when tag in wrong place. + - fixed Ticket #841 Spell Checker - Won't return to xinha. + - fixed Ticket #914 All buttons stay grey & this.getParentElement is not a function message when not calling + Xinha.loadPlugins() in xinha_init function + - fixed Ticket #911 Background color does not work in Firefox + - fixed Ticket #912 an error is thrown in Mozilla when clicking merge cells button and fewer than 2 cells are selected + - fixed Ticket #816 CharacterMap and ListType panel modes make editor jump to top in IE + - fixed Ticket #917 getHTMLWrapper in IE renders attributes like _stylist_usedtobe="[object Object]" + - fixed Ticket #556 stripBaseHref didn't work without baseHref defined explicitly. + - Update InsertPicture plugin Update + - fixed Ticket #921 EFM extended file manager - iframe height problem (IE) + - Ticket #923 colorPicker face lift & localisation + - fixed Ticket #924 EFM + ImageManager re-transforming of url to original image after automatic resize broken + - Ticket #900- retain editing position position between modes + - fixed Ticket #928 ImageManager fails if (another) Files.php exists in include path + - fixed Ticket #935 EFM demo_images php upload allowed: possible security risk + - Ticket #939 Japanese langage support + - fixed Ticket #3 Horizontal Rule Selection + - Plugin ExtendedFileManager: added doc to allowed upload extensions + - Plugin PasteText update + - Plugin HtmlEntities: default preset iso-8859-1 + - fixed Ticket #948 IE: inline styles are not rendered by DOMwalk getHTML() + - Plugin HorizontalRule update + - Plugin SaveSubmit update + - Plugin Linker update + - fixed Ticket #823 editor contents was not submitted when using JavaScript form.submit() without prior form.onsubmit() + - fixed Ticket #459 all body attributes removed in full page mode in FireFox + - _editor_url is now converted to absolute if it is relative. + - fixed Ticket #594 IE: insertHTML() inserts HTML outside editor when editor is not focussed + - Ticket #954 FullScreen mode can now be called programmatically or on startup with or without button + - fixed Ticket #321 FullScreen : select elements show through in IE6 + - fixed Ticket #953 Statusbar has ugly white gap at the bottom when switching back from full screen in IE + - fixed Ticket #952 FullScreen: scrollbars don't disappear in IE in QuirksMode + - fixed Ticket #603 Popop Dialog Height problems + - fixed Ticket #955 DOMwalk getHTML outputs empty attribute with value "true" instead of attribute name and some are skipped at all + +Xinha 0.91beta + - changed namespace from HTMLArea to Xinha + - the core file is now named XinhaCore.js instead of htmlarea.js, + please change your pages accordingly (the htmlarea.js will be removed!) + - the color picker script is now loaded on demand to reduce initial loading time + +Xinha 0.9beta +This equals Xinha revision 635 of Jan 11 2007 + - All JavaScript files over 2kb have been compressed using the dojo JavaScript compressor + - All gifs have been optimized using Trout's GIF Optimizer version 2.3 \ No newline at end of file