home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume06 / btoa < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  9.6 KB

  1. From decwrl!purdue!mailrus!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!allbery Sun Jan 22 15:42:20 PST 1989
  2. Article 776 of comp.sources.misc:
  3. Path: granite!decwrl!purdue!mailrus!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!allbery
  4. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5. Newsgroups: comp.sources.misc
  6. Subject: v06i001: btoa, tarmail
  7. Message-ID: <46897@uunet.UU.NET>
  8. Date: 21 Jan 89 20:19:33 GMT
  9. Sender: allbery@uunet.UU.NET
  10. Reply-To: per@philabs.Philips.Com (Paul E. Rutter)
  11. Lines: 419
  12. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  13.  
  14. Posting-number: Volume 6, Issue 1
  15. Submitted-by: per@philabs.Philips.Com (Paul E. Rutter)
  16. Archive-name: btoa
  17.  
  18. [I thought this came with Usenet news sources?!  ++bsa]
  19.  
  20.   As I have seen a number of requests for btoa lately in comp.sources.wanted,
  21. and received a number of requests personally through round about email, it
  22. seems like it is time to repost sources to btoa/atob and tarmail/untarmail.
  23. A man page is included in the following shar file.  I am the original author
  24. of btoa.
  25.  
  26.                             Paul Rutter
  27.                             per@philabs.philips.com
  28.  
  29. #! /bin/sh
  30. # The rest of this file is a shell script which will extract:
  31. # Makefile atob.c btoa.c btoa.man tarmail untarmail
  32. # Suggested restore procedure:
  33. # Edit off anything above these comment lines,
  34. # save this file in an empty directory,
  35. # then say: sh < file
  36. echo x - Makefile
  37. cat >Makefile <<'!Funky!Stuff!'
  38. CC=cc -O -s
  39. BIN=/usr/local/bin
  40. MAN=/usr/man/manl
  41. L=l
  42.  
  43. install: atob btoa tarmail untarmail
  44.     rm -f $(BIN)/atob $(BIN)/btoa $(BIN)/tarmail $(BIN)/untarmail
  45.     cp atob btoa $(BIN)
  46.     cp tarmail untarmail $(BIN)
  47.     make man clean
  48.  
  49. man:    btoa.man
  50.     rm -f $(MAN)/btoa.$(L) $(MAN)/tarmail.$(L)
  51.     cp btoa.man $(MAN)/btoa.$(L)
  52.     cp btoa.man $(MAN)/tarmail.$(L)
  53.  
  54. atob:    atob.c
  55.     $(CC) atob.c -o atob
  56.  
  57. btoa:    btoa.c
  58.     $(CC) btoa.c -o btoa
  59.  
  60. clean:
  61.     rm -f *.o atob btoa
  62. !Funky!Stuff!
  63. echo x - atob.c
  64. cat >atob.c <<'!Funky!Stuff!'
  65. /* atob
  66.  * stream filter to change printable ascii from "btoa" back into 8 bit bytes
  67.  * if bad chars, or Csums do not match: exit(1) [and NO output]
  68.  *
  69.  * Paul Rutter Joe Orost
  70.  */
  71.  
  72. #include <stdio.h>
  73.  
  74. #define reg register
  75.  
  76. #define streq(s0, s1)  strcmp(s0, s1) == 0
  77.  
  78. #define times85(x)    ((((((x<<2)+x)<<2)+x)<<2)+x)
  79.  
  80. long int Ceor = 0;
  81. long int Csum = 0;
  82. long int Crot = 0;
  83. long int word = 0;
  84. long int bcount = 0;
  85.  
  86. fatal() {
  87.   fprintf(stderr, "bad format or Csum to atob\n");
  88.   exit(1);
  89. }
  90.  
  91. #define DE(c) ((c) - '!')
  92.  
  93. decode(c) reg c;
  94. {
  95.   if (c == 'z') {
  96.     if (bcount != 0) {
  97.       fatal();
  98.     } 
  99.     else {
  100.       byteout(0);
  101.       byteout(0);
  102.       byteout(0);
  103.       byteout(0);
  104.     }
  105.   } 
  106.   else if ((c >= '!') && (c < ('!' + 85))) {
  107.     if (bcount == 0) {
  108.       word = DE(c);
  109.       ++bcount;
  110.     } 
  111.     else if (bcount < 4) {
  112.       word = times85(word);
  113.       word += DE(c);
  114.       ++bcount;
  115.     } 
  116.     else {
  117.       word = times85(word) + DE(c);
  118.       byteout((int)((word >> 24) & 255));
  119.       byteout((int)((word >> 16) & 255));
  120.       byteout((int)((word >> 8) & 255));
  121.       byteout((int)(word & 255));
  122.       word = 0;
  123.       bcount = 0;
  124.     }
  125.   } 
  126.   else {
  127.     fatal();
  128.   }
  129. }
  130.  
  131. FILE *tmp_file;
  132.  
  133. byteout(c) reg c;
  134. {
  135.   Ceor ^= c;
  136.   Csum += c;
  137.   Csum += 1;
  138.   if ((Crot & 0x80000000)) {
  139.     Crot <<= 1;
  140.     Crot += 1;
  141.   } 
  142.   else {
  143.     Crot <<= 1;
  144.   }
  145.   Crot += c;
  146.   putc(c, tmp_file);
  147. }
  148.  
  149. main(argc, argv) char **argv;
  150. {
  151.   reg c;
  152.   reg long int i;
  153.   char tmp_name[100];
  154.   char buf[100];
  155.   long int n1, n2, oeor, osum, orot;
  156.  
  157.   if (argc != 1) {
  158.     fprintf(stderr,"bad args to %s\n", argv[0]);
  159.     exit(2);
  160.   }
  161.   sprintf(tmp_name, "/usr/tmp/atob.%x", getpid());
  162.   tmp_file = fopen(tmp_name, "w+");
  163.   if (tmp_file == NULL) {
  164.     fatal();
  165.   }
  166.   unlink(tmp_name); /* Make file disappear */
  167.   /*search for header line*/
  168.   for (;;) {
  169.     if (fgets(buf, sizeof buf, stdin) == NULL) {
  170.       fatal();
  171.     }
  172.     if (streq(buf, "xbtoa Begin\n")) {
  173.       break;
  174.     }
  175.   }
  176.  
  177.   while ((c = getchar()) != EOF) {
  178.     if (c == '\n') {
  179.       continue;
  180.     } 
  181.     else if (c == 'x') {
  182.       break;
  183.     } 
  184.     else {
  185.       decode(c);
  186.     }
  187.   }
  188.   if (scanf("btoa End N %ld %lx E %lx S %lx R %lx\n", &n1, &n2, &oeor, &osum, &
  189. orot) != 5) {
  190.     fatal();
  191.   }
  192.   if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) {
  193.     fatal();
  194.   } 
  195.   else {
  196.     /* Now that we know everything is OK, copy tmp file to stdout */
  197.     fseek(tmp_file, 0L, 0);
  198.     for (i = n1; --i >= 0;) {
  199.       putchar(getc(tmp_file));
  200.     }
  201.   }
  202.   exit(0);
  203. }
  204. !Funky!Stuff!
  205. echo x - btoa.c
  206. cat >btoa.c <<'!Funky!Stuff!'
  207. /* btoa: version 4.0
  208.  * stream filter to change 8 bit bytes into printable ascii
  209.  * computes the number of bytes, and three kinds of simple checksums
  210.  * incoming bytes are collected into 32-bit words, then printed in base 85
  211.  * exp(85,5) > exp(2,32)
  212.  * the ASCII characters used are between '!' and 'u'
  213.  * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
  214.  *
  215.  * Paul Rutter Joe Orost
  216.  */
  217.  
  218. #include <stdio.h>
  219.  
  220. #define reg register
  221.  
  222. #define MAXPERLINE 78
  223.  
  224. long int Ceor = 0;
  225. long int Csum = 0;
  226. long int Crot = 0;
  227.  
  228. long int ccount = 0;
  229. long int bcount = 0;
  230. long int word;
  231.  
  232. #define EN(c)    (int) ((c) + '!')
  233.  
  234. encode(c) reg c;
  235. {
  236.   Ceor ^= c;
  237.   Csum += c;
  238.   Csum += 1;
  239.   if ((Crot & 0x80000000)) {
  240.     Crot <<= 1;
  241.     Crot += 1;
  242.   } 
  243.   else {
  244.     Crot <<= 1;
  245.   }
  246.   Crot += c;
  247.  
  248.   word <<= 8;
  249.   word |= c;
  250.   if (bcount == 3) {
  251.     wordout(word);
  252.     bcount = 0;
  253.   } 
  254.   else {
  255.     bcount += 1;
  256.   }
  257. }
  258.  
  259. wordout(word) reg long int word;
  260. {
  261.   if (word == 0) {
  262.     charout('z');
  263.   } 
  264.   else {
  265.     reg int tmp = 0;
  266.  
  267.     if (word < 0)
  268.     { /* Because some don't support unsigned long */
  269.       tmp = 32;
  270.       word = word - (long)(85L * 85 * 85 * 85 * 32);
  271.     }
  272.     if (word < 0) {
  273.       tmp = 64;
  274.       word = word - (long)(85L * 85 * 85 * 85 * 32);
  275.     }
  276.     charout(EN((word / (long)(85L * 85 * 85 * 85)) + tmp));
  277.     word %= (long)(85L * 85 * 85 * 85);
  278.     charout(EN(word / (85L * 85 * 85)));
  279.     word %= (85L * 85 * 85);
  280.     charout(EN(word / (85L * 85)));
  281.     word %= (85L * 85);
  282.     charout(EN(word / 85));
  283.     word %= 85;
  284.     charout(EN(word));
  285.   }
  286. }
  287.  
  288. charout(c) {
  289.   putchar(c);
  290.   ccount += 1;
  291.   if (ccount == MAXPERLINE) {
  292.     putchar('\n');
  293.     ccount = 0;
  294.   }
  295. }
  296.  
  297. main(argc,argv)
  298. char **argv;
  299. {
  300.   reg c;
  301.   reg long int n;
  302.  
  303.   if (argc != 1) {
  304.     fprintf(stderr,"bad args to %s\n", argv[0]);
  305.     exit(2);
  306.   }
  307.   printf("xbtoa Begin\n");
  308.   n = 0;
  309.   while ((c = getchar()) != EOF) {
  310.     encode(c);
  311.     n += 1;
  312.   }
  313.   while (bcount != 0) {
  314.     encode(0);
  315.   }
  316.   /* n is written twice as crude cross check*/
  317.   if (ccount == 0) /* ccount == 0 means '\n' just written in charout() */
  318.     ; /* this avoids bug in BITNET, which changes blank line to spaces */
  319.   else
  320.     putchar('\n');
  321.   printf("xbtoa End N %ld %lx E %lx S %lx R %lx\n", n, n, Ceor, Csum, Crot);
  322.   exit(0);
  323. }
  324. !Funky!Stuff!
  325. echo x - btoa.man
  326. cat >btoa.man <<'!Funky!Stuff!'
  327. .TH BTOA 1 local
  328. .SH NAME
  329. btoa, atob, tarmail, untarmail \- encode/decode binary to printable ASCII
  330. .SH SYNOPSIS
  331. .B btoa
  332. .br
  333. .B atob
  334. .br
  335. .B tarmail
  336. who files ...
  337. .br
  338. .B untarmail
  339. [ file ]
  340. .SH DESCRIPTION
  341. .I Btoa
  342. is a filter that reads anything from the standard input, and encodes it into
  343. printable ASCII on the standard output.  It also attaches a header and checksum
  344. information used by the reverse filter 
  345. .I atob 
  346. to find the start of the data and to check integrity.
  347. .PP
  348. .I Atob
  349. reads an encoded file, strips off any leading and trailing lines added by
  350. mailers, and recreates a copy of the original file on the standard output.
  351. .I Atob
  352. gives NO output (and exits with an error message) if its input is garbage or
  353. the checksums do not check.  (The checksum is at the end; giving no output on
  354. checksum error guarantees that no "partial things" will be created if there
  355. was an error in transit).
  356. .PP
  357. .I Tarmail
  358. is a shell script that tar's up all the given files, pipes them 
  359. through 
  360. .IR compress ","
  361. .IR btoa ","
  362. and mails them to the given person.  For
  363. example:
  364. .PP
  365. .in 1i
  366. tarmail ralph foo.c a.out
  367. .in -1i
  368. .PP
  369. Will package up files "foo.c" and "a.out" and mail them to "ralph".
  370. .PP
  371. .I Tarmail 
  372. with no args will print a short message reminding you what the required args 
  373. are.  When the mail is received at the other end, that person should use
  374. mail to save the message in some temporary file name (say "xx").
  375. Then saying "untarmail xx"
  376. will decode the message and untar it.  
  377. .I Untarmail 
  378. can also be used as a filter.  By using 
  379. .IR tarmail ","
  380. binary files and
  381. entire directory structures can be easily transmitted between machines.
  382. Naturally, you should understand what tar itself does before you use 
  383. .IR tarmail "."
  384. .PP
  385. Other uses:
  386. .PP
  387. compress < secrets | crypt | btoa | mail ralph
  388. .PP
  389. will mail the encrypted contents of the file "secrets" to ralph.  If ralph
  390. knows the encryption key, he can decode it by saving the mail (say in "xx"),
  391. and then running:
  392. .PP
  393. atob < xx | crypt | uncompress
  394. .PP
  395. (crypt requests the key from the terminal,
  396. and the "secrets" come out on the terminal).
  397. .SH AUTHOR
  398. Paul Rutter
  399. .SH FEATURES
  400. .I Btoa
  401. uses a compact base-85 encoding so that
  402. 4 bytes are encoded into 5 characters (file is expanded by 25%).
  403. As a special case, 32-bit zero is encoded as one character.  This encoding
  404. produces less output than
  405. .IR uuencode "(1)."
  406. .SH "SEE ALSO"
  407. compress(1), crypt(1), uuencode(1), mail(1)
  408. !Funky!Stuff!
  409. echo x - tarmail
  410. cat >tarmail <<'!Funky!Stuff!'
  411. if test $# -lt 2; then
  412.   echo "Usage: tarmail mailpath directory-or-file(s)"
  413.   exit
  414. else
  415.   mailpath=$1
  416.   echo "mailpath = $mailpath"
  417.   shift
  418.   echo files = $*
  419.   tar cvf - $* | compress | btoa | mail $mailpath
  420. fi
  421. !Funky!Stuff!
  422. echo x - untarmail
  423. cat >untarmail <<'!Funky!Stuff!'
  424. if test $# -ge 1; then
  425.    atob < $1 | uncompress | tar xvpf -
  426.    mv $1 /tmp/$1.$$
  427.    echo tarmail file moved to: /usr/tmp/$1.$$
  428. else
  429.    atob | uncompress | tar xvpf -
  430. fi
  431. !Funky!Stuff!
  432. exit 0
  433.  
  434.  
  435.