17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*126530deSAjaykumar Venkatesulu * Common Development and Distribution License (the "License"). 6*126530deSAjaykumar Venkatesulu * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*126530deSAjaykumar Venkatesulu * Copyright (c) 1984, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 267c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 307c478bd9Sstevel@tonic-gate * under license from the Regents of the University of California. 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate /* 347c478bd9Sstevel@tonic-gate * uuencode [-m] [input] decode_pathname 357c478bd9Sstevel@tonic-gate * 367c478bd9Sstevel@tonic-gate * Encode a file so it can be mailed to a remote system. 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate #include <unistd.h> 397c478bd9Sstevel@tonic-gate #include <limits.h> 407c478bd9Sstevel@tonic-gate #include <stdlib.h> 417c478bd9Sstevel@tonic-gate #include <string.h> 427c478bd9Sstevel@tonic-gate #include <stdio.h> 437c478bd9Sstevel@tonic-gate #include <locale.h> 447c478bd9Sstevel@tonic-gate #include <sys/types.h> 457c478bd9Sstevel@tonic-gate #include <sys/stat.h> 467c478bd9Sstevel@tonic-gate #include <errno.h> 477c478bd9Sstevel@tonic-gate #include <assert.h> 487c478bd9Sstevel@tonic-gate #include <signal.h> 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* 517c478bd9Sstevel@tonic-gate * (Size of TABLE_SIZE octal is large enough to convert a basic 6-bit 527c478bd9Sstevel@tonic-gate * data chunk.) 537c478bd9Sstevel@tonic-gate */ 547c478bd9Sstevel@tonic-gate #define TABLE_SIZE 0x40 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate static unsigned char base64_table_initializer[] = 587c478bd9Sstevel@tonic-gate "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 597c478bd9Sstevel@tonic-gate "abcdefghijklmnopqrstuvwxyz0123456789+/"; 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static unsigned char encode_table[TABLE_SIZE]; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* ENC is the basic 1 character encoding function to make a char printing */ 647c478bd9Sstevel@tonic-gate #define ENC(c) encode_table[(c) & 077] 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate static void encode(FILE *, FILE *, int); 677c478bd9Sstevel@tonic-gate static char *prog; 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate int 707c478bd9Sstevel@tonic-gate main(int argc, char **argv) 717c478bd9Sstevel@tonic-gate { 727c478bd9Sstevel@tonic-gate FILE *in; 737c478bd9Sstevel@tonic-gate struct stat sbuf; 747c478bd9Sstevel@tonic-gate mode_t mode = 0; 757c478bd9Sstevel@tonic-gate int c, i; 767c478bd9Sstevel@tonic-gate int errflag = 0; 777c478bd9Sstevel@tonic-gate int base64flag = 0; 787c478bd9Sstevel@tonic-gate char oline[PATH_MAX + 20]; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate prog = argv[0]; 817c478bd9Sstevel@tonic-gate (void) signal(SIGPIPE, SIG_DFL); 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate /* Set locale environment variables local definitions */ 847c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 857c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 867c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ 877c478bd9Sstevel@tonic-gate #endif 887c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "m")) != EOF) 917c478bd9Sstevel@tonic-gate switch (c) { 927c478bd9Sstevel@tonic-gate case 'm': 937c478bd9Sstevel@tonic-gate base64flag++; 947c478bd9Sstevel@tonic-gate break; 957c478bd9Sstevel@tonic-gate default: 967c478bd9Sstevel@tonic-gate case '?': 977c478bd9Sstevel@tonic-gate errflag++; 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate argc -= optind; 1017c478bd9Sstevel@tonic-gate argv = &argv[optind]; 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* optional 1st argument */ 1047c478bd9Sstevel@tonic-gate if (argc > 1) { 1057c478bd9Sstevel@tonic-gate if ((in = fopen(*argv, "r")) == NULL) { 1067c478bd9Sstevel@tonic-gate perror(*argv); 1077c478bd9Sstevel@tonic-gate exit(1); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate argv++; argc--; 1107c478bd9Sstevel@tonic-gate } else { 1117c478bd9Sstevel@tonic-gate in = stdin; 1127c478bd9Sstevel@tonic-gate mode = 0777; 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate if ((argc != 1) || errflag) { 1167c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1177c478bd9Sstevel@tonic-gate gettext("Usage: %s [-m] [infile] remotefile\n"), prog); 1187c478bd9Sstevel@tonic-gate exit(2); 1197c478bd9Sstevel@tonic-gate } 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate /* figure out the input file mode */ 1227c478bd9Sstevel@tonic-gate errno = 0; 1237c478bd9Sstevel@tonic-gate if (fstat(fileno(in), &sbuf) < 0 || !S_ISREG(sbuf.st_mode)) { 1247c478bd9Sstevel@tonic-gate mode = 0666 & ~umask(0666); 1257c478bd9Sstevel@tonic-gate } else { 1267c478bd9Sstevel@tonic-gate mode = sbuf.st_mode & 0777; 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate /* 1307c478bd9Sstevel@tonic-gate * encoding varies depending on whether we are 1317c478bd9Sstevel@tonic-gate * using base64 encoding or the historical algorithm 1327c478bd9Sstevel@tonic-gate */ 1337c478bd9Sstevel@tonic-gate if (base64flag) { 1347c478bd9Sstevel@tonic-gate (void) memcpy(encode_table, base64_table_initializer, 135*126530deSAjaykumar Venkatesulu sizeof (encode_table)); 1367c478bd9Sstevel@tonic-gate } else { 1377c478bd9Sstevel@tonic-gate for (i = 0; i < TABLE_SIZE; i++) 1387c478bd9Sstevel@tonic-gate encode_table[i] = (unsigned char)i + 0x20; 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /* 1427c478bd9Sstevel@tonic-gate * here's the meat of the whole thing 1437c478bd9Sstevel@tonic-gate */ 1447c478bd9Sstevel@tonic-gate if (base64flag) 1457c478bd9Sstevel@tonic-gate (void) snprintf(oline, sizeof (oline), "begin-base64 %lo %s\n", 1467c478bd9Sstevel@tonic-gate (long)mode, *argv); 1477c478bd9Sstevel@tonic-gate else 1487c478bd9Sstevel@tonic-gate (void) snprintf(oline, sizeof (oline), "begin %lo %s\n", 1497c478bd9Sstevel@tonic-gate (long)mode, *argv); 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate if (printf("%s", oline) < 0) { 1527c478bd9Sstevel@tonic-gate perror(prog); 1537c478bd9Sstevel@tonic-gate exit(6); 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate encode(in, stdout, base64flag); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate if (base64flag) 1597c478bd9Sstevel@tonic-gate (void) snprintf(oline, sizeof (oline), "====\n"); 1607c478bd9Sstevel@tonic-gate else 1617c478bd9Sstevel@tonic-gate (void) snprintf(oline, sizeof (oline), "end\n"); 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate if (printf("%s", oline) < 0) { 1647c478bd9Sstevel@tonic-gate perror(prog); 1657c478bd9Sstevel@tonic-gate exit(6); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate if (ferror(stdout) != 0 || fclose(stdout) != 0) { 1697c478bd9Sstevel@tonic-gate perror(prog); 1707c478bd9Sstevel@tonic-gate exit(6); 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate return (0); 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate /* 1777c478bd9Sstevel@tonic-gate * copy from in to out, encoding as you go along. 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate static void 1807c478bd9Sstevel@tonic-gate encode(FILE *in, FILE *out, int base64) 1817c478bd9Sstevel@tonic-gate { 1827c478bd9Sstevel@tonic-gate unsigned char in_buf[80]; 1837c478bd9Sstevel@tonic-gate unsigned char out_buf[112]; 1847c478bd9Sstevel@tonic-gate unsigned char *iptr, *optr; 1857c478bd9Sstevel@tonic-gate int i; 1867c478bd9Sstevel@tonic-gate size_t n, opos; 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate if (! base64) { 1897c478bd9Sstevel@tonic-gate /* historical algorithm */ 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate for (;;) { 1927c478bd9Sstevel@tonic-gate iptr = in_buf; 1937c478bd9Sstevel@tonic-gate optr = out_buf; 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate /* 1 (up to) 45 character line */ 1967c478bd9Sstevel@tonic-gate n = fread(iptr, 1, 45, in); 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate *(optr++) = ENC(n); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate for (i = 0; i < n; i += 3) { 2017c478bd9Sstevel@tonic-gate *(optr++) = ENC(*iptr >> 2); 2027c478bd9Sstevel@tonic-gate *(optr++) = ENC((*iptr << 4) & 060 | 2037c478bd9Sstevel@tonic-gate (*(iptr + 1) >> 4) & 017); 2047c478bd9Sstevel@tonic-gate *(optr++) = ENC((*(iptr + 1) << 2) & 074 | 2057c478bd9Sstevel@tonic-gate (*(iptr + 2) >> 6) & 03); 2067c478bd9Sstevel@tonic-gate *(optr++) = ENC(*(iptr + 2) & 077); 2077c478bd9Sstevel@tonic-gate iptr += 3; 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate *(optr++) = '\n'; 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate /*LINTED*/ 2137c478bd9Sstevel@tonic-gate (void) fwrite(out_buf, 1, (size_t)(optr - out_buf), 2147c478bd9Sstevel@tonic-gate out); 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate if (ferror(out)) { 2177c478bd9Sstevel@tonic-gate perror(prog); 2187c478bd9Sstevel@tonic-gate exit(6); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate if (n == 0) 2227c478bd9Sstevel@tonic-gate break; 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate } else { 2257c478bd9Sstevel@tonic-gate /* base64 algorithm */ 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate optr = out_buf; 2287c478bd9Sstevel@tonic-gate /* 2297c478bd9Sstevel@tonic-gate * read must be a multiple of 3 bytes for 2307c478bd9Sstevel@tonic-gate * this algorithm to work, and also must 2317c478bd9Sstevel@tonic-gate * be small enough that read_size * (4/3) 2327c478bd9Sstevel@tonic-gate * will always be 76 bytes or less, since 2337c478bd9Sstevel@tonic-gate * base64 lines can be no longer than that 2347c478bd9Sstevel@tonic-gate */ 2357c478bd9Sstevel@tonic-gate while ((n = fread(in_buf, 1, 51, in)) > 0) { 2367c478bd9Sstevel@tonic-gate opos = 0; 2377c478bd9Sstevel@tonic-gate iptr = in_buf; 2387c478bd9Sstevel@tonic-gate for (i = 0; i < n / 3; i++) { 2397c478bd9Sstevel@tonic-gate *(optr++) = ENC(*iptr >> 2); 2407c478bd9Sstevel@tonic-gate *(optr++) = ENC((*iptr << 4) & 060 | 2417c478bd9Sstevel@tonic-gate (*(iptr + 1) >> 4) & 017); 2427c478bd9Sstevel@tonic-gate *(optr++) = ENC((*(iptr + 1) << 2) 2437c478bd9Sstevel@tonic-gate & 074 | (*(iptr + 2) >> 6) & 03); 2447c478bd9Sstevel@tonic-gate *(optr++) = ENC(*(iptr + 2) & 077); 2457c478bd9Sstevel@tonic-gate iptr += 3; 2467c478bd9Sstevel@tonic-gate opos += 3; 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate /* need output padding ? */ 2497c478bd9Sstevel@tonic-gate if (n - opos < 3) 2507c478bd9Sstevel@tonic-gate break; 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate (void) fwrite(out_buf, 1, 2537c478bd9Sstevel@tonic-gate /*LINTED*/ 2547c478bd9Sstevel@tonic-gate (size_t)(optr - out_buf), out); 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate if (ferror(out)) { 2577c478bd9Sstevel@tonic-gate perror(prog); 2587c478bd9Sstevel@tonic-gate exit(6); 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate optr = out_buf; 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate /* 2647c478bd9Sstevel@tonic-gate * Take care of any output padding that is 2657c478bd9Sstevel@tonic-gate * necessary. 2667c478bd9Sstevel@tonic-gate */ 2677c478bd9Sstevel@tonic-gate assert(n - opos < 3); 2687c478bd9Sstevel@tonic-gate switch (n - opos) { 2697c478bd9Sstevel@tonic-gate case 0: 2707c478bd9Sstevel@tonic-gate /* no-op - 24 bits of data encoded */ 2717c478bd9Sstevel@tonic-gate *(optr++) = '\n'; 2727c478bd9Sstevel@tonic-gate break; 2737c478bd9Sstevel@tonic-gate case 1: 2747c478bd9Sstevel@tonic-gate /* 8 bits encoded - pad with 2 '=' */ 2757c478bd9Sstevel@tonic-gate *(optr++) = ENC((*iptr & 0xFC) >> 2); 2767c478bd9Sstevel@tonic-gate *(optr++) = ENC((*iptr & 0x03) << 4); 2777c478bd9Sstevel@tonic-gate *(optr++) = '='; 2787c478bd9Sstevel@tonic-gate *(optr++) = '='; 2797c478bd9Sstevel@tonic-gate *(optr++) = '\n'; 2807c478bd9Sstevel@tonic-gate break; 2817c478bd9Sstevel@tonic-gate case 2: 2827c478bd9Sstevel@tonic-gate /* 16 bits encoded - pad with 1 '=' */ 2837c478bd9Sstevel@tonic-gate *(optr++) = ENC((*iptr & 0xFC) >> 2); 2847c478bd9Sstevel@tonic-gate *(optr++) = ENC(((*iptr & 0x03) << 4) | 2857c478bd9Sstevel@tonic-gate ((*(iptr + 1) & 0xF0) >> 4)); 2867c478bd9Sstevel@tonic-gate *(optr++) = ENC((*(iptr + 1) & 0x0F) 2877c478bd9Sstevel@tonic-gate << 2); 2887c478bd9Sstevel@tonic-gate *(optr++) = '='; 2897c478bd9Sstevel@tonic-gate *(optr++) = '\n'; 2907c478bd9Sstevel@tonic-gate break; 2917c478bd9Sstevel@tonic-gate default: 2927c478bd9Sstevel@tonic-gate /* impossible */ 2937c478bd9Sstevel@tonic-gate break; 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate (void) fwrite(out_buf, 1, 2967c478bd9Sstevel@tonic-gate /*LINTED*/ 2977c478bd9Sstevel@tonic-gate (size_t)(optr - out_buf), out); 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate if (ferror(out)) { 3007c478bd9Sstevel@tonic-gate perror(prog); 3017c478bd9Sstevel@tonic-gate exit(6); 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate optr = out_buf; 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate } 308