home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3873 < prev    next >
Encoding:
Internet Message Format  |  1991-08-22  |  12.3 KB

  1. Xref: wupost comp.lang.perl:7228 alt.sources:3873
  2. Path: wupost!uunet!island!daniel
  3. From: daniel@island.COM (Daniel Smith - innovate or die...)
  4. Newsgroups: comp.lang.perl,alt.sources
  5. Subject: pearmail.pl - replacement for tarmail
  6. Summary: handle large files/binary data easily by mail
  7. Keywords: perl archiving mail encoding
  8. Message-ID: <4460@island.COM>
  9. Date: 20 Aug 91 21:31:58 GMT
  10. Followup-To: comp.lang.perl
  11. Organization: Island Graphics, Marin County, California
  12. Lines: 415
  13.  
  14.  
  15.     pearmail 1.1, August 20, 1991
  16.  
  17.  
  18.     What this is:
  19.  
  20.     pearmail (uses perl to encode and archive mail, also rhymes with
  21. "airmail") is a replacement for tarmail.  You can use it to safely send
  22. any data to others via email.  By default, pearmail makes a tar file,
  23. uuencodes that, and splits that into separate mail messages.  The recipient
  24. then saves these messages to individual files, and runs "pearmail -extract"
  25. on them.  The recipient does not have to save the messages to consecutive
  26. filenames, pearmail figures out the right order.  There is also a "-helpthem"
  27. option, so that the pearmail script gets sent with your files.  This makes
  28. it easy for your recipient to unpack them, and is an easy way to propagate
  29. this script to perl installations everywhere :-)
  30.  
  31.  
  32.     What to try:
  33.  
  34.     Mail yourself some files.  This line will work in most shells:
  35.  
  36.     cd $HOME; pearmail $USER "backup of dot files" .[a-z]*
  37.  
  38.     send some files to a friend, and give them the pearmail script:
  39.  
  40.     pearmail -helpthem some_friend "here are those files" some_files
  41.  
  42.     extracting:
  43.  
  44.     When you receive mail, save all of the letters to individual files.
  45.     If you use mush, you can do something like:
  46.  
  47.     pick -s dot files | s -s
  48.  
  49.     to some empty directory, and then in a shell:
  50.  
  51.     pearmail -extract *
  52.  
  53.     for additonal help, run "pearmail" by itself.
  54.  
  55.  
  56.     If you make improvements to pearmail, SEND ME DIFFS... I've made
  57. this very easy to do by including my address in the help screen.  This
  58. has the potential to handle a lot of different formats in a consistent
  59. manner, making it easier for end users to unpack things.
  60.  
  61.     If you need to do any customization, look at the leading section of
  62. the script.  Also, if you do customizations, such as using atob, abe, zip,
  63. etc., use the -helpthem option so that people receiving your mail have an
  64. easy way to deal with your scheme.
  65.  
  66.             enjoy!
  67.  
  68.                 Daniel
  69.  
  70. ------- snip --- cut ----- tear ----- chop  -----
  71. #!/bin/sh
  72. # This is a shell archive (shar 3.10)
  73. # made 08/20/1991 21:30 UTC by daniel@bermuda
  74. # Source directory /usr/bermuda/people/daniel/src/perl
  75. #
  76. # existing files WILL be overwritten
  77. #
  78. # This shar contains:
  79. # length  mode       name
  80. # ------ ---------- ------------------------------------------
  81. #   2152 -rw-r--r-- README.pearmail
  82. #   6366 -rwxr-xr-x pearmail
  83. #
  84. touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$
  85. if [ -s /tmp/s3_touch$$ ]
  86. then
  87.     TOUCH=can
  88. else
  89.     TOUCH=cannot
  90. fi
  91. rm -f /tmp/s3_touch$$
  92. # ============= README.pearmail ==============
  93. echo "x - extracting README.pearmail (Text)"
  94. sed 's/^X//' << 'SHAR_EOF' > README.pearmail &&
  95. X
  96. X
  97. X    pearmail 1.1, August 20, 1991
  98. X
  99. X
  100. X    What this is:
  101. X
  102. X    pearmail (uses perl to encode and archive mail, also rhymes with
  103. X"airmail") is a replacement for tarmail.  You can use it to safely send
  104. Xany data to others via email.  By default, pearmail makes a tar file,
  105. Xuuencodes that, and splits that into separate mail messages.  The recipient
  106. Xthen saves these messages to individual files, and runs "pearmail -extract"
  107. Xon them.  The recipient does not have to save the messages to consecutive
  108. Xfilenames, pearmail figures out the right order.  There is also a "-helpthem"
  109. Xoption, so that the pearmail script gets sent with your files.  This makes
  110. Xit easy for your recipient to unpack them, and is an easy way to propagate
  111. Xthis script to perl installations everywhere :-)
  112. X
  113. X
  114. X    What to try:
  115. X
  116. X    Mail yourself some files.  This line will work in most shells:
  117. X
  118. X    cd $HOME; pearmail $USER "backup of dot files" .[a-z]*
  119. X
  120. X    send some files to a friend, and give them the pearmail script:
  121. X
  122. X    pearmail -helpthem some_friend "here are those files" some_files
  123. X
  124. X    extracting:
  125. X
  126. X    When you receive mail, save all of the letters to individual files.
  127. X    If you use mush, you can do something like:
  128. X
  129. X    pick -s dot files | s -s
  130. X
  131. X    to some empty directory, and then in a shell:
  132. X
  133. X    pearmail -extract *
  134. X
  135. X    for additonal help, run "pearmail" by itself.
  136. X
  137. X
  138. X    If you make improvements to pearmail, SEND ME DIFFS... I've made
  139. Xthis very easy to do by including my address in the help screen.  This
  140. Xhas the potential to handle a lot of different formats in a consistent
  141. Xmanner, making it easier for end users to unpack things.
  142. X
  143. X    If you need to do any customization, look at the leading section of
  144. Xthe script.  Also, if you do customizations, such as using atob, abe, zip,
  145. Xetc., use the -helpthem option so that people receiving your mail have an
  146. Xeasy way to deal with your scheme.
  147. X
  148. X            enjoy!
  149. X
  150. X                Daniel
  151. X
  152. X   daniel@island.com       daniel@world.std.com       dansmith@well.sf.ca.us
  153. XDaniel Smith, Island Graphics, 94903, CA (415) 491 0765 x 250(w), 491 0402(fax)
  154. X              Disclaimer: written by a highly caffeinated mammal
  155. X$|=1;for("..."," hacker"," perl"," a","just"){print $l=$_.$l,"\015";sleep 1;}
  156. SHAR_EOF
  157. chmod 0644 README.pearmail || echo "restore of README.pearmail fails"
  158. if [ $TOUCH = can ]
  159. then
  160.     touch -am 0820142991 README.pearmail
  161. fi
  162. # ============= pearmail ==============
  163. echo "x - extracting pearmail (Text)"
  164. sed 's/^X//' << 'SHAR_EOF' > pearmail &&
  165. X#! /usr/bin/perl
  166. X#
  167. X#    pearmail - use perl to send and extract uuencoded, t'archived mail
  168. X#
  169. X#    Daniel Smith, daniel@island.com, July, August 1991
  170. X
  171. X&usage unless @ARGV;
  172. X@command_line_args = @ARGV;    # for -helpthem
  173. X
  174. X#    things to customize
  175. X$tmp_dir = "/tmp";
  176. X$how_we_mail = "Mail -s";
  177. X$how_we_package = "tar cvf -";
  178. X$how_we_compress = "compress";
  179. X$how_we_encode = "uuencode pearmail.tar.Z";
  180. X$how_we_decode = "uudecode";
  181. X$how_we_split = "split -700 - $tmp_dir/pearmail.";
  182. X
  183. X# more portable...
  184. X#$how_we_extract = "cat pearmail.tar.Z | uncompress | tar -xvf - ";
  185. X$how_we_extract = "zcat pearmail.tar.Z | tar xvf - ";
  186. X
  187. X#    set up the way we'll process our options
  188. X%options = (
  189. X    '-helpthem',     '&set_help',
  190. X    '-extract',    '&set_extract',
  191. X    '-x',        '&set_extract',
  192. X    '-e',        '&set_extract',
  193. X    '-h',        '&usage',
  194. X    '-help',    '&usage',
  195. X    '-usage',    '&usage',
  196. X);
  197. X
  198. X#    *anything* to avoid "if elsif elsif" ad infinitum :-)
  199. Xwhile ($_ = shift @ARGV) {
  200. X    if (/^-/) {
  201. X        eval ($options{$_}) || print "no such option: $_\n";
  202. X    } else {
  203. X        push (@our_args, $_);
  204. X    }
  205. X}
  206. X
  207. Xif ($we_are_extracting) {
  208. X    &arrange_filenames;
  209. X    &do_extract;
  210. X    exit;
  211. X}
  212. X
  213. X#    otherwise, we're sending something...
  214. X
  215. Xif (($#our_args + 1) < 3) {
  216. X    print "not enough arguments, run \"pearmail -usage\" for help...\n";
  217. X    exit 0;
  218. X}
  219. X
  220. X$recipient = shift @our_args;
  221. X$subject = shift @our_args;
  222. X
  223. Xif ($send_them_help) {
  224. X    &send_myself;
  225. X}
  226. X
  227. X#    now all the rest of @our_args are files that we are sending
  228. X
  229. X$how_to_send = join ('|', $how_we_package." @our_args", $how_we_compress,
  230. X            $how_we_encode);
  231. X
  232. Xopen (SENDPIPE, "$how_to_send | split -700 - $tmp_dir/pearmail.$$.|")  ||
  233. X        die "can't set up pipe!: $!\n";
  234. Xwhile (<SENDPIPE>) {
  235. X    print;        # output of pipe (tar) commands...
  236. X}
  237. Xwait;
  238. X
  239. X@files_we_send = <$tmp_dir/pearmail.$$.*>;
  240. X$cur_part = 1;
  241. X$total = ($#files_we_send + 1);
  242. X@fname_exts =  'xaa'..'xdz';
  243. X($fname_subject = $subject) =~ tr/ \t":;`'/_/s;
  244. Xwhile ( <$tmp_dir/pearmail.$$.*> ) {
  245. X    $full_subject = "$subject part $cur_part of $total";
  246. X    open (MAILPIPE, "|$how_we_mail \"$full_subject\" $recipient")
  247. X            || die "can't set up pipe!: $!\n";
  248. X    open (STUFF_TO_MAIL, $_);
  249. X    print MAILPIPE <<"PREAMBLE";
  250. X
  251. XPEARMAIL_HEADER_START
  252. X    This is part $cur_part of $total
  253. X
  254. X    This file was created with pearmail, and contains an archive
  255. X    of:
  256. X    @our_args
  257. X
  258. X    Save this part, and any other parts, to separate files (it won't
  259. X    matter what names you give the files), and run:
  260. X
  261. X    pearmail -extract <filenames>
  262. X
  263. X    on them.  You will then have the decoded contents of the archive.
  264. X
  265. X    SUBJECT: $subject
  266. X    FILENAME: $fname_subject.$fname_exts[$cur_part - 1]
  267. X
  268. X    The steps involved with creating the entire archive were:
  269. X    $how_to_send
  270. XPEARMAIL_HEADER_END
  271. XPREAMBLE
  272. X
  273. X    print MAILPIPE "PEARMAIL_DATA_START\n";
  274. X    print MAILPIPE <STUFF_TO_MAIL>;
  275. X    print MAILPIPE "PEARMAIL_DATA_END\n";
  276. X    $cur_part++;
  277. X    close (STUFF_TO_MAIL);
  278. X    unlink $_ || die "can not rm tmp files: !$\n";
  279. X}
  280. X
  281. X
  282. Xsub send_myself {
  283. X    open (MYSELF, $0) || die "can't open myself!: $!\n";
  284. X    open (MAILME,
  285. X    "|$how_we_mail \"pearmail script - sent with: $subject\" $recipient")
  286. X                    || die "can't set up pipe!: $!\n";
  287. X
  288. X    while (<MYSELF>) {
  289. X        if ($. == 6) {
  290. X            print MAILME "
  291. X#    This script was automatically generated by $ENV{'USER'}
  292. X#    running this command from $ENV{'SHELL'}:
  293. X#    $0 @command_line_args
  294. X#
  295. X#    if this was mailed to you, and you are wondering what to do, follow
  296. X#    these simple steps:
  297. X#
  298. X#    1) save this message without any headers (or trim them off later).  The
  299. X#    very first line should say \"#! /usr/bin/perl\".  Save this to the
  300. X#    filename \"pearmail\".
  301. X#
  302. X#    2) make this an executable script by entering \"chmod +x pearmail\"
  303. X#    from a shell.
  304. X#
  305. X#    3) if someone sent you some files along with this script via mail,
  306. X#    save the messages out to separate files, and run the command
  307. X#    \"pearmail -extract <the filenames>\" on them.
  308. X#
  309. X";
  310. X        }
  311. X        print MAILME;
  312. X    }
  313. X}
  314. X
  315. Xsub set_help {
  316. X    $send_them_help = "yep";
  317. X}
  318. X
  319. Xsub set_extract {
  320. X    $we_are_extracting = "yep";
  321. X}
  322. X
  323. Xsub arrange_filenames {
  324. X    if ($#our_args < 0) {
  325. X        die "you haven't told me which files to extract from...\n";
  326. X    }
  327. X    foreach $raw_file (@our_args) {
  328. X        open (RAW, $raw_file) || warn "cannot open $raw_file: $!\n";
  329. X        while (<RAW>) {
  330. X            next unless /PEARMAIL_HEADER_START/;
  331. X            last;
  332. X        }
  333. X        if (eof (RAW)) {
  334. X            print "can't find pearmail header in $raw_file\n";
  335. X        } else {
  336. X            while (<RAW>) {
  337. X                if (/PEARMAIL_HEADER_END/) {
  338. X                    last;
  339. X                }
  340. X                if (/FILENAME: /o) {
  341. X                    chop ($_);
  342. X                    ($skip, $all_raw_files{$raw_file}) =
  343. X                            split (/ /, $_);
  344. X                    last;
  345. X                }
  346. X            }
  347. X        }
  348. X    }
  349. X    foreach $old_name (keys %all_raw_files) {
  350. X        print "$old_name becomes $all_raw_files{$old_name} ....\n";
  351. X        close RAW;
  352. X        rename ($old_name, $all_raw_files{$old_name});
  353. X    }
  354. X}
  355. X
  356. Xsub do_extract {
  357. X    $| = 1;
  358. X    #open (DEBUG_FILE, "> debug") || die "can't set up debug file!: $!\n";
  359. X    open (DECODE_PIPE, "|$how_we_decode") ||
  360. X                die "can't set up pipe!: $!\n";
  361. X
  362. X    foreach $workfile (sort (values %all_raw_files)) {
  363. X        print "now working with $workfile\n";
  364. X
  365. X        open (CUR_WORK_FILE, $workfile) ||
  366. X                die "can't open $workfile!: $!\n";
  367. X        while (<CUR_WORK_FILE>) {
  368. X            next unless /PEARMAIL_DATA_START/o;
  369. X            last;    # ok, now we want the next line...
  370. X        }
  371. X        while (<CUR_WORK_FILE>) {
  372. X            last if /PEARMAIL_DATA_END/;
  373. X            print DECODE_PIPE;
  374. X            # print DEBUG_FILE;
  375. X        }
  376. X        close (CUR_WORK_FILE);
  377. X    }
  378. X
  379. X    # very important to have this...flush out the end of the tar,,,
  380. X    close (DECODE_PIPE);
  381. X
  382. X        open (EXTRACT_PIPE, "$how_we_extract|") ||
  383. X                die "can't set up pipe!: $!\n";
  384. X    while (<EXTRACT_PIPE>) {
  385. X        print;
  386. X    }
  387. X}
  388. X
  389. Xsub usage {
  390. X    print "Usage: pearmail [options] person@somewhere \"Subject\" files.
  391. X
  392. Xpearmail is used to send groups of files to someone.  By default,
  393. Xa tar file is created, uuencoded, and sent in parts through mail.
  394. XThe recipient then saves those parts to separate files (with any names
  395. Xthey want), and runs pearmail -extract on them.
  396. X
  397. Xoptions:
  398. X    -helpthem        forward a copy of this script
  399. X    -extract        unarchive the files
  400. Xexamples:
  401. X    pearmail -helpthem daniel@island.com \"diffs to pearmail\" diffs
  402. X    pearmail gumby@claytown.com \"blockhead jokes\" bjokes
  403. X
  404. X    The first example sends the files to someone, and also sends this
  405. X    script, giving you an easy way to give this to them.
  406. X
  407. X    The second example is everyday usage; sending to some one who already
  408. X    has pearmail.
  409. X
  410. X    When someone gets their mail, they may save the parts to any file
  411. X    names they wish.  They then run \"pearmail -extract files\" to get
  412. X    the archive extracted.
  413. X";
  414. X    exit 0;
  415. X}
  416. X__END__
  417. SHAR_EOF
  418. chmod 0755 pearmail || echo "restore of pearmail fails"
  419. if [ $TOUCH = can ]
  420. then
  421.     touch -am 0820141391 pearmail
  422. fi
  423. exit 0
  424. -- 
  425.    daniel@island.com       daniel@world.std.com       dansmith@well.sf.ca.us
  426. Daniel Smith, Island Graphics, 94903, CA (415) 491 0765 x 250(w), 491 0402(fax)
  427.               Disclaimer: written by a highly caffeinated mammal
  428.          "fgrep is a dog, and a mad one at that." - Tom Christiansen
  429.