diff options
author | sjg <sjg@FreeBSD.org> | 2013-10-13 02:35:19 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2013-10-13 02:35:19 +0000 |
commit | 7fcd33c1faf567506b5c0b4148c7a15a10788a5d (patch) | |
tree | 2c6f4d1ca5d1c643faea64e1f4c90105a1ab406a /usr.bin | |
parent | 2a59274eda20cc626e28052fff7aa8b7bf6a3683 (diff) | |
parent | 5cca672bb0892f1c5da630c34a1f98e2de4d7064 (diff) | |
download | FreeBSD-src-7fcd33c1faf567506b5c0b4148c7a15a10788a5d.zip FreeBSD-src-7fcd33c1faf567506b5c0b4148c7a15a10788a5d.tar.gz |
Merge head@256284
Diffstat (limited to 'usr.bin')
39 files changed, 2521 insertions, 312 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 09fb97c..92958ae 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 c7bd544..66403fe 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 0000000..6e3b339 --- /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 6531bba..374fbef 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 87e705c..0138fd2 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 edabe10..13a456b 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 6cf0346..4222d7b 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 2ea0865..0f34882 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 a46913c..e5507a1 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 db5fae7..a61a418 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 0000000..6869b8d --- /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 b76a0ca..0000000 --- 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 3740d82..0000000 --- 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 0000000..a963bfc --- /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 25dfd2d..5962454 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 0000000..9331ca5 --- /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 0000000..03525df --- /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 0000000..1088d69 --- /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 0000000..e8d4768 --- /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 0000000..b44fc3b --- /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 0000000..78b237f --- /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 0000000..f6c03ae --- /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 0de183c..24bb0fd 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 2a16e37..1859086 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 4ed0e92..0000000 --- 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 82922d8..0000000 --- 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 593d589..0000000 --- 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 82922d8..0000000 --- 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 956482c..1743678 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 c19918b..6980676 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 faa296c..d7b7d3f 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 0000000..89bbda8 --- /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 0000000..919714e --- /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 0000000..ba15aa6 --- /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 0ce5d85..37e7f83 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 fcbbbd3..492a4f1 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 00eb0fc..0611095 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 94776a0..b0d3461 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 99a377f..06c2511 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); } |