Hi,

I've put these patches together in this e-mail to make it easy for
David to pick them up.

0001-Fix-segfault-in-tail-1.patch
0002-Fix-warnings-about-strcpy-etc.-on-OpenBSD.patch
0003-Add-not-implemented-errors-for-unimplemented-flags.patch
0004-Add-initial-support-for-id-1.patch
0005-Add-strings-1.patch (no manpage)
0006-Add-stat-1.patch (no manpage)

Thanks,
sin
>From 19753fe2c0a672033b67a6bbd5146e3eacdf0f84 Mon Sep 17 00:00:00 2001
From: sin <[email protected]>
Date: Thu, 15 Aug 2013 12:38:10 +0100
Subject: [PATCH 1/6] Fix segfault in tail(1)

We should not be looking at optarg, that's uninitialized.  We
are not using getopt.
---
 tail.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tail.c b/tail.c
index 3fbd606..037030e 100644
--- a/tail.c
+++ b/tail.c
@@ -21,11 +21,13 @@ main(int argc, char *argv[])
        long n = 10;
        FILE *fp;
        void (*tail)(FILE *, const char *, long) = taketail;
+       char *opt;
 
        ARGBEGIN {
        case 'n':
-               n = abs(estrtol(EARGF(usage()), 0));
-               if(optarg[0] == '+')
+               opt = EARGF(usage());
+               n = abs(estrtol(opt, 0));
+               if(opt[0] == '+')
                        tail = dropinit;
                break;
        default:
-- 
1.8.2.3

>From a11e68705415f045f2e20e00258dea570b09fe44 Mon Sep 17 00:00:00 2001
From: sin <[email protected]>
Date: Thu, 15 Aug 2013 12:34:38 +0100
Subject: [PATCH 2/6] Fix warnings about strcpy() etc. on OpenBSD

---
 ls.c            | 5 +++--
 split.c         | 2 +-
 util/afgets.c   | 3 ++-
 util/getlines.c | 5 +++--
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/ls.c b/ls.c
index f61d7c5..e3a440f 100644
--- a/ls.c
+++ b/ls.c
@@ -112,6 +112,7 @@ lsdir(const char *path)
        struct dirent *d;
        DIR *dp;
        Entry ent, *ents = NULL;
+       size_t sz;
 
        cwd = agetcwd();
        if(!(dp = opendir(path)))
@@ -135,9 +136,9 @@ lsdir(const char *path)
                } else {
                        if(!(ents = realloc(ents, ++n * sizeof *ents)))
                                eprintf("realloc:");
-                       if(!(p = malloc(strlen(d->d_name)+1)))
+                       if(!(p = malloc((sz = strlen(d->d_name)+1))))
                                eprintf("malloc:");
-                       strcpy(p, d->d_name);
+                       memcpy(p, d->d_name, sz);
                        mkent(&ents[n-1], p, tflag || lflag);
                }
        }
diff --git a/split.c b/split.c
index cf22125..633c02e 100644
--- a/split.c
+++ b/split.c
@@ -74,7 +74,7 @@ main(int argc, char **argv)
        plen = strlen(prefix);
        if(plen+slen > NAME_MAX)
                eprintf("split: names cannot exceed %d bytes", NAME_MAX);
-       strcpy(name, prefix);
+       snprintf(name, sizeof(name), "%s", prefix);
 
        if(file && strcmp(file, "-") != 0) {
                in = fopen(file, "r");
diff --git a/util/afgets.c b/util/afgets.c
index e1d719d..4b4ffe2 100644
--- a/util/afgets.c
+++ b/util/afgets.c
@@ -17,7 +17,8 @@ afgets(char **p, size_t *size, FILE *fp)
                if(len+1 > *size && !(*p = realloc(*p, len+1)))
                        eprintf("realloc:");
 
-               strcpy(&(*p)[len-n], buf);
+               memcpy(&(*p)[len-n], buf, n);
+               (*p)[len] = '\0';
 
                if(buf[n-1] == '\n' || feof(fp))
                        break;
diff --git a/util/getlines.c b/util/getlines.c
index d3152ec..f1c3453 100644
--- a/util/getlines.c
+++ b/util/getlines.c
@@ -11,6 +11,7 @@ getlines(FILE *fp, struct linebuf *b)
 {
        char *line = NULL, **nline;
        size_t size = 0;
+       size_t linelen;
 
        while(afgets(&line, &size, fp)) {
                if(++b->nlines > b->capacity) {
@@ -20,9 +21,9 @@ getlines(FILE *fp, struct linebuf *b)
                                eprintf("realloc:");
                        b->lines = nline;
                }
-               if(!(b->lines[b->nlines-1] = malloc(strlen(line)+1)))
+               if(!(b->lines[b->nlines-1] = malloc((linelen = 
strlen(line)+1))))
                        eprintf("malloc:");
-               strcpy(b->lines[b->nlines-1], line);
+               memcpy(b->lines[b->nlines-1], line, linelen);
        }
        free(line);
 }
-- 
1.8.2.3

>From 323dbeec1cc8e110746643bf1dbcefdb92db10c2 Mon Sep 17 00:00:00 2001
From: sin <[email protected]>
Date: Thu, 15 Aug 2013 10:55:21 +0100
Subject: [PATCH 3/6] Add 'not implemented' errors for unimplemented flags

These used to live in TODO but we got rid off them.  Make sure
we keep track of what we want to support by printing a message
when those flags are unimplemented.
---
 expand.c    | 4 +++-
 md5sum.c    | 4 +++-
 readlink.c  | 5 ++++-
 sha1sum.c   | 4 +++-
 sha256sum.c | 4 +++-
 sha512sum.c | 4 +++-
 uniq.c      | 4 +++-
 7 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/expand.c b/expand.c
index 68336ec..7ad43b8 100644
--- a/expand.c
+++ b/expand.c
@@ -14,7 +14,7 @@ static int expand(Fdescr *f, int tabstop);
 static void
 usage(void)
 {
-       eprintf("usage: %s [-t n] [file...]\n", argv0);
+       eprintf("usage: %s [-i] [-t n] [file...]\n", argv0);
 }
 
 int
@@ -25,6 +25,8 @@ main(int argc, char *argv[])
        int tabstop = 8;
 
        ARGBEGIN {
+       case 'i':
+               eprintf("not implemented\n");
        case 't':
                tabstop = estrtol(EARGF(usage()), 0);
                break;
diff --git a/md5sum.c b/md5sum.c
index 4fd449f..7618663 100644
--- a/md5sum.c
+++ b/md5sum.c
@@ -17,7 +17,7 @@ struct crypt_ops md5_ops = {
 static void
 usage(void)
 {
-       eprintf("usage: %s [file...]\n", argv0);
+       eprintf("usage: %s [-c] [file...]\n", argv0);
 }
 
 int
@@ -27,6 +27,8 @@ main(int argc, char *argv[])
        uint8_t md[MD5_DIGEST_LENGTH];
 
        ARGBEGIN {
+       case 'c':
+               eprintf("not implemented\n");
        default:
                usage();
        } ARGEND;
diff --git a/readlink.c b/readlink.c
index 065c05d..f54fd51 100644
--- a/readlink.c
+++ b/readlink.c
@@ -11,7 +11,7 @@
 static void
 usage(void)
 {
-       eprintf("usage: %s [-fn] file\n", argv0);
+       eprintf("usage: %s [-efmn] file\n", argv0);
 }
 
 int
@@ -23,6 +23,9 @@ main(int argc, char *argv[])
        ssize_t n;
 
        ARGBEGIN {
+       case 'e':
+       case 'm':
+               eprintf("not implemented\n");
        case 'f':
                fflag = true;
                break;
diff --git a/sha1sum.c b/sha1sum.c
index 11b9111..6d79f15 100644
--- a/sha1sum.c
+++ b/sha1sum.c
@@ -17,7 +17,7 @@ struct crypt_ops sha1_ops = {
 static void
 usage(void)
 {
-       eprintf("usage: %s [file...]\n", argv0);
+       eprintf("usage: %s [-c] [file...]\n", argv0);
 }
 
 int
@@ -27,6 +27,8 @@ main(int argc, char *argv[])
        uint8_t md[SHA1_DIGEST_LENGTH];
 
        ARGBEGIN {
+       case 'c':
+               eprintf("not implemented\n");
        default:
                usage();
        } ARGEND;
diff --git a/sha256sum.c b/sha256sum.c
index ce97435..5dfc6a5 100644
--- a/sha256sum.c
+++ b/sha256sum.c
@@ -17,7 +17,7 @@ struct crypt_ops sha256_ops = {
 static void
 usage(void)
 {
-       eprintf("usage: %s [file...]\n", argv0);
+       eprintf("usage: %s [-c] [file...]\n", argv0);
 }
 
 int
@@ -27,6 +27,8 @@ main(int argc, char *argv[])
        uint8_t md[SHA256_DIGEST_LENGTH];
 
        ARGBEGIN {
+       case 'c':
+               eprintf("not implemented\n");
        default:
                usage();
        } ARGEND;
diff --git a/sha512sum.c b/sha512sum.c
index 972f2c7..edb1cd3 100644
--- a/sha512sum.c
+++ b/sha512sum.c
@@ -17,7 +17,7 @@ struct crypt_ops sha512_ops = {
 static void
 usage(void)
 {
-       eprintf("usage: %s [file...]\n", argv0);
+       eprintf("usage: %s [-c] [file...]\n", argv0);
 }
 
 int
@@ -27,6 +27,8 @@ main(int argc, char *argv[])
        uint8_t md[SHA512_DIGEST_LENGTH];
 
        ARGBEGIN {
+       case 'c':
+               eprintf("not implemented\n");
        default:
                usage();
        } ARGEND;
diff --git a/uniq.c b/uniq.c
index 7eb49f3..9c85668 100644
--- a/uniq.c
+++ b/uniq.c
@@ -22,7 +22,7 @@ static long prev_line_count = 0;
 static void
 usage(void)
 {
-       eprintf("usage: %s [-cdu] [input]]\n", argv0);
+       eprintf("usage: %s [-cdiu] [input]]\n", argv0);
 }
 
 int
@@ -31,6 +31,8 @@ main(int argc, char *argv[])
        FILE *fp;
 
        ARGBEGIN {
+       case 'i':
+               eprintf("not implemented\n");
        case 'c':
                countfmt = "%7ld ";
                break;
-- 
1.8.2.3

>From 56a02a57e4a1d482434e3729006de6bd4dfae88a Mon Sep 17 00:00:00 2001
From: sin <[email protected]>
Date: Wed, 7 Aug 2013 13:40:21 +0100
Subject: [PATCH 4/6] Add initial support for id(1)

---
 Makefile |  1 +
 id.1     |  8 ++++++++
 id.c     | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+)
 create mode 100644 id.1
 create mode 100644 id.c

diff --git a/Makefile b/Makefile
index 2e31f33..33c78a0 100644
--- a/Makefile
+++ b/Makefile
@@ -46,6 +46,7 @@ SRC = \
        fold.c     \
        grep.c     \
        head.c     \
+       id.c       \
        kill.c     \
        ln.c       \
        ls.c       \
diff --git a/id.1 b/id.1
new file mode 100644
index 0000000..a5678e3
--- /dev/null
+++ b/id.1
@@ -0,0 +1,8 @@
+.TH ID 1 sbase\-VERSION
+.SH NAME
+id \- print real and effective user and group IDs
+.SH DESCRIPTION
+.B id
+Print user and group information for the current user.
+.SH SEE ALSO
+.IR who(1)
diff --git a/id.c b/id.c
new file mode 100644
index 0000000..19248d0
--- /dev/null
+++ b/id.c
@@ -0,0 +1,70 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/types.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdio.h>
+#include <limits.h>
+#include "util.h"
+
+static void
+usage(void)
+{
+       eprintf("usage: %s\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+       struct passwd *pw;
+       struct group *gr;
+       uid_t uid, euid;
+       gid_t gid, egid, groups[NGROUPS_MAX];
+       int ngroups;
+       int i;
+
+       ARGBEGIN {
+       default:
+               usage();
+       } ARGEND;
+
+       /* Print uid/euid info */
+       uid = getuid();
+       printf("uid=%u", uid);
+       if (!(pw = getpwuid(uid)))
+               eprintf("getpwuid:");
+       printf("(%s)", pw->pw_name);
+       if ((euid = geteuid()) != uid) {
+               printf(" euid=%u", euid);
+               if (!(pw = getpwuid(euid)))
+                       eprintf("getpwuid:");
+               printf("(%s)", pw->pw_name);
+       }
+
+       /* Print gid/egid info */
+       gid = getgid();
+       printf(" gid=%u", gid);
+       if (!(gr = getgrgid(gid)))
+               eprintf("getgrgid:");
+       printf("(%s)", gr->gr_name);
+       if ((egid = getegid()) != gid) {
+               printf(" egid=%u", egid);
+               if (!(gr = getgrgid(egid)))
+                       eprintf("getgrgid:");
+               printf("(%s)", gr->gr_name);
+       }
+
+       /* Print groups */
+       ngroups = getgroups(NGROUPS_MAX, groups);
+       if (ngroups < 0)
+               eprintf("getgroups:");
+       for (i = 0; i < ngroups; i++) {
+               gid = groups[i];
+               printf("%s%u", !i ? " groups=" : ",", gid);
+               if (!(gr = getgrgid(gid)))
+                       eprintf("getgrgid:");
+               printf("(%s)", gr->gr_name);
+       }
+       putchar('\n');
+       return 0;
+}
-- 
1.8.2.3

>From 298be2bfbb4aa2ecbc3753acecddbc96877be27f Mon Sep 17 00:00:00 2001
From: sin <[email protected]>
Date: Wed, 14 Aug 2013 10:41:55 +0100
Subject: [PATCH 5/6] Add strings(1)

---
 Makefile  |  1 +
 strings.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)
 create mode 100644 strings.c

diff --git a/Makefile b/Makefile
index 33c78a0..6bc091a 100644
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,7 @@ SRC = \
        sort.c     \
        split.c    \
        sponge.c   \
+       strings.c  \
        sync.c     \
        tail.c     \
        tar.c      \
diff --git a/strings.c b/strings.c
new file mode 100644
index 0000000..7386963
--- /dev/null
+++ b/strings.c
@@ -0,0 +1,56 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "util.h"
+
+static void dostrings(FILE *fp, const char *fname);
+
+static void
+usage(void)
+{
+       eprintf("usage: %s file\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+       FILE *fp;
+
+       ARGBEGIN {
+       default:
+               usage();
+       } ARGEND;
+
+       if (argc > 0) {
+               if (!(fp = fopen(argv[0], "r")))
+                       eprintf("open %s:", argv[0]);
+               dostrings(fp, argv[0]);
+               fclose(fp);
+       } else {
+               dostrings(stdin, "<stdin>");
+       }
+
+       return 0;
+}
+
+static void
+dostrings(FILE *fp, const char *fname)
+{
+       unsigned char buf[BUFSIZ];
+       int c, i = 0;
+       off_t offset = 0;
+
+       do {
+               offset++;
+               if (isprint(c = getc(fp)))
+                       buf[i++] = c;
+               if ((!isprint(c) && i >= 6) || i == sizeof(buf) - 1) {
+                       buf[i] = '\0';
+                       printf("%8ld: %s\n", (long)offset - i - 1, buf);
+                       i = 0;
+               }
+       } while (c != EOF);
+       if (ferror(fp))
+               eprintf("%s read error:", fname);
+}
-- 
1.8.2.3

>From f84109d7654be752d47a50995c65ddc1c4da76ee Mon Sep 17 00:00:00 2001
From: sin <[email protected]>
Date: Thu, 15 Aug 2013 10:04:38 +0100
Subject: [PATCH 6/6] Add stat(1)

---
 Makefile |  1 +
 stat.c   | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)
 create mode 100644 stat.c

diff --git a/Makefile b/Makefile
index 6bc091a..010391c 100644
--- a/Makefile
+++ b/Makefile
@@ -86,6 +86,7 @@ SRC = \
        sha1sum.c  \
        sha256sum.c\
        sha512sum.c\
+       stat.c     \
        wc.c       \
        who.c      \
        yes.c
diff --git a/stat.c b/stat.c
new file mode 100644
index 0000000..7ce2cf5
--- /dev/null
+++ b/stat.c
@@ -0,0 +1,73 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <time.h>
+#include "util.h"
+
+static void show_stat(const char *file, struct stat *st);
+
+static void
+usage(void)
+{
+       eprintf("usage: %s [-L] file...\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+       struct stat st;
+       int i, ret = 0;
+       int Lflag = 0;
+       int (*fn)(const char *, struct stat *);
+
+       ARGBEGIN {
+       case 'L':
+               Lflag = 1;
+               break;
+       default:
+               usage();
+       } ARGEND;
+
+       if (argc == 0) {
+               if (fstat(STDIN_FILENO, &st) < 0)
+                       eprintf("stat <stdin>:");
+               show_stat("<stdin>", &st);
+       }
+
+       for (i = 0; i < argc; i++) {
+               fn = Lflag ? stat : lstat;
+               if (fn(argv[i], &st) == -1) {
+                       fprintf(stderr, "%s %s: ", Lflag ? "stat" : "lstat",
+                               argv[i]);
+                       perror(NULL);
+                       ret = 1;
+                       continue;
+               }
+               show_stat(argv[i], &st);
+       }
+
+       return ret;
+}
+
+static void
+show_stat(const char *file, struct stat *st)
+{
+       char buf[100];
+
+       printf("  File: ā€˜%s’\n", file);
+       printf("  Size: %lu\tBlocks: %lu\tIO Block: %lu\n", (unsigned 
long)st->st_size,
+              (unsigned long)st->st_blocks, (unsigned long)st->st_blksize);
+       printf("Device: %xh/%ud\tInode: %lu\tLinks %lu\n", major(st->st_dev),
+              minor(st->st_dev), (unsigned long)st->st_ino, (unsigned 
long)st->st_nlink);
+       printf("Access: %04o\tUid: %u\tGid: %u\n", st->st_mode & 0777, 
st->st_uid, st->st_gid);
+       strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", 
localtime(&st->st_atime));
+       printf("Access: %s\n", buf);
+       strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", 
localtime(&st->st_mtime));
+       printf("Modify: %s\n", buf);
+       strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", 
localtime(&st->st_ctime));
+       printf("Change: %s\n", buf);
+}
-- 
1.8.2.3

Reply via email to