aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2013-10-13 02:35:19 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2013-10-13 02:35:19 +0000
commit3caf0790a80c2e10c82a3a07719cddb2065c65d1 (patch)
tree2c6f4d1ca5d1c643faea64e1f4c90105a1ab406a /usr.bin
parentaab5fee0721846740415f201b41c920033a49303 (diff)
parent006a42a9cb173cefe32d169c46748d6f00c41315 (diff)
downloadsrc-3caf0790a80c2e10c82a3a07719cddb2065c65d1.tar.gz
src-3caf0790a80c2e10c82a3a07719cddb2065c65d1.zip
Merge head@256284
Notes
Notes: svn path=/projects/bmake/; revision=256424
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/Makefile14
-rw-r--r--usr.bin/calendar/Makefile2
-rw-r--r--usr.bin/calendar/calcpp.c229
-rw-r--r--usr.bin/calendar/calendar.119
-rw-r--r--usr.bin/calendar/calendar.h7
-rw-r--r--usr.bin/calendar/calendars/calendar.dutch22
-rw-r--r--usr.bin/calendar/calendars/calendar.freebsd1
-rw-r--r--usr.bin/calendar/io.c86
-rw-r--r--usr.bin/calendar/pathnames.h1
-rw-r--r--usr.bin/clang/Makefile8
-rw-r--r--usr.bin/clang/lldb/Makefile135
-rw-r--r--usr.bin/dig/Makefile28
-rw-r--r--usr.bin/dig/Makefile.depend27
-rw-r--r--usr.bin/drill/Makefile19
-rw-r--r--usr.bin/host/Makefile28
-rw-r--r--usr.bin/iscsictl/Makefile19
-rw-r--r--usr.bin/iscsictl/iscsictl.8153
-rw-r--r--usr.bin/iscsictl/iscsictl.c742
-rw-r--r--usr.bin/iscsictl/iscsictl.h116
-rw-r--r--usr.bin/iscsictl/parse.y333
-rw-r--r--usr.bin/iscsictl/periphs.c186
-rw-r--r--usr.bin/iscsictl/token.l93
-rw-r--r--usr.bin/kdump/kdump.c50
-rw-r--r--usr.bin/kdump/mksubr66
-rw-r--r--usr.bin/nslookup/Makefile25
-rw-r--r--usr.bin/nslookup/Makefile.depend30
-rw-r--r--usr.bin/nsupdate/Makefile29
-rw-r--r--usr.bin/nsupdate/Makefile.depend30
-rw-r--r--usr.bin/patch/patch.c11
-rw-r--r--usr.bin/patch/util.c2
-rw-r--r--usr.bin/procstat/procstat.16
-rw-r--r--usr.bin/protect/Makefile6
-rw-r--r--usr.bin/protect/protect.189
-rw-r--r--usr.bin/protect/protect.c122
-rw-r--r--usr.bin/svn/lib/libapr/apr.h6
-rw-r--r--usr.bin/svn/lib/libapr/apr_private.h2
-rw-r--r--usr.bin/svn/svn_private_config.h2
-rw-r--r--usr.bin/truss/syscall.h2
-rw-r--r--usr.bin/truss/syscalls.c87
39 files changed, 2521 insertions, 312 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index 09fb97c66e2f..92958ae55f12 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -68,6 +68,7 @@ SUBDIR= alias \
id \
ipcrm \
ipcs \
+ iscsictl \
join \
jot \
${_kdump} \
@@ -131,6 +132,7 @@ SUBDIR= alias \
printenv \
printf \
procstat \
+ protect \
rctl \
renice \
rev \
@@ -216,13 +218,6 @@ _atf= atf
SUBDIR+= atm
.endif
-.if ${MK_BIND_UTILS} != "no"
-SUBDIR+= dig
-SUBDIR+= host
-SUBDIR+= nslookup
-SUBDIR+= nsupdate
-.endif
-
.if ${MK_BLUETOOTH} != "no"
SUBDIR+= bluetooth
.endif
@@ -263,6 +258,7 @@ SUBDIR+= compile_et
.endif
.if ${MK_LDNS_UTILS} != "no"
+SUBDIR+= drill
SUBDIR+= host
.endif
@@ -370,13 +366,9 @@ SUBDIR+= users
SUBDIR+= who
.endif
-.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64" || \
- ${MACHINE_ARCH} == "sparc64" || ${MACHINE_ARCH} == "i386" || \
- (${MACHINE_ARCH} == "armv6" && ${COMPILER_TYPE} == "clang")
.if ${MK_SVN} == "yes" || ${MK_SVNLITE} == "yes"
SUBDIR+= svn
.endif
-.endif
.include <bsd.arch.inc.mk>
diff --git a/usr.bin/calendar/Makefile b/usr.bin/calendar/Makefile
index c7bd5445df08..66403fe2b44c 100644
--- a/usr.bin/calendar/Makefile
+++ b/usr.bin/calendar/Makefile
@@ -3,7 +3,7 @@
PROG= calendar
SRCS= calendar.c locale.c events.c dates.c parsedata.c io.c day.c \
- ostern.c paskha.c pom.c sunpos.c
+ ostern.c paskha.c pom.c sunpos.c calcpp.c
DPADD= ${LIBM}
LDADD= -lm
INTER= de_AT.ISO_8859-15 de_DE.ISO8859-1 fr_FR.ISO8859-1 \
diff --git a/usr.bin/calendar/calcpp.c b/usr.bin/calendar/calcpp.c
new file mode 100644
index 000000000000..6e3b3398b0a6
--- /dev/null
+++ b/usr.bin/calendar/calcpp.c
@@ -0,0 +1,229 @@
+/*-
+ * Copyright (c) 2013 Diane Bruce
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * $FreeBSD$
+ */
+
+/* calendar fake cpp does a very limited cpp version */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <langinfo.h>
+#include <locale.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pathnames.h"
+#include "calendar.h"
+
+#define MAXFPSTACK 50
+static FILE *fpstack[MAXFPSTACK];
+static int curfpi;
+static void pushfp(FILE *fp);
+static FILE *popfp(void);
+static int tokenscpp(char *buf, char *string);
+
+#define T_INVALID -1
+#define T_INCLUDE 0
+#define T_DEFINE 1
+#define T_IFNDEF 2
+#define T_ENDIF 3
+
+#define MAXSYMS 100
+static char *symtable[MAXSYMS];
+static void addsym(const char *name);
+static int findsym(const char *name);
+
+FILE *
+fincludegets(char *buf, int size, FILE *fp)
+{
+ char name[MAXPATHLEN];
+ FILE *nfp=NULL;
+ char *p;
+ int ch;
+
+ if (fp == NULL)
+ return(NULL);
+
+ if (fgets(buf, size, fp) == NULL) {
+ *buf = '\0';
+ fclose(fp);
+ fp = popfp();
+ return (fp);
+ }
+ if ((p = strchr(buf, '\n')) != NULL)
+ *p = '\0';
+ else {
+ /* Flush this line */
+ while ((ch = fgetc(fp)) != '\n' && ch != EOF);
+ if (ch == EOF) {
+ *buf = '\0';
+ fclose(fp);
+ fp = popfp();
+ return(fp);
+ }
+ }
+ switch (tokenscpp(buf, name)) {
+ case T_INCLUDE:
+ *buf = '\0';
+ if ((nfp = fopen(name, "r")) != NULL) {
+ pushfp(fp);
+ fp = nfp;
+ }
+ break;
+ case T_DEFINE:
+ addsym(name);
+ break;
+ case T_IFNDEF:
+ if (findsym(name)) {
+ fclose(fp);
+ fp = popfp();
+ *buf = '\0';
+ }
+ break;
+ case T_ENDIF:
+ *buf = '\0';
+ break;
+ default:
+ break;
+ }
+ return (fp);
+}
+
+static int
+tokenscpp(char *buf, char *string)
+{
+ char *p;
+ char *s;
+
+ if ((p = strstr(buf, "#define")) != NULL) {
+ p += 8;
+ while (isspace((unsigned char)*p))
+ p++;
+ s = p;
+ while(!isspace((unsigned char)*p))
+ p++;
+ strncpy(string, s, MAXPATHLEN);
+ return(T_DEFINE);
+ } else if ((p = strstr(buf, "#ifndef")) != NULL) {
+ p += 8;
+ while (isspace((unsigned char)*p))
+ p++;
+ s = p;
+ while(!isspace((unsigned char)*p))
+ p++;
+ *p = '\0';
+ strncpy(string, s, MAXPATHLEN);
+ return(T_IFNDEF);
+ } else if ((p = strstr(buf, "#endif")) != NULL) {
+ return(T_ENDIF);
+ } if ((p = strstr(buf, "#include")) != NULL) {
+ p += 8;
+ while (isspace((unsigned char)*p))
+ p++;
+ if (*p == '<') {
+ s = p+1;
+ if ((p = strchr(s, '>')) != NULL)
+ *p = '\0';
+ snprintf (string, MAXPATHLEN, "%s/%s",
+ _PATH_INCLUDE, s);
+ } else if (*p == '(') {
+ s = p+1;
+ if ((p = strchr(p, '>')) != NULL)
+ *p = '\0';
+ snprintf (string, MAXPATHLEN, "%s", s);
+ }
+ return(T_INCLUDE);
+ }
+ return(T_INVALID);
+}
+
+static void
+pushfp(FILE *fp)
+{
+ curfpi++;
+ if (curfpi == MAXFPSTACK)
+ errx(1, "Max #include reached");
+ fpstack[curfpi] = fp;
+}
+
+static
+FILE *popfp(void)
+{
+ FILE *tmp;
+
+ assert(curfpi >= 0);
+ tmp = fpstack[curfpi];
+ curfpi--;
+ return(tmp);
+}
+
+void
+initcpp(void)
+{
+ int i;
+
+ for (i=0; i < MAXSYMS; i++)
+ symtable[i] = NULL;
+ fpstack[0] = NULL;
+ curfpi = 0;
+}
+
+
+static void
+addsym(const char *name)
+{
+ int i;
+
+ if (!findsym(name))
+ for (i=0; i < MAXSYMS; i++) {
+ if (symtable[i] == NULL) {
+ symtable[i] = strdup(name);
+ if (symtable[i] == NULL)
+ errx(1, "malloc error in addsym");
+ return;
+ }
+ }
+ errx(1, "symbol table full\n");
+}
+
+static int
+findsym(const char *name)
+{
+ int i;
+
+ for (i=0; i < MAXSYMS; i++)
+ if (symtable[i] != NULL && strcmp(symtable[i],name) == 0)
+ return (1);
+ return (0);
+}
diff --git a/usr.bin/calendar/calendar.1 b/usr.bin/calendar/calendar.1
index 6531bba51930..374fbefd0cf1 100644
--- a/usr.bin/calendar/calendar.1
+++ b/usr.bin/calendar/calendar.1
@@ -177,12 +177,15 @@ if the line does not contain a <tab> character, it is not displayed.
If the first character in the line is a <tab> character, it is treated as
a continuation of the previous line.
.Pp
-The ``calendar'' file is preprocessed by
-.Xr cpp 1 ,
-allowing the inclusion of shared files such as lists of company holidays or
-meetings.
-If the shared file is not referenced by a full pathname,
+The
+.Nm
+file is preprocessed by a limited subset of
.Xr cpp 1
+internally, allowing the inclusion of shared files such as
+lists of company holidays or meetings.
+This limited subset consists of \fB#include #ifndef #endif\fR and \fB#define\fR.
+If the shared file is not referenced by a full pathname,
+.Xr calendar 1
searches in the current (or home) directory first, and then in the
directory
.Pa /usr/share/calendar .
@@ -321,7 +324,11 @@ double-check the start and end time of solar and lunar events.
.Sh BUGS
The
.Nm
-utility does not handle Jewish holidays.
+internal cpp does not correctly do #ifndef and will discard the rest
+of the file if a #ifndef is triggered.
+It also has a maximum of 50 include file and/or 100 #defines
+and only recognises #include, #define and
+#ifndef.
.Pp
There is no possibility to properly specify the local position
needed for solar and lunar calculations.
diff --git a/usr.bin/calendar/calendar.h b/usr.bin/calendar/calendar.h
index 87e705c9e981..0138fd2f1c86 100644
--- a/usr.bin/calendar/calendar.h
+++ b/usr.bin/calendar/calendar.h
@@ -165,7 +165,12 @@ void dodebug(char *type);
/* io.c */
void cal(void);
void closecal(FILE *);
-FILE *opencal(void);
+FILE *opencalin(void);
+FILE *opencalout(void);
+
+/* calcpp.c */
+void initcpp(void);
+FILE *fincludegets(char *buf, int size, FILE *fp);
/* ostern.c / paskha.c */
int paskha(int);
diff --git a/usr.bin/calendar/calendars/calendar.dutch b/usr.bin/calendar/calendars/calendar.dutch
index edabe106e616..13a456b2ec48 100644
--- a/usr.bin/calendar/calendars/calendar.dutch
+++ b/usr.bin/calendar/calendars/calendar.dutch
@@ -22,11 +22,11 @@ nov/01 Allerheiligen
nov/02 Allerzielen
nov/11 Sint Maarten
nov/11 Elfde-van-de-elfde
-dec/05 Sinterklaas avond
+dec/05 Sinterklaasavond
dec/15 Koninkrijksdag
dec/24 Kerstavond
-dec/25 Eerste kerstdag
-dec/26 Tweede kerstdag
+dec/25 Eerste Kerstdag
+dec/26 Tweede Kerstdag
dec/28 Feest der Onnozele Kinderen
dec/31 Oudjaar
@@ -40,10 +40,10 @@ Pasen-47 Carnaval (Vastenavond)
Pasen-46 Aswoensdag
Pasen-7 Palmzondag
Pasen-3 Witte Donderdag
-Pasen-2 Goede vrijdag
-Pasen-1 Stille zaterdag
-Pasen Eerste paasdag
-Pasen+1 Tweede paasdag
+Pasen-2 Goede Vrijdag
+Pasen-1 Stille Zaterdag
+Pasen Eerste Paasdag
+Pasen+1 Tweede Paasdag
Pasen+39 Hemelvaartsdag
Pasen+49 Eerste Pinksterdag
Pasen+50 Tweede Pinksterdag
@@ -65,15 +65,15 @@ feb/17 Prins Willem III (1817 - 1890)
feb/18 Prinses Christina (1947)
apr/10 Prinses Ariane (2007)
apr/19 Prins Hendrik (1876 - 1934)
-apr/27 Koning Willem Alexander (1967)
+apr/27 Koning Willem-Alexander (1967)
apr/30 Prinses Juliana (1909 - 2004)
apr/30 Mr. Pieter van Vollenhoven (1939)
-mei/17 Prinses Maxima (1971)
+mei/17 Koningin Maxima (1971)
jun/26 Prinses Alexia (2005)
jun/29 Prins Bernhard (1911 - 2004)
aug/05 Prinses Irene (1939)
aug/31 Prinses Wilhelmina (1880 - 1962)
sep/06 Prins Claus (1925 - 2002)
-sep/25 Prins Johan Friso (1968)
+sep/25 Prins Johan Friso (1968 - 2013)
okt/11 Prins Constantijn (1969)
-dec/07 Prinses Catharina-Amalia (2003)
+dec/07 Kroonprinses Catharina-Amalia (2003)
diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd
index 6cf03461a410..4222d7b9a94f 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -329,6 +329,7 @@
11/09 Coleman Kane <cokane@FreeBSD.org> born in Cincinnati, Ohio, United States, 1980
11/09 Antoine Brodin <antoine@FreeBSD.org> born in Bagnolet, France, 1981
11/10 Gregory Neil Shapiro <gshapiro@FreeBSD.org> born in Providence, Rhode Island, United States, 1970
+11/11 Danilo E. Gondolfo <danilo@FreeBSD.org> born in Lobato, Parana, Brazil, 1987
11/13 John Baldwin <jhb@FreeBSD.org> born in Stuart, Virginia, United States, 1977
11/14 Jeremie Le Hen <jlh@FreeBSD.org> born in Nancy, France, 1980
11/15 Lars Engels <lme@FreeBSD.org> born in Hilden, Nordrhein-Westfalen, Germany, 1980
diff --git a/usr.bin/calendar/io.c b/usr.bin/calendar/io.c
index 2ea086503614..0f34882a237a 100644
--- a/usr.bin/calendar/io.c
+++ b/usr.bin/calendar/io.c
@@ -81,8 +81,9 @@ void
cal(void)
{
char *pp, p;
- FILE *fp;
- int ch, l;
+ FILE *fpin;
+ FILE *fpout;
+ int l;
int count, i;
int month[MAXCOUNT];
int day[MAXCOUNT];
@@ -95,6 +96,7 @@ cal(void)
struct tm tm;
char dbuf[80];
+ initcpp();
extradata = (char **)calloc(MAXCOUNT, sizeof(char *));
for (i = 0; i < MAXCOUNT; i++) {
extradata[i] = (char *)calloc(1, 20);
@@ -107,16 +109,18 @@ cal(void)
tm.tm_wday = 0;
count = 0;
- if ((fp = opencal()) == NULL) {
+ if ((fpin = opencalin()) == NULL) {
free(extradata);
return;
}
- while (fgets(buf, sizeof(buf), stdin) != NULL) {
- if ((pp = strchr(buf, '\n')) != NULL)
- *pp = '\0';
- else
- /* Flush this line */
- while ((ch = getchar()) != '\n' && ch != EOF);
+ if ((fpout = opencalout()) == NULL) {
+ fclose(fpin);
+ free(extradata);
+ return;
+ }
+ while ((fpin = fincludegets(buf, sizeof(buf), fpin)) != NULL) {
+ if (*buf == '\0')
+ continue;
for (l = strlen(buf);
l > 0 && isspace((unsigned char)buf[l - 1]);
l--)
@@ -204,27 +208,27 @@ cal(void)
}
}
- event_print_all(fp);
- closecal(fp);
+ event_print_all(fpout);
+ closecal(fpout);
free(extradata);
}
FILE *
-opencal(void)
+opencalin(void)
{
- uid_t uid;
size_t i;
- int fd, found, pdes[2];
+ int found;
struct stat sbuf;
+ FILE *fpin;
- /* open up calendar file as stdin */
- if (!freopen(calendarFile, "r", stdin)) {
+ /* open up calendar file */
+ if ((fpin = fopen(calendarFile, "r")) == NULL) {
if (doall) {
if (chdir(calendarHomes[0]) != 0)
return (NULL);
if (stat(calendarNoMail, &sbuf) == 0)
return (NULL);
- if (!freopen(calendarFile, "r", stdin))
+ if ((fpin = fopen(calendarFile, "r")) == NULL)
return (NULL);
} else {
char *home = getenv("HOME");
@@ -235,7 +239,7 @@ opencal(void)
for (found = i = 0; i < sizeof(calendarHomes) /
sizeof(calendarHomes[0]); i++)
if (chdir(calendarHomes[i]) == 0 &&
- freopen(calendarFile, "r", stdin)) {
+ (fpin = fopen(calendarFile, "r")) != NULL) {
found = 1;
break;
}
@@ -245,50 +249,20 @@ opencal(void)
calendarFile, strerror(errno), errno);
}
}
- if (pipe(pdes) < 0)
- return (NULL);
- switch (fork()) {
- case -1: /* error */
- (void)close(pdes[0]);
- (void)close(pdes[1]);
- return (NULL);
- case 0:
- /* child -- stdin already setup, set stdout to pipe input */
- if (pdes[1] != STDOUT_FILENO) {
- (void)dup2(pdes[1], STDOUT_FILENO);
- (void)close(pdes[1]);
- }
- (void)close(pdes[0]);
- uid = geteuid();
- if (setuid(getuid()) < 0) {
- warnx("first setuid failed");
- _exit(1);
- };
- if (setgid(getegid()) < 0) {
- warnx("setgid failed");
- _exit(1);
- }
- if (setuid(uid) < 0) {
- warnx("setuid failed");
- _exit(1);
- }
- execl(_PATH_CPP, "cpp", "-P",
- "-traditional-cpp", "-nostdinc", /* GCC specific opts */
- "-I.", "-I", _PATH_INCLUDE, (char *)NULL);
- warn(_PATH_CPP);
- _exit(1);
- }
- /* parent -- set stdin to pipe output */
- (void)dup2(pdes[0], STDIN_FILENO);
- (void)close(pdes[0]);
- (void)close(pdes[1]);
+ return (fpin);
+}
+
+FILE *
+opencalout(void)
+{
+ int fd;
/* not reading all calendar files, just set output to stdout */
if (!doall)
return (stdout);
/* set output to a temporary file, so if no output don't send mail */
- (void)snprintf(path, sizeof(path), "%s/_calXXXXXX", _PATH_TMP);
+ snprintf(path, sizeof(path), "%s/_calXXXXXX", _PATH_TMP);
if ((fd = mkstemp(path)) < 0)
return (NULL);
return (fdopen(fd, "w+"));
diff --git a/usr.bin/calendar/pathnames.h b/usr.bin/calendar/pathnames.h
index a46913c38d27..e5507a110fcc 100644
--- a/usr.bin/calendar/pathnames.h
+++ b/usr.bin/calendar/pathnames.h
@@ -32,5 +32,4 @@
#include <paths.h>
-#define _PATH_CPP "/usr/bin/gcpp"
#define _PATH_INCLUDE "/usr/share/calendar"
diff --git a/usr.bin/clang/Makefile b/usr.bin/clang/Makefile
index db5fae747b8c..a61a418bd4df 100644
--- a/usr.bin/clang/Makefile
+++ b/usr.bin/clang/Makefile
@@ -4,7 +4,8 @@
SUBDIR= clang clang-tblgen tblgen
-.if ${MK_CLANG_EXTRAS} != "no" && !defined(TOOLS_PREFIX)
+.if !defined(TOOLS_PREFIX)
+.if ${MK_CLANG_EXTRAS} != "no"
SUBDIR+=bugpoint \
llc \
lli \
@@ -25,4 +26,9 @@ SUBDIR+=bugpoint \
opt
.endif
+.if ${MK_LLDB} != "no"
+SUBDIR+=lldb
+.endif
+.endif # TOOLS_PREFIX
+
.include <bsd.subdir.mk>
diff --git a/usr.bin/clang/lldb/Makefile b/usr.bin/clang/lldb/Makefile
new file mode 100644
index 000000000000..6869b8da9f88
--- /dev/null
+++ b/usr.bin/clang/lldb/Makefile
@@ -0,0 +1,135 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+PROG_CXX=lldb
+
+LLDB_SRCS=${.CURDIR}/../../../contrib/llvm/tools/lldb
+
+CFLAGS+= -I${LLDB_SRCS}/include
+CXXFLAGS+= -std=c++11
+
+SRCDIR= tools/lldb/tools/driver
+SRCS= Driver.cpp \
+ IOChannel.cpp
+
+lldb.1:
+ ln -fs ${LLDB_SRCS}/docs/lldb.1 ${.TARGET}
+
+DPADD= ${LIBEDIT} ${LIBCURSES} ${LIBEXECINFO}
+LDADD= -ledit -lcurses -lexecinfo
+
+LLDB_LIBS=\
+ lldb \
+ \
+ lldbAPI \
+ lldbBreakpoint \
+ lldbCommands \
+ lldbCore \
+ lldbDataFormatters \
+ lldbExpression \
+ lldbHostFreeBSD \
+ lldbHostCommon \
+ lldbInterpreter \
+ lldbSymbol \
+ lldbTarget \
+ lldbUtility \
+ \
+ lldbPluginABISysV_x86_64 \
+ lldbPluginCXXItaniumABI \
+ lldbPluginDisassemblerLLVM \
+ lldbPluginInstructionARM \
+ lldbPluginSymbolFileDWARF \
+ lldbPluginSymbolFileSymtab \
+ lldbPluginDynamicLoaderStatic \
+ lldbPluginDynamicLoaderPosixDYLD \
+ lldbPluginObjectContainerBSDArchive \
+ lldbPluginObjectFileELF \
+ lldbPluginSymbolVendorELF \
+ lldbPluginPlatformFreeBSD \
+ lldbPluginPlatformGDB \
+ lldbPluginProcessElfCore \
+ lldbPluginProcessFreeBSD \
+ lldbPluginProcessGDBRemote \
+ lldbPluginProcessUtility \
+ lldbPluginProcessPOSIX \
+ lldbPluginUnwindAssemblyInstEmulation \
+ lldbPluginUnwindAssemblyX86
+
+LDADD+= -Wl,--start-group
+.for lib in ${LLDB_LIBS}
+DPADD+= ${.OBJDIR}/../../../lib/clang/lib${lib}/lib${lib}.a
+LDADD+= ${.OBJDIR}/../../../lib/clang/lib${lib}/lib${lib}.a
+.endfor
+LDADD+= -Wl,--end-group
+
+# Clang and LLVM libraries
+LIBDEPS=\
+ clangfrontend \
+ clangdriver \
+ clangserialization \
+ clangcodegen \
+ clangparse \
+ clangsema \
+ clanganalysis \
+ clangedit \
+ clangast \
+ clangbasic \
+ clanglex \
+ \
+ llvmarmasmparser \
+ llvmarmcodegen \
+ llvminstrumentation \
+ llvmirreader \
+ llvmlinker \
+ llvmmipsasmparser \
+ llvmmipscodegen \
+ llvmmipsdisassembler \
+ llvmobjcarcopts \
+ llvmpowerpccodegen \
+ llvmx86asmparser \
+ llvmx86codegen \
+ llvmx86disassembler \
+ llvmmcjit \
+ llvmmcdisassembler \
+ llvmarmdisassembler \
+ llvmselectiondag \
+ llvmipo \
+ llvmbitwriter \
+ llvmbitreader \
+ llvmasmparser \
+ llvminterpreter \
+ llvmjit \
+ llvmarmdesc \
+ llvmasmprinter \
+ llvmmipsdesc \
+ llvmmipsinstprinter \
+ llvmpowerpcdesc \
+ llvmpowerpcinstprinter \
+ llvmruntimedyld \
+ llvmvectorize \
+ llvmx86desc \
+ llvmx86instprinter \
+ llvmexecutionengine \
+ llvmcodegen \
+ llvmscalaropts \
+ llvmarminfo \
+ llvmarminstprinter \
+ llvmmcparser \
+ llvmmipsinfo \
+ llvmpowerpcinfo \
+ llvmx86info \
+ llvmx86utils \
+ llvmobject \
+ llvminstcombine \
+ llvmtransformutils \
+ llvmipa \
+ llvmanalysis \
+ llvmtarget \
+ llvmcore \
+ llvmmc \
+ llvmsupport
+
+.include "../clang.prog.mk"
+
+LDADD+= -lpthread
diff --git a/usr.bin/dig/Makefile b/usr.bin/dig/Makefile
deleted file mode 100644
index b76a0cacc2b1..000000000000
--- a/usr.bin/dig/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-# $FreeBSD$
-
-BIND_DIR= ${.CURDIR}/../../contrib/bind9
-LIB_BIND_REL= ../../lib/bind
-LIB_BIND_DIR= ${.CURDIR}/${LIB_BIND_REL}
-SRCDIR= ${BIND_DIR}/bin/dig
-
-.include "${LIB_BIND_DIR}/config.mk"
-
-PROG= dig
-
-.PATH: ${SRCDIR}
-SRCS+= dig.c dighost.c
-
-CFLAGS+= -I${SRCDIR}/include
-CFLAGS+= -I${BIND_DIR}/lib/isc/${ISC_ATOMIC_ARCH}/include
-
-.if ${MK_BIND_IDN} == "yes"
-CFLAGS+= -DWITH_IDN -I/usr/local/include
-CFLAGS+= -L/usr/local/lib -lidnkit -R/usr/local/lib -liconv
-.endif
-
-WARNS?= 0
-
-DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
-LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/dig/Makefile.depend b/usr.bin/dig/Makefile.depend
deleted file mode 100644
index 3740d8204809..000000000000
--- a/usr.bin/dig/Makefile.depend
+++ /dev/null
@@ -1,27 +0,0 @@
-# Autogenerated - do NOT edit!
-
-DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
-
-DIRDEPS = \
- gnu/lib/libgcc \
- include \
- include/arpa \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/bind/bind9 \
- lib/bind/dns \
- lib/bind/isc \
- lib/bind/isccc \
- lib/bind/isccfg \
- lib/bind/lwres \
- lib/libc \
- lib/libcompiler_rt \
- lib/libthr \
- secure/lib/libcrypto \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.bin/drill/Makefile b/usr.bin/drill/Makefile
new file mode 100644
index 000000000000..a963bfc79d1e
--- /dev/null
+++ b/usr.bin/drill/Makefile
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+# Vendor sources and generated files
+LDNSDIR= ${.CURDIR}/../../contrib/ldns
+
+.PATH: ${LDNSDIR}/drill
+
+PROG= drill
+SRCS= drill.c drill_util.c error.c root.c work.c \
+ chasetrace.c dnssec.c securetrace.c
+CFLAGS+= -I${LDNSDIR}
+NO_WERROR= true
+MAN= drill.1
+
+DPADD+= ${LIBLDNS} ${LIBCRYPTO}
+LDADD+= -lldns -lcrypto
+USEPRIVATELIB= ldns
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/host/Makefile b/usr.bin/host/Makefile
index 25dfd2d1dff9..596245499bfe 100644
--- a/usr.bin/host/Makefile
+++ b/usr.bin/host/Makefile
@@ -1,9 +1,5 @@
# $FreeBSD$
-.include <bsd.own.mk>
-
-.if ${MK_LDNS_UTILS} != "no"
-
LDNSDIR= ${.CURDIR}/../../contrib/ldns
LDNSHOSTDIR= ${.CURDIR}/../../contrib/ldns-host
@@ -22,28 +18,4 @@ DPADD+= ${LIBLDNS} ${LIBCRYPTO}
LDADD+= -lldns -lcrypto
USEPRIVATELIB= ldns
-.else
-
-BIND_DIR= ${.CURDIR}/../../contrib/bind9
-LIB_BIND_REL= ../../lib/bind
-LIB_BIND_DIR= ${.CURDIR}/${LIB_BIND_REL}
-SRCDIR= ${BIND_DIR}/bin/dig
-
-.include "${LIB_BIND_DIR}/config.mk"
-
-PROG= host
-
-.PATH: ${SRCDIR}
-SRCS+= dighost.c host.c
-
-CFLAGS+= -I${SRCDIR}/include
-CFLAGS+= -I${BIND_DIR}/lib/isc/${ISC_ATOMIC_ARCH}/include
-
-WARNS?= 0
-
-DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD}
-LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD}
-
-.endif
-
.include <bsd.prog.mk>
diff --git a/usr.bin/iscsictl/Makefile b/usr.bin/iscsictl/Makefile
new file mode 100644
index 000000000000..9331ca57563c
--- /dev/null
+++ b/usr.bin/iscsictl/Makefile
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+PROG= iscsictl
+SRCS= iscsictl.c periphs.c parse.y token.l y.tab.h
+CFLAGS+= -I${.CURDIR}
+CFLAGS+= -I${.CURDIR}/../../sys/dev/iscsi
+MAN= iscsictl.8
+
+DPADD= ${LIBCAM} ${LIBUTIL}
+LDADD= -lcam -lfl -lutil
+
+YFLAGS+= -v
+LFLAGS+= -i
+CLEANFILES= y.tab.c y.tab.h y.output
+
+WARNS= 6
+NO_WMISSING_VARIABLE_DECLARATIONS=
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/iscsictl/iscsictl.8 b/usr.bin/iscsictl/iscsictl.8
new file mode 100644
index 000000000000..03525df1238a
--- /dev/null
+++ b/usr.bin/iscsictl/iscsictl.8
@@ -0,0 +1,153 @@
+.\" Copyright (c) 2012 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This software was developed by Edward Tomasz Napierala under sponsorship
+.\" from the FreeBSD Foundation.
+.\"
+.\" 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 AUTHORS AND CONTRIBUTORS ``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 AUTHORS OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 20, 2012
+.Dt ISCSICTL 8
+.Os
+.Sh NAME
+.Nm iscsictl
+.Nd iSCSI initiator management utility
+.Sh SYNOPSIS
+.Nm
+.Fl A
+.Fl h Ar host Fl t Ar target Op Fl u Ar user Fl s Ar secret
+.Nm
+.Fl A
+.Fl d Ar discovery-host Op Fl u Ar user Fl s Ar secret
+.Nm
+.Fl A
+.Fl a Op Fl c Ar path
+.Nm
+.Fl A
+.Fl n Ar nickname Op Fl c Ar path
+.Nm
+.Fl R
+.Op Fl h Ar host
+.Op Fl t Ar target
+.Nm
+.Fl R
+.Fl a
+.Nm
+.Fl R
+.Fl n Ar nickname Op Fl c Ar path
+.Nm
+.Fl L
+.Op Fl v
+.Sh DESCRIPTION
+The
+.Nm
+utility is used to configure the iSCSI initiator.
+.Pp
+The following options are available:
+.Bl -tag -width ".Fl A"
+.It Fl A
+Add session.
+.It Fl R
+Remove session.
+.It Fl L
+List sessions.
+.It Fl a
+When adding, add all sessions defined in the configuration file.
+When removing, remove all currently established sessions.
+.It Fl c
+Path to the configuration file.
+The default is
+.Pa /etc/iscsi.conf .
+.It Fl d
+Target host name or address used for SendTargets discovery.
+When used, it will add a temporary discovery session.
+After discovery is done, sessions will be added for each discovered target,
+and the temporary discovery sesion will be removed.
+.It Fl h
+Target host name or address for statically defined targets.
+.It Fl n
+The "nickname" of session defined in the configuration file.
+.It Fl t
+Target name.
+.It Fl v
+Verbose mode.
+.El
+.Pp
+Since connecting to the target is performed in background, non-zero
+exit status does not mean that the session was successfully established.
+Use
+.Nm Fl L
+to check the connection status.
+The initiator notifies
+.Xr devd 8
+when session gets connected or disconnected.
+.Pp
+Note that in order to the iSCSI initiator to be able to connect to a target,
+the
+.Xr iscsid 8
+daemon must be running.
+.Pp
+Also note that
+.Fx
+currently supports two different initiators: the old one,
+.Xr iscsi_initiator 4 ,
+with its control utility
+.Xr iscontrol 8 ,
+and the new one,
+.Xr iscsi 4 ,
+with
+.Nm
+and
+.Xr iscsid 8 .
+The only thing the two have in common is the configuration file,
+.Xr iscsi.conf 5 .
+.Sh FILES
+.Bl -tag -width ".Pa /etc/iscsi.conf" -compact
+.It Pa /etc/iscsi.conf
+iSCSI initiator configuration file.
+.El
+.Sh EXIT STATUS
+The
+.Nm
+utility exits 0 on success, and >0 if an error occurs.
+.Sh EXAMPLES
+Attach to target qn.2012-06.com.example:target0, served by 192.168.1.1:
+.Dl Nm Fl A Fl t Ar qn.2012-06.com.example:target0 Fl h Ar 192.168.1.1
+.Pp
+Disconnect all iSCSI sessions:
+.Dl Nm Fl Ra
+.Sh SEE ALSO
+.Xr iscsi.conf 5 ,
+.Xr iscsid 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Fx 10.0 .
+.Sh AUTHORS
+The
+.Nm
+was developed by
+.An Edward Tomasz Napierala Aq trasz@FreeBSD.org
+under sponsorship from the FreeBSD Foundation.
diff --git a/usr.bin/iscsictl/iscsictl.c b/usr.bin/iscsictl/iscsictl.c
new file mode 100644
index 000000000000..1088d69f03e7
--- /dev/null
+++ b/usr.bin/iscsictl/iscsictl.c
@@ -0,0 +1,742 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/linker.h>
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <iscsi_ioctl.h>
+#include "iscsictl.h"
+
+struct conf *
+conf_new(void)
+{
+ struct conf *conf;
+
+ conf = calloc(1, sizeof(*conf));
+ if (conf == NULL)
+ err(1, "calloc");
+
+ TAILQ_INIT(&conf->conf_targets);
+
+ return (conf);
+}
+
+struct target *
+target_find(struct conf *conf, const char *nickname)
+{
+ struct target *targ;
+
+ TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
+ if (targ->t_nickname != NULL &&
+ strcasecmp(targ->t_nickname, nickname) == 0)
+ return (targ);
+ }
+
+ return (NULL);
+}
+
+struct target *
+target_new(struct conf *conf)
+{
+ struct target *targ;
+
+ targ = calloc(1, sizeof(*targ));
+ if (targ == NULL)
+ err(1, "calloc");
+ targ->t_conf = conf;
+ TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next);
+
+ return (targ);
+}
+
+void
+target_delete(struct target *targ)
+{
+
+ TAILQ_REMOVE(&targ->t_conf->conf_targets, targ, t_next);
+ free(targ);
+}
+
+
+static char *
+default_initiator_name(void)
+{
+ char *name;
+ size_t namelen;
+ int error;
+
+ namelen = _POSIX_HOST_NAME_MAX + strlen(DEFAULT_IQN);
+
+ name = calloc(1, namelen + 1);
+ if (name == NULL)
+ err(1, "calloc");
+ strcpy(name, DEFAULT_IQN);
+ error = gethostname(name + strlen(DEFAULT_IQN),
+ namelen - strlen(DEFAULT_IQN));
+ if (error != 0)
+ err(1, "gethostname");
+
+ return (name);
+}
+
+static bool
+valid_hex(const char ch)
+{
+ switch (ch) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ return (true);
+ default:
+ return (false);
+ }
+}
+
+bool
+valid_iscsi_name(const char *name)
+{
+ int i;
+
+ if (strlen(name) >= MAX_NAME_LEN) {
+ warnx("overlong name for \"%s\"; max length allowed "
+ "by iSCSI specification is %d characters",
+ name, MAX_NAME_LEN);
+ return (false);
+ }
+
+ /*
+ * In the cases below, we don't return an error, just in case the admin
+ * was right, and we're wrong.
+ */
+ if (strncasecmp(name, "iqn.", strlen("iqn.")) == 0) {
+ for (i = strlen("iqn."); name[i] != '\0'; i++) {
+ /*
+ * XXX: We should verify UTF-8 normalisation, as defined
+ * by 3.2.6.2: iSCSI Name Encoding.
+ */
+ if (isalnum(name[i]))
+ continue;
+ if (name[i] == '-' || name[i] == '.' || name[i] == ':')
+ continue;
+ warnx("invalid character \"%c\" in iSCSI name "
+ "\"%s\"; allowed characters are letters, digits, "
+ "'-', '.', and ':'", name[i], name);
+ break;
+ }
+ /*
+ * XXX: Check more stuff: valid date and a valid reversed domain.
+ */
+ } else if (strncasecmp(name, "eui.", strlen("eui.")) == 0) {
+ if (strlen(name) != strlen("eui.") + 16)
+ warnx("invalid iSCSI name \"%s\"; the \"eui.\" "
+ "should be followed by exactly 16 hexadecimal "
+ "digits", name);
+ for (i = strlen("eui."); name[i] != '\0'; i++) {
+ if (!valid_hex(name[i])) {
+ warnx("invalid character \"%c\" in iSCSI "
+ "name \"%s\"; allowed characters are 1-9 "
+ "and A-F", name[i], name);
+ break;
+ }
+ }
+ } else if (strncasecmp(name, "naa.", strlen("naa.")) == 0) {
+ if (strlen(name) > strlen("naa.") + 32)
+ warnx("invalid iSCSI name \"%s\"; the \"naa.\" "
+ "should be followed by at most 32 hexadecimal "
+ "digits", name);
+ for (i = strlen("naa."); name[i] != '\0'; i++) {
+ if (!valid_hex(name[i])) {
+ warnx("invalid character \"%c\" in ISCSI "
+ "name \"%s\"; allowed characters are 1-9 "
+ "and A-F", name[i], name);
+ break;
+ }
+ }
+ } else {
+ warnx("invalid iSCSI name \"%s\"; should start with "
+ "either \".iqn\", \"eui.\", or \"naa.\"",
+ name);
+ }
+ return (true);
+}
+
+void
+conf_verify(struct conf *conf)
+{
+ struct target *targ;
+
+ TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
+ assert(targ->t_nickname != NULL);
+ if (targ->t_session_type == SESSION_TYPE_UNSPECIFIED)
+ targ->t_session_type = SESSION_TYPE_NORMAL;
+ if (targ->t_session_type == SESSION_TYPE_NORMAL &&
+ targ->t_name == NULL)
+ errx(1, "missing TargetName for target \"%s\"",
+ targ->t_nickname);
+ if (targ->t_session_type == SESSION_TYPE_DISCOVERY &&
+ targ->t_name != NULL)
+ errx(1, "cannot specify TargetName for discovery "
+ "sessions for target \"%s\"", targ->t_nickname);
+ if (targ->t_name != NULL) {
+ if (valid_iscsi_name(targ->t_name) == false)
+ errx(1, "invalid target name \"%s\"",
+ targ->t_name);
+ }
+ if (targ->t_protocol == PROTOCOL_UNSPECIFIED)
+ targ->t_protocol = PROTOCOL_ISCSI;
+#ifndef ICL_KERNEL_PROXY
+ if (targ->t_protocol == PROTOCOL_ISER)
+ errx(1, "iSER support requires ICL_KERNEL_PROXY; "
+ "see iscsi(4) for details");
+#endif
+ if (targ->t_address == NULL)
+ errx(1, "missing TargetAddress for target \"%s\"",
+ targ->t_nickname);
+ if (targ->t_initiator_name == NULL)
+ targ->t_initiator_name = default_initiator_name();
+ if (valid_iscsi_name(targ->t_initiator_name) == false)
+ errx(1, "invalid initiator name \"%s\"",
+ targ->t_initiator_name);
+ if (targ->t_header_digest == DIGEST_UNSPECIFIED)
+ targ->t_header_digest = DIGEST_NONE;
+ if (targ->t_data_digest == DIGEST_UNSPECIFIED)
+ targ->t_data_digest = DIGEST_NONE;
+ if (targ->t_auth_method == AUTH_METHOD_UNSPECIFIED) {
+ if (targ->t_user != NULL || targ->t_secret != NULL ||
+ targ->t_mutual_user != NULL ||
+ targ->t_mutual_secret != NULL)
+ targ->t_auth_method =
+ AUTH_METHOD_CHAP;
+ else
+ targ->t_auth_method =
+ AUTH_METHOD_NONE;
+ }
+ if (targ->t_auth_method == AUTH_METHOD_CHAP) {
+ if (targ->t_user == NULL) {
+ errx(1, "missing chapIName for target \"%s\"",
+ targ->t_nickname);
+ }
+ if (targ->t_secret == NULL)
+ errx(1, "missing chapSecret for target \"%s\"",
+ targ->t_nickname);
+ if (targ->t_mutual_user != NULL ||
+ targ->t_mutual_secret != NULL) {
+ if (targ->t_mutual_user == NULL)
+ errx(1, "missing tgtChapName for "
+ "target \"%s\"", targ->t_nickname);
+ if (targ->t_mutual_secret == NULL)
+ errx(1, "missing tgtChapSecret for "
+ "target \"%s\"", targ->t_nickname);
+ }
+ }
+ }
+}
+
+static void
+conf_from_target(struct iscsi_session_conf *conf,
+ const struct target *targ)
+{
+ memset(conf, 0, sizeof(*conf));
+
+ /*
+ * XXX: Check bounds and return error instead of silently truncating.
+ */
+ if (targ->t_initiator_name != NULL)
+ strlcpy(conf->isc_initiator, targ->t_initiator_name,
+ sizeof(conf->isc_initiator));
+ if (targ->t_initiator_address != NULL)
+ strlcpy(conf->isc_initiator_addr, targ->t_initiator_address,
+ sizeof(conf->isc_initiator_addr));
+ if (targ->t_initiator_alias != NULL)
+ strlcpy(conf->isc_initiator_alias, targ->t_initiator_alias,
+ sizeof(conf->isc_initiator_alias));
+ if (targ->t_name != NULL)
+ strlcpy(conf->isc_target, targ->t_name,
+ sizeof(conf->isc_target));
+ if (targ->t_address != NULL)
+ strlcpy(conf->isc_target_addr, targ->t_address,
+ sizeof(conf->isc_target_addr));
+ if (targ->t_user != NULL)
+ strlcpy(conf->isc_user, targ->t_user,
+ sizeof(conf->isc_user));
+ if (targ->t_secret != NULL)
+ strlcpy(conf->isc_secret, targ->t_secret,
+ sizeof(conf->isc_secret));
+ if (targ->t_mutual_user != NULL)
+ strlcpy(conf->isc_mutual_user, targ->t_mutual_user,
+ sizeof(conf->isc_mutual_user));
+ if (targ->t_mutual_secret != NULL)
+ strlcpy(conf->isc_mutual_secret, targ->t_mutual_secret,
+ sizeof(conf->isc_mutual_secret));
+ if (targ->t_session_type == SESSION_TYPE_DISCOVERY)
+ conf->isc_discovery = 1;
+ if (targ->t_protocol == PROTOCOL_ISER)
+ conf->isc_iser = 1;
+ if (targ->t_header_digest == DIGEST_CRC32C)
+ conf->isc_header_digest = ISCSI_DIGEST_CRC32C;
+ else
+ conf->isc_header_digest = ISCSI_DIGEST_NONE;
+ if (targ->t_data_digest == DIGEST_CRC32C)
+ conf->isc_data_digest = ISCSI_DIGEST_CRC32C;
+ else
+ conf->isc_data_digest = ISCSI_DIGEST_NONE;
+}
+
+static int
+kernel_add(int iscsi_fd, const struct target *targ)
+{
+ struct iscsi_session_add isa;
+ int error;
+
+ memset(&isa, 0, sizeof(isa));
+ conf_from_target(&isa.isa_conf, targ);
+ error = ioctl(iscsi_fd, ISCSISADD, &isa);
+ if (error != 0)
+ warn("ISCSISADD");
+ return (error);
+}
+
+static int
+kernel_remove(int iscsi_fd, const struct target *targ)
+{
+ struct iscsi_session_remove isr;
+ int error;
+
+ memset(&isr, 0, sizeof(isr));
+ conf_from_target(&isr.isr_conf, targ);
+ error = ioctl(iscsi_fd, ISCSISREMOVE, &isr);
+ if (error != 0)
+ warn("ISCSISREMOVE");
+ return (error);
+}
+
+/*
+ * XXX: Add filtering.
+ */
+static int
+kernel_list(int iscsi_fd, const struct target *targ __unused,
+ int verbose)
+{
+ struct iscsi_session_state *states = NULL;
+ const struct iscsi_session_state *state;
+ const struct iscsi_session_conf *conf;
+ struct iscsi_session_list isl;
+ unsigned int i, nentries = 1;
+ int error;
+ bool show_periphs;
+
+ for (;;) {
+ states = realloc(states,
+ nentries * sizeof(struct iscsi_session_state));
+ if (states == NULL)
+ err(1, "realloc");
+
+ memset(&isl, 0, sizeof(isl));
+ isl.isl_nentries = nentries;
+ isl.isl_pstates = states;
+
+ error = ioctl(iscsi_fd, ISCSISLIST, &isl);
+ if (error != 0 && errno == EMSGSIZE) {
+ nentries *= 4;
+ continue;
+ }
+ break;
+ }
+ if (error != 0) {
+ warn("ISCSISLIST");
+ return (error);
+ }
+
+ if (verbose != 0) {
+ for (i = 0; i < isl.isl_nentries; i++) {
+ state = &states[i];
+ conf = &state->iss_conf;
+
+ printf("Session ID: %d\n", state->iss_id);
+ printf("Initiator name: %s\n", conf->isc_initiator);
+ printf("Initiator addr: %s\n",
+ conf->isc_initiator_addr);
+ printf("Initiator alias: %s\n",
+ conf->isc_initiator_alias);
+ printf("Target name: %s\n", conf->isc_target);
+ printf("Target addr: %s\n",
+ conf->isc_target_addr);
+ printf("Target alias: %s\n",
+ state->iss_target_alias);
+ printf("User: %s\n", conf->isc_user);
+ printf("Secret: %s\n", conf->isc_secret);
+ printf("Mutual user: %s\n",
+ conf->isc_mutual_user);
+ printf("Mutual secret: %s\n",
+ conf->isc_mutual_secret);
+ printf("Session type: %s\n",
+ conf->isc_discovery ? "Discovery" : "Normal");
+ printf("Session state: %s\n",
+ state->iss_connected ?
+ "Connected" : "Disconnected");
+ printf("Failure reason: %s\n", state->iss_reason);
+ printf("Header digest: %s\n",
+ state->iss_header_digest == ISCSI_DIGEST_CRC32C ?
+ "CRC32C" : "None");
+ printf("Data digest: %s\n",
+ state->iss_data_digest == ISCSI_DIGEST_CRC32C ?
+ "CRC32C" : "None");
+ printf("DataSegmentLen: %d\n",
+ state->iss_max_data_segment_length);
+ printf("ImmediateData: %s\n",
+ state->iss_immediate_data ? "Yes" : "No");
+ printf("iSER (RDMA): %s\n",
+ conf->isc_iser ? "Yes" : "No");
+ printf("Device nodes: ");
+ print_periphs(state->iss_id);
+ printf("\n\n");
+ }
+ } else {
+ printf("%-36s %-16s %s\n",
+ "Target name", "Target addr", "State");
+ for (i = 0; i < isl.isl_nentries; i++) {
+ state = &states[i];
+ conf = &state->iss_conf;
+ show_periphs = false;
+
+ printf("%-36s %-16s ",
+ conf->isc_target, conf->isc_target_addr);
+
+ if (state->iss_reason[0] != '\0') {
+ printf("%s\n", state->iss_reason);
+ } else {
+ if (conf->isc_discovery) {
+ printf("Discovery\n");
+ } else if (state->iss_connected) {
+ printf("Connected: ");
+ print_periphs(state->iss_id);
+ printf("\n");
+ } else {
+ printf("Disconnected\n");
+ }
+ }
+ }
+ }
+
+ return (0);
+}
+
+static void
+usage(void)
+{
+
+ fprintf(stderr, "usage: iscsictl -A -h host -t target "
+ "[-u user -s secret]\n");
+ fprintf(stderr, " iscsictl -A -d discovery-host "
+ "[-u user -s secret]\n");
+ fprintf(stderr, " iscsictl -A -a [-c path]\n");
+ fprintf(stderr, " iscsictl -A -n nickname [-c path]\n");
+ fprintf(stderr, " iscsictl -R [-h host] [-t target]\n");
+ fprintf(stderr, " iscsictl -R -a\n");
+ fprintf(stderr, " iscsictl -R -n nickname [-c path]\n");
+ fprintf(stderr, " iscsictl -L [-v]\n");
+ exit(1);
+}
+
+char *
+checked_strdup(const char *s)
+{
+ char *c;
+
+ c = strdup(s);
+ if (c == NULL)
+ err(1, "strdup");
+ return (c);
+}
+
+int
+main(int argc, char **argv)
+{
+ int Aflag = 0, Rflag = 0, Lflag = 0, aflag = 0, vflag = 0;
+ const char *conf_path = DEFAULT_CONFIG_PATH;
+ char *nickname = NULL, *discovery_host = NULL, *host = NULL,
+ *target = NULL, *user = NULL, *secret = NULL;
+ int ch, error, iscsi_fd, retval, saved_errno;
+ int failed = 0;
+ struct conf *conf;
+ struct target *targ;
+
+ while ((ch = getopt(argc, argv, "ARLac:d:n:h:t:u:s:v")) != -1) {
+ switch (ch) {
+ case 'A':
+ Aflag = 1;
+ break;
+ case 'R':
+ Rflag = 1;
+ break;
+ case 'L':
+ Lflag = 1;
+ break;
+ case 'a':
+ aflag = 1;
+ break;
+ case 'c':
+ conf_path = optarg;
+ break;
+ case 'd':
+ discovery_host = optarg;
+ break;
+ case 'n':
+ nickname = optarg;
+ break;
+ case 'h':
+ host = optarg;
+ break;
+ case 't':
+ target = optarg;
+ break;
+ case 'u':
+ user = optarg;
+ break;
+ case 's':
+ secret = optarg;
+ break;
+ case 'v':
+ vflag = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ if (argc != 0)
+ usage();
+
+ if (Aflag + Rflag + Lflag == 0)
+ Lflag = 1;
+ if (Aflag + Rflag + Lflag > 1)
+ errx(1, "at most one of -A, -R, or -L may be specified");
+
+ /*
+ * Note that we ignore unneccessary/inapplicable "-c" flag; so that
+ * people can do something like "alias ISCSICTL="iscsictl -c path"
+ * in shell scripts.
+ */
+ if (Aflag != 0) {
+ if (aflag != 0) {
+ if (host != NULL)
+ errx(1, "-a and -h and mutually exclusive");
+ if (target != NULL)
+ errx(1, "-a and -t and mutually exclusive");
+ if (user != NULL)
+ errx(1, "-a and -u and mutually exclusive");
+ if (secret != NULL)
+ errx(1, "-a and -s and mutually exclusive");
+ if (nickname != NULL)
+ errx(1, "-a and -n and mutually exclusive");
+ if (discovery_host != NULL)
+ errx(1, "-a and -d and mutually exclusive");
+ } else if (nickname != NULL) {
+ if (host != NULL)
+ errx(1, "-n and -h and mutually exclusive");
+ if (target != NULL)
+ errx(1, "-n and -t and mutually exclusive");
+ if (user != NULL)
+ errx(1, "-n and -u and mutually exclusive");
+ if (secret != NULL)
+ errx(1, "-n and -s and mutually exclusive");
+ if (discovery_host != NULL)
+ errx(1, "-n and -d and mutually exclusive");
+ } else if (discovery_host != NULL) {
+ if (host != NULL)
+ errx(1, "-d and -h and mutually exclusive");
+ if (target != NULL)
+ errx(1, "-d and -t and mutually exclusive");
+ } else {
+ if (target == NULL && host == NULL)
+ errx(1, "must specify -a, -n or -t/-h");
+
+ if (target != NULL && host == NULL)
+ errx(1, "-t must always be used with -h");
+ if (host != NULL && target == NULL)
+ errx(1, "-h must always be used with -t");
+ }
+
+ if (user != NULL && secret == NULL)
+ errx(1, "-u must always be used with -s");
+ if (secret != NULL && user == NULL)
+ errx(1, "-s must always be used with -u");
+
+ if (vflag != 0)
+ errx(1, "-v cannot be used with -A");
+
+ } else if (Rflag != 0) {
+ if (user != NULL)
+ errx(1, "-R and -u are mutually exclusive");
+ if (secret != NULL)
+ errx(1, "-R and -s are mutually exclusive");
+ if (discovery_host != NULL)
+ errx(1, "-R and -d are mutually exclusive");
+
+ if (aflag != 0) {
+ if (host != NULL)
+ errx(1, "-a and -h and mutually exclusive");
+ if (target != NULL)
+ errx(1, "-a and -t and mutually exclusive");
+ if (nickname != NULL)
+ errx(1, "-a and -n and mutually exclusive");
+ } else if (nickname != NULL) {
+ if (host != NULL)
+ errx(1, "-n and -h and mutually exclusive");
+ if (target != NULL)
+ errx(1, "-n and -t and mutually exclusive");
+ } else if (host != NULL) {
+ if (target != NULL)
+ errx(1, "-h and -t and mutually exclusive");
+ } else if (target != NULL) {
+ if (host != NULL)
+ errx(1, "-t and -h and mutually exclusive");
+ } else
+ errx(1, "must specify either-a, -n, -t, or -h");
+
+ if (vflag != 0)
+ errx(1, "-v cannot be used with -R");
+
+ } else {
+ assert(Lflag != 0);
+
+ if (host != NULL)
+ errx(1, "-L and -h and mutually exclusive");
+ if (target != NULL)
+ errx(1, "-L and -t and mutually exclusive");
+ if (user != NULL)
+ errx(1, "-L and -u and mutually exclusive");
+ if (secret != NULL)
+ errx(1, "-L and -s and mutually exclusive");
+ if (nickname != NULL)
+ errx(1, "-L and -n and mutually exclusive");
+ if (discovery_host != NULL)
+ errx(1, "-L and -d and mutually exclusive");
+ }
+
+ iscsi_fd = open(ISCSI_PATH, O_RDWR);
+ if (iscsi_fd < 0 && errno == ENOENT) {
+ saved_errno = errno;
+ retval = kldload("iscsi");
+ if (retval != -1)
+ iscsi_fd = open(ISCSI_PATH, O_RDWR);
+ else
+ errno = saved_errno;
+ }
+ if (iscsi_fd < 0)
+ err(1, "failed to open %s", ISCSI_PATH);
+
+ if (Aflag != 0 && aflag != 0) {
+ conf = conf_new_from_file(conf_path);
+
+ TAILQ_FOREACH(targ, &conf->conf_targets, t_next)
+ failed += kernel_add(iscsi_fd, targ);
+ } else if (nickname != NULL) {
+ conf = conf_new_from_file(conf_path);
+ targ = target_find(conf, nickname);
+ if (targ == NULL)
+ errx(1, "target %s not found in the configuration file",
+ nickname);
+
+ if (Aflag != 0)
+ failed += kernel_add(iscsi_fd, targ);
+ else if (Rflag != 0)
+ failed += kernel_remove(iscsi_fd, targ);
+ else
+ failed += kernel_list(iscsi_fd, targ, vflag);
+ } else {
+ if (Aflag != 0 && target != NULL) {
+ if (valid_iscsi_name(target) == false)
+ errx(1, "invalid target name \"%s\"", target);
+ }
+ conf = conf_new();
+ targ = target_new(conf);
+ targ->t_initiator_name = default_initiator_name();
+ targ->t_header_digest = DIGEST_NONE;
+ targ->t_data_digest = DIGEST_NONE;
+ targ->t_name = target;
+ if (discovery_host != NULL) {
+ targ->t_session_type = SESSION_TYPE_DISCOVERY;
+ targ->t_address = discovery_host;
+ } else {
+ targ->t_session_type = SESSION_TYPE_NORMAL;
+ targ->t_address = host;
+ }
+ targ->t_user = user;
+ targ->t_secret = secret;
+
+ if (Aflag != 0)
+ failed += kernel_add(iscsi_fd, targ);
+ else if (Rflag != 0)
+ failed += kernel_remove(iscsi_fd, targ);
+ else
+ failed += kernel_list(iscsi_fd, targ, vflag);
+ }
+
+ error = close(iscsi_fd);
+ if (error != 0)
+ err(1, "close");
+
+ if (failed > 0)
+ return (1);
+ return (0);
+}
diff --git a/usr.bin/iscsictl/iscsictl.h b/usr.bin/iscsictl/iscsictl.h
new file mode 100644
index 000000000000..e8d4768a88f5
--- /dev/null
+++ b/usr.bin/iscsictl/iscsictl.h
@@ -0,0 +1,116 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ISCSICTL_H
+#define ISCSICTL_H
+
+#include <sys/queue.h>
+#include <stdbool.h>
+#include <libutil.h>
+
+#define DEFAULT_CONFIG_PATH "/etc/iscsi.conf"
+#define DEFAULT_IQN "iqn.1994-09.org.freebsd:"
+
+#define MAX_NAME_LEN 223
+#define MAX_DATA_SEGMENT_LENGTH 65536
+
+#define AUTH_METHOD_UNSPECIFIED 0
+#define AUTH_METHOD_NONE 1
+#define AUTH_METHOD_CHAP 2
+
+#define DIGEST_UNSPECIFIED 0
+#define DIGEST_NONE 1
+#define DIGEST_CRC32C 2
+
+#define SESSION_TYPE_UNSPECIFIED 0
+#define SESSION_TYPE_NORMAL 1
+#define SESSION_TYPE_DISCOVERY 2
+
+#define PROTOCOL_UNSPECIFIED 0
+#define PROTOCOL_ISCSI 1
+#define PROTOCOL_ISER 2
+
+struct target {
+ TAILQ_ENTRY(target) t_next;
+ struct conf *t_conf;
+ char *t_nickname;
+ char *t_name;
+ char *t_address;
+ char *t_initiator_name;
+ char *t_initiator_address;
+ char *t_initiator_alias;
+ int t_header_digest;
+ int t_data_digest;
+ int t_auth_method;
+ int t_session_type;
+ int t_protocol;
+ char *t_user;
+ char *t_secret;
+ char *t_mutual_user;
+ char *t_mutual_secret;
+};
+
+struct conf {
+ TAILQ_HEAD(, target) conf_targets;
+};
+
+#define CONN_SESSION_TYPE_NONE 0
+#define CONN_SESSION_TYPE_DISCOVERY 1
+#define CONN_SESSION_TYPE_NORMAL 2
+
+struct connection {
+ struct target *conn_target;
+ int conn_socket;
+ int conn_session_type;
+ uint32_t conn_cmdsn;
+ uint32_t conn_statsn;
+ size_t conn_max_data_segment_length;
+ size_t conn_max_burst_length;
+ size_t conn_max_outstanding_r2t;
+ int conn_header_digest;
+ int conn_data_digest;
+};
+
+struct conf *conf_new(void);
+struct conf *conf_new_from_file(const char *path);
+void conf_delete(struct conf *conf);
+void conf_verify(struct conf *conf);
+
+struct target *target_new(struct conf *conf);
+struct target *target_find(struct conf *conf, const char *nickname);
+void target_delete(struct target *ic);
+
+void print_periphs(int session_id);
+
+char *checked_strdup(const char *);
+bool valid_iscsi_name(const char *name);
+
+#endif /* !ISCSICTL_H */
diff --git a/usr.bin/iscsictl/parse.y b/usr.bin/iscsictl/parse.y
new file mode 100644
index 000000000000..b44fc3bb35fb
--- /dev/null
+++ b/usr.bin/iscsictl/parse.y
@@ -0,0 +1,333 @@
+%{
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "iscsictl.h"
+
+extern FILE *yyin;
+extern char *yytext;
+extern int lineno;
+
+static struct conf *conf;
+static struct target *target;
+
+extern void yyerror(const char *);
+extern int yylex(void);
+extern void yyrestart(FILE *);
+
+%}
+
+%token AUTH_METHOD HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS
+%token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET
+%token MUTUAL_USER MUTUAL_SECRET SESSION_TYPE PROTOCOL IGNORED
+%token EQUALS OPENING_BRACKET CLOSING_BRACKET
+
+%union
+{
+ char *str;
+}
+
+%token <str> STR
+
+%%
+
+statements:
+ |
+ statements target_statement
+ ;
+
+target_statement: STR OPENING_BRACKET target_entries CLOSING_BRACKET
+ {
+ if (target_find(conf, $1) != NULL)
+ errx(1, "duplicated target %s", $1);
+ target->t_nickname = $1;
+ target = target_new(conf);
+ }
+ ;
+
+target_entries:
+ |
+ target_entries target_entry
+ ;
+
+target_entry:
+ target_name_statement
+ |
+ target_address_statement
+ |
+ initiator_name_statement
+ |
+ initiator_address_statement
+ |
+ initiator_alias_statement
+ |
+ user_statement
+ |
+ secret_statement
+ |
+ mutual_user_statement
+ |
+ mutual_secret_statement
+ |
+ auth_method_statement
+ |
+ header_digest_statement
+ |
+ data_digest_statement
+ |
+ session_type_statement
+ |
+ protocol_statement
+ |
+ ignored_statement
+ ;
+
+target_name_statement: TARGET_NAME EQUALS STR
+ {
+ if (target->t_name != NULL)
+ errx(1, "duplicated TargetName at line %d", lineno + 1);
+ target->t_name = $3;
+ }
+ ;
+
+target_address_statement: TARGET_ADDRESS EQUALS STR
+ {
+ if (target->t_address != NULL)
+ errx(1, "duplicated TargetAddress at line %d", lineno + 1);
+ target->t_address = $3;
+ }
+ ;
+
+initiator_name_statement: INITIATOR_NAME EQUALS STR
+ {
+ if (target->t_initiator_name != NULL)
+ errx(1, "duplicated InitiatorName at line %d", lineno + 1);
+ target->t_initiator_name = $3;
+ }
+ ;
+
+initiator_address_statement: INITIATOR_ADDRESS EQUALS STR
+ {
+ if (target->t_initiator_address != NULL)
+ errx(1, "duplicated InitiatorAddress at line %d", lineno + 1);
+ target->t_initiator_address = $3;
+ }
+ ;
+
+initiator_alias_statement: INITIATOR_ALIAS EQUALS STR
+ {
+ if (target->t_initiator_alias != NULL)
+ errx(1, "duplicated InitiatorAlias at line %d", lineno + 1);
+ target->t_initiator_alias = $3;
+ }
+ ;
+
+user_statement: USER EQUALS STR
+ {
+ if (target->t_user != NULL)
+ errx(1, "duplicated chapIName at line %d", lineno + 1);
+ target->t_user = $3;
+ }
+ ;
+
+secret_statement: SECRET EQUALS STR
+ {
+ if (target->t_secret != NULL)
+ errx(1, "duplicated chapSecret at line %d", lineno + 1);
+ target->t_secret = $3;
+ }
+ ;
+
+mutual_user_statement: MUTUAL_USER EQUALS STR
+ {
+ if (target->t_mutual_user != NULL)
+ errx(1, "duplicated tgtChapName at line %d", lineno + 1);
+ target->t_mutual_user = $3;
+ }
+ ;
+
+mutual_secret_statement:MUTUAL_SECRET EQUALS STR
+ {
+ if (target->t_mutual_secret != NULL)
+ errx(1, "duplicated tgtChapSecret at line %d", lineno + 1);
+ target->t_mutual_secret = $3;
+ }
+ ;
+
+auth_method_statement: AUTH_METHOD EQUALS STR
+ {
+ if (target->t_auth_method != AUTH_METHOD_UNSPECIFIED)
+ errx(1, "duplicated AuthMethod at line %d", lineno + 1);
+ if (strcasecmp($3, "none") == 0)
+ target->t_auth_method = AUTH_METHOD_NONE;
+ else if (strcasecmp($3, "chap") == 0)
+ target->t_auth_method = AUTH_METHOD_CHAP;
+ else
+ errx(1, "invalid AuthMethod at line %d; "
+ "must be either \"none\" or \"CHAP\"", lineno + 1);
+ }
+ ;
+
+header_digest_statement: HEADER_DIGEST EQUALS STR
+ {
+ if (target->t_header_digest != DIGEST_UNSPECIFIED)
+ errx(1, "duplicated HeaderDigest at line %d", lineno + 1);
+ if (strcasecmp($3, "none") == 0)
+ target->t_header_digest = DIGEST_NONE;
+ else if (strcasecmp($3, "CRC32C") == 0)
+ target->t_header_digest = DIGEST_CRC32C;
+ else
+ errx(1, "invalid HeaderDigest at line %d; "
+ "must be either \"none\" or \"CRC32C\"", lineno + 1);
+ }
+ ;
+
+data_digest_statement: DATA_DIGEST EQUALS STR
+ {
+ if (target->t_data_digest != DIGEST_UNSPECIFIED)
+ errx(1, "duplicated DataDigest at line %d", lineno + 1);
+ if (strcasecmp($3, "none") == 0)
+ target->t_data_digest = DIGEST_NONE;
+ else if (strcasecmp($3, "CRC32C") == 0)
+ target->t_data_digest = DIGEST_CRC32C;
+ else
+ errx(1, "invalid DataDigest at line %d; "
+ "must be either \"none\" or \"CRC32C\"", lineno + 1);
+ }
+ ;
+
+session_type_statement: SESSION_TYPE EQUALS STR
+ {
+ if (target->t_session_type != SESSION_TYPE_UNSPECIFIED)
+ errx(1, "duplicated SessionType at line %d", lineno + 1);
+ if (strcasecmp($3, "normal") == 0)
+ target->t_session_type = SESSION_TYPE_NORMAL;
+ else if (strcasecmp($3, "discovery") == 0)
+ target->t_session_type = SESSION_TYPE_DISCOVERY;
+ else
+ errx(1, "invalid SessionType at line %d; "
+ "must be either \"normal\" or \"discovery\"", lineno + 1);
+ }
+ ;
+
+protocol_statement: PROTOCOL EQUALS STR
+ {
+ if (target->t_protocol != PROTOCOL_UNSPECIFIED)
+ errx(1, "duplicated protocol at line %d", lineno + 1);
+ if (strcasecmp($3, "iscsi") == 0)
+ target->t_protocol = PROTOCOL_ISCSI;
+ else if (strcasecmp($3, "iser") == 0)
+ target->t_protocol = PROTOCOL_ISER;
+ else
+ errx(1, "invalid protocol at line %d; "
+ "must be either \"iscsi\" or \"iser\"", lineno + 1);
+ }
+ ;
+
+ignored_statement: IGNORED EQUALS STR
+ {
+ warnx("obsolete statement ignored at line %d", lineno + 1);
+ }
+ ;
+
+%%
+
+void
+yyerror(const char *str)
+{
+
+ errx(1, "error in configuration file at line %d near '%s': %s",
+ lineno + 1, yytext, str);
+}
+
+static void
+check_perms(const char *path)
+{
+ struct stat sb;
+ int error;
+
+ error = stat(path, &sb);
+ if (error != 0) {
+ warn("stat");
+ return;
+ }
+ if (sb.st_mode & S_IWOTH) {
+ warnx("%s is world-writable", path);
+ } else if (sb.st_mode & S_IROTH) {
+ warnx("%s is world-readable", path);
+ } else if (sb.st_mode & S_IXOTH) {
+ /*
+ * Ok, this one doesn't matter, but still do it,
+ * just for consistency.
+ */
+ warnx("%s is world-executable", path);
+ }
+
+ /*
+ * XXX: Should we also check for owner != 0?
+ */
+}
+
+struct conf *
+conf_new_from_file(const char *path)
+{
+ int error;
+
+ conf = conf_new();
+ target = target_new(conf);
+
+ yyin = fopen(path, "r");
+ if (yyin == NULL)
+ err(1, "unable to open configuration file %s", path);
+ check_perms(path);
+ lineno = 0;
+ yyrestart(yyin);
+ error = yyparse();
+ assert(error == 0);
+ fclose(yyin);
+
+ assert(target->t_nickname == NULL);
+ target_delete(target);
+
+ conf_verify(conf);
+
+ return (conf);
+}
diff --git a/usr.bin/iscsictl/periphs.c b/usr.bin/iscsictl/periphs.c
new file mode 100644
index 000000000000..78b237f4aea8
--- /dev/null
+++ b/usr.bin/iscsictl/periphs.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 1997-2007 Kenneth D. Merry
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Edward Tomasz Napierala
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/ioctl.h>
+#include <sys/stdint.h>
+#include <sys/types.h>
+#include <sys/endian.h>
+#include <sys/sbuf.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <err.h>
+
+#include <cam/cam.h>
+#include <cam/cam_debug.h>
+#include <cam/cam_ccb.h>
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_da.h>
+#include <cam/scsi/scsi_pass.h>
+#include <cam/scsi/scsi_message.h>
+#include <cam/scsi/smp_all.h>
+#include <cam/ata/ata_all.h>
+#include <camlib.h>
+
+#include "iscsictl.h"
+
+void
+print_periphs(int session_id)
+{
+ union ccb ccb;
+ int bufsize, fd;
+ unsigned int i;
+ int skip_bus, skip_device;
+
+ if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
+ warn("couldn't open %s", XPT_DEVICE);
+ return;
+ }
+
+ /*
+ * First, iterate over the whole list to find the bus.
+ */
+
+ bzero(&ccb, sizeof(union ccb));
+
+ ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
+ ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
+ ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
+
+ ccb.ccb_h.func_code = XPT_DEV_MATCH;
+ bufsize = sizeof(struct dev_match_result) * 100;
+ ccb.cdm.match_buf_len = bufsize;
+ ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
+ if (ccb.cdm.matches == NULL) {
+ warnx("can't malloc memory for matches");
+ close(fd);
+ return;
+ }
+ ccb.cdm.num_matches = 0;
+
+ /*
+ * We fetch all nodes, since we display most of them in the default
+ * case, and all in the verbose case.
+ */
+ ccb.cdm.num_patterns = 0;
+ ccb.cdm.pattern_buf_len = 0;
+
+ /*
+ * We do the ioctl multiple times if necessary, in case there are
+ * more than 100 nodes in the EDT.
+ */
+ do {
+ if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
+ warn("error sending CAMIOCOMMAND ioctl");
+ break;
+ }
+
+ if ((ccb.ccb_h.status != CAM_REQ_CMP)
+ || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
+ && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
+ warnx("got CAM error %#x, CDM error %d\n",
+ ccb.ccb_h.status, ccb.cdm.status);
+ break;
+ }
+
+ skip_bus = 1;
+ skip_device = 1;
+
+ for (i = 0; i < ccb.cdm.num_matches; i++) {
+ switch (ccb.cdm.matches[i].type) {
+ case DEV_MATCH_BUS: {
+ struct bus_match_result *bus_result;
+
+ bus_result = &ccb.cdm.matches[i].result.bus_result;
+
+ skip_bus = 1;
+
+ if (strcmp(bus_result->dev_name, "iscsi") != 0) {
+ //printf("not iscsi\n");
+ continue;
+ }
+
+ if ((int)bus_result->unit_number != session_id) {
+ //printf("wrong unit, %d != %d\n", bus_result->unit_number, session_id);
+ continue;
+ }
+
+ skip_bus = 0;
+ }
+ case DEV_MATCH_DEVICE: {
+ skip_device = 1;
+
+ if (skip_bus != 0)
+ continue;
+
+ skip_device = 0;
+
+ break;
+ }
+ case DEV_MATCH_PERIPH: {
+ struct periph_match_result *periph_result;
+
+ periph_result =
+ &ccb.cdm.matches[i].result.periph_result;
+
+ if (skip_device != 0)
+ continue;
+
+ if (strcmp(periph_result->periph_name, "pass") == 0)
+ continue;
+
+ fprintf(stdout, "%s%d ",
+ periph_result->periph_name,
+ periph_result->unit_number);
+
+ break;
+ }
+ default:
+ fprintf(stdout, "unknown match type\n");
+ break;
+ }
+ }
+
+ } while ((ccb.ccb_h.status == CAM_REQ_CMP)
+ && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
+
+ close(fd);
+}
+
diff --git a/usr.bin/iscsictl/token.l b/usr.bin/iscsictl/token.l
new file mode 100644
index 000000000000..f6c03aecc750
--- /dev/null
+++ b/usr.bin/iscsictl/token.l
@@ -0,0 +1,93 @@
+%{
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "iscsictl.h"
+#include "y.tab.h"
+
+int lineno;
+
+#define YY_DECL int yylex(void)
+extern int yylex(void);
+
+%}
+
+%option noinput
+%option nounput
+
+%%
+HeaderDigest { return HEADER_DIGEST; }
+DataDigest { return DATA_DIGEST; }
+TargetName { return TARGET_NAME; }
+TargetAddress { return TARGET_ADDRESS; }
+InitiatorName { return INITIATOR_NAME; }
+InitiatorAddress { return INITIATOR_ADDRESS; }
+InitiatorAlias { return INITIATOR_ALIAS; }
+chapIName { return USER; }
+chapSecret { return SECRET; }
+tgtChapName { return MUTUAL_USER; }
+tgtChapSecret { return MUTUAL_SECRET; }
+AuthMethod { return AUTH_METHOD; }
+SessionType { return SESSION_TYPE; }
+protocol { return PROTOCOL; }
+port { return IGNORED; }
+MaxConnections { return IGNORED; }
+TargetAlias { return IGNORED; }
+TargetPortalGroupTag { return IGNORED; }
+InitialR2T { return IGNORED; }
+ImmediateData { return IGNORED; }
+MaxRecvDataSegmentLength { return IGNORED; }
+MaxBurstLength { return IGNORED; }
+FirstBurstLength { return IGNORED; }
+DefaultTime2Wait { return IGNORED; }
+DefaultTime2Retain { return IGNORED; }
+MaxOutstandingR2T { return IGNORED; }
+DataPDUInOrder { return IGNORED; }
+DataSequenceInOrder { return IGNORED; }
+ErrorRecoveryLevel { return IGNORED; }
+tags { return IGNORED; }
+maxluns { return IGNORED; }
+sockbufsize { return IGNORED; }
+chapDigest { return IGNORED; }
+\"[^"]+\" { yylval.str = strndup(yytext + 1,
+ strlen(yytext) - 2); return STR; }
+[a-zA-Z0-9\.\-_/\:\[\]]+ { yylval.str = strdup(yytext); return STR; }
+\{ { return OPENING_BRACKET; }
+\} { return CLOSING_BRACKET; }
+= { return EQUALS; }
+#.*$ /* ignore comments */;
+\n { lineno++; }
+[ \t]+ /* ignore whitespace */;
+%%
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 0de183c1a224..24bb0fd34e03 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -59,6 +59,7 @@ extern int errno;
#include <sys/sysent.h>
#include <sys/un.h>
#include <sys/queue.h>
+#include <sys/wait.h>
#ifdef IPX
#include <sys/types.h>
#include <netipx/ipx.h>
@@ -666,8 +667,30 @@ ktrsyscall(struct ktr_syscall *ktr, u_int flags)
case SYS_wait4:
print_number(ip, narg, c);
print_number(ip, narg, c);
+ /*
+ * A flags value of zero is valid for
+ * wait4() but not for wait6(), so
+ * handle zero special here.
+ */
+ if (*ip == 0) {
+ print_number(ip, narg, c);
+ } else {
+ putchar(',');
+ wait6optname(*ip);
+ ip++;
+ narg--;
+ }
+ break;
+ case SYS_wait6:
+ putchar('(');
+ idtypename(*ip, decimal);
+ c = ',';
+ ip++;
+ narg--;
+ print_number(ip, narg, c);
+ print_number(ip, narg, c);
putchar(',');
- wait4optname(*ip);
+ wait6optname(*ip);
ip++;
narg--;
break;
@@ -1138,6 +1161,18 @@ ktrsyscall(struct ktr_syscall *ktr, u_int flags)
ip++;
narg--;
break;
+ case SYS_procctl:
+ putchar('(');
+ idtypename(*ip, decimal);
+ c = ',';
+ ip++;
+ narg--;
+ print_number(ip, narg, c);
+ putchar(',');
+ procctlcmdname(*ip);
+ ip++;
+ narg--;
+ break;
}
}
while (narg > 0) {
@@ -1620,10 +1655,15 @@ ktrstat(struct stat *statp)
* buffer exactly sizeof(struct stat) bytes long.
*/
printf("struct stat {");
- strmode(statp->st_mode, mode);
- printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ",
- (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode,
- (uintmax_t)statp->st_nlink);
+ printf("dev=%ju, ino=%ju, ",
+ (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino);
+ if (resolv == 0)
+ printf("mode=0%jo, ", (uintmax_t)statp->st_mode);
+ else {
+ strmode(statp->st_mode, mode);
+ printf("mode=%s, ", mode);
+ }
+ printf("nlink=%ju, ", (uintmax_t)statp->st_nlink);
if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
printf("uid=%ju, ", (uintmax_t)statp->st_uid);
else
diff --git a/usr.bin/kdump/mksubr b/usr.bin/kdump/mksubr
index 2a16e37b8f07..1859086af1c8 100644
--- a/usr.bin/kdump/mksubr
+++ b/usr.bin/kdump/mksubr
@@ -169,6 +169,7 @@ cat <<_EOF_
#include <netinet/in.h>
#include <sys/param.h>
#include <sys/mount.h>
+#include <sys/procctl.h>
#include <sys/ptrace.h>
#include <sys/resource.h>
#include <sys/reboot.h>
@@ -327,6 +328,68 @@ flagsandmodename(int flags, int mode, int decimal)
}
}
+/* MANUAL */
+void
+idtypename(idtype_t idtype, int decimal)
+{
+ switch(idtype) {
+ case P_PID:
+ printf("P_PID");
+ break;
+ case P_PPID:
+ printf("P_PPID");
+ break;
+ case P_PGID:
+ printf("P_PGID");
+ break;
+ case P_SID:
+ printf("P_SID");
+ break;
+ case P_CID:
+ printf("P_CID");
+ break;
+ case P_UID:
+ printf("P_UID");
+ break;
+ case P_GID:
+ printf("P_GID");
+ break;
+ case P_ALL:
+ printf("P_ALL");
+ break;
+ case P_LWPID:
+ printf("P_LWPID");
+ break;
+ case P_TASKID:
+ printf("P_TASKID");
+ break;
+ case P_PROJID:
+ printf("P_PROJID");
+ break;
+ case P_POOLID:
+ printf("P_POOLID");
+ break;
+ case P_JAILID:
+ printf("P_JAILID");
+ break;
+ case P_CTID:
+ printf("P_CTID");
+ break;
+ case P_CPUID:
+ printf("P_CPUID");
+ break;
+ case P_PSETID:
+ printf("P_PSETID");
+ break;
+ default:
+ if (decimal) {
+ printf("%d", idtype);
+ } else {
+ printf("%#x", idtype);
+ }
+ }
+}
+
/*
* MANUAL
*
@@ -403,6 +466,7 @@ auto_or_type "mountflagsname" "MNT_[A-Z]+[[:space:]]+0x[0-9]+"
auto_switch_type "msyncflagsname" "MS_[A-Z]+[[:space:]]+0x[0-9]+" "sys/mman.h"
auto_or_type "nfssvcname" "NFSSVC_[A-Z0-9]+[[:space:]]+0x[0-9]+" "nfs/nfssvc.h"
auto_switch_type "prioname" "PRIO_[A-Z]+[[:space:]]+[0-9]" "sys/resource.h"
+auto_switch_type "procctlcmdname" "PROC_[A-Z]+[[:space:]]+[0-9]" "sys/procctl.h"
auto_switch_type "ptraceopname" "PT_[[:alnum:]_]+[[:space:]]+[0-9]+" "sys/ptrace.h"
auto_switch_type "quotactlname" "Q_[A-Z]+[[:space:]]+0x[0-9]+" "ufs/ufs/quota.h"
auto_or_type "rebootoptname" "RB_[A-Z]+[[:space:]]+0x[0-9]+" "sys/reboot.h"
@@ -426,7 +490,7 @@ auto_switch_type "sockoptname" "SO_[A-Z]+[[:space:]]+0x[0-9]+"
auto_switch_type "socktypename" "SOCK_[A-Z]+[[:space:]]+[1-9]+[0-9]*" "sys/socket.h"
auto_or_type "thrcreateflagsname" "THR_[A-Z]+[[:space:]]+0x[0-9]+" "sys/thr.h"
auto_switch_type "vmresultname" "KERN_[A-Z]+[[:space:]]+[0-9]+" "vm/vm_param.h"
-auto_or_type "wait4optname" "W[A-Z]+[[:space:]]+[0-9]+" "sys/wait.h"
+auto_or_type "wait6optname" "W[A-Z]+[[:space:]]+[0-9]+" "sys/wait.h"
auto_switch_type "whencename" "SEEK_[A-Z]+[[:space:]]+[0-9]+" "sys/unistd.h"
cat <<_EOF_
diff --git a/usr.bin/nslookup/Makefile b/usr.bin/nslookup/Makefile
deleted file mode 100644
index 4ed0e92584b1..000000000000
--- a/usr.bin/nslookup/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-# $FreeBSD$
-
-BIND_DIR= ${.CURDIR}/../../contrib/bind9
-LIB_BIND_REL= ../../lib/bind
-LIB_BIND_DIR= ${.CURDIR}/${LIB_BIND_REL}
-SRCDIR= ${BIND_DIR}/bin/dig
-
-.include "${LIB_BIND_DIR}/config.mk"
-
-PROG= nslookup
-
-.PATH: ${SRCDIR}
-SRCS+= dighost.c nslookup.c
-
-CFLAGS+= -I${SRCDIR}/include -ledit
-CFLAGS+= -I${BIND_DIR}/lib/isc/${ISC_ATOMIC_ARCH}/include
-
-DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD} ${LIBEDIT}
-LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD} ${LIBEDIT}
-
-WARNS?= 0
-
-MANFILTER= sed -e "s@^host \[server\]@\\\fBhost\\\fR \\\fI[server]\\\fR@"
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/nslookup/Makefile.depend b/usr.bin/nslookup/Makefile.depend
deleted file mode 100644
index 82922d837f64..000000000000
--- a/usr.bin/nslookup/Makefile.depend
+++ /dev/null
@@ -1,30 +0,0 @@
-# Autogenerated - do NOT edit!
-
-DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
-
-DIRDEPS = \
- gnu/lib/libgcc \
- gnu/lib/libreadline/readline \
- include \
- include/arpa \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/bind/bind9 \
- lib/bind/dns \
- lib/bind/isc \
- lib/bind/isccc \
- lib/bind/isccfg \
- lib/bind/lwres \
- lib/libc \
- lib/libcompiler_rt \
- lib/libedit \
- lib/libthr \
- lib/ncurses/ncurses \
- secure/lib/libcrypto \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.bin/nsupdate/Makefile b/usr.bin/nsupdate/Makefile
deleted file mode 100644
index 593d58923f6a..000000000000
--- a/usr.bin/nsupdate/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-# $FreeBSD$
-
-BIND_DIR= ${.CURDIR}/../../contrib/bind9
-LIB_BIND_REL= ../../lib/bind
-LIB_BIND_DIR= ${.CURDIR}/${LIB_BIND_REL}
-SRCDIR= ${BIND_DIR}/bin/nsupdate
-
-.include "${LIB_BIND_DIR}/config.mk"
-
-PROG= nsupdate
-
-.PATH: ${SRCDIR}
-SRCS+= nsupdate.c
-
-CFLAGS+= -I${SRCDIR}/include -ledit
-CFLAGS+= -I${BIND_DIR}/lib/isc/${ISC_ATOMIC_ARCH}/include
-CFLAGS+= -DSESSION_KEYFILE=\"/var/run/named/session.key\"
-
-DPADD+= ${BIND_DPADD} ${CRYPTO_DPADD} ${PTHREAD_DPADD} ${LIBEDIT}
-LDADD+= ${BIND_LDADD} ${CRYPTO_LDADD} ${PTHREAD_LDADD} ${LIBEDIT}
-
-WARNS?= 1
-
-MAN= nsupdate.1
-
-MANFILTER= sed -e "s@/etc/named\.conf@/etc/namedb/named.conf@g" \
- -e "s@^\.HP [0-9]* @@"
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/nsupdate/Makefile.depend b/usr.bin/nsupdate/Makefile.depend
deleted file mode 100644
index 82922d837f64..000000000000
--- a/usr.bin/nsupdate/Makefile.depend
+++ /dev/null
@@ -1,30 +0,0 @@
-# Autogenerated - do NOT edit!
-
-DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
-
-DIRDEPS = \
- gnu/lib/libgcc \
- gnu/lib/libreadline/readline \
- include \
- include/arpa \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/bind/bind9 \
- lib/bind/dns \
- lib/bind/isc \
- lib/bind/isccc \
- lib/bind/isccfg \
- lib/bind/lwres \
- lib/libc \
- lib/libcompiler_rt \
- lib/libedit \
- lib/libthr \
- lib/ncurses/ncurses \
- secure/lib/libcrypto \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/usr.bin/patch/patch.c b/usr.bin/patch/patch.c
index 956482cb38f1..1743678626c5 100644
--- a/usr.bin/patch/patch.c
+++ b/usr.bin/patch/patch.c
@@ -145,7 +145,7 @@ int
main(int argc, char *argv[])
{
int error = 0, hunk, failed, i, fd;
- bool patch_seen;
+ bool patch_seen, reverse_seen;
LINENUM where = 0, newwhere, fuzz, mymaxfuzz;
const char *tmpdir;
char *v;
@@ -247,6 +247,7 @@ main(int argc, char *argv[])
/* apply each hunk of patch */
hunk = 0;
failed = 0;
+ reverse_seen = false;
out_of_mem = false;
while (another_hunk()) {
hunk++;
@@ -257,7 +258,7 @@ main(int argc, char *argv[])
if (!skip_rest_of_patch) {
do {
where = locate_hunk(fuzz);
- if (hunk == 1 && where == 0 && !force) {
+ if (hunk == 1 && where == 0 && !force && !reverse_seen) {
/* dwim for reversed patch? */
if (!pch_swap()) {
if (fuzz == 0)
@@ -293,6 +294,8 @@ main(int argc, char *argv[])
ask("Apply anyway? [n] ");
if (*buf != 'y')
skip_rest_of_patch = true;
+ else
+ reverse_seen = true;
where = 0;
reverse = !reverse;
if (!pch_swap())
@@ -406,8 +409,8 @@ main(int argc, char *argv[])
say("%d out of %d hunks %s--saving rejects to %s\n",
failed, hunk, skip_rest_of_patch ? "ignored" : "failed", rejname);
else
- say("%d out of %d hunks %s\n",
- failed, hunk, skip_rest_of_patch ? "ignored" : "failed");
+ say("%d out of %d hunks %s while patching %s\n",
+ failed, hunk, skip_rest_of_patch ? "ignored" : "failed", filearg[0]);
if (!check_only && move_file(TMPREJNAME, rejname) < 0)
trejkeep = true;
}
diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c
index c19918b04e9d..698067630208 100644
--- a/usr.bin/patch/util.c
+++ b/usr.bin/patch/util.c
@@ -412,7 +412,7 @@ checked_in(char *file)
void
version(void)
{
- fprintf(stderr, "patch 2.0-12u9 FreeBSD\n");
+ fprintf(stderr, "patch 2.0-12u10 FreeBSD\n");
my_exit(EXIT_SUCCESS);
}
diff --git a/usr.bin/procstat/procstat.1 b/usr.bin/procstat/procstat.1
index faa296c7f935..d7b7d3f08276 100644
--- a/usr.bin/procstat/procstat.1
+++ b/usr.bin/procstat/procstat.1
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 20, 2013
+.Dd September 17, 2013
.Dt PROCSTAT 1
.Os
.Sh NAME
@@ -234,7 +234,7 @@ If the
flag is specified, the vnode type, reference count, and offset fields will be
omitted, and a new capabilities field will be included listing capabilities,
as described in
-.Xr cap_new 2 ,
+.Xr cap_rights_limit 2 ,
present for each capability descriptor.
.Ss Signal Disposition Information
Display signal pending and disposition for a process:
@@ -449,7 +449,7 @@ grows up (bottom-up stack)
.Xr ps 1 ,
.Xr sockstat 1 ,
.Xr cap_enter 2 ,
-.Xr cap_new 2 ,
+.Xr cap_rights_limit 2 ,
.Xr ddb 4 ,
.Xr stack 9
.Sh AUTHORS
diff --git a/usr.bin/protect/Makefile b/usr.bin/protect/Makefile
new file mode 100644
index 000000000000..89bbda8a1bc2
--- /dev/null
+++ b/usr.bin/protect/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+PROG= protect
+WARNS?= 6
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/protect/protect.1 b/usr.bin/protect/protect.1
new file mode 100644
index 000000000000..919714e9a1dc
--- /dev/null
+++ b/usr.bin/protect/protect.1
@@ -0,0 +1,89 @@
+.\" Copyright (c) 2013 Advanced Computing Technologies LLC
+.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 19, 2013
+.Dt PROTECT 1
+.Os
+.Sh NAME
+.Nm protect
+.Nd "protect processes from being killed when swap space is exhausted"
+.Sh SYNOPSIS
+.Nm
+.Op Fl i
+.Ar command
+.Nm
+.Op Fl cdi
+.Fl g Ar pgrp | Fl p Ar pid
+.Sh DESCRIPTION
+The
+.Nm
+command is used to mark processes as protected.
+The kernel does not kill protected processes when swap space is exhausted.
+Note that this protected state is not inherited by child processes by default.
+.Pp
+The options are:
+.Bl -tag -width XXXXXXXXXX
+.It Fl c
+Remove protection from the specified processes.
+.It Fl d
+Apply the operation to all current children of the specified processes.
+.It Fl i
+Apply the operation to all future children of the specified processes.
+.It Fl g Ar pgrp
+Apply the operation to all processes in the specified process group.
+.It Fl p Ar pid
+Apply the operation to the specified process.
+.It Ar command
+Execute
+.Ar command
+as a protected process.
+.El
+.Pp
+Note that only one of the
+.Fl p
+or
+.Fl g
+flags may be specified when adjusting the state of existing processes.
+.Sh EXIT STATUS
+.Ex -std
+.Sh EXAMPLES
+Mark the Xorg server as protected:
+.Pp
+.Dl "pgrep Xorg | xargs protect -p"
+.Pp
+Protect all ssh sessions and their child processes:
+.Pp
+.Dl "pgrep sshd | xargs protect -dip"
+.Pp
+Remove protection from all current and future processes:
+.Pp
+.Dl "protect -cdi -p 1"
+.Sh SEE ALSO
+.Xr procctl 2
+.Sh BUGS
+If you protect a runaway process that allocates all memory the system will
+deadlock.
diff --git a/usr.bin/protect/protect.c b/usr.bin/protect/protect.c
new file mode 100644
index 000000000000..ba15aa642093
--- /dev/null
+++ b/usr.bin/protect/protect.c
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Written by: John H. Baldwin <jhb@FreeBSD.org>
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/procctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <err.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void
+usage(void)
+{
+
+ fprintf(stderr, "usage: protect [-i] command\n");
+ fprintf(stderr, " protect [-cdi] -g pgrp | -p pid\n");
+ exit(1);
+}
+
+static id_t
+parse_id(char *id)
+{
+ static bool first = true;
+ long value;
+ char *ch;
+
+ if (!first) {
+ warnx("only one -g or -p flag is permitted");
+ usage();
+ }
+ value = strtol(id, &ch, 0);
+ if (*ch != '\0') {
+ warnx("invalid process id");
+ usage();
+ }
+ return (value);
+}
+
+int
+main(int argc, char *argv[])
+{
+ idtype_t idtype;
+ id_t id;
+ int ch, flags;
+ bool descend, inherit, idset;
+
+ idtype = P_PID;
+ id = getpid();
+ flags = PPROT_SET;
+ descend = inherit = idset = false;
+ while ((ch = getopt(argc, argv, "cdig:p:")) != -1)
+ switch (ch) {
+ case 'c':
+ flags = PPROT_CLEAR;
+ break;
+ case 'd':
+ descend = true;
+ break;
+ case 'i':
+ inherit = true;
+ break;
+ case 'g':
+ idtype = P_PGID;
+ id = parse_id(optarg);
+ idset = true;
+ break;
+ case 'p':
+ idtype = P_PID;
+ id = parse_id(optarg);
+ idset = true;
+ break;
+ }
+ argc -= optind;
+ argv += optind;
+
+ if ((idset && argc != 0) || (!idset && (argc == 0 || descend)))
+ usage();
+
+ if (descend)
+ flags |= PPROT_DESCEND;
+ if (inherit)
+ flags |= PPROT_INHERIT;
+ if (procctl(idtype, id, PROC_SPROTECT, &flags) == -1)
+ err(1, "procctl");
+
+ if (argc != 0) {
+ errno = 0;
+ execvp(*argv, argv);
+ err(errno == ENOENT ? 127 : 126, "%s", *argv);
+ }
+ return (0);
+}
diff --git a/usr.bin/svn/lib/libapr/apr.h b/usr.bin/svn/lib/libapr/apr.h
index 0ce5d85200dd..37e7f83d3665 100644
--- a/usr.bin/svn/lib/libapr/apr.h
+++ b/usr.bin/svn/lib/libapr/apr.h
@@ -373,7 +373,13 @@ typedef apr_uint32_t apr_uintptr_t;
#endif
/* Are we big endian? */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
#define APR_IS_BIGENDIAN 0
+#elif _BYTE_ORDER == _BIG_ENDIAN
+#define APR_IS_BIGENDIAN 1
+#else
+#error Unknown byte order.
+#endif
/* Mechanisms to properly type numeric literals */
#define APR_INT64_C(val) INT64_C(val)
diff --git a/usr.bin/svn/lib/libapr/apr_private.h b/usr.bin/svn/lib/libapr/apr_private.h
index fcbbbd30cb2b..492a4f1df0cc 100644
--- a/usr.bin/svn/lib/libapr/apr_private.h
+++ b/usr.bin/svn/lib/libapr/apr_private.h
@@ -97,7 +97,9 @@
#define HAVE_ARPA_INET_H 1
/* Define if compiler provides atomic builtins */
+#if !defined(__mips__) && !defined(__arm__)
#define HAVE_ATOMIC_BUILTINS 1
+#endif
/* Define if BONE_VERSION is defined in sys/socket.h */
/* #undef HAVE_BONE_VERSION */
diff --git a/usr.bin/svn/svn_private_config.h b/usr.bin/svn/svn_private_config.h
index 00eb0fc5d5e7..061109534b70 100644
--- a/usr.bin/svn/svn_private_config.h
+++ b/usr.bin/svn/svn_private_config.h
@@ -153,7 +153,7 @@
#define SVN_FS_WANT_DB_PATCH 14
/* Define if compiler provides atomic builtins */
-#define SVN_HAS_ATOMIC_BUILTINS 1
+#define SVN_HAS_ATOMIC_BUILTINS 0
/* Is GNOME Keyring support enabled? */
/* #undef SVN_HAVE_GNOME_KEYRING */
diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h
index 94776a0dddb9..b0d3461adbcc 100644
--- a/usr.bin/truss/syscall.h
+++ b/usr.bin/truss/syscall.h
@@ -40,7 +40,7 @@ enum Argtype { None = 1, Hex, Octal, Int, Name, Ptr, Stat, Ioctl, Quad,
Fd_set, Sigaction, Fcntl, Mprot, Mmapflags, Whence, Readlinkres,
Umtx, Sigset, Sigprocmask, Kevent, Sockdomain, Socktype, Open,
Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2,
- Pathconf, Rforkflags };
+ Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl };
#define ARG_MASK 0xff
#define OUT 0x100
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index 99a377f75f0e..06c25117ab6b 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -39,12 +39,14 @@ static const char rcsid[] =
* arguments.
*/
-#include <sys/mman.h>
#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/procctl.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
+#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioccom.h>
@@ -263,6 +265,14 @@ static struct syscall syscalls[] = {
.args = { { Name , 0 } , { Name, 1 } } },
{ .name = "posix_openpt", .ret_type = 1, .nargs = 1,
.args = { { Open, 0 } } },
+ { .name = "wait4", .ret_type = 1, .nargs = 4,
+ .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 },
+ { Rusage | OUT, 3 } } },
+ { .name = "wait6", .ret_type = 1, .nargs = 6,
+ .args = { { Idtype, 0 }, { Int, 1 }, { ExitStatus | OUT, 2 },
+ { Waitoptions, 3 }, { Rusage | OUT, 4 }, { Ptr, 5 } } },
+ { .name = "procctl", .ret_type = 1, .nargs = 4,
+ .args = { { Idtype, 0 }, { Int, 1 }, { Procctl, 2 }, { Ptr, 3 } } },
{ .name = 0 },
};
@@ -381,6 +391,21 @@ static struct xlat rfork_flags[] = {
X(RFSIGSHARE) X(RFTSIGZMB) X(RFLINUXTHPN) XEND
};
+static struct xlat wait_options[] = {
+ X(WNOHANG) X(WUNTRACED) X(WCONTINUED) X(WNOWAIT) X(WEXITED)
+ X(WTRAPPED) XEND
+};
+
+static struct xlat idtype_arg[] = {
+ X(P_PID) X(P_PPID) X(P_PGID) X(P_SID) X(P_CID) X(P_UID) X(P_GID)
+ X(P_ALL) X(P_LWPID) X(P_TASKID) X(P_PROJID) X(P_POOLID) X(P_JAILID)
+ X(P_CTID) X(P_CPUID) X(P_PSETID) XEND
+};
+
+static struct xlat procctl_arg[] = {
+ X(PROC_SPROTECT) XEND
+};
+
#undef X
#undef XEND
@@ -537,6 +562,16 @@ get_string(pid_t pid, void *offset, int max)
}
}
+static char *
+strsig2(int sig)
+{
+ char *tmp;
+
+ tmp = strsig(sig);
+ if (tmp == NULL)
+ asprintf(&tmp, "%d", sig);
+ return (tmp);
+}
/*
* print_arg
@@ -822,19 +857,14 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval,
free(fds);
break;
}
- case Signal: {
- long sig;
-
- sig = args[sc->offset];
- tmp = strsig(sig);
- if (tmp == NULL)
- asprintf(&tmp, "%ld", sig);
+ case Signal:
+ tmp = strsig2(args[sc->offset]);
break;
- }
case Sigset: {
long sig;
sigset_t ss;
int i, used;
+ char *signame;
sig = args[sc->offset];
if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
@@ -845,8 +875,11 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval,
tmp = malloc(sys_nsig * 8); /* 7 bytes avg per signal name */
used = 0;
for (i = 1; i < sys_nsig; i++) {
- if (sigismember(&ss, i))
- used += sprintf(tmp + used, "%s|", strsig(i));
+ if (sigismember(&ss, i)) {
+ signame = strsig(i);
+ used += sprintf(tmp + used, "%s|", signame);
+ free(signame);
+ }
}
if (used)
tmp[used-1] = 0;
@@ -1143,6 +1176,38 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval,
asprintf(&tmp, "0x%lx", args[sc->offset]);
break;
}
+ case ExitStatus: {
+ char *signame;
+ int status;
+ signame = NULL;
+ if (get_struct(pid, (void *)args[sc->offset], &status,
+ sizeof(status)) != -1) {
+ if (WIFCONTINUED(status))
+ tmp = strdup("{ CONTINUED }");
+ else if (WIFEXITED(status))
+ asprintf(&tmp, "{ EXITED,val=%d }",
+ WEXITSTATUS(status));
+ else if (WIFSIGNALED(status))
+ asprintf(&tmp, "{ SIGNALED,sig=%s%s }",
+ signame = strsig2(WTERMSIG(status)),
+ WCOREDUMP(status) ? ",cored" : "");
+ else
+ asprintf(&tmp, "{ STOPPED,sig=%s }",
+ signame = strsig2(WTERMSIG(status)));
+ } else
+ asprintf(&tmp, "0x%lx", args[sc->offset]);
+ free(signame);
+ break;
+ }
+ case Waitoptions:
+ tmp = strdup(xlookup_bits(wait_options, args[sc->offset]));
+ break;
+ case Idtype:
+ tmp = strdup(xlookup(idtype_arg, args[sc->offset]));
+ break;
+ case Procctl:
+ tmp = strdup(xlookup(procctl_arg, args[sc->offset]));
+ break;
default:
errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
}