Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Jan 2009 19:55:17 +0000 (UTC)
From:      Sam Leffler <sam@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r186703 - in user/sam/wifi: . lib/libarchive sys/conf sys/dev/syscons sys/dev/syscons/teken sys/kern sys/net80211 sys/pc98/cbus sys/security/audit sys/sparc64/include sys/sparc64/sparc6...
Message-ID:  <200901021955.n02JtHRa006098@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sam
Date: Fri Jan  2 19:55:17 2009
New Revision: 186703
URL: http://svn.freebsd.org/changeset/base/186703

Log:
  sync with HEAD

Added:
  user/sam/wifi/sys/dev/syscons/scterm-teken.c
     - copied unchanged from r186686, head/sys/dev/syscons/scterm-teken.c
  user/sam/wifi/sys/dev/syscons/teken/
     - copied from r186686, head/sys/dev/syscons/teken/
  user/sam/wifi/sys/pc98/cbus/sctermvar.h
     - copied unchanged from r186686, head/sys/pc98/cbus/sctermvar.h
Deleted:
  user/sam/wifi/sys/dev/syscons/scterm-dumb.c
  user/sam/wifi/sys/dev/syscons/scterm-sc.c
  user/sam/wifi/sys/dev/syscons/sctermvar.h
Modified:
  user/sam/wifi/   (props changed)
  user/sam/wifi/lib/libarchive/archive_read_support_compression_gzip.c
  user/sam/wifi/sys/conf/files
  user/sam/wifi/sys/conf/files.amd64
  user/sam/wifi/sys/conf/files.i386
  user/sam/wifi/sys/conf/files.ia64
  user/sam/wifi/sys/conf/files.powerpc
  user/sam/wifi/sys/conf/files.sparc64
  user/sam/wifi/sys/dev/syscons/scterm.c
  user/sam/wifi/sys/dev/syscons/syscons.c
  user/sam/wifi/sys/dev/syscons/syscons.h
  user/sam/wifi/sys/kern/kern_mbuf.c
  user/sam/wifi/sys/kern/kern_sysctl.c
  user/sam/wifi/sys/kern/uipc_usrreq.c
  user/sam/wifi/sys/net80211/ieee80211_hostap.c
  user/sam/wifi/sys/net80211/ieee80211_node.c
  user/sam/wifi/sys/net80211/ieee80211_output.c
  user/sam/wifi/sys/net80211/ieee80211_wds.c
  user/sam/wifi/sys/pc98/cbus/scterm-sck.c
  user/sam/wifi/sys/security/audit/audit_pipe.c
  user/sam/wifi/sys/sparc64/include/tlb.h
  user/sam/wifi/sys/sparc64/sparc64/machdep.c
  user/sam/wifi/sys/sparc64/sparc64/pmap.c
  user/sam/wifi/sys/sys/elf64.h
  user/sam/wifi/sys/sys/elf_common.h
  user/sam/wifi/sys/sys/elf_generic.h
  user/sam/wifi/sys/sys/file.h
  user/sam/wifi/sys/sys/imgact_elf.h
  user/sam/wifi/sys/sys/link_elf.h
  user/sam/wifi/sys/vm/vm_map.c
  user/sam/wifi/sys/vm/vm_map.h
  user/sam/wifi/usr.sbin/mergemaster/mergemaster.8
  user/sam/wifi/usr.sbin/mergemaster/mergemaster.sh
  user/sam/wifi/usr.sbin/sysinstall/menus.c

Modified: user/sam/wifi/lib/libarchive/archive_read_support_compression_gzip.c
==============================================================================
--- user/sam/wifi/lib/libarchive/archive_read_support_compression_gzip.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/lib/libarchive/archive_read_support_compression_gzip.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -428,8 +428,9 @@ gzip_source_read(struct archive_read_sou
 						"Failed to clean up gzip decompressor");
 					return (ARCHIVE_FATAL);
 				}
-				/* Restart header parser with the next block. */
-				state->header_state = state->header_done = 0;
+				/* zlib has been torn down */
+				state->header_done = 0;
+				state->eof = 1;
 				/* FALL THROUGH */
 			case Z_OK: /* Decompressor made some progress. */
 				/* If we filled our buffer, update stats and return. */

Modified: user/sam/wifi/sys/conf/files
==============================================================================
--- user/sam/wifi/sys/conf/files	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/conf/files	Fri Jan  2 19:55:17 2009	(r186703)
@@ -75,6 +75,11 @@ pccarddevs.h			standard				   \
 	compile-with	"${AWK} -f $S/tools/pccarddevs2h.awk $S/dev/pccard/pccarddevs" \
 	no-obj no-implicit-rule before-depend				   \
 	clean		"pccarddevs.h"
+teken_state.h		optional sc					   \
+	dependency	"$S/dev/syscons/teken/gensequences $S/dev/syscons/teken/sequences" \
+	compile-with	"${AWK} -f $S/dev/syscons/teken/gensequences $S/dev/syscons/teken/sequences > teken_state.h" \
+	no-obj no-implicit-rule before-depend				   \
+	clean		"teken_state.h"
 usbdevs.h			optional usb				   \
 	dependency	"$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \
 	compile-with	"${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -h" \
@@ -1424,7 +1429,6 @@ dev/syscons/logo/logo_saver.c	optional l
 dev/syscons/rain/rain_saver.c	optional rain_saver
 dev/syscons/schistory.c		optional sc
 dev/syscons/scmouse.c		optional sc
-dev/syscons/scterm-dumb.c	optional sc
 dev/syscons/scterm.c		optional sc
 dev/syscons/scvidctl.c		optional sc
 dev/syscons/snake/snake_saver.c	optional snake_saver

Modified: user/sam/wifi/sys/conf/files.amd64
==============================================================================
--- user/sam/wifi/sys/conf/files.amd64	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/conf/files.amd64	Fri Jan  2 19:55:17 2009	(r186703)
@@ -196,9 +196,10 @@ dev/sio/sio_pci.c		optional	sio pci
 dev/sio/sio_puc.c		optional	sio puc
 dev/speaker/spkr.c		optional	speaker
 dev/syscons/apm/apm_saver.c	optional	apm_saver apm
-dev/syscons/scterm-sc.c		optional	sc
+dev/syscons/scterm-teken.c	optional	sc
 dev/syscons/scvgarndr.c		optional	sc vga
 dev/syscons/scvtb.c		optional	sc
+dev/syscons/teken/teken.c	optional sc
 dev/uart/uart_cpu_amd64.c	optional	uart
 dev/wpi/if_wpi.c		optional	wpi
 isa/atrtc.c			standard

Modified: user/sam/wifi/sys/conf/files.i386
==============================================================================
--- user/sam/wifi/sys/conf/files.i386	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/conf/files.i386	Fri Jan  2 19:55:17 2009	(r186703)
@@ -220,10 +220,11 @@ dev/sio/sio_puc.c		optional sio puc
 dev/speaker/spkr.c		optional speaker
 dev/sr/if_sr_isa.c		optional sr isa
 dev/syscons/apm/apm_saver.c	optional apm_saver apm
-dev/syscons/scterm-sc.c		optional sc
+dev/syscons/scterm-teken.c	optional sc
 dev/syscons/scvesactl.c		optional sc vga vesa
 dev/syscons/scvgarndr.c		optional sc vga
 dev/syscons/scvtb.c		optional sc
+dev/syscons/teken/teken.c	optional sc
 dev/uart/uart_cpu_i386.c	optional uart
 dev/acpica/acpi_if.m		standard
 dev/wpi/if_wpi.c		optional wpi

Modified: user/sam/wifi/sys/conf/files.ia64
==============================================================================
--- user/sam/wifi/sys/conf/files.ia64	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/conf/files.ia64	Fri Jan  2 19:55:17 2009	(r186703)
@@ -57,9 +57,10 @@ dev/fb/fb.c			optional	fb | vga
 dev/fb/vga.c			optional	vga
 dev/hwpmc/hwpmc_ia64.c		optional	hwpmc
 dev/kbd/kbd.c			optional	atkbd | sc | ukbd
-dev/syscons/scterm-sc.c		optional	sc
+dev/syscons/scterm-teken.c	optional	sc
 dev/syscons/scvgarndr.c		optional	sc vga
 dev/syscons/scvtb.c		optional	sc
+dev/syscons/teken/teken.c	optional sc
 dev/uart/uart_cpu_ia64.c	optional	uart
 dev/acpica/acpi_if.m		standard
 ia64/acpica/OsdEnvironment.c	optional	acpi

Modified: user/sam/wifi/sys/conf/files.powerpc
==============================================================================
--- user/sam/wifi/sys/conf/files.powerpc	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/conf/files.powerpc	Fri Jan  2 19:55:17 2009	(r186703)
@@ -39,8 +39,9 @@ dev/powermac_nvram/powermac_nvram.c opti
 dev/quicc/quicc_bfe_ocp.c	optional	quicc mpc85xx
 dev/scc/scc_bfe_macio.c		optional	scc powermac
 dev/syscons/scgfbrndr.c		optional	sc
-dev/syscons/scterm-sc.c		optional	sc
+dev/syscons/scterm-teken.c	optional	sc
 dev/syscons/scvtb.c		optional	sc
+dev/syscons/teken/teken.c	optional sc
 dev/tsec/if_tsec.c		optional	tsec
 dev/tsec/if_tsec_ocp.c		optional	tsec mpc85xx
 dev/uart/uart_bus_ocp.c		optional	uart mpc85xx

Modified: user/sam/wifi/sys/conf/files.sparc64
==============================================================================
--- user/sam/wifi/sys/conf/files.sparc64	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/conf/files.sparc64	Fri Jan  2 19:55:17 2009	(r186703)
@@ -55,8 +55,9 @@ dev/pcf/pcf_ebus.c		optional	pcf ebus
 dev/sound/sbus/cs4231.c		optional	snd_audiocs ebus | \
 						snd_audiocs sbus
 dev/syscons/scgfbrndr.c		optional	sc
-dev/syscons/scterm-sc.c		optional	sc
+dev/syscons/scterm-teken.c	optional	sc
 dev/syscons/scvtb.c		optional	sc
+dev/syscons/teken/teken.c	optional sc
 dev/uart/uart_cpu_sparc64.c	optional	uart
 dev/uart/uart_kbd_sun.c		optional	uart sc
 kern/syscalls.c			optional	ktr

Copied: user/sam/wifi/sys/dev/syscons/scterm-teken.c (from r186686, head/sys/dev/syscons/scterm-teken.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/sam/wifi/sys/dev/syscons/scterm-teken.c	Fri Jan  2 19:55:17 2009	(r186703, copy of r186686, head/sys/dev/syscons/scterm-teken.c)
@@ -0,0 +1,504 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * All rights reserved.
+ *
+ * Copyright (c) 2008-2009 Ed Schouten <ed@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 as
+ *    the first lines of this file unmodified.
+ * 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 ``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 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 "opt_syscons.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/consio.h>
+
+#if defined(__sparc64__) || defined(__powerpc__)
+#include <machine/sc_machdep.h>
+#else
+#include <machine/pc/display.h>
+#endif
+
+#include <dev/syscons/syscons.h>
+
+#include <dev/syscons/teken/teken.h>
+
+static void scteken_revattr(unsigned char, teken_attr_t *);
+
+static sc_term_init_t	scteken_init;
+static sc_term_term_t	scteken_term;
+static sc_term_puts_t	scteken_puts;
+static sc_term_ioctl_t	scteken_ioctl;
+static sc_term_default_attr_t scteken_default_attr;
+static sc_term_clear_t	scteken_clear;
+static sc_term_input_t	scteken_input;
+static void		scteken_nop(void);
+
+typedef struct {
+	teken_t		ts_teken;
+	int		ts_busy;
+} teken_stat;
+
+static teken_stat	reserved_teken_stat;
+
+static sc_term_sw_t sc_term_scteken = {
+	{ NULL, NULL },
+	"scteken",			/* emulator name */
+	"teken terminal",		/* description */
+	"*",				/* matching renderer */
+	sizeof(teken_stat),		/* softc size */
+	0,
+	scteken_init,
+	scteken_term,
+	scteken_puts,
+	scteken_ioctl,
+	(sc_term_reset_t *)scteken_nop,
+	scteken_default_attr,
+	scteken_clear,
+	(sc_term_notify_t *)scteken_nop,
+	scteken_input,
+};
+
+SCTERM_MODULE(scteken, sc_term_scteken);
+
+static tf_bell_t	scteken_bell;
+static tf_cursor_t	scteken_cursor;
+static tf_putchar_t	scteken_putchar;
+static tf_fill_t	scteken_fill;
+static tf_copy_t	scteken_copy;
+static tf_param_t	scteken_param;
+static tf_respond_t	scteken_respond;
+
+static const teken_funcs_t scteken_funcs = {
+	.tf_bell	= scteken_bell,
+	.tf_cursor	= scteken_cursor,
+	.tf_putchar	= scteken_putchar,
+	.tf_fill	= scteken_fill,
+	.tf_copy	= scteken_copy,
+	.tf_param	= scteken_param,
+	.tf_respond	= scteken_respond,
+};
+
+static int
+scteken_init(scr_stat *scp, void **softc, int code)
+{
+	teken_stat *ts = scp->ts;
+	teken_pos_t tp;
+
+	if (*softc == NULL) {
+		if (reserved_teken_stat.ts_busy)
+			return (EINVAL);
+		*softc = &reserved_teken_stat;
+	}
+	ts = *softc;
+
+	switch (code) {
+	case SC_TE_COLD_INIT:
+		++sc_term_scteken.te_refcount;
+		ts->ts_busy = 1;
+		/* FALLTHROUGH */
+	case SC_TE_WARM_INIT:
+		teken_init(&ts->ts_teken, &scteken_funcs, scp);
+
+		tp.tp_row = scp->ysize;
+		tp.tp_col = scp->xsize;
+		teken_set_winsize(&ts->ts_teken, &tp);
+
+		tp.tp_row = scp->cursor_pos / scp->xsize;
+		tp.tp_col = scp->cursor_pos % scp->xsize;
+		teken_set_cursor(&ts->ts_teken, &tp);
+		break;
+	}
+
+	return (0);
+}
+
+static int
+scteken_term(scr_stat *scp, void **softc)
+{
+
+	if (*softc == &reserved_teken_stat) {
+		*softc = NULL;
+		reserved_teken_stat.ts_busy = 0;
+	}
+	--sc_term_scteken.te_refcount;
+
+	return (0);
+}
+
+static void
+scteken_puts(scr_stat *scp, u_char *buf, int len)
+{
+	teken_stat *ts = scp->ts;
+
+	scp->sc->write_in_progress++;
+	teken_input(&ts->ts_teken, buf, len);
+	scp->sc->write_in_progress--;
+}
+
+static int
+scteken_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data,
+	     struct thread *td)
+{
+	vid_info_t *vi;
+
+	switch (cmd) {
+	case GIO_ATTR:      	/* get current attributes */
+		*(int*)data = SC_NORM_ATTR;
+		return (0);
+	case CONS_GETINFO:  	/* get current (virtual) console info */
+		/* XXX: INCORRECT! */
+		vi = (vid_info_t *)data;
+		if (vi->size != sizeof(struct vid_info))
+			return EINVAL;
+		vi->mv_norm.fore = SC_NORM_ATTR & 0x0f;
+		vi->mv_norm.back = (SC_NORM_ATTR >> 4) & 0x0f;
+		vi->mv_rev.fore = SC_NORM_ATTR & 0x0f;
+		vi->mv_rev.back = (SC_NORM_ATTR >> 4) & 0x0f;
+		/*
+		 * The other fields are filled by the upper routine. XXX
+		 */
+		return (ENOIOCTL);
+	}
+
+	return (ENOIOCTL);
+}
+
+static void
+scteken_default_attr(scr_stat *scp, int color, int rev_color)
+{
+	teken_stat *ts = scp->ts;
+	teken_attr_t ta;
+
+	scteken_revattr(color, &ta);
+	teken_set_defattr(&ts->ts_teken, &ta);
+}
+
+static void
+scteken_clear(scr_stat *scp)
+{
+
+	sc_move_cursor(scp, 0, 0);
+	sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], SC_NORM_ATTR << 8);
+	mark_all(scp);
+}
+
+static int
+scteken_input(scr_stat *scp, int c, struct tty *tp)
+{
+
+	return FALSE;
+}
+
+static void
+scteken_nop(void)
+{
+
+}
+
+/*
+ * libteken routines.
+ */
+
+static const unsigned char fgcolors_normal[TC_NCOLORS] = {
+	FG_BLACK,     FG_RED,          FG_GREEN,      FG_BROWN,
+	FG_BLUE,      FG_MAGENTA,      FG_CYAN,       FG_LIGHTGREY,
+};
+
+static const unsigned char fgcolors_bold[TC_NCOLORS] = {
+	FG_DARKGREY,  FG_LIGHTRED,     FG_LIGHTGREEN, FG_YELLOW,
+	FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN,  FG_WHITE,
+};
+
+static const unsigned char bgcolors[TC_NCOLORS] = {
+	BG_BLACK,     BG_RED,          BG_GREEN,      BG_BROWN,
+	BG_BLUE,      BG_MAGENTA,      BG_CYAN,       BG_LIGHTGREY,
+};
+
+static void
+scteken_revattr(unsigned char color, teken_attr_t *a)
+{
+	teken_color_t fg, bg;
+
+	/*
+	 * XXX: Reverse conversion of syscons to teken attributes. Not
+	 * realiable. Maybe we should turn it into a 1:1 mapping one of
+	 * these days?
+	 */
+
+	a->ta_format = 0;
+	a->ta_fgcolor = TC_WHITE;
+	a->ta_bgcolor = TC_BLACK;
+
+#ifdef FG_BLINK
+	if (color & FG_BLINK) {
+		a->ta_format |= TF_BLINK;
+		color &= ~FG_BLINK;
+	}
+#endif /* FG_BLINK */
+
+	for (fg = 0; fg < TC_NCOLORS; fg++) {
+		for (bg = 0; bg < TC_NCOLORS; bg++) {
+			if ((fgcolors_normal[fg] | bgcolors[bg]) == color) {
+				a->ta_fgcolor = fg;
+				a->ta_bgcolor = bg;
+				return;
+			}
+
+			if ((fgcolors_bold[fg] | bgcolors[bg]) == color) {
+				a->ta_fgcolor = fg;
+				a->ta_bgcolor = bg;
+				a->ta_format |= TF_BOLD;
+				return;
+			}
+		}
+	}
+}
+
+static inline unsigned int
+scteken_attr(const teken_attr_t *a)
+{
+	unsigned int attr = 0;
+
+	if (a->ta_format & TF_BOLD)
+		attr |= fgcolors_bold[a->ta_fgcolor];
+	else
+		attr |= fgcolors_normal[a->ta_fgcolor];
+	attr |= bgcolors[a->ta_bgcolor];
+
+#ifdef FG_UNDERLINE
+	if (a->ta_format & TF_UNDERLINE)
+		attr |= FG_UNDERLINE;
+#endif /* FG_UNDERLINE */
+#ifdef FG_BLINK
+	if (a->ta_format & TF_BLINK)
+		attr |= FG_BLINK;
+#endif /* FG_BLINK */
+
+	return (attr << 8);
+}
+
+static void
+scteken_bell(void *arg)
+{
+	scr_stat *scp = arg;
+
+	sc_bell(scp, scp->bell_pitch, scp->bell_duration);
+}
+
+static void
+scteken_cursor(void *arg, const teken_pos_t *p)
+{
+	scr_stat *scp = arg;
+
+	sc_move_cursor(scp, p->tp_col, p->tp_row);
+}
+
+static void
+scteken_putchar(void *arg, const teken_pos_t *tp, teken_char_t c,
+    const teken_attr_t *a)
+{
+	scr_stat *scp = arg;
+	u_char *map;
+	u_char ch;
+	vm_offset_t p;
+	int cursor, attr;
+
+#ifdef TEKEN_UTF8
+	if (c >= 0x80) {
+		/* XXX: Don't display UTF-8 yet. */
+		attr = (FG_YELLOW|BG_RED) << 8;
+		ch = '?';
+	} else
+#endif /* TEKEN_UTF8 */
+	{
+		attr = scteken_attr(a);
+		ch = c;
+	}
+
+	map = scp->sc->scr_map;
+
+	cursor = tp->tp_row * scp->xsize + tp->tp_col;
+	p = sc_vtb_pointer(&scp->vtb, cursor);
+	sc_vtb_putchar(&scp->vtb, p, map[ch], attr);
+
+	mark_for_update(scp, cursor);
+	/*
+	 * XXX: Why do we need this? Only marking `cursor' should be
+	 * enough. Without this line, we get artifacts.
+	 */
+	mark_for_update(scp, imin(cursor + 1, scp->xsize * scp->ysize - 1));
+}
+
+static void
+scteken_fill(void *arg, const teken_rect_t *r, teken_char_t c,
+    const teken_attr_t *a)
+{
+	scr_stat *scp = arg;
+	u_char *map;
+	u_char ch;
+	unsigned int width;
+	int attr, row;
+
+#ifdef TEKEN_UTF8
+	if (c >= 0x80) {
+		/* XXX: Don't display UTF-8 yet. */
+		attr = (FG_YELLOW|BG_RED) << 8;
+		ch = '?';
+	} else
+#endif /* TEKEN_UTF8 */
+	{
+		attr = scteken_attr(a);
+		ch = c;
+	}
+
+	map = scp->sc->scr_map;
+
+	if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) {
+		/* Single contiguous region to fill. */
+		sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row * scp->xsize,
+		    (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize,
+		    map[ch], attr);
+	} else {
+		/* Fill display line by line. */
+		width = r->tr_end.tp_col - r->tr_begin.tp_col;
+
+		for (row = r->tr_begin.tp_row; row < r->tr_end.tp_row; row++) {
+			sc_vtb_erase(&scp->vtb, r->tr_begin.tp_row *
+			    scp->xsize + r->tr_begin.tp_col,
+			    width, map[ch], attr);
+		}
+	}
+
+	/* Mark begin and end positions to be refreshed. */
+	mark_for_update(scp,
+	    r->tr_begin.tp_row * scp->xsize + r->tr_begin.tp_col);
+	mark_for_update(scp,
+	    (r->tr_end.tp_row - 1) * scp->xsize + (r->tr_end.tp_col - 1));
+	sc_remove_cutmarking(scp);
+}
+
+static void
+scteken_copy(void *arg, const teken_rect_t *r, const teken_pos_t *p)
+{
+	scr_stat *scp = arg;
+	unsigned int width;
+	int src, dst, end;
+
+#ifndef SC_NO_HISTORY
+	/*
+	 * We count a line of input as history if we perform a copy of
+	 * one whole line upward. In other words: if a line of text gets
+	 * overwritten by a rectangle that's right below it.
+	 */
+	if (scp->history != NULL &&
+	    r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize &&
+	    r->tr_begin.tp_row == p->tp_row + 1) {
+		sc_hist_save_one_line(scp, p->tp_row);
+	}
+#endif
+
+	if (r->tr_begin.tp_col == 0 && r->tr_end.tp_col == scp->xsize) {
+		/* Single contiguous region to copy. */
+		sc_vtb_move(&scp->vtb, r->tr_begin.tp_row * scp->xsize,
+		    p->tp_row * scp->xsize,
+		    (r->tr_end.tp_row - r->tr_begin.tp_row) * scp->xsize);
+	} else {
+		/* Copy line by line. */
+		width = r->tr_end.tp_col - r->tr_begin.tp_col;
+
+		if (p->tp_row < r->tr_begin.tp_row) {
+			/* Copy from top to bottom. */
+			src = r->tr_begin.tp_row * scp->xsize +
+			    r->tr_begin.tp_col;
+			end = r->tr_end.tp_row * scp->xsize +
+			    r->tr_end.tp_col;
+			dst = p->tp_row * scp->xsize + p->tp_col;
+
+			while (src < end) {
+				sc_vtb_move(&scp->vtb, src, dst, width);
+			
+				src += scp->xsize;
+				dst += scp->xsize;
+			}
+		} else {
+			/* Copy from bottom to top. */
+			src = (r->tr_end.tp_row - 1) * scp->xsize +
+			    r->tr_begin.tp_col;
+			end = r->tr_begin.tp_row * scp->xsize +
+			    r->tr_begin.tp_col;
+			dst = (p->tp_row + r->tr_end.tp_row -
+			    r->tr_begin.tp_row - 1) * scp->xsize + p->tp_col;
+
+			while (src >= end) {
+				sc_vtb_move(&scp->vtb, src, dst, width);
+			
+				src -= scp->xsize;
+				dst -= scp->xsize;
+			}
+		}
+	}
+
+	/* Mark begin and end positions to be refreshed. */
+	mark_for_update(scp,
+	    p->tp_row * scp->xsize + p->tp_col);
+	mark_for_update(scp,
+	    (p->tp_row + r->tr_end.tp_row - r->tr_begin.tp_row - 1) *
+	    scp->xsize +
+	    (p->tp_col + r->tr_end.tp_col - r->tr_begin.tp_col - 1));
+	sc_remove_cutmarking(scp);
+}
+
+static void
+scteken_param(void *arg, int cmd, int value)
+{
+	scr_stat *scp = arg;
+
+	switch (cmd) {
+	case TP_SHOWCURSOR:
+		if (value) {
+			sc_change_cursor_shape(scp,
+			    CONS_RESET_CURSOR|CONS_LOCAL_CURSOR, -1, -1);
+		} else {
+			sc_change_cursor_shape(scp,
+			    CONS_HIDDEN_CURSOR|CONS_LOCAL_CURSOR, -1, -1);
+		}
+		break;
+	case TP_SWITCHVT:
+		sc_switch_scr(scp->sc, value);
+		break;
+	}
+}
+
+static void
+scteken_respond(void *arg, const void *buf, size_t len)
+{
+	scr_stat *scp = arg;
+
+	sc_respond(scp, buf, len);
+}

Modified: user/sam/wifi/sys/dev/syscons/scterm.c
==============================================================================
--- user/sam/wifi/sys/dev/syscons/scterm.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/dev/syscons/scterm.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/consio.h>
 
 #include <dev/syscons/syscons.h>
-#include <dev/syscons/sctermvar.h>
 
 SET_DECLARE(scterm_set, sc_term_sw_t);
 

Modified: user/sam/wifi/sys/dev/syscons/syscons.c
==============================================================================
--- user/sam/wifi/sys/dev/syscons/syscons.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/dev/syscons/syscons.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -2741,6 +2741,16 @@ scinit(int unit, int flags)
 	    init_scp(sc, sc->first_vty, scp);
 	    sc_vtb_init(&scp->vtb, VTB_MEMORY, scp->xsize, scp->ysize,
 			(void *)sc_buffer, FALSE);
+
+	    /* move cursors to the initial positions */
+	    if (col >= scp->xsize)
+		col = 0;
+	    if (row >= scp->ysize)
+		row = scp->ysize - 1;
+	    scp->xpos = col;
+	    scp->ypos = row;
+	    scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
+
 	    if (sc_init_emulator(scp, SC_DFLT_TERM))
 		sc_init_emulator(scp, "*");
 	    (*scp->tsw->te_default_attr)(scp,
@@ -2764,15 +2774,6 @@ scinit(int unit, int flags)
 	    sc_vtb_copy(&scp->scr, 0, &scp->vtb, 0, scp->xsize*scp->ysize);
 #endif
 
-	/* move cursors to the initial positions */
-	if (col >= scp->xsize)
-	    col = 0;
-	if (row >= scp->ysize)
-	    row = scp->ysize - 1;
-	scp->xpos = col;
-	scp->ypos = row;
-	scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
-
 	if (bios_value.cursor_end < scp->font_size)
 	    sc->dflt_curs_attr.base = scp->font_size - 
 					  bios_value.cursor_end - 1;
@@ -3569,7 +3570,7 @@ sc_show_font(scr_stat *scp, int page)
 #endif /* !SC_NO_FONT_LOADING */
 
 void
-sc_paste(scr_stat *scp, u_char *p, int count) 
+sc_paste(scr_stat *scp, const u_char *p, int count) 
 {
     struct tty *tp;
     u_char *rmap;
@@ -3584,6 +3585,22 @@ sc_paste(scr_stat *scp, u_char *p, int c
 }
 
 void
+sc_respond(scr_stat *scp, const u_char *p, int count) 
+{
+    struct tty *tp;
+
+    tp = SC_DEV(scp->sc, scp->sc->cur_scp->index);
+    if (!tty_opened(tp))
+	return;
+    for (; count > 0; --count)
+	ttydisc_rint(tp, *p++, 0);
+#if 0
+    /* XXX: we can't call ttydisc_rint_done() here! */
+    ttydisc_rint_done(tp);
+#endif
+}
+
+void
 sc_bell(scr_stat *scp, int pitch, int duration)
 {
     if (cold || shutdown_in_progress || !enable_bell)

Modified: user/sam/wifi/sys/dev/syscons/syscons.h
==============================================================================
--- user/sam/wifi/sys/dev/syscons/syscons.h	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/dev/syscons/syscons.h	Fri Jan  2 19:55:17 2009	(r186703)
@@ -563,7 +563,8 @@ int		sc_clean_up(scr_stat *scp);
 int		sc_switch_scr(sc_softc_t *sc, u_int next_scr);
 void		sc_alloc_scr_buffer(scr_stat *scp, int wait, int discard);
 int		sc_init_emulator(scr_stat *scp, char *name);
-void		sc_paste(scr_stat *scp, u_char *p, int count);
+void		sc_paste(scr_stat *scp, const u_char *p, int count);
+void		sc_respond(scr_stat *scp, const u_char *p, int count);
 void		sc_bell(scr_stat *scp, int pitch, int duration);
 
 /* schistory.c */

Modified: user/sam/wifi/sys/kern/kern_mbuf.c
==============================================================================
--- user/sam/wifi/sys/kern/kern_mbuf.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/kern/kern_mbuf.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -420,6 +420,7 @@ mb_ctor_mbuf(void *mem, int size, void *
 		m->m_pkthdr.csum_data = 0;
 		m->m_pkthdr.tso_segsz = 0;
 		m->m_pkthdr.ether_vtag = 0;
+		m->m_pkthdr.flowid = 0;
 		SLIST_INIT(&m->m_pkthdr.tags);
 #ifdef MAC
 		/* If the label init fails, fail the alloc */
@@ -644,6 +645,7 @@ mb_ctor_pack(void *mem, int size, void *
 		m->m_pkthdr.csum_data = 0;
 		m->m_pkthdr.tso_segsz = 0;
 		m->m_pkthdr.ether_vtag = 0;
+		m->m_pkthdr.flowid = 0;
 		SLIST_INIT(&m->m_pkthdr.tags);
 #ifdef MAC
 		/* If the label init fails, fail the alloc */

Modified: user/sam/wifi/sys/kern/kern_sysctl.c
==============================================================================
--- user/sam/wifi/sys/kern/kern_sysctl.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/kern/kern_sysctl.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -1371,8 +1371,11 @@ __sysctl(struct thread *td, struct sysct
 		uap->new, uap->newlen, &j, 0);
 	if (error && error != ENOMEM)
 		return (error);
-	if (uap->oldlenp)
-		error = copyout(&j, uap->oldlenp, sizeof(j));
+	if (uap->oldlenp) {
+		int i = copyout(&j, uap->oldlenp, sizeof(j));
+		if (i)
+			return (i);
+	}
 	return (error);
 }
 

Modified: user/sam/wifi/sys/kern/uipc_usrreq.c
==============================================================================
--- user/sam/wifi/sys/kern/uipc_usrreq.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/kern/uipc_usrreq.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -1229,14 +1229,14 @@ unp_connect(struct socket *so, struct so
 			unp3->unp_addr = (struct sockaddr_un *) sa;
 			sa = NULL;
 		}
+
 		/*
-		 * unp_peercred management:
-		 *
 		 * The connecter's (client's) credentials are copied from its
 		 * process structure at the time of connect() (which is now).
 		 */
 		cru2x(td->td_ucred, &unp3->unp_peercred);
 		unp3->unp_flags |= UNP_HAVEPC;
+
 		/*
 		 * The receiver's (server's) credentials are copied from the
 		 * unp_peercred member of socket on which the former called

Modified: user/sam/wifi/sys/net80211/ieee80211_hostap.c
==============================================================================
--- user/sam/wifi/sys/net80211/ieee80211_hostap.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/net80211/ieee80211_hostap.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -355,7 +355,7 @@ hostap_deliver_data(struct ieee80211vap 
 		if (mcopy != NULL) {
 			int len, err;
 			len = mcopy->m_pkthdr.len;
-			err = (ifp->if_transmit)(ifp, mcopy);
+			err = ifp->if_transmit(ifp, mcopy);
 			if (err) {
 				/* NB: IFQ_HANDOFF reclaims mcopy */
 			} else {

Modified: user/sam/wifi/sys/net80211/ieee80211_node.c
==============================================================================
--- user/sam/wifi/sys/net80211/ieee80211_node.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/net80211/ieee80211_node.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -1334,6 +1334,10 @@ ieee80211_init_neighbor(struct ieee80211
 
 	if (ieee80211_ies_init(&ni->ni_ies, sp->ies, sp->ies_len)) {
 		ieee80211_ies_expand(&ni->ni_ies);
+		if (ni->ni_ies.wme_ie != NULL)
+			ni->ni_flags |= IEEE80211_NODE_QOS;
+		else
+			ni->ni_flags &= ~IEEE80211_NODE_QOS;
 		if (ni->ni_ies.ath_ie != NULL)
 			ieee80211_parse_ath(ni, ni->ni_ies.ath_ie);
 	}

Modified: user/sam/wifi/sys/net80211/ieee80211_output.c
==============================================================================
--- user/sam/wifi/sys/net80211/ieee80211_output.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/net80211/ieee80211_output.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -266,7 +266,7 @@ ieee80211_start(struct ifnet *ifp)
 		m->m_pkthdr.rcvif = (void *)ni;
 
 		/* XXX defer if_start calls? */
-		error = (parent->if_transmit)(parent, m);
+		error = parent->if_transmit(parent, m);
 		if (error != 0) {
 			/* NB: IFQ_HANDOFF reclaims mbuf */
 			ieee80211_free_node(ni);

Modified: user/sam/wifi/sys/net80211/ieee80211_wds.c
==============================================================================
--- user/sam/wifi/sys/net80211/ieee80211_wds.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/net80211/ieee80211_wds.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -278,7 +278,7 @@ ieee80211_dwds_mcast(struct ieee80211vap
 		mcopy->m_flags |= M_MCAST | M_WDS;
 		mcopy->m_pkthdr.rcvif = (void *) ni;
 
-		err = (parent->if_transmit)(parent, mcopy);
+		err = parent->if_transmit(parent, mcopy);
 		if (err) {
 			/* NB: IFQ_HANDOFF reclaims mbuf */
 			ifp->if_oerrors++;

Modified: user/sam/wifi/sys/pc98/cbus/scterm-sck.c
==============================================================================
--- user/sam/wifi/sys/pc98/cbus/scterm-sck.c	Fri Jan  2 13:56:45 2009	(r186702)
+++ user/sam/wifi/sys/pc98/cbus/scterm-sck.c	Fri Jan  2 19:55:17 2009	(r186703)
@@ -37,9 +37,7 @@
 #include <machine/pc/display.h>
 
 #include <dev/syscons/syscons.h>
-#include <dev/syscons/sctermvar.h>
-
-#ifndef SC_DUMB_TERMINAL
+#include <pc98/cbus/sctermvar.h>
 
 #define MAX_ESC_PAR	5
 
@@ -1212,5 +1210,3 @@ mask2attr(term_stat *tcp)
 
 	return (attr << 8);
 }
-
-#endif /* SC_DUMB_TERMINAL */

Copied: user/sam/wifi/sys/pc98/cbus/sctermvar.h (from r186686, head/sys/pc98/cbus/sctermvar.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/sam/wifi/sys/pc98/cbus/sctermvar.h	Fri Jan  2 19:55:17 2009	(r186703, copy of r186686, head/sys/pc98/cbus/sctermvar.h)
@@ -0,0 +1,432 @@
+/*-
+ * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ * 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 as
+ *    the first lines of this file unmodified.
+ * 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 ``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 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 _DEV_SYSCONS_SCTERMVAR_H_
+#define _DEV_SYSCONS_SCTERMVAR_H_
+
+/*
+ * building blocks for terminal emulator modules.
+ */
+
+static __inline void	sc_term_ins_line(scr_stat *scp, int y, int n, int ch,
+					 int attr, int tail);
+static __inline void	sc_term_del_line(scr_stat *scp, int y, int n, int ch,
+					 int attr, int tail);
+static __inline void	sc_term_ins_char(scr_stat *scp, int n, int ch,
+					 int attr);
+static __inline void	sc_term_del_char(scr_stat *scp, int n, int ch,
+					 int attr);
+static __inline void	sc_term_col(scr_stat *scp, int n);
+static __inline void	sc_term_row(scr_stat *scp, int n);
+static __inline void	sc_term_up(scr_stat *scp, int n, int head);
+static __inline void	sc_term_down(scr_stat *scp, int n, int tail);
+static __inline void	sc_term_left(scr_stat *scp, int n);
+static __inline void	sc_term_right(scr_stat *scp, int n);
+static __inline void	sc_term_up_scroll(scr_stat *scp, int n, int ch,
+					  int attr, int head, int tail);
+static __inline void	sc_term_down_scroll(scr_stat *scp, int n, int ch,
+					    int attr, int head, int tail);
+static __inline void	sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr);
+static __inline void	sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr);
+static __inline void	sc_term_tab(scr_stat *scp, int n);
+static __inline void	sc_term_backtab(scr_stat *scp, int n);
+static __inline void	sc_term_respond(scr_stat *scp, u_char *s);
+static __inline void	sc_term_gen_print(scr_stat *scp, u_char **buf, int *len,
+					  int attr);
+static __inline void	sc_term_gen_scroll(scr_stat *scp, int ch, int attr);
+
+static __inline void
+sc_term_ins_line(scr_stat *scp, int y, int n, int ch, int attr, int tail)
+{
+	if (tail <= 0)
+		tail = scp->ysize;
+	if (n < 1)
+		n = 1;
+	if (n > tail - y)
+		n = tail - y;
+	sc_vtb_ins(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr);
+	mark_for_update(scp, y*scp->xsize);
+	mark_for_update(scp, scp->xsize*tail - 1);
+}
+
+static __inline void
+sc_term_del_line(scr_stat *scp, int y, int n, int ch, int attr, int tail)
+{
+	if (tail <= 0)
+		tail = scp->ysize;
+	if (n < 1)
+		n = 1;
+	if (n > tail - y)
+		n = tail - y;
+	sc_vtb_delete(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr);
+	mark_for_update(scp, y*scp->xsize);
+	mark_for_update(scp, scp->xsize*tail - 1);
+}
+
+static __inline void
+sc_term_ins_char(scr_stat *scp, int n, int ch, int attr)
+{
+	int count;
+
+	if (n < 1)
+		n = 1;
+	if (n > scp->xsize - scp->xpos)
+		n = scp->xsize - scp->xpos;
+	count = scp->xsize - (scp->xpos + n);
+	sc_vtb_move(&scp->vtb, scp->cursor_pos, scp->cursor_pos + n, count);
+	sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, ch, attr);
+	mark_for_update(scp, scp->cursor_pos);
+	mark_for_update(scp, scp->cursor_pos + n + count - 1);
+}
+
+static __inline void
+sc_term_del_char(scr_stat *scp, int n, int ch, int attr)
+{
+	int count;
+
+	if (n < 1)
+		n = 1;
+	if (n > scp->xsize - scp->xpos)
+		n = scp->xsize - scp->xpos;
+	count = scp->xsize - (scp->xpos + n);
+	sc_vtb_move(&scp->vtb, scp->cursor_pos + n, scp->cursor_pos, count);
+	sc_vtb_erase(&scp->vtb, scp->cursor_pos + count, n, ch, attr);
+	mark_for_update(scp, scp->cursor_pos);
+	mark_for_update(scp, scp->cursor_pos + n + count - 1);
+}
+
+static __inline void
+sc_term_col(scr_stat *scp, int n)
+{
+	if (n < 1)
+		n = 1;
+	sc_move_cursor(scp, n - 1, scp->ypos);
+}
+
+static __inline void
+sc_term_row(scr_stat *scp, int n)
+{
+	if (n < 1)
+		n = 1;
+	sc_move_cursor(scp, scp->xpos, n - 1);
+}
+
+static __inline void
+sc_term_up(scr_stat *scp, int n, int head)
+{
+	if (n < 1)
+		n = 1;
+	n = imin(n, scp->ypos - head);
+	if (n <= 0)
+		return;
+	sc_move_cursor(scp, scp->xpos, scp->ypos - n);
+}
+
+static __inline void
+sc_term_down(scr_stat *scp, int n, int tail)
+{
+	if (tail <= 0)
+		tail = scp->ysize;
+	if (n < 1)
+		n = 1;
+	n = imin(n, tail - scp->ypos - 1);
+	if (n <= 0)
+		return;
+	sc_move_cursor(scp, scp->xpos, scp->ypos + n);
+}
+
+static __inline void
+sc_term_left(scr_stat *scp, int n)
+{
+	if (n < 1)
+		n = 1;
+	sc_move_cursor(scp, scp->xpos - n, scp->ypos);
+}
+
+static __inline void
+sc_term_right(scr_stat *scp, int n)
+{
+	if (n < 1)
+		n = 1;
+	sc_move_cursor(scp, scp->xpos + n, scp->ypos);
+}
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901021955.n02JtHRa006098>