From: Thomas Veerman Date: Wed, 6 Jun 2012 12:01:38 +0000 (+0000) Subject: Add mk and h files needed for cross compilation X-Git-Tag: v3.2.1~506 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/pkcs11-destroy.html?a=commitdiff_plain;h=be9962e21f8caa80da026aade2f1991be986d0ed;p=minix.git Add mk and h files needed for cross compilation --- diff --git a/share/mk/bsd.clean.mk b/share/mk/bsd.clean.mk new file mode 100644 index 000000000..32fba13b1 --- /dev/null +++ b/share/mk/bsd.clean.mk @@ -0,0 +1,83 @@ +# $NetBSD: bsd.clean.mk,v 1.5 2011/11/22 18:25:48 apb Exp $ + +# +# +# Public targets: +# +# clean: Delete files listed in ${CLEANFILES}. +# cleandir: Delete files listed in ${CLEANFILES} and ${CLEANDIRFILES}. +# +# Public variables: +# +# CLEANFILES Files to remove for both the clean and cleandir targets. +# +# CLEANDIRFILES Files to remove for the cleandir target, but not for +# the clean target. +# +# MKCLEANSRC Whether or not to clean the source directory +# in addition to the object directory. +# +# MKCLEANVERIFY Whether or not to verify that the file deletion worked. +# + +.if !defined(_BSD_CLEAN_MK_) +_BSD_CLEAN_MK_=1 + +.include + +MKCLEANSRC?= yes +MKCLEANVERIFY?= yes + +clean: .PHONY __doclean +__doclean: .PHONY .MADE __cleanuse CLEANFILES +cleandir: .PHONY clean __docleandir +__docleandir: .PHONY .MADE __cleanuse CLEANDIRFILES + +# __cleanuse is invoked with ${.ALLSRC} as the name of a variable +# (such as CLEANFILES or CLEANDIRFILES), or possibly a list of +# variable names. ${.ALLSRC:@v@${${v}}@} will be the list of +# files to delete. (We pass the variable name, e.g. CLEANFILES, +# instead of the file names, e.g. ${CLEANFILES}, because we don't +# want make to replace any of the file names with the result of +# searching .PATH.) +# +# If the list of files is empty, then the commands +# reduce to "true", with an "@" prefix to prevent echoing. +# +# The use of :M* is needed to handle the case that CLEANFILES +# or CLEANDIRFILES is not completely empty but contains spaces. +# This can easily happen when CLEANFILES or CLEANDIRFILES is set +# from other variables that happen to be empty.) +# +# The use of :Q is needed to handle the case that CLEANFILES +# or CLEANDIRFILES contains quoted strings, such as +# CLEANFILES = "filename with spaces". +# +__cleanuse: .USE +.if 0 # print "# clean CLEANFILES" for debugging + ${"${.ALLSRC:@v@${${v}:M*}@:Q}" == "":?@true:${_MKMSG} \ + "clean" ${.ALLSRC} } +.endif +.for _d in ${"${.OBJDIR}" == "${.CURDIR}" || "${MKCLEANSRC}" == "no" \ + :? ${.OBJDIR} \ + : ${.OBJDIR} ${.CURDIR} } + ${"${.ALLSRC:@v@${${v}:M*}@:Q}" == "":?@true: \ + (cd ${_d} && rm -f ${.ALLSRC:@v@${${v}}@} || true) } +.if "${MKCLEANVERIFY}" == "yes" + @${"${.ALLSRC:@v@${${v}:M*}@:Q}" == "":?true: \ + bad="\$(cd ${_d} && ls -d ${.ALLSRC:@v@${${v}}@} 2>/dev/null)"; \ + if test -n "\$bad"; then \ + echo "Failed to remove files from ${_d}:" ; \ + echo "\$bad" ; \ + false ; \ + fi } +.endif +.endfor + +# Don't automatically load ".depend" files during "make clean" +# or "make cleandir". +.if make(clean) || make(cleandir) +.MAKE.DEPENDFILE := .depend.no-such-file +.endif + +.endif # !defined(_BSD_CLEAN_MK) diff --git a/share/mk/bsd.hostlib.mk b/share/mk/bsd.hostlib.mk new file mode 100644 index 000000000..f757e7b9c --- /dev/null +++ b/share/mk/bsd.hostlib.mk @@ -0,0 +1,57 @@ +# $NetBSD: bsd.hostlib.mk,v 1.16 2011/09/10 16:57:35 apb Exp $ + +.include +.include + +##### Basic targets + +##### Default values +CFLAGS+= ${COPTS} +HOST_MKDEP?= CC=${HOST_CC:Q} mkdep +MKDEP_SUFFIXES?= .o .lo + +# Override these: +MKDEP:= ${HOST_MKDEP} + +.if ${TOOLCHAIN_MISSING} == "no" || defined(EXTERNAL_TOOLCHAIN) +OBJHOSTMACHINE= # set +.endif + +##### Build rules +.if defined(HOSTLIB) +_YHLSRCS= ${SRCS:M*.[ly]:C/\..$/.c/} ${YHEADER:D${SRCS:M*.y:.y=.h}} +DPSRCS+= ${_YHLSRCS} +CLEANFILES+= ${_YHLSRCS} +.endif # defined(HOSTLIB) + +.if !empty(SRCS:N*.h:N*.sh) +OBJS+= ${SRCS:N*.h:N*.sh:R:S/$/.lo/g} +.endif + +.if defined(OBJS) && !empty(OBJS) +.NOPATH: lib${HOSTLIB}.a ${OBJS} ${_YHLSRCS} + +${OBJS}: ${DPSRCS} + +lib${HOSTLIB}.a: ${OBJS} ${DPADD} + ${_MKTARGET_BUILD} + rm -f ${.TARGET} + ${HOST_AR} cq ${.TARGET} ${OBJS} + ${HOST_RANLIB} ${.TARGET} + +.endif # defined(OBJS) && !empty(OBJS) + +realall: lib${HOSTLIB}.a + +CLEANFILES+= a.out [Ee]rrs mklog core *.core lib${HOSTLIB}.a ${OBJS} + +beforedepend: +CFLAGS:= ${HOST_CFLAGS} +CPPFLAGS:= ${HOST_CPPFLAGS} + +##### Pull in related .mk logic +.include +.include +.include + +${TARGETS}: # ensure existence diff --git a/share/mk/bsd.hostprog.mk b/share/mk/bsd.hostprog.mk new file mode 100644 index 000000000..969387bc4 --- /dev/null +++ b/share/mk/bsd.hostprog.mk @@ -0,0 +1,165 @@ +# $NetBSD: bsd.hostprog.mk,v 1.67 2012/02/29 20:07:57 tron Exp $ +# @(#)bsd.prog.mk 8.2 (Berkeley) 4/2/94 + +.include +.include + +##### Basic targets + +##### Default values +LIBATF_C?= /usr/lib/libatf-c.a +LIBATF_CXX?= /usr/lib/libatf-c++.a +LIBBLUETOOTH?= /usr/lib/libbluetooth.a +LIBBZ2?= /usr/lib/libbz2.a +LIBC?= /usr/lib/libc.a +LIBC_PIC?= /usr/lib/libc_pic.a +LIBC_SO?= /usr/lib/libc.so +LIBCOMPAT?= /usr/lib/libcompat.a +LIBCRYPT?= /usr/lib/libcrypt.a +LIBCURSES?= /usr/lib/libcurses.a +LIBDBM?= /usr/lib/libdbm.a +LIBDES?= /usr/lib/libdes.a +LIBEDIT?= /usr/lib/libedit.a +LIBEVENT?= /usr/lib/libevent.a +LIBEXPAT?= /usr/lib/libexpat.a +LIBFETCH?= /usr/lib/libfetch.a +LIBFORM?= /usr/lib/libform.a +LIBGCC?= /usr/lib/libgcc.a +LIBGNUMALLOC?= /usr/lib/libgnumalloc.a +LIBINTL?= /usr/lib/libintl.a +LIBIPSEC?= /usr/lib/libipsec.a +LIBKVM?= /usr/lib/libkvm.a +LIBL?= /usr/lib/libl.a +LIBLZMA?= /usr/lib/liblzma.a +LIBM?= /usr/lib/libm.a +LIBMAGIC?= /usr/lib/libmagic.a +LIBMENU?= /usr/lib/libmenu.a +LIBMP?= /usr/lib/libmp.a +LIBNTP?= /usr/lib/libntp.a +LIBOBJC?= /usr/lib/libobjc.a +LIBP2K?= /usr/lib/libp2k.a +LIBPC?= /usr/lib/libpc.a +LIBPCAP?= /usr/lib/libpcap.a +LIBPCI?= /usr/lib/libpci.a +LIBPLOT?= /usr/lib/libplot.a +LIBPOSIX?= /usr/lib/libposix.a +LIBPUFFS?= /usr/lib/libpuffs.a +LIBQUOTA?= /usr/lib/libquota.a +LIBRESOLV?= /usr/lib/libresolv.a +LIBRPCSVC?= /usr/lib/librpcsvc.a +LIBRUMP?= /usr/lib/librump.a +LIBRUMPCLIENT?= /usr/lib/librumpclient.a +LIBRUMPNET?= /usr/lib/librumpnet.a +LIBRUMPUSER?= /usr/lib/librumpuser.a +LIBRUMPVFS?= /usr/lib/librumpvfs.a +LIBSKEY?= /usr/lib/libskey.a +LIBSQLITE3?= /usr/lib/libsqlite3.a +LIBSSP?= /usr/lib/libssp.a +LIBSTDCXX?= /usr/lib/libstdc++.a +LIBSUPCXX?= /usr/lib/libsupc++.a +LIBTERMINFO?= /usr/lib/libterminfo.a +LIBUTIL?= /usr/lib/libutil.a +LIBWRAP?= /usr/lib/libwrap.a +LIBUKFS?= /usr/lib/libukfs.a +LIBY?= /usr/lib/liby.a +LIBZ?= /usr/lib/libz.a + +##### rump file system modules +LIBRUMPFS_CD9660FS?= /usr/lib/librumpfs_cd9660fs.a +LIBRUMPFS_EFS?= /usr/lib/librumpfs_efs.a +LIBRUMPFS_EXT2FS?= /usr/lib/librumpfs_ext2fs.a +LIBRUMPFS_FFS?= /usr/lib/librumpfs_ffs.a +LIBRUMPFS_HFS?= /usr/lib/librumpfs_hfs.a +LIBRUMPFS_LFS?= /usr/lib/librumpfs_lfs.a +LIBRUMPFS_MSDOSFS?= /usr/lib/librumpfs_msdosfs.a +LIBRUMPFS_NTFS?= /usr/lib/librumpfs_ntfs.a +LIBRUMPFS_SYSPUFFS?= /usr/lib/librumpfs_syspuffs.a +LIBRUMPFS_TMPFS?= /usr/lib/librumpfs_tmpfs.a +LIBRUMPFS_UDF?= /usr/lib/librumpfs_udf.a +LIBRUMPFS_UFS?= /usr/lib/librumpfs_ufs.a + +HOST_MKDEP?= CC=${HOST_CC:Q} mkdep +MKDEP_SUFFIXES?= .lo .ln + +# Override these: +INSTALL:= ${INSTALL:NSTRIP=*} +MKDEP:= ${HOST_MKDEP} + +.if ${TOOLCHAIN_MISSING} == "no" || defined(EXTERNAL_TOOLCHAIN) +OBJHOSTMACHINE= # set +.endif + +##### Build rules +.if defined(HOSTPROG_CXX) +HOSTPROG= ${HOSTPROG_CXX} +.endif + +.if defined(HOSTPROG) +SRCS?= ${HOSTPROG}.c + +_YHPSRCS= ${SRCS:M*.[ly]:C/\..$/.c/} ${YHEADER:D${SRCS:M*.y:.y=.h}} +DPSRCS+= ${_YHPSRCS} +CLEANFILES+= ${_YHPSRCS} + +.if !empty(SRCS:N*.h:N*.sh) +OBJS+= ${SRCS:N*.h:N*.sh:R:S/$/.lo/g} +LOBJS+= ${LSRCS:.c=.ln} ${SRCS:M*.c:.c=.ln} +.endif + +.if defined(OBJS) && !empty(OBJS) +.NOPATH: ${OBJS} ${HOSTPROG} ${_YHPSRCS} + +${OBJS} ${LOBJS}: ${DPSRCS} +${HOSTPROG}: ${OBJS} ${DPADD} + ${_MKTARGET_LINK} + ${HOST_LINK.c} ${HOST_LDSTATIC} -o ${.TARGET} ${OBJS} ${LDADD} + +.endif # defined(OBJS) && !empty(OBJS) + +.if !defined(MAN) +MAN= ${HOSTPROG}.1 +.endif # !defined(MAN) +.endif # defined(HOSTPROG) + +realall: ${HOSTPROG} + +CLEANFILES+= a.out [Ee]rrs mklog core *.core ${HOSTPROG} ${OBJS} ${LOBJS} + +beforedepend: +CFLAGS:= ${HOST_CFLAGS} +CPPFLAGS:= ${HOST_CPPFLAGS:N-Wp,-iremap,*} + +lint: ${LOBJS} +.if defined(LOBJS) && !empty(LOBJS) + ${LINT} ${LINTFLAGS} ${LDFLAGS:C/-L[ ]*/-L/Wg:M-L*} ${LOBJS} ${LDADD} +.endif + +##### Pull in related .mk logic +LINKSMODE?= ${BINMODE} +.include +.include +.include +.include +.include +.include +.include + +${TARGETS}: # ensure existence + +# Override YACC/LEX rules so nbtool_config.h can be forced as the 1st include +.l.c: + ${_MKTARGET_LEX} + ${LEX.l} -o${.TARGET} ${.IMPSRC} + echo '#if HAVE_NBTOOL_CONFIG_H' > ${.TARGET}.1 + echo '#include "nbtool_config.h"' >> ${.TARGET}.1 + echo '#endif' >> ${.TARGET}.1 + cat ${.TARGET} >> ${.TARGET}.1 + mv ${.TARGET}.1 ${.TARGET} +.y.c: + ${_MKTARGET_YACC} + ${YACC.y} -o ${.TARGET} ${.IMPSRC} + echo '#if HAVE_NBTOOL_CONFIG_H' > ${.TARGET}.1 + echo '#include "nbtool_config.h"' >> ${.TARGET}.1 + echo '#endif' >> ${.TARGET}.1 + cat ${.TARGET} >> ${.TARGET}.1 + mv ${.TARGET}.1 ${.TARGET} diff --git a/share/mk/bsd.kernobj.mk b/share/mk/bsd.kernobj.mk new file mode 100644 index 000000000..5d4184d62 --- /dev/null +++ b/share/mk/bsd.kernobj.mk @@ -0,0 +1,26 @@ +# $NetBSD: bsd.kernobj.mk,v 1.13 2010/01/25 00:43:00 christos Exp $ + +# KERNSRCDIR Is the location of the top of the kernel src. +# It defaults to `${NETBSDSRCDIR}/sys'. +# +# KERNARCHDIR Is the location of the machine dependent kernel sources. +# It defaults to `arch/${MACHINE}', but may be overridden +# in case ${MACHINE} is not correct. +# +# KERNCONFDIR Is where the configuration files for kernels are found. +# It defaults to `${KERNSRCDIR}/${KERNARCHDIR}/conf'. +# +# KERNOBJDIR Is the kernel build directory. The kernel GENERIC for +# instance will be compiled in ${KERNOBJDIR}/GENERIC. +# The default is the .OBJDIR of +# `${KERNSRCDIR}/${KERNARCHDIR}/compile'. +# + +.include + +KERNSRCDIR?= ${NETBSDSRCDIR}/sys +KERNARCHDIR?= arch/${MACHINE} +KERNCONFDIR?= ${KERNSRCDIR}/${KERNARCHDIR}/conf +.if !defined(KERNOBJDIR) && exists(${KERNSRCDIR}/${KERNARCHDIR}/compile) +KERNOBJDIR!= cd "${KERNSRCDIR}/${KERNARCHDIR}/compile" && ${PRINTOBJDIR} +.endif diff --git a/share/mk/bsd.nls.mk b/share/mk/bsd.nls.mk new file mode 100644 index 000000000..0fefdbe32 --- /dev/null +++ b/share/mk/bsd.nls.mk @@ -0,0 +1,71 @@ +# $NetBSD: bsd.nls.mk,v 1.47 2011/09/10 16:57:35 apb Exp $ + +.include + +##### Basic targets +realinstall: nlsinstall + +##### Default values +NLSNAME?= ${PROG:Ulib${LIB}} + +NLS?= + +##### Build rules +.if ${MKNLS} != "no" + +NLSALL= ${NLS:.msg=.cat} + +realall: ${NLSALL} +.NOPATH: ${NLSALL} + +.SUFFIXES: .cat .msg + +.msg.cat: + @rm -f ${.TARGET} + ${_MKTARGET_CREATE} + ${TOOL_GENCAT} ${.TARGET} ${.IMPSRC} + +.endif # ${MKNLS} != "no" + +##### Install rules +nlsinstall:: # ensure existence +.PHONY: nlsinstall + +.if ${MKNLS} != "no" + +__nlsinstall: .USE + ${_MKTARGET_INSTALL} + ${INSTALL_FILE} -o ${NLSOWN} -g ${NLSGRP} -m ${NLSMODE} \ + ${.ALLSRC} ${.TARGET} + +.for F in ${NLSALL:O:u} +_F:= ${DESTDIR}${NLSDIR}/${F:T:R}/${NLSNAME}.cat # installed path + +.if ${MKUPDATE} == "no" +${_F}! ${F} __nlsinstall # install rule +.if !defined(BUILD) && !make(all) && !make(${F}) +${_F}! .MADE # no build at install +.endif +.else +${_F}: ${F} __nlsinstall # install rule +.if !defined(BUILD) && !make(all) && !make(${F}) +${_F}: .MADE # no build at install +.endif +.endif + +nlsinstall:: ${_F} +.PRECIOUS: ${_F} # keep if install fails +.endfor + +.undef _F +.endif # ${MKNLS} != "no" + +##### Clean rules +.if ${MKNLS} != "no" && !empty(NLS) +CLEANDIRFILES+= ${NLSALL} +.endif + +##### Pull in related .mk logic +.include +.include +.include diff --git a/sys/sys/md4.h b/sys/sys/md4.h new file mode 100644 index 000000000..62789efee --- /dev/null +++ b/sys/sys/md4.h @@ -0,0 +1,58 @@ +/* $NetBSD: md4.h,v 1.7 2005/12/26 18:41:36 perry Exp $ */ + +/* + * This file is derived from the RSA Data Security, Inc. MD4 Message-Digest + * Algorithm and has been modified by Jason R. Thorpe + * for portability and formatting. + */ + +/* + * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + * rights reserved. + * + * License to copy and use this software is granted provided that it + * is identified as the "RSA Data Security, Inc. MD4 Message-Digest + * Algorithm" in all material mentioning or referencing this software + * or this function. + * + * License is also granted to make and use derivative works provided + * that such works are identified as "derived from the RSA Data + * Security, Inc. MD4 Message-Digest Algorithm" in all material + * mentioning or referencing the derived work. + * + * RSA Data Security, Inc. makes no representations concerning either + * the merchantability of this software or the suitability of this + * software for any particular purpose. It is provided "as is" + * without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this + * documentation and/or software. + */ + +#ifndef _SYS_MD4_H_ +#define _SYS_MD4_H_ + +#include +#include + +#define MD4_DIGEST_LENGTH 16 + +/* MD4 context. */ +typedef struct MD4Context { + uint32_t state[4]; /* state (ABCD) */ + uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD4_CTX; + +__BEGIN_DECLS +void MD4Init(MD4_CTX *); +void MD4Update(MD4_CTX *, const unsigned char *, unsigned int); +void MD4Final(unsigned char[MD4_DIGEST_LENGTH], MD4_CTX *); +#ifndef _KERNEL +char *MD4End(MD4_CTX *, char *); +char *MD4File(const char *, char *); +char *MD4Data(const unsigned char *, unsigned int, char *); +#endif /* _KERNEL */ +__END_DECLS + +#endif /* _SYS_MD4_H_ */ diff --git a/sys/sys/md5.h b/sys/sys/md5.h new file mode 100644 index 000000000..d2715ec74 --- /dev/null +++ b/sys/sys/md5.h @@ -0,0 +1,58 @@ +/* $NetBSD: md5.h,v 1.9 2005/12/26 18:41:36 perry Exp $ */ + +/* + * This file is derived from the RSA Data Security, Inc. MD5 Message-Digest + * Algorithm and has been modified by Jason R. Thorpe + * for portability and formatting. + */ + +/* + * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + * rights reserved. + * + * License to copy and use this software is granted provided that it + * is identified as the "RSA Data Security, Inc. MD5 Message-Digest + * Algorithm" in all material mentioning or referencing this software + * or this function. + * + * License is also granted to make and use derivative works provided + * that such works are identified as "derived from the RSA Data + * Security, Inc. MD5 Message-Digest Algorithm" in all material + * mentioning or referencing the derived work. + * + * RSA Data Security, Inc. makes no representations concerning either + * the merchantability of this software or the suitability of this + * software for any particular purpose. It is provided "as is" + * without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this + * documentation and/or software. + */ + +#ifndef _SYS_MD5_H_ +#define _SYS_MD5_H_ + +#include + +#define MD5_DIGEST_LENGTH 16 +#define MD5_DIGEST_STRING_LENGTH 33 + +/* MD5 context. */ +typedef struct MD5Context { + uint32_t state[4]; /* state (ABCD) */ + uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +__BEGIN_DECLS +void MD5Init(MD5_CTX *); +void MD5Update(MD5_CTX *, const unsigned char *, unsigned int); +void MD5Final(unsigned char[MD5_DIGEST_LENGTH], MD5_CTX *); +#ifndef _KERNEL +char *MD5End(MD5_CTX *, char *); +char *MD5File(const char *, char *); +char *MD5Data(const unsigned char *, unsigned int, char *); +#endif /* _KERNEL */ +__END_DECLS + +#endif /* _SYS_MD5_H_ */ diff --git a/sys/sys/null.h b/sys/sys/null.h new file mode 100644 index 000000000..a69dde306 --- /dev/null +++ b/sys/sys/null.h @@ -0,0 +1,21 @@ +/* $NetBSD: null.h,v 1.9 2010/07/06 11:56:20 kleink Exp $ */ + +/* + * Written by Klaus Klein , December 22, 1999. + * Public domain. + */ + +#ifndef _SYS_NULL_H_ +#define _SYS_NULL_H_ +#ifndef NULL +#if !defined(__GNUG__) || __GNUG__ < 2 || (__GNUG__ == 2 && __GNUC_MINOR__ < 90) +#if !defined(__cplusplus) +#define NULL ((void *)0) +#else +#define NULL 0 +#endif /* !__cplusplus */ +#else +#define NULL __null +#endif +#endif +#endif /* _SYS_NULL_H_ */ diff --git a/sys/sys/queue.h b/sys/sys/queue.h new file mode 100644 index 000000000..368830b4e --- /dev/null +++ b/sys/sys/queue.h @@ -0,0 +1,743 @@ +/* $NetBSD: queue.h,v 1.53 2011/11/19 22:51:31 tls Exp $ */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +#include + +/* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues, and circular queues. + * + * A singly-linked list is headed by a single forward pointer. The + * elements are singly linked for minimum space and pointer manipulation + * overhead at the expense of O(n) removal for arbitrary elements. New + * elements can be added to the list after an existing element or at the + * head of the list. Elements being removed from the head of the list + * should use the explicit macro for this purpose for optimum + * efficiency. A singly-linked list may only be traversed in the forward + * direction. Singly-linked lists are ideal for applications with large + * datasets and few or no removals or for implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ +#if defined(_KERNEL) && defined(QUEUEDEBUG) +#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) \ + if ((head)->lh_first && \ + (head)->lh_first->field.le_prev != &(head)->lh_first) \ + panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__); +#define QUEUEDEBUG_LIST_OP(elm, field) \ + if ((elm)->field.le_next && \ + (elm)->field.le_next->field.le_prev != \ + &(elm)->field.le_next) \ + panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\ + if (*(elm)->field.le_prev != (elm)) \ + panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__); +#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) \ + (elm)->field.le_next = (void *)1L; \ + (elm)->field.le_prev = (void *)1L; +#else +#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field) +#define QUEUEDEBUG_LIST_OP(elm, field) +#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field) +#endif + +#define LIST_INIT(head) do { \ + (head)->lh_first = NULL; \ +} while (/*CONSTCOND*/0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + QUEUEDEBUG_LIST_OP((listelm), field) \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (/*CONSTCOND*/0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + QUEUEDEBUG_LIST_OP((listelm), field) \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (/*CONSTCOND*/0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field) \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (/*CONSTCOND*/0) + +#define LIST_REMOVE(elm, field) do { \ + QUEUEDEBUG_LIST_OP((elm), field) \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ + QUEUEDEBUG_LIST_POSTREMOVE((elm), field) \ +} while (/*CONSTCOND*/0) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = ((head)->lh_first); \ + (var); \ + (var) = ((var)->field.le_next)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) +/* + * List access methods. + */ +#define LIST_EMPTY(head) ((head)->lh_first == NULL) +#define LIST_FIRST(head) ((head)->lh_first) +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_INIT(head) do { \ + (head)->slh_first = NULL; \ +} while (/*CONSTCOND*/0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (/*CONSTCOND*/0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (/*CONSTCOND*/0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (/*CONSTCOND*/0) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if ((head)->slh_first == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = (head)->slh_first; \ + while(curelm->field.sle_next != (elm)) \ + curelm = curelm->field.sle_next; \ + curelm->field.sle_next = \ + curelm->field.sle_next->field.sle_next; \ + } \ +} while (/*CONSTCOND*/0) + +#define SLIST_REMOVE_AFTER(slistelm, field) do { \ + (slistelm)->field.sle_next = \ + SLIST_NEXT(SLIST_NEXT((slistelm), field), field); \ +} while (/*CONSTCOND*/0) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +/* + * Singly-linked List access methods. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first; /* first element */ \ + struct type **stqh_last; /* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_INIT(head) do { \ + (head)->stqh_first = NULL; \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (/*CONSTCOND*/0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (head)->stqh_first = (elm); \ +} while (/*CONSTCOND*/0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &(elm)->field.stqe_next; \ +} while (/*CONSTCOND*/0) + +#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (listelm)->field.stqe_next = (elm); \ +} while (/*CONSTCOND*/0) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (/*CONSTCOND*/0) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if ((head)->stqh_first == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } else { \ + struct type *curelm = (head)->stqh_first; \ + while (curelm->field.stqe_next != (elm)) \ + curelm = curelm->field.stqe_next; \ + if ((curelm->field.stqe_next = \ + curelm->field.stqe_next->field.stqe_next) == NULL) \ + (head)->stqh_last = &(curelm)->field.stqe_next; \ + } \ +} while (/*CONSTCOND*/0) + +#define STAILQ_FOREACH(var, head, field) \ + for ((var) = ((head)->stqh_first); \ + (var); \ + (var) = ((var)->field.stqe_next)) + +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (/*CONSTCOND*/0) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *)(void *) \ + ((char *)((head)->stqh_last) - offsetof(struct type, field)))) + +/* + * Singly-linked Tail queue access methods. + */ +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) +#define STAILQ_FIRST(head) ((head)->stqh_first) +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + + +/* + * Simple queue definitions. + */ +#define SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define SIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue functions. + */ +#define SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_REMOVE(head, elm, type, field) do { \ + if ((head)->sqh_first == (elm)) { \ + SIMPLEQ_REMOVE_HEAD((head), field); \ + } else { \ + struct type *curelm = (head)->sqh_first; \ + while (curelm->field.sqe_next != (elm)) \ + curelm = curelm->field.sqe_next; \ + if ((curelm->field.sqe_next = \ + curelm->field.sqe_next->field.sqe_next) == NULL) \ + (head)->sqh_last = &(curelm)->field.sqe_next; \ + } \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_FOREACH(var, head, field) \ + for ((var) = ((head)->sqh_first); \ + (var); \ + (var) = ((var)->field.sqe_next)) + +#define SIMPLEQ_FOREACH_SAFE(var, head, field, next) \ + for ((var) = ((head)->sqh_first); \ + (var) && ((next = ((var)->field.sqe_next)), 1); \ + (var) = (next)) + +#define SIMPLEQ_CONCAT(head1, head2) do { \ + if (!SIMPLEQ_EMPTY((head2))) { \ + *(head1)->sqh_last = (head2)->sqh_first; \ + (head1)->sqh_last = (head2)->sqh_last; \ + SIMPLEQ_INIT((head2)); \ + } \ +} while (/*CONSTCOND*/0) + +#define SIMPLEQ_LAST(head, type, field) \ + (SIMPLEQ_EMPTY((head)) ? \ + NULL : \ + ((struct type *)(void *) \ + ((char *)((head)->sqh_last) - offsetof(struct type, field)))) + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL) +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + + +/* + * Tail queue definitions. + */ +#define _TAILQ_HEAD(name, type, qual) \ +struct name { \ + qual type *tqh_first; /* first element */ \ + qual type *qual *tqh_last; /* addr of last next element */ \ +} +#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,) + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define _TAILQ_ENTRY(type, qual) \ +struct { \ + qual type *tqe_next; /* next element */ \ + qual type *qual *tqe_prev; /* address of previous next element */\ +} +#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,) + +/* + * Tail queue functions. + */ +#if defined(_KERNEL) && defined(QUEUEDEBUG) +#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field) \ + if ((head)->tqh_first && \ + (head)->tqh_first->field.tqe_prev != &(head)->tqh_first) \ + panic("TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__); +#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field) \ + if (*(head)->tqh_last != NULL) \ + panic("TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__); +#define QUEUEDEBUG_TAILQ_OP(elm, field) \ + if ((elm)->field.tqe_next && \ + (elm)->field.tqe_next->field.tqe_prev != \ + &(elm)->field.tqe_next) \ + panic("TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\ + if (*(elm)->field.tqe_prev != (elm)) \ + panic("TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__); +#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field) \ + if ((elm)->field.tqe_next == NULL && \ + (head)->tqh_last != &(elm)->field.tqe_next) \ + panic("TAILQ_PREREMOVE head %p elm %p %s:%d", \ + (head), (elm), __FILE__, __LINE__); +#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field) \ + (elm)->field.tqe_next = (void *)1L; \ + (elm)->field.tqe_prev = (void *)1L; +#else +#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field) +#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field) +#define QUEUEDEBUG_TAILQ_OP(elm, field) +#define QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field) +#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field) +#endif + +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (/*CONSTCOND*/0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field) \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (/*CONSTCOND*/0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field) \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (/*CONSTCOND*/0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + QUEUEDEBUG_TAILQ_OP((listelm), field) \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (/*CONSTCOND*/0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + QUEUEDEBUG_TAILQ_OP((listelm), field) \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (/*CONSTCOND*/0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field) \ + QUEUEDEBUG_TAILQ_OP((elm), field) \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ + QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field); \ +} while (/*CONSTCOND*/0) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = ((head)->tqh_first); \ + (var); \ + (var) = ((var)->field.tqe_next)) + +#define TAILQ_FOREACH_SAFE(var, head, field, next) \ + for ((var) = ((head)->tqh_first); \ + (var) != NULL && ((next) = TAILQ_NEXT(var, field), 1); \ + (var) = (next)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \ + (var); \ + (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var) && ((prev) = TAILQ_PREV((var), headname, field), 1);\ + (var) = (prev)) + +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + } \ +} while (/*CONSTCOND*/0) + +/* + * Tail queue access methods. + */ +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + + +/* + * Circular queue definitions. + */ +#if defined(_KERNEL) && defined(QUEUEDEBUG) +#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \ + if ((head)->cqh_first != (void *)(head) && \ + (head)->cqh_first->field.cqe_prev != (void *)(head)) \ + panic("CIRCLEQ head forw %p %s:%d", (head), \ + __FILE__, __LINE__); \ + if ((head)->cqh_last != (void *)(head) && \ + (head)->cqh_last->field.cqe_next != (void *)(head)) \ + panic("CIRCLEQ head back %p %s:%d", (head), \ + __FILE__, __LINE__); +#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \ + if ((elm)->field.cqe_next == (void *)(head)) { \ + if ((head)->cqh_last != (elm)) \ + panic("CIRCLEQ elm last %p %s:%d", (elm), \ + __FILE__, __LINE__); \ + } else { \ + if ((elm)->field.cqe_next->field.cqe_prev != (elm)) \ + panic("CIRCLEQ elm forw %p %s:%d", (elm), \ + __FILE__, __LINE__); \ + } \ + if ((elm)->field.cqe_prev == (void *)(head)) { \ + if ((head)->cqh_first != (elm)) \ + panic("CIRCLEQ elm first %p %s:%d", (elm), \ + __FILE__, __LINE__); \ + } else { \ + if ((elm)->field.cqe_prev->field.cqe_next != (elm)) \ + panic("CIRCLEQ elm prev %p %s:%d", (elm), \ + __FILE__, __LINE__); \ + } +#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field) \ + (elm)->field.cqe_next = (void *)1L; \ + (elm)->field.cqe_prev = (void *)1L; +#else +#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) +#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) +#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field) +#endif + +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_HEAD_INITIALIZER(head) \ + { (void *)&head, (void *)&head } + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue functions. + */ +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = (void *)(head); \ + (head)->cqh_last = (void *)(head); \ +} while (/*CONSTCOND*/0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ + QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (/*CONSTCOND*/0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ + QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (/*CONSTCOND*/0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = (void *)(head); \ + if ((head)->cqh_last == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (/*CONSTCOND*/0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ + (elm)->field.cqe_next = (void *)(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (/*CONSTCOND*/0) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ + QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field) \ + if ((elm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ + QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field) \ +} while (/*CONSTCOND*/0) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for ((var) = ((head)->cqh_first); \ + (var) != (const void *)(head); \ + (var) = ((var)->field.cqe_next)) + +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for ((var) = ((head)->cqh_last); \ + (var) != (const void *)(head); \ + (var) = ((var)->field.cqe_prev)) + +/* + * Circular queue access methods. + */ +#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) +#define CIRCLEQ_LAST(head) ((head)->cqh_last) +#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) +#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) + +#define CIRCLEQ_LOOP_NEXT(head, elm, field) \ + (((elm)->field.cqe_next == (void *)(head)) \ + ? ((head)->cqh_first) \ + : (elm->field.cqe_next)) +#define CIRCLEQ_LOOP_PREV(head, elm, field) \ + (((elm)->field.cqe_prev == (void *)(head)) \ + ? ((head)->cqh_last) \ + : (elm->field.cqe_prev)) + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/sys/sys/rmd160.h b/sys/sys/rmd160.h new file mode 100644 index 000000000..0ef2c748f --- /dev/null +++ b/sys/sys/rmd160.h @@ -0,0 +1,56 @@ +/* $NetBSD: rmd160.h,v 1.2 2008/02/16 17:37:13 apb Exp $ */ +/* $KAME: rmd160.h,v 1.2 2003/07/25 09:37:55 itojun Exp $ */ +/* $OpenBSD: rmd160.h,v 1.3 2002/03/14 01:26:51 millert Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _RMD160_H +#define _RMD160_H + +#include +#include + +#define RMD160_DIGEST_LENGTH 20 +#define RMD160_DIGEST_STRING_LENGTH 41 + +/* RMD160 context. */ +typedef struct RMD160Context { + uint32_t state[5]; /* state */ + uint64_t count; /* number of bits, modulo 2^64 */ + u_char buffer[64]; /* input buffer */ +} RMD160_CTX; + +__BEGIN_DECLS +void RMD160Init(RMD160_CTX *); +void RMD160Transform(uint32_t [5], const u_char [64]); +void RMD160Update(RMD160_CTX *, const u_char *, uint32_t); +void RMD160Final(u_char [RMD160_DIGEST_LENGTH], RMD160_CTX *); +#ifndef _KERNEL +char *RMD160End(RMD160_CTX *, char *); +char *RMD160FileChunk(const char *, char *, off_t, off_t); +char *RMD160File(const char *, char *); +char *RMD160Data(const u_char *, size_t, char *); +#endif /* _KERNEL */ +__END_DECLS + +#endif /* _RMD160_H */ diff --git a/sys/sys/sha1.h b/sys/sys/sha1.h new file mode 100644 index 000000000..b936c3938 --- /dev/null +++ b/sys/sys/sha1.h @@ -0,0 +1,37 @@ +/* $NetBSD: sha1.h,v 1.14 2009/11/06 20:31:19 joerg Exp $ */ + +/* + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + */ + +#ifndef _SYS_SHA1_H_ +#define _SYS_SHA1_H_ + +#include +#include + +#define SHA1_DIGEST_LENGTH 20 +#define SHA1_DIGEST_STRING_LENGTH 41 + +typedef struct { + uint32_t state[5]; + uint32_t count[2]; + uint8_t buffer[64]; +} SHA1_CTX; + +__BEGIN_DECLS +void SHA1Transform(uint32_t[5], const uint8_t[64]); +void SHA1Init(SHA1_CTX *); +void SHA1Update(SHA1_CTX *, const uint8_t *, unsigned int); +void SHA1Final(uint8_t[SHA1_DIGEST_LENGTH], SHA1_CTX *); +#ifndef _KERNEL +char *SHA1End(SHA1_CTX *, char *); +char *SHA1FileChunk(const char *, char *, off_t, off_t); +char *SHA1File(const char *, char *); +char *SHA1Data(const uint8_t *, size_t, char *); +#endif /* _KERNEL */ +__END_DECLS + +#endif /* _SYS_SHA1_H_ */ diff --git a/sys/sys/sha2.h b/sys/sys/sha2.h new file mode 100644 index 000000000..b985efccf --- /dev/null +++ b/sys/sys/sha2.h @@ -0,0 +1,120 @@ +/* $NetBSD: sha2.h,v 1.3 2009/05/26 08:04:12 joerg Exp $ */ +/* $KAME: sha2.h,v 1.4 2003/07/20 00:28:38 itojun Exp $ */ + +/* + * sha2.h + * + * Version 1.0.0beta1 + * + * Written by Aaron D. Gifford + * + * Copyright 2000 Aaron D. Gifford. 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. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``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(S) OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef __SHA2_H__ +#define __SHA2_H__ + +#include +#include + +/*** SHA-224/256/384/512 Various Length Definitions ***********************/ +#define SHA224_BLOCK_LENGTH 64 +#define SHA224_DIGEST_LENGTH 28 +#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1) +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + + +/*** SHA-256/384/512 Context Structures *******************************/ +typedef struct _SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; + +typedef struct _SHA512_CTX { + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +typedef SHA256_CTX SHA224_CTX; +typedef SHA512_CTX SHA384_CTX; + + +/*** SHA-256/384/512 Function Prototypes ******************************/ +__BEGIN_DECLS +int SHA224_Init(SHA224_CTX *); +int SHA224_Update(SHA224_CTX*, const uint8_t*, size_t); +int SHA224_Final(uint8_t[SHA224_DIGEST_LENGTH], SHA224_CTX*); +#ifndef _KERNEL +char *SHA224_End(SHA224_CTX *, char[SHA224_DIGEST_STRING_LENGTH]); +char *SHA224_FileChunk(const char *, char *, off_t, off_t); +char *SHA224_File(const char *, char *); +char *SHA224_Data(const uint8_t *, size_t, char[SHA224_DIGEST_STRING_LENGTH]); +#endif /* !_KERNEL */ + +int SHA256_Init(SHA256_CTX *); +int SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); +int SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +#ifndef _KERNEL +char *SHA256_End(SHA256_CTX *, char[SHA256_DIGEST_STRING_LENGTH]); +char *SHA256_FileChunk(const char *, char *, off_t, off_t); +char *SHA256_File(const char *, char *); +char *SHA256_Data(const uint8_t *, size_t, char[SHA256_DIGEST_STRING_LENGTH]); +#endif /* !_KERNEL */ + +int SHA384_Init(SHA384_CTX*); +int SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); +int SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +#ifndef _KERNEL +char *SHA384_End(SHA384_CTX *, char[SHA384_DIGEST_STRING_LENGTH]); +char *SHA384_FileChunk(const char *, char *, off_t, off_t); +char *SHA384_File(const char *, char *); +char *SHA384_Data(const uint8_t *, size_t, char[SHA384_DIGEST_STRING_LENGTH]); +#endif /* !_KERNEL */ + +int SHA512_Init(SHA512_CTX*); +int SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); +int SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +#ifndef _KERNEL +char *SHA512_End(SHA512_CTX *, char[SHA512_DIGEST_STRING_LENGTH]); +char *SHA512_FileChunk(const char *, char *, off_t, off_t); +char *SHA512_File(const char *, char *); +char *SHA512_Data(const uint8_t *, size_t, char[SHA512_DIGEST_STRING_LENGTH]); +#endif /* !_KERNEL */ +__END_DECLS + +#endif /* __SHA2_H__ */