summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorray <ray@openbsd.org>2007-03-23 01:47:11 +0000
committerray <ray@openbsd.org>2007-03-23 01:47:11 +0000
commit5ae6585fed5562f798fedc89869f8bfdb41e12b3 (patch)
treea91e9ace08699a4bb31cb48b105049beb6eb945d
parentcannot remember what the vax -O0 workaround in 2002 was for. wish the (diff)
downloadwireguard-openbsd-5ae6585fed5562f798fedc89869f8bfdb41e12b3.tar.xz
wireguard-openbsd-5ae6585fed5562f798fedc89869f8bfdb41e12b3.zip
Import public domain rewrite of sendbug, written by Ray Lai. =)
Replaces GNU sendbug/sendpr, the wonderful shell script that had trouble dealing with signals, behaved differently depending on what file it read upon startup, and suffered from issues plaguing most large shell scripts. OK deraadt@.
-rw-r--r--usr.bin/sendbug/Makefile7
-rw-r--r--usr.bin/sendbug/atomicio.c62
-rw-r--r--usr.bin/sendbug/atomicio.h39
-rw-r--r--usr.bin/sendbug/sendbug.147
-rw-r--r--usr.bin/sendbug/sendbug.c315
5 files changed, 470 insertions, 0 deletions
diff --git a/usr.bin/sendbug/Makefile b/usr.bin/sendbug/Makefile
new file mode 100644
index 00000000000..36564c80347
--- /dev/null
+++ b/usr.bin/sendbug/Makefile
@@ -0,0 +1,7 @@
+# $OpenBSD: Makefile,v 1.1.1.1 2007/03/23 01:47:11 ray Exp $
+
+PROG=sendbug
+SRCS=atomicio.c sendbug.c
+COPTS+=-Wall -W
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/sendbug/atomicio.c b/usr.bin/sendbug/atomicio.c
new file mode 100644
index 00000000000..d5800109d6b
--- /dev/null
+++ b/usr.bin/sendbug/atomicio.c
@@ -0,0 +1,62 @@
+/* $OpenBSD: atomicio.c,v 1.1.1.1 2007/03/23 01:47:11 ray Exp $ */
+/*
+ * Copyright (c) 2006 Damien Miller. All rights reserved.
+ * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
+ * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include "atomicio.h"
+
+/*
+ * ensure all of data on socket comes through. f==read || f==vwrite
+ */
+size_t
+atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
+{
+ char *s = _s;
+ size_t pos = 0;
+ ssize_t res;
+
+ while (n > pos) {
+ res = (f) (fd, s + pos, n - pos);
+ switch (res) {
+ case -1:
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ return 0;
+ case 0:
+ errno = EPIPE;
+ return pos;
+ default:
+ pos += (size_t)res;
+ }
+ }
+ return (pos);
+}
diff --git a/usr.bin/sendbug/atomicio.h b/usr.bin/sendbug/atomicio.h
new file mode 100644
index 00000000000..72595dba99f
--- /dev/null
+++ b/usr.bin/sendbug/atomicio.h
@@ -0,0 +1,39 @@
+/* $OpenBSD: atomicio.h,v 1.1.1.1 2007/03/23 01:47:11 ray Exp $ */
+
+/*
+ * Copyright (c) 2006 Damien Miller. All rights reserved.
+ * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ATOMICIO_H
+#define _ATOMICIO_H
+
+/*
+ * Ensure all of data on socket comes through. f==read || f==vwrite
+ */
+size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
+
+#define vwrite (ssize_t (*)(int, void *, size_t))write
+
+#endif /* _ATOMICIO_H */
diff --git a/usr.bin/sendbug/sendbug.1 b/usr.bin/sendbug/sendbug.1
new file mode 100644
index 00000000000..1bbafad0a1c
--- /dev/null
+++ b/usr.bin/sendbug/sendbug.1
@@ -0,0 +1,47 @@
+.\" $OpenBSD: sendbug.1,v 1.1.1.1 2007/03/23 01:47:11 ray Exp $
+.\"
+.\" Written by Raymond Lai <ray@cyth.net>.
+.\" Public domain.
+.\"
+.Dd March 22, 2007
+.Dt SENDBUG 1
+.Os
+.Sh NAME
+.Nm sendbug
+.Nd report a bug in
+.Ox
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+.Nm
+is used to send bug reports to
+.Ox .
+Some system information is filled out in a temporary file,
+which is then opened by an editor.
+See
+.Ev EDITOR
+below,
+for details of which editor, if any, is invoked.
+.Pp
+Once the bug report is filled out,
+it is e-mailed to the
+.Ox
+developers.
+.Sh ENVIRONMENT
+.Bl -tag -width Ds
+.It Ev EDITOR
+Specifies an editor to use.
+If
+.Ev EDITOR
+is not set,
+the default is
+.Xr vi 1 .
+.It Ev TMPDIR
+Specifies a directory for temporary files to be created.
+The default is
+.Pa /tmp .
+.El
+.Sh AUTHORS
+.Nm
+was written from scratch for the public domain by
+.An Ray Lai Aq ray@cyth.net .
diff --git a/usr.bin/sendbug/sendbug.c b/usr.bin/sendbug/sendbug.c
new file mode 100644
index 00000000000..aeac2dcd9bd
--- /dev/null
+++ b/usr.bin/sendbug/sendbug.c
@@ -0,0 +1,315 @@
+/* $OpenBSD: sendbug.c,v 1.1.1.1 2007/03/23 01:47:11 ray Exp $ */
+
+/*
+ * Written by Ray Lai <ray@cyth.net>.
+ * Public domain.
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "atomicio.h"
+
+int init(void);
+int prompt(void);
+int send_file(const char *, int dst);
+int sendmail(const char *);
+void template(FILE *);
+
+struct passwd *pw;
+const char *categories = "system user library documentation ports kernel "
+ "alpha amd64 arm i386 m68k m88k mips ppc sgi sparc sparc64 vax";
+char os[BUFSIZ], rel[BUFSIZ], mach[BUFSIZ];
+char *fullname;
+
+int
+main(int argc, char *argv[])
+{
+ struct stat sb;
+ FILE *fp;
+ const char *editor, *tmpdir;
+ char *tmppath = NULL;
+ time_t mtime;
+ int c, fd, ret = 1;
+
+ if ((tmpdir = getenv("TMPDIR")) == NULL || tmpdir[0] == '\0')
+ tmpdir = _PATH_TMP;
+ if (asprintf(&tmppath, "%s/p.XXXXXXXXXX", tmpdir) == -1) {
+ warn("asprintf");
+ goto quit;
+ }
+ if ((fd = mkstemp(tmppath)) == -1)
+ err(1, "mkstemp");
+ if ((fp = fdopen(fd, "w+")) == NULL) {
+ warn("fdopen");
+ goto cleanup;
+ }
+
+ if (init() == -1)
+ goto cleanup;
+
+ template(fp);
+
+ if (fflush(fp) == EOF || fstat(fd, &sb) == -1 || fclose(fp) == EOF) {
+ warn("error creating template");
+ goto cleanup;
+ }
+ mtime = sb.st_mtime;
+
+ edit:
+ if ((editor = getenv("EDITOR")) == NULL)
+ editor = "vi";
+ switch (fork()) {
+ case -1:
+ warn("fork");
+ goto cleanup;
+ case 0:
+ execlp(editor, editor, tmppath, NULL);
+ err(1, "execlp");
+ default:
+ wait(NULL);
+ break;
+ }
+
+ if (stat(tmppath, &sb) == -1) {
+ warn("stat");
+ goto cleanup;
+ }
+ if (mtime == sb.st_mtime) {
+ warnx("report unchanged, nothing sent");
+ goto cleanup;
+ }
+
+ prompt:
+ c = prompt();
+ switch (c) {
+ case 'a': case EOF:
+ warnx("unsent report in %s", tmppath);
+ goto quit;
+ case 'e':
+ goto edit;
+ case 's':
+ if (sendmail(tmppath) == -1)
+ goto quit;
+ break;
+ default:
+ goto prompt;
+ }
+
+ ret = 0;
+
+ cleanup:
+ if (tmppath && unlink(tmppath) == -1)
+ warn("unlink");
+
+ quit:
+ return (ret);
+}
+
+int
+prompt(void)
+{
+ int c, ret;
+
+ fpurge(stdin);
+ fprintf(stderr, "a)bort, e)dit, or s)end: ");
+ fflush(stderr);
+ ret = getchar();
+ if (ret == EOF || ret == '\n')
+ return (ret);
+ do {
+ c = getchar();
+ } while (c != EOF && c != '\n');
+ return (ret);
+}
+
+int
+sendmail(const char *tmppath)
+{
+ int filedes[2];
+
+ if (pipe(filedes) == -1) {
+ warn("pipe: unsent report in %s", tmppath);
+ return (-1);
+ }
+ switch (fork()) {
+ case -1:
+ warn("fork error: unsent report in %s",
+ tmppath);
+ return (-1);
+ case 0:
+ close(filedes[1]);
+ if (dup2(filedes[0], STDIN_FILENO) == -1) {
+ warn("dup2 error: unsent report in %s",
+ tmppath);
+ return (-1);
+ }
+ close(filedes[0]);
+ execl("/usr/sbin/sendmail", "sendmail",
+ "-oi", "-t", NULL);
+ warn("sendmail error: unsent report in %s",
+ tmppath);
+ return (-1);
+ default:
+ close(filedes[0]);
+ /* Pipe into sendmail. */
+ if (send_file(tmppath, filedes[1]) == -1) {
+ warn("send_file error: unsent report in %s",
+ tmppath);
+ return (-1);
+ }
+ close(filedes[1]);
+ wait(NULL);
+ break;
+ }
+ return (0);
+}
+
+int
+init(void)
+{
+ size_t len;
+ int sysname[2];
+
+ if ((pw = getpwuid(getuid())) == NULL) {
+ warn("getpwuid");
+ return (-1);
+ }
+
+ /* Get full name. */
+ len = strcspn(pw->pw_gecos, ",");
+ if ((fullname = malloc(len + 1)) == NULL) {
+ warn("malloc");
+ return (-1);
+ }
+ memcpy(fullname, pw->pw_gecos, len);
+ fullname[len] = '\0';
+
+ sysname[0] = CTL_KERN;
+ sysname[1] = KERN_OSTYPE;
+ len = sizeof(os) - 1;
+ if (sysctl(sysname, 2, &os, &len, NULL, 0) == -1) {
+ warn("sysctl");
+ return (-1);
+ }
+
+ sysname[0] = CTL_KERN;
+ sysname[1] = KERN_OSRELEASE;
+ len = sizeof(rel) - 1;
+ if (sysctl(sysname, 2, &rel, &len, NULL, 0) == -1) {
+ warn("sysctl");
+ return (-1);
+ }
+
+ sysname[0] = CTL_HW;
+ sysname[1] = HW_MACHINE;
+ len = sizeof(mach) - 1;
+ if (sysctl(sysname, 2, &mach, &len, NULL, 0) == -1) {
+ warn("sysctl");
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+send_file(const char *file, int dst)
+{
+ FILE *fp;
+ char *buf;
+ size_t len;
+ int blank = 0;
+
+ if ((fp = fopen(file, "r")) == NULL)
+ return (-1);
+ while ((buf = fgetln(fp, &len))) {
+ /* Skip lines starting with "SENDBUG". */
+ if (len >= sizeof("SENDBUG") - 1 &&
+ memcmp(buf, "SENDBUG", sizeof("SENDBUG") - 1) == 0)
+ continue;
+ if (len == 1 && buf[0] == '\n')
+ blank = 1;
+ /* Skip comments, but only if we encountered a blank line. */
+ while (len) {
+ char *sp, *ep = NULL;
+ size_t copylen;
+
+ if (blank && (sp = memchr(buf, '<', len)) != NULL)
+ ep = memchr(sp, '>', len - (sp - buf + 1));
+ /* Length of string before comment. */
+ copylen = ep ? sp - buf : len;
+ if (atomicio(vwrite, dst, buf, copylen) != copylen) {
+ int saved_errno = errno;
+
+ fclose(fp);
+ errno = saved_errno;
+ return (-1);
+ }
+ if (!ep)
+ break;
+ /* Skip comment. */
+ len -= ep - buf + 1;
+ buf = ep + 1;
+ }
+ }
+ fclose(fp);
+ return (0);
+}
+
+void
+template(FILE *fp)
+{
+ fprintf(fp, "SENDBUG: -*- sendbug -*-\n");
+ fprintf(fp, "SENDBUG: Lines starting with `SENDBUG' will be removed automatically, as\n");
+ fprintf(fp, "SENDBUG: will all comments (text enclosed in `<' and `>'). \n");
+ fprintf(fp, "SENDBUG:\n");
+ fprintf(fp, "SENDBUG: Choose from the following categories:\n");
+ fprintf(fp, "SENDBUG:\n");
+ fprintf(fp, "SENDBUG: %s\n", categories);
+ fprintf(fp, "SENDBUG:\n");
+ fprintf(fp, "SENDBUG:\n");
+ fprintf(fp, "To: %s\n", "gnats@openbsd.org");
+ fprintf(fp, "Subject: \n");
+ fprintf(fp, "From: %s\n", pw->pw_name);
+ fprintf(fp, "Cc: \n");
+ fprintf(fp, "Reply-To: %s\n", pw->pw_name);
+ fprintf(fp, "X-sendbug-version: 4.2\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "\n");
+ fprintf(fp, ">Submitter-Id:\tnet\n");
+ fprintf(fp, ">Originator:\t%s\n", fullname);
+ fprintf(fp, ">Organization:\n");
+ fprintf(fp, "net\n");
+ fprintf(fp, ">Synopsis:\t<synopsis of the problem (one line)>\n");
+ fprintf(fp, ">Severity:\t<[ non-critical | serious | critical ] (one line)>\n");
+ fprintf(fp, ">Priority:\t<[ low | medium | high ] (one line)>\n");
+ fprintf(fp, ">Category:\t<PR category (one line)>\n");
+ fprintf(fp, ">Class:\t\t<[ sw-bug | doc-bug | change-request | support ] (one line)>\n");
+ fprintf(fp, ">Release:\t<release number or tag (one line)>\n");
+ fprintf(fp, ">Environment:\n");
+ fprintf(fp, "\t<machine, os, target, libraries (multiple lines)>\n");
+ fprintf(fp, "\tSystem : %s %s\n", os, rel);
+ fprintf(fp, "\tArchitecture: %s.%s\n", os, mach);
+ fprintf(fp, "\tMachine : %s\n", mach);
+ fprintf(fp, ">Description:\n");
+ fprintf(fp, "\t<precise description of the problem (multiple lines)>\n");
+ fprintf(fp, ">How-To-Repeat:\n");
+ fprintf(fp, "\t<code/input/activities to reproduce the problem (multiple lines)>\n");
+ fprintf(fp, ">Fix:\n");
+ fprintf(fp, "\t<how to correct or work around the problem, if known (multiple lines)>\n");
+}