Отправляет email-рассылки с помощью сервиса Sendsay

Linux Gazette на русском

  Все выпуски  

Linux Gazette на русском


Информационный Канал Subscribe.Ru

[lg86]: Как послать энциклопедию по e-mail

Linux Gazette на русском | Выпуск #123 | Тираж 8518 экз.


Здравствуйте! У нас в команде прибавление -- Павел Соколов. Прошу, так сказать, любить и жаловать. :-) И Вашему вниманию предлагается его перевод статьи, описывающей способ отправки через электронную почту файлов больших размеров. Жаль, что в статье описан только скрипт, разбивающий файл на части и отправляющий его через e-mail, но совершенно упущена из виду необходимость по прибытию собрать файл воедино. Возможно, Graham посчитал, что достаточно полно осветил этот вопрос в другой статье: "Безопасная печать с PGP"

Спасибо за перевод Павлу Соколову!

Теперь разбор полётов. Статья "Преодолевая консольный барьер". Вот, что пишет Jedi (jedi at perm.raid.ru):

Это, конечно, подвиг. И статья просто классная - автор, хотя и не очень
углубляясь в суть (кому надо - спрсит у Маньки) описал возможные заслоны на
пути к привычным с детства досообразнвм едиторам.
НО! Не будем уподобляться китайским комсомольцам хуйнавейбинам! Все
гоооооораздо проще. Есть FreePascal. Работа в нем через иодуль CRT полностью
аналогична досовской. А можно и по-консольному, линуксоидно. Поддерживает
Борландовский диалект, Гнутый диалект, Объектный Паскаль (Дельфоидный
диалект то бишь), и, похоже, еще какие-то странные диалекты, где конструктор
должен обязательно зваться Инитом. Что приятно, без специальной опции он
GoTo за ошибку считает - я,правда, не проверял, но в доках сказано... Можно
перекрывать функции (перегружать то бишь), добавлять и переопределять
операторы, подключать сишные библиотеки. Портируется под Винду, дос, Осину
(она еще жива, не в курсе?), ну и под *никсы разные. Оченно приятная вещь.
Это даже если оставить в стороне священные войны насильников с
пасквилянтами.

А теперь статья "Мечты об идеальном текстовом редакторе". Вот, как ругается :-) Михаил Шигорин (mike at osdn.org.ua):

 ...skip...

Этот бомж -- кипящий чайник :(

 ..и живет на hotmail.  Полная красота.

>    Вспомните, те из нас, кто перешёл с Windows на Линукс, по крайней мере,
>    ожидали, что там будет текстовый редактор с функциями выделения текста
>    мышью и диалоговыми окнами с менюшками. Из всех редакторов такими
>    способностями обладает только mcedit из состава файлового менеджера
>    Midnight Commander. [И как правило, именно его я и использую, если нужно
>    что-то подредактировать по-быстрому. Мнение редактора.] У других нет ни
>    диалогов, ни поддержки мыши, либо эти функции в минимальном наборе и
>    пользоваться ими просто невозможно.

И vim, и *emacs умеют мышей и все что угодно.  И на них мир не
закончился.

>    Многие из нас, увлечённые Линукс, нормальные люди, а не
>    супермены.  Совершенно излишне и даже жестоко заставлять
>    кого-то изучать второй язык программирования параллельно с
>    основным.

Чушь, причем полная.  Сколько ты знаешь языков программирования
-- столько раз ты программист.

>    Поэтому Emacs не инструмент. Это тест умственных способностей.

Это пачка инструментов для совсем обленившихся умных людей.
Я не совсем обленившийся и предпочитаю vim :)

> Настали времена, чтобы простые люди выступили против
> высоколобой элиты, для которой изучение emacs сущий пустяк.

Какая высокопарность.

> Ведь согласитесь, вам не нужно было учиться как работать в
> mcedit, он просто выполняет то, что вы от него ожидали.

Вот только он действительно многого не умеет -- следовательно,
или упрешься в потолок, или не будешь расти, тратя лишнее время
на выполнение руками того, что в мощных редакторах делается в два
нажатия.

>    Идеальный Редактор должен обладать такими же функциями как и
>    emacs: расширяемый редактор с интуитивно понятным
>    интерфейсом с поддержкой мышки и меню.  Только вместо того,
>    чтобы учить второй язык для его расширения, всё должно
>    создаваться на С++.

Он _полный_ чайник, занесите в блэклист ...  мнение этого человека
не стоит того, чтобы его выслушивать.

Emacs -- это не текстовый редактор, а Lisp-машина.  ОС.

На це++ этот бомж напишет в лучшем разе кривые win3.11.

>   О, прекрасная программа
>
>    Сейчас я опишу вам каким должен быть Идеальный Редактор. Итак, вы
>    скачиваете его, собираете, и обнаруживаете у него основные функции mcedit.

Тьфу.

>    У него есть возможность выделения мышью, возможность работы мышью с меню,
>    ну и диалог открытия файлов, позволяющий перемещаться по директориям при
>    помощи двойного щелчка.

Ужыс какой.

>    У него есть несколько функций: Открыть Файл, Сохранить Файл, Выход,
>    Вырезать, Скопировать, Вставить, Удалить и Помощь. Но у него нет функции
>    поиска! Не беда, подробный README объяснит, что исходник для функции
>    поиска входит в состав, и опишет как его подключить. Окажется, что
>    необходимые строки кода уже написаны в исходнике, но они просто
>    закомментированы.

В каком нафиг исходнике?????  Этот человек _никогда_ не писал
промышленного кода!!

>    2. Объявить функцию в начале файла main.cc, к примеру вот так:
>
>     int show_search_dlg();
>
>    3. Добавить строку в main() (то есть просто её раскомментировать):
>
>     ed.add_menu_cmd( show_search_dlg, "Search", "Edit", F2_key, SHIFT_PRESSED
> );
>
>    ...которая добавляет команду "Search" в меню "Edit", имеющую "горячую
>    клавишу" Shift-F2.

Урод.


>    4. В Makefile добавить (раскомментировать) правило для компиляции
>    исходника и добавить его имя к списку объектов, подлежащих компоновке
>    (линкованию).
>
>    5. Запустить Make и убедиться, что функция поиска присутствует в меню.

Дважды урод. :(

>    [Всё это конечно замечательно, но если уж автор завёл речь о создании
>    расширяемого редактора, то лучше рассмотреть варинат редактора,
>    использующего плагины. Russian Linux Gazette публиковала перевод на эту
>    тему. Прим.ред.]

Ну ты это понимаешь.  А этот пионер -- нет :((

>    Где ты, С++ программист?

В [beep] -- неужто непонятно?

Что добавить к этому? Разве, что комментарий RXL (rxl at mail.ru):

Вот что рекомендую прочесть тем кто решил выводить на терминал что-то сложнее printf():
pinfo ncurses
http://dickey.his.com/ncurses/ncurses.faq.html
http://www.dstu.edu.ru/manuals/HOWTO/Text-Terminal-HOWTO.html
Все тексты, к сожалению, на английском. Возможно где-то есть переводы.

Оопс! Спасибо всем за комментарии и замечания -- мы постараемся учесть их при подборе переводов.

Александр Куприн


Как послать энциклопедию по e-mail
Автор: Graham Jenkins
Перевод: Павел Соколов


С чего бы это вам посылать по e-mail энциклопедию?

Хорошо, не обязательно энциклопедию. Это может быть фильм. Или большая директория, которую вы упаковали в один tar-файл и заархивировали. И, конечно, вы могли бы переслать её по FTP. Или, возможно, не могли бы. Ваша машина может работать в корпоративной сети без доступа к внешним FTP серверам. Или на компьютере-пункте назначения отключен протокол FTP в целях безопасности. Другой вариант - закодировать передаваемый объект в строку из символов ASCII и послать его по почте. Вы можете воспользоваться утилитой uuencode для такого кодирования, либо вы можете использовать метод Base64, описанный в RFC 2045 "Многоцелевые расширения электронной почты (MIME), Часть первая (Multipurpose Internet Mail Extensions (MIME) Part One)".

[Прим. пер. - Отсюда совсем не понятно, зачем кодировать строку. Изначально при передаче почты существовали ограничения на передаваемые символы - они кодировались только 7 битами.]

Как же запаковать энциклопедию?

Если бы вы физически посылали по почте энциклопедию, скорее всего, вы бы упаковали её в одну коробку. Это было бы хорошим решением, если бы все почтовые службы на пути следования могли принимать коробки такого веса и размера. Если же это не так, тогда бы вам пришлось распределить энциклопедию по нескольким посылкам приемлемого размера и веса.

Аналогично, когда мы посылаем энциклопедию по электронной почте, нам надо обеспечить, чтобы размер письма, в котором мы посылаем энциклопедию, не вышел за ограничения, с которыми оно может столкнуться в пути. Для этого придётся разбить письмо на несколько частей. Это можно сделать в соответствии с RFC 2046 "Многоцелевые расширения электронной почты (MIME), Часть вторая (Multipurpose Internet Mail Extensions (MIME) Part Two)".

Обобщая, если мы последуем рекомендациям RFC 2045 и RFC 2046, мы должны закодировать всю энциклопедию, используя Base64, а затем разбить результат на то количество частей, которое нам нужно. Тогда, посылаемые по почте части, будут выглядеть примерно так:

  From grahjenk@au1.ibm.com Tue Dec 31 13:14:34 2002
  Content-Disposition: inline
  Content-Transfer-Encoding: 7bit
  Content-Type: message/partial; id="300870"; number="1"
  Subject: Graham's Encylopedia

  owF1Vb+P3EQUPhLRrBSFlHQjRYCQsthe/1q7CNrbREjocnvK3hHREM3ac7fWeWfM
  zPh2L38ASomEIro0SNBBg2hBSDTwR0BBEwqQaFJF8J499tob0EjW7rzv+96b772x
   ...
  szJb9DUMvKdRUIV+RY5Xu3UkRQqvJCzdzHtHoQL36Ke6elnYLgwH8MfxCU9ymq1Y

  --
  From grahjenk@au1.ibm.com Tue Dec 31 13:14:34 2002
  Content-Disposition: inline
  Content-Transfer-Encoding: 7bit
  Content-Type: message/partial; id="300870"; number="9"; total="9"
  Subject: Graham's Encyclopedia

  dc45xuruv3m3e8z/OGRD6lxz13GC5m0XbXvcWlyFW4vxbSSK5KEoTOIIuxTFs2JK
  UnZKy1wTAV9TWr2dev7WrLbXkeOHUVQnjuyXEptwm3hBgfT43auvVh/v5mt+48pb
  n+09Hf7+5Nvyx5tf/fP4o+PJ398Xf958cW3v6ejzL17/9YPfPs4unv08efvr68O/
  njz/Fw==

  --

Другой вариант упаковки энциклопедии

Для получателя не всегда легко собрать части в правильном порядке, а затем отбросить заголовки и передать данные Base64 декодеру. Если получатель использует старую Unix-машину, у него может вообще не быть Base64 декодера. Если же он использует машину с ОС от Microsoft, существует вероятность того, что он не сможет правильно обработать части сообщения.

Так что альтернативный вариант - разбить энциклопедию на пронумерованные части, а затем отдельно обработать uuencode для пересылки. Большинство версий утилиты uudecode достаточно сообразительны, чтобы отбросить строки с заголовками. Это срабатывает даже с Microsoft Outlook.

Хитрость здесь - пронумеровать части таким образом, чтобы их легко можно было выбирать (например, используя cat) в правильной последовательности и передавать по конвейеру (например, для разархивации и развёртывания: unzip и untar), либо выводить в файл. Части теперь выглядят примерно так:

  From grahjenk@au1.ibm.com Tue Dec 31 13:49:07 2002
  Subject: encyclo part 1/ size/sum 1024/16571

  begin 644 001_encyclo
  M<F]O=#IX.CZ,3I3=7!E<BU5<V5R.B\Z+W-B:6XO<V@*9&%E;6]N.G@Z,3HQ
  M.CHO.@IB:6XZ>#HR.C(Z.B]U<W(O8FEN.@IS>7,Z>#HS.C,Z.B\Z"F%D;3IX
   ...
  M8W)E<',Z+V)I;B]K<V@*=V-O8F%T8V@Z>#HU,#(X.#HQ.D%L97@@=&AE(%=A
  B;FME<CHO97AP;W)T+VAO;64O=V-O8F%T8V@Z+V)I;B]K<P

  end

  --
  From grahjenk@au1.ibm.com Tue Dec 31 13:49:07 2002
  Subject: encyclo part 2/2 size/sum 945/12218

  begin 644 002_encyclo
  M:IC-S0S-#0P.G@Z-38T-C,Z-3P-#I!;F1R97<@3'5O;F<Z+VAO;64O861M
  M;W!E<F%T;W(Z+V5X<&]R="]H;VUE+V]P8U]O<#HO8FEN+W-H"F,Y,34W.3DZ
  M>#HU,#(Y,#HQ.CHO:&]M92]A9&UI;B]C.3$U-SDY.B]U<W(O8FEN+V)A<V@*

  end

  --

Обратите внимание, что мы теперь используем символы только верхнего регистра, и что в сообщении появилось несколько скобок и других символов. Некоторые из них не могут быть эквивалентным образом переведены в другие варианты кодирования символов. Поэтому RFC 2045 рекомендует использовать Base64 вместо uuencode.

"Упаковщик энциклопедий"

Вот вариант программы-упаковщика. Для простоты и рассмотрения наиболее общего случая, мы используем альтернативный вариант, описанный ранее. Такого рода программы существуют уже давно. Они обычно написаны на C, хотя существуют варианты и на языке Bourne-Shell. И обычно они создают временные файлы.

Можно написать элегантную реализацию схемы упаковки на Perl, не использующую никаких временных файлов. Конечная программа - и проста, и может быть перенесена на другую ОС. Поэтому это то, что мы и сделали. (Единственное на что хочу обратить ваше внимание -- это путь к интерпретатору Perl в заголовке скрипта. Как правило, это /usr/bin/perl , а не /usr/local/bin/perl Прим.ред.)

#!/usr/local/bin/perl -w
# @(#) filemail.pl      Разбивает входящий поток на части, а затем кодирует
#                       каждую часть и посылает её по e-mail указанному получателю.
#                       Vers. 2.05; Graham Jenkins, IBM GSA, Декабрь 2002.

use strict;             # Части кодируются и высылаются по схеме с двойным буфером.
use File::Basename;     # Используется Uuencode для сокращения зависимости от модулей.
my  $PSize = 700;       # Размер части на входе по умолчанию.
my  ($Count,$Sum,$Size,$Total,$InpBuf,$InpLen,$OutBuf,$j);

if ($#ARGV eq 2) { if ($ARGV[0] =~ m/^-\d+$/ ) { $PSize=0-$ARGV[0]; shift } }

die "Использование: cat файл  |".basename($0)." [-KbНаЧасть] получатель ИмяФайла\n".
    "Например: tar cf - .|".basename($0)." -64 smith\@popser.acme.com mydir.tar\n".
    "(Примечание: размер незакодированной части по умолчанию = $PSize","kb)\n"  if ($#ARGV ne 1);

open(INFILE,"-") || die "Не могу прочесть входные данные!\n";
$Count = 0; $Total = "";# Цикл пока не кончатся данные.

do { $InpLen = read(INFILE, $InpBuf, 1024 * $PSize);
     $Total  = $Count if $InpLen lt 1;
     do { $Size = length($OutBuf);
          print STDERR "$ARGV[1] part $Count/$Total => $ARGV[0] $Size bytes\n";
          $Sum  = unpack("%32C*", $OutBuf);
          foreach $j (1,2) {$Sum = ($Sum & 0xffff) + int($Sum/0x10000)}
          open(PIPE, "| Mail -s" .
            "'$ARGV[1] part $Count/$Total size/sum $Size/$Sum' $ARGV[0]");
          $j = $Count ; while (length($j) < 3 ) { $j = "0" . $j }
          $j = dirname($ARGV[1])."/".$j if dirname($ARGV[1]) ne ".";
          print PIPE "begin 644 ",$j,"_", basename($ARGV[1]),"\n",
            pack("u",$OutBuf),"\\nend\n";
          close(PIPE)                                   } if $Count gt 0;
     $Count++; $OutBuf = $InpBuf                          } until $InpLen lt 1;

Perl предоставляет инструкцию read, которая позволяет указать количество байт, которое она должна попробовать прочитать в указанную строку. Как можно видеть, мы просто продолжаем читать из стандартного ввода до тех пор, пока в $InpBuf не будет возвращена пустая строка. Каждый раз, когда мы получаем непустую строку, мы кодируем всё, что находится в $OutBuf, с помощью uuencode и передаём содержимое буфера в почтовую программу. Затем мы сохраняем содержимое $InpBuf в $OutBuf для последующей итерации.

Perl способен кодировать строку по uuencode, как это показано, с помощью инструкции pack с параметром u; никаких дополнительных модулей не требуется. В действительности, в этом нет необходимости, но в этом случае, как дополнительной возможностью, мы можем воспользоваться инструкцией unpack для расчёта контрольной суммы по каждой посылаемой части.

Вы можете заметить, что мы фактически открываем канал (pipe) в программу Mail, входящую в ОС Unix/Linux, для обработки исходящей почты. Для большей переносимости на другие ОС, мы могли бы установить и воспользоваться модулем Net::SMTP.

Программа может быть вызвана с опциональным параметром, регулирующим размер передаваемых частей, чтобы скорректировать установленный по умолчанию размер некодированной части - 700kb.

Программы, делающие подобные вещи

Некоторые из вас могут заметить, что такое разбиение сообщений аналогично тому, что мы делали в "Безопасная печать с PGP". (Перевод статьи вы найдёте здесь. Прим.ред.) Для тех, кому интересно: существуют обновлённые версии программы из этой статьи, их можно найти в "Репозиторий скриптов CPAN". Эти программы используют рекомендованный в RFC метод "закодировать по Base64, затем разбить".

Более ранняя статья, "Linux-клиент для Интернет-протокола печати Brother", включает в себя скрипт для shell, который использует метод "разбить, затем послать части"; он также использует кодирование Base64. (Перевод статьи вы найдёте здесь. Прим.ред.)

Graham - специалист по Unix, работает в IBM Global Services, Австралия. Живёт в Мельбурне, создал и администрировал множество проприетарных и открытых систем на нескольких платформах.


Copyright (c) 2003, Graham Jenkins. Copying license http://www.linuxgazette.com/copying.html
Опубликовано в выпуске 86 Linux Gazette, январь 2003


Команда переводчиков:
Владимир Меренков, Александр Михайлов, Иван Песин, Сергей Скороходов, Александр Саввин, Роман Шумихин, Александр Куприн, Андрей Киселев, Игорь Яровинский, Юрий Прушинский, Павел Соколов

Со всеми предложениями, идеями и комментариями обращайтесь к Александру Куприну (ru_classic at mail.ru). Убедительная просьба: указывайте сразу, не возражаете ли Вы против публикации Ваших отзывов в рассылке.

Сайт рассылки: http://gazette.linux.ru.net
Эту статью можно взять здесь: http://gazette.linux.ru.net/lg86/jenkins.html
Архивы выпусков находятся здесь: http://gazette.linux.ru.net/archive/




http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное