summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2019-10-07 21:28:39 -0400
committerJakob Kaivo <jkk@ung.org>2019-10-07 21:28:39 -0400
commit2787f07c97ca4a517a5e9d4f03edae9f5554b39b (patch)
tree664aec837d63903dab8d8b48f19af432550811f4
parent62f5154aebe5a267d815b2f0312c0bef5e923127 (diff)
clean up code
-rw-r--r--uuencode.c123
1 files changed, 72 insertions, 51 deletions
diff --git a/uuencode.c b/uuencode.c
index 9b1965c..066e992 100644
--- a/uuencode.c
+++ b/uuencode.c
@@ -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);
}