logo

utils-std

Collection of commonly available Unix tools
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:

Mcmd/base64.18++++++++
Mcmd/base64.c56+++++++++++++++++++++++++++++++++-----------------------
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"); }