commit: 7a35d61357d0e10ded9ed30db1ab0711d265fca1
parent 7e734462c1628962c49dd20457b5f75473926584
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Wed, 1 Nov 2023 11:45:49 +0100
cmd/base64: Add -w option
Diffstat:
2 files changed, 41 insertions(+), 23 deletions(-)
diff --git a/cmd/base64.1 b/cmd/base64.1
@@ -10,6 +10,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl d
+.Op Fl w Ar wrap
.Op Ar file ...
.Sh DESCRIPTION
.Nm
@@ -25,6 +26,13 @@ reads from the standard input.
.Bl -tag -width Ds
.It Fl d
Decode input instead of encoding it.
+.It Fl w Ar wrap
+Write at most
+.Ar wrap
+characters per line.
+If
+.Ar wrap
+is 0, then no newlines are written.
.El
.Sh EXIT STATUS
.Ex -std
diff --git a/cmd/base64.c b/cmd/base64.c
@@ -17,8 +17,20 @@
// 64(26+26+10+2)
static char b64_encmap[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static size_t c_out = 0;
-// TODO: -w option ; 76 is lowest of all base64 related RFCs
-static size_t wrap_nl = 76;
+// 76 is lowest of all base64 related RFCs
+static long wrap_nl = 76;
+
+static int
+xputc(int c, FILE *stream)
+{
+ if(fputc(c, stream) == EOF)
+ {
+ fprintf(stderr, "base64: Error writing: %s\n", strerror(errno));
+ return 1;
+ }
+
+ return 0;
+}
static inline uint8_t
b64_get(uint8_t pos)
@@ -78,21 +90,17 @@ encode(FILE *fin, const char *name)
obuf[4 - pad] = '=';
}
- if(write(1, (char *)obuf, 4) != 4)
+ if(fwrite((char *)obuf, 4, 1, stdout) != 1)
{
fprintf(stderr, "base64: Error writing: %s\n", strerror(errno));
return 1;
}
c_out += 4;
- if(wrap_nl != 0 && c_out >= wrap_nl)
+ if(wrap_nl != 0 && (c_out + 4) > wrap_nl)
{
c_out = 0;
- if(write(1, "\n", 1) != 1)
- {
- fprintf(stderr, "base64: Error writing: %s\n", strerror(errno));
- return 1;
- }
+ if(xputc('\n', stdout) != 0) return 1;
}
if(feof(fin)) return 0;
@@ -101,18 +109,6 @@ encode(FILE *fin, const char *name)
abort(); // unreachable
}
-static int
-xputc(int c, FILE *stream)
-{
- if(fputc(c, stream) == EOF)
- {
- fprintf(stderr, "base64: Error writing: %s\n", strerror(errno));
- return 1;
- }
-
- return 0;
-}
-
// This function is based on NetBSD's code, which contains the following notices:
// Copyright (c) 2018 The NetBSD Foundation, Inc.
//
@@ -216,13 +212,27 @@ main(int argc, char *argv[])
int c = 0, ret = 0;
- while((c = getopt(argc, argv, ":d")) != -1)
+ while((c = getopt(argc, argv, ":dw:")) != -1)
{
switch(c)
{
case 'd':
process = &decode;
break;
+ case 'w':
+ errno = 0;
+ char *e = "";
+ wrap_nl = strtol(optarg, &e, 10);
+
+ // extraneous characters is invalid
+ if(*e != 0) errno = EINVAL;
+
+ if(errno != 0)
+ {
+ fprintf(stderr, "base64: Option `-w %s`: %s\n", optarg, strerror(errno));
+ return 1;
+ }
+ break;
case ':':
fprintf(stderr, "base64: Error: Missing operand for option: ā-%cā\n", optopt);
return 1;
@@ -281,7 +291,7 @@ main(int argc, char *argv[])
}
end:
- if(c_out > 0)
+ if(wrap_nl != 0 && c_out > 0)
{
printf("\n");
}