diff options
author | Jakob Kaivo <jkk@ung.org> | 2019-10-07 21:28:39 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2019-10-07 21:28:39 -0400 |
commit | 2787f07c97ca4a517a5e9d4f03edae9f5554b39b (patch) | |
tree | 664aec837d63903dab8d8b48f19af432550811f4 | |
parent | 62f5154aebe5a267d815b2f0312c0bef5e923127 (diff) |
clean up code
-rw-r--r-- | uuencode.c | 123 |
1 files changed, 72 insertions, 51 deletions
@@ -23,7 +23,10 @@ */ #define _XOPEN_SOURCE 700 +#include <errno.h> +#include <locale.h> #include <stdio.h> +#include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -31,83 +34,101 @@ static const char *b64s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static int encode(FILE * in, char *out, int mode, int b64) +static inline int encodechunk(char *in, char *out, int n, int b64) { - char bin[3], bout[76]; - int nread = 0, lread = 0, lpos = 0; - int linelength = b64 ? 54 : 43; - int i; - - printf("begin%s %03o %s\n", b64 ? "-base64" : "", mode, out); - - while (!feof(in)) { - nread = fread(bin, sizeof(char), 3, in); - if (nread > 0) { - bout[lpos++] = (bin[0] >> 2) & 0x3f; - bout[lpos++] = - ((bin[0] << 4) | ((bin[1] >> 4) & 0xf)) & 0x3f; - bout[lpos++] = - ((bin[1] << 2) | ((bin[2] >> 6) & 0x3)) & 0x3f; - bout[lpos++] = (bin[2]) & 0x3f; - bin[0] = bin[1] = bin[2] = 0; - lread += nread; + out[0] = (in[0] >> 2) & 0x3f; + out[1] = ((in[0] << 4) | ((in[1] >> 4) & 0xf)) & 0x3f; + out[2] = ((in[1] << 2) | ((in[2] >> 6) & 0x3)) & 0x3f; + out[3] = (in[2]) & 0x3f; + + for (int i = 0; i < 4; i++) { + out[i] = b64 ? b64s[(int)(out[i])] : out[i] + 0x20; + } + + if (n < 2) { + out[2] = b64 ? '=' : ((in[0] << 4) & 0x3f) + 0x20; + } + + if (n < 3) { + out[3] = b64 ? '=' : ((in[1] << 2) & 0x3f) + 0x20; + } + + return b64 ? 4 : 4 - (3-n); +} + +static int encode(FILE * in, const char *path, mode_t mode, int b64) +{ + printf("begin%s %03o %s\n", b64 ? "-base64" : "", mode, path); + + int lpos = 0; + int linelength = b64 ? 75 : 43; + + int nread = 0; + char ibuf[3] = {0}; + char obuf[76] = {0}; + + while ((nread = fread(ibuf, 1, sizeof(ibuf), in)) != 0) { + if (nread < 0) { + perror("uuencode"); + return 1; } - if (feof(in) || nread == 0 || lread > linelength) { - for (i = 0; i < lpos; i++) - bout[i] = b64 ? b64s[bout[i]] : bout[i] + 0x20; + lpos += encodechunk(ibuf, obuf + lpos, nread, b64); - if (b64) { - if (nread == 1) - bout[lpos - 2] = '='; - if (nread == 1 || nread == 2) - bout[lpos - 1] = '='; + if (lpos > linelength || nread < 3) { + if (!b64) { + fputc(0x20 + lpos, stdout); } - if (!b64) - putchar(0x20 + lread); - fwrite(bout, sizeof(char), lpos, stdout); + fwrite(obuf, 1, lpos, stdout); fputc('\n', stdout); - lread = 0; lpos = 0; + memset(obuf, 0, sizeof(obuf)); } + memset(ibuf, 0, sizeof(ibuf)); } - if (b64) - printf("====\n"); - else - printf("%c\nend\n", 0x20); - + printf("%s\n", b64 ? "====" : "end"); return 0; } int main(int argc, char *argv[]) { - int b64 = 0, mode = 0644, c; - FILE *input; - struct stat st; + int mime_base64 = 0; + mode_t mode = 0644; + FILE *input = stdin; + int c; + + setlocale(LC_ALL, ""); - while ((c = getopt(argc, argv, ":m")) != -1) { + while ((c = getopt(argc, argv, "m")) != -1) { switch (c) { case 'm': - b64 = 1; + mime_base64 = 1; break; + default: return 1; } } - if (argc - optind == 2) { - input = fopen(argv[optind++], "r"); - if (fstat(fileno(input), &st) == 0) - mode = st.st_mode & 0777; - } else if (argc - optind == 1) - input = stdin; - else + if (optind > argc) { + fprintf(stderr, "uuencode: missing operand\n"); return 1; + } - if (input == NULL) - return 1; // File I/O error + if (argc - optind == 2) { + input = fopen(argv[optind], "r"); + if (input == NULL) { + fprintf(stderr, "uuencode: %s: %s\n", argv[optind], strerror(errno)); + return 1; + } + + struct stat st; + if (fstat(fileno(input), &st) == 0) { + mode = st.st_mode & 0777; + } + } - return encode(input, argv[optind], mode, b64); + return encode(input, argv[argc - 1], mode, mime_base64); } |