Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 29 Apr 2001 02:40:03 +0200 (CEST)
From:      Boris Nikolaus <bn@tellique.de>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/26955: Patches for DVD-ROM ioctl()s for Linux emulator
Message-ID:  <200104290040.f3T0e3I29593@rubens.tellique.de>

next in thread | raw e-mail | index | archive | help

>Number:         26955
>Category:       kern
>Synopsis:       Patches to get the DVD-ROM ioctl()s in the Linux emulator.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Sun Apr 29 07:10:06 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        FreeBSD 4.3-STABLE i386
>Organization:
>Environment:
System: FreeBSD home.asn1c.com 4.3-STABLE FreeBSD 4.3-STABLE #13: Sat Apr 28 05:28:59 CEST 2001     root@home.asn1c.com:/usr/src/sys/compile/BORIS  i386


>Description:
I've added the missing ioctl()s for DVD-ROM access to the Linux emulator.
Please submit the patches to the cvs tree.

>How-To-Repeat:
>Fix:
Here are context-diffs to the latest stable versions of linux_ioctl.c (1.55.2.4)
and linux_ioctl.h (1.4.2.1):

*** linux_ioctl.c.orig	Sat Apr 28 03:08:21 2001
--- linux_ioctl.c	Sun Apr 29 01:39:56 2001
***************
*** 33,38 ****
--- 33,39 ----
  #include <sys/sysproto.h>
  #include <sys/proc.h>
  #include <sys/cdio.h>
+ #include <sys/dvdio.h>
  #include <sys/fcntl.h>
  #include <sys/file.h>
  #include <sys/filedesc.h>
***************
*** 827,832 ****
--- 828,958 ----
  	union linux_cdrom_addr cdsc_reladdr;
  };
  
+ struct linux_dvd_layer {
+ 	u_char	book_version:4;
+ 	u_char	book_type:4;
+ 	u_char	min_rate:4;
+ 	u_char	disc_size:4;
+ 	u_char	layer_type:4;
+ 	u_char	track_path:1;
+ 	u_char	nlayers:2;
+ 	u_char	track_density:4;
+ 	u_char	linear_density:4;
+ 	u_char	bca:1;
+ 	u_int32_t start_sector;
+ 	u_int32_t end_sector;
+ 	u_int32_t end_sector_l0;
+ };
+ 
+ struct linux_dvd_physical {
+ 	u_char	type;
+ 	u_char	layer_num;
+ 	struct linux_dvd_layer layer[4];
+ };
+ 
+ struct linux_dvd_copyright {
+ 	u_char	type;
+ 	u_char	layer_num;
+ 	u_char	cpst;
+ 	u_char	rmi;
+ };
+ 
+ struct linux_dvd_disckey {
+     	u_char	type;
+ 	unsigned agid:2;
+ 	u_char	value[2048];
+ };
+ 
+ struct linux_dvd_bca {
+     	u_char	type;
+ 	int	len;
+ 	u_char	value[188];
+ };
+ 
+ struct linux_dvd_manufact {
+ 	u_char	type;
+ 	u_char	layer_num;
+ 	int	len;
+ 	u_char	value[2048];
+ };
+ 
+ typedef union {
+ 	u_char	type;
+ 	struct linux_dvd_physical physical;
+ 	struct linux_dvd_copyright copyright;
+ 	struct linux_dvd_disckey disckey;
+ 	struct linux_dvd_bca bca;
+ 	struct linux_dvd_manufact manufact;
+ } linux_dvd_struct;
+ 
+ typedef u_char linux_dvd_key[5];
+ typedef u_char linux_dvd_challenge[10];
+ 
+ struct linux_dvd_lu_send_agid {
+     	u_char	type;
+ 	unsigned agid:2;
+ };
+ 
+ struct linux_dvd_host_send_challenge {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	linux_dvd_challenge chal;
+ };
+ 
+ struct linux_dvd_send_key {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	linux_dvd_key key;
+ };
+ 
+ struct linux_dvd_lu_send_challenge {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	linux_dvd_challenge chal;
+ };
+ 
+ struct linux_dvd_lu_send_title_key {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	linux_dvd_key title_key;
+ 	int	lba;
+ 	unsigned cpm:1;
+ 	unsigned cp_sec:1;
+ 	unsigned cgms:2;
+ };
+ 
+ struct linux_dvd_lu_send_asf {
+ 	u_char	type;
+ 	unsigned agid:2;
+ 	unsigned asf:1;
+ };
+ 
+ struct linux_dvd_host_send_rpcstate {
+ 	u_char	type;
+ 	u_char	pdrc;
+ };
+ 
+ struct linux_dvd_lu_send_rpcstate {
+ 	u_char	type:2;
+ 	u_char	vra:3;
+ 	u_char	ucca:3;
+ 	u_char	region_mask;
+ 	u_char	rpc_scheme;
+ };
+ 
+ typedef union {
+ 	u_char					type;
+ 	struct linux_dvd_lu_send_agid		lsa;
+ 	struct linux_dvd_host_send_challenge	hsc;
+ 	struct linux_dvd_send_key		lsk;
+ 	struct linux_dvd_lu_send_challenge	lsc;
+ 	struct linux_dvd_send_key		hsk;
+ 	struct linux_dvd_lu_send_title_key	lstk;
+ 	struct linux_dvd_lu_send_asf		lsasf;
+ 	struct linux_dvd_host_send_rpcstate	hrpcs;
+ 	struct linux_dvd_lu_send_rpcstate	lrpcs;
+ } linux_dvd_authinfo;
+ 
  static void
  bsd_to_linux_msf_lba(u_char af, union msf_lba *bp, union linux_cdrom_addr *lp)
  {
***************
*** 853,858 ****
--- 979,1160 ----
  }
  
  static int
+ linux_to_bsd_dvd_struct(linux_dvd_struct *lp, struct dvd_struct *bp)
+ {
+ 	bp->format = lp->type;
+ 	switch (bp->format) {
+ 	case DVD_STRUCT_PHYSICAL:
+ 		if (bp->layer_num >= 4)
+ 			return (EINVAL);
+ 		bp->layer_num = lp->physical.layer_num;
+ 		return 0;
+ 	case DVD_STRUCT_COPYRIGHT:
+ 		bp->layer_num = lp->copyright.layer_num;
+ 		return 0;
+ 	case DVD_STRUCT_DISCKEY:
+ 		bp->agid = lp->disckey.agid;
+ 		return 0;
+ 	case DVD_STRUCT_BCA:
+ 		return 0;
+ 	case DVD_STRUCT_MANUFACT:
+ 		return 0;
+ 	}
+ 	return (ENOIOCTL);
+ }
+ 
+ static int
+ bsd_to_linux_dvd_struct(struct dvd_struct *bp, linux_dvd_struct *lp)
+ {
+ 	switch (bp->format) {
+ 	case DVD_STRUCT_PHYSICAL: {
+ 		struct dvd_layer *blp = (struct dvd_layer *)bp->data;
+ 		struct linux_dvd_layer *llp =
+ 		    &lp->physical.layer[bp->layer_num];
+ 		memset(llp, 0, sizeof(*llp));
+ 		llp->book_version = blp->book_version;
+ 		llp->book_type = blp->book_type;
+ 		llp->min_rate = blp->max_rate;
+ 		llp->disc_size = blp->disc_size;
+ 		llp->layer_type = blp->layer_type;
+ 		llp->track_path = blp->track_path;
+ 		llp->nlayers = blp->nlayers;
+ 		llp->track_density = blp->track_density;
+ 		llp->linear_density = blp->linear_density;
+ 		llp->bca = blp->bca;
+ 		llp->start_sector = blp->start_sector;
+ 		llp->end_sector = blp->end_sector;
+ 		llp->end_sector_l0 = blp->end_sector_l0;
+ 		return 0;
+ 	}
+ 	case DVD_STRUCT_COPYRIGHT:
+ 		lp->copyright.cpst = bp->cpst;
+ 		lp->copyright.rmi = bp->rmi;
+ 		return 0;
+ 	case DVD_STRUCT_DISCKEY:
+ 		memcpy(lp->disckey.value, bp->data,
+ 		    sizeof(lp->disckey.value));
+ 		return 0;
+ 	case DVD_STRUCT_BCA:
+ 		lp->bca.len = bp->length;
+ 		memcpy(lp->bca.value, bp->data, sizeof(lp->bca.value));
+ 		return 0;
+ 	case DVD_STRUCT_MANUFACT:
+ 		lp->manufact.len = bp->length;
+ 		memcpy(lp->manufact.value, bp->data,
+ 		    sizeof(lp->manufact.value));
+ 		/* lp->manufact.layer_num is unused in linux (redhat 7.0) */
+ 		return 0;
+ 	}
+ 	return (ENOIOCTL);
+ }
+ 
+ static int
+ linux_to_bsd_dvd_authinfo(linux_dvd_authinfo *lp,
+ 	int *bcode, struct dvd_authinfo *bp)
+ {
+ 	switch (lp->type) {
+ 	case LINUX_DVD_LU_SEND_AGID:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_AGID;
+ 		bp->agid = lp->lsa.agid;
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_CHALLENGE:
+ 		*bcode = DVDIOCSENDKEY;
+ 		bp->format = DVD_SEND_CHALLENGE;
+ 		bp->agid = lp->hsc.agid;
+ 		memcpy(bp->keychal, lp->hsc.chal, 10);
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_KEY1:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_KEY1;
+ 		bp->agid = lp->lsk.agid;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_CHALLENGE:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_CHALLENGE;
+ 		bp->agid = lp->lsc.agid;
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_KEY2:
+ 		*bcode = DVDIOCSENDKEY;
+ 		bp->format = DVD_SEND_KEY2;
+ 		bp->agid = lp->hsk.agid;
+ 		memcpy(bp->keychal, lp->hsk.key, 5);
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_TITLE_KEY:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_TITLE_KEY;
+ 		bp->agid = lp->lstk.agid;
+ 		bp->lba = lp->lstk.lba;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_ASF:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_ASF;
+ 		bp->agid = lp->lsasf.agid;
+ 		return 0;
+ 	case LINUX_DVD_INVALIDATE_AGID:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_INVALIDATE_AGID;
+ 		bp->agid = lp->lsa.agid;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_RPC_STATE:
+ 		*bcode = DVDIOCREPORTKEY;
+ 		bp->format = DVD_REPORT_RPC;
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_RPC_STATE:
+ 		*bcode = DVDIOCSENDKEY;
+ 		bp->format = DVD_SEND_RPC;
+ 		bp->region = lp->hrpcs.pdrc;
+ 		return 0;
+ 	}
+ 	return (ENOIOCTL);
+ }
+ 
+ static int
+ bsd_to_linux_dvd_authinfo(struct dvd_authinfo *bp,
+ 	linux_dvd_authinfo *lp)
+ {
+ 	switch (lp->type) {
+ 	case LINUX_DVD_LU_SEND_AGID:
+ 		lp->lsa.agid = bp->agid;
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_CHALLENGE:
+ 		lp->type = LINUX_DVD_LU_SEND_KEY1;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_KEY1:
+ 		memcpy(lp->lsk.key, bp->keychal, sizeof(lp->lsk.key));
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_CHALLENGE:
+ 		memcpy(lp->lsc.chal, bp->keychal, sizeof(lp->lsc.chal));
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_KEY2:
+ 		lp->type = LINUX_DVD_AUTH_ESTABLISHED;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_TITLE_KEY:
+ 		memcpy(lp->lstk.title_key, bp->keychal,
+ 		    sizeof(lp->lstk.title_key));
+ 		lp->lstk.cpm = bp->cpm;
+ 		lp->lstk.cp_sec = bp->cp_sec;
+ 		lp->lstk.cgms = bp->cgms;
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_ASF:
+ 		lp->lsasf.asf = bp->asf;
+ 		return 0;
+ 	case LINUX_DVD_INVALIDATE_AGID:
+ 		return 0;
+ 	case LINUX_DVD_LU_SEND_RPC_STATE:
+ 		lp->lrpcs.type = bp->reg_type;
+ 		lp->lrpcs.vra = bp->vend_rsts;
+ 		lp->lrpcs.ucca = bp->user_rsts;
+ 		lp->lrpcs.region_mask = bp->region;
+ 		lp->lrpcs.rpc_scheme = bp->rpc_scheme;
+ 		return 0;
+ 	case LINUX_DVD_HOST_SEND_RPC_STATE:
+ 		return 0;
+ 	}
+ 	return (ENOIOCTL);
+ }
+ 
+ static int
  linux_ioctl_cdrom(struct proc *p, struct linux_ioctl_args *args)
  {
  	struct file *fp = p->p_fd->fd_ofiles[args->fd];
***************
*** 972,978 ****
--- 1274,1348 ----
  	/* LINUX_CDROMREADALL */
  	/* LINUX_CDROMCLOSETRAY */
  	/* LINUX_CDROMLOADFROMSLOT */
+ 	/* LINUX_CDROMGETSPINDOWN */
+ 	/* LINUX_CDROMSETSPINDOWN */
+ 	/* LINUX_CDROM_SET_OPTIONS */
+ 	/* LINUX_CDROM_CLEAR_OPTIONS */
+ 	/* LINUX_CDROM_SELECT_SPEED */
+ 	/* LINUX_CDROM_SELECT_DISC */
+ 	/* LINUX_CDROM_MEDIA_CHANGED */
+ 	/* LINUX_CDROM_DRIVE_STATUS */
+ 	/* LINUX_CDROM_DISC_STATUS */
+ 	/* LINUX_CDROM_CHANGER_NSLOTS */
+ 	/* LINUX_CDROM_LOCKDOOR */
+ 	/* LINUX_CDROM_DEBUG */
+ 	/* LINUX_CDROM_GET_CAPABILITY */
+ 	/* LINUX_CDROMAUDIOBUFSIZ */
+ 
+ 	case LINUX_DVD_READ_STRUCT: {
+ 		linux_dvd_struct lds;
+ 		struct dvd_struct bds;
+ 		error = copyin((caddr_t)args->arg, &lds,
+ 		    sizeof(linux_dvd_struct));
+ 		if (error)
+ 			return (error);
+ 		error = linux_to_bsd_dvd_struct(&lds, &bds);
+ 		if (error)
+ 		    	return (error);
+ 		error = fo_ioctl(fp, DVDIOCREADSTRUCTURE, (caddr_t)&bds, p);
+ 		if (error)
+ 			return (error);
+ 		error = bsd_to_linux_dvd_struct(&bds, &lds);
+ 		if (error)
+ 			return (error);
+ 		error = copyout(&lds, (caddr_t)args->arg,
+ 		    sizeof(linux_dvd_struct));
+ 		return (error);
+ 	}
+ 
+ 	/* LINUX_DVD_WRITE_STRUCT */
+ 
+ 	case LINUX_DVD_AUTH: {
+ 		linux_dvd_authinfo lda;
+ 		struct dvd_authinfo bda;
+ 		int bcode;
+ 		error = copyin((caddr_t)args->arg, &lda,
+ 		    sizeof(linux_dvd_authinfo));
+ 		if (error)
+ 			return (error);
+ 		error = linux_to_bsd_dvd_authinfo(&lda, &bcode, &bda);
+ 		if (error)
+ 		    	return (error);
+ 		error = fo_ioctl(fp, bcode, (caddr_t)&bda, p);
+ 		if (error) {
+ 			if (lda.type == LINUX_DVD_HOST_SEND_KEY2) {
+ 				lda.type = LINUX_DVD_AUTH_FAILURE;
+ 				copyout(&lda, (caddr_t)args->arg,
+ 				    sizeof(linux_dvd_authinfo));
+ 			}
+ 			return (error);
+ 		}
+ 		error = bsd_to_linux_dvd_authinfo(&bda, &lda);
+ 		if (error)
+ 			return (error);
+ 		error = copyout(&lda, (caddr_t)args->arg,
+ 		    sizeof(linux_dvd_authinfo));
+ 		return (error);
+ 	}
  
+ 	/* LINUX_CDROM_SEND_PACKET */
+ 	/* LINUX_CDROM_NEXT_WRITABLE */
+ 	/* LINUX_CDROM_LAST_WRITTEN */
  	}
  
  	return (ENOIOCTL);

*** linux_ioctl.h.orig	Sat Apr 28 03:08:13 2001
--- linux_ioctl.h	Sun Apr 29 01:39:56 2001
***************
*** 53,90 ****
  /*
   * cdrom
   */
! #define	LINUX_CDROMPAUSE	0x5301 
! #define	LINUX_CDROMRESUME	0x5302
! #define	LINUX_CDROMPLAYMSF	0x5303
! #define	LINUX_CDROMPLAYTRKIND	0x5304
! #define	LINUX_CDROMREADTOCHDR	0x5305
! #define	LINUX_CDROMREADTOCENTRY	0x5306
! #define	LINUX_CDROMSTOP		0x5307
! #define	LINUX_CDROMSTART	0x5308
! #define	LINUX_CDROMEJECT	0x5309
! #define	LINUX_CDROMVOLCTRL	0x530a
! #define	LINUX_CDROMSUBCHNL	0x530b
! #define	LINUX_CDROMREADMODE2	0x530c
! #define	LINUX_CDROMREADMODE1	0x530d
! #define	LINUX_CDROMREADAUDIO	0x530e
! #define	LINUX_CDROMEJECT_SW	0x530f
! #define	LINUX_CDROMMULTISESSION	0x5310
! #define	LINUX_CDROM_GET_UPC	0x5311
! #define	LINUX_CDROMRESET	0x5312
! #define	LINUX_CDROMVOLREAD	0x5313
! #define	LINUX_CDROMREADRAW	0x5314
! #define	LINUX_CDROMREADCOOKED	0x5315
! #define	LINUX_CDROMSEEK		0x5316
! #define	LINUX_CDROMPLAYBLK	0x5317
! #define	LINUX_CDROMREADALL	0x5318
! #define	LINUX_CDROMCLOSETRAY	0x5319
! #define	LINUX_CDROMLOADFROMSLOT	0x531a
  
  #define	LINUX_IOCTL_CDROM_MIN	LINUX_CDROMPAUSE
! #define	LINUX_IOCTL_CDROM_MAX	LINUX_CDROMLOADFROMSLOT
  
  #define	LINUX_CDROM_LBA		0x01
  #define	LINUX_CDROM_MSF		0x02
  
  /*
   * console
--- 53,123 ----
  /*
   * cdrom
   */
! #define	LINUX_CDROMPAUSE		0x5301 
! #define	LINUX_CDROMRESUME		0x5302
! #define	LINUX_CDROMPLAYMSF		0x5303
! #define	LINUX_CDROMPLAYTRKIND		0x5304
! #define	LINUX_CDROMREADTOCHDR		0x5305
! #define	LINUX_CDROMREADTOCENTRY		0x5306
! #define	LINUX_CDROMSTOP			0x5307
! #define	LINUX_CDROMSTART		0x5308
! #define	LINUX_CDROMEJECT		0x5309
! #define	LINUX_CDROMVOLCTRL		0x530a
! #define	LINUX_CDROMSUBCHNL		0x530b
! #define	LINUX_CDROMREADMODE2		0x530c
! #define	LINUX_CDROMREADMODE1		0x530d
! #define	LINUX_CDROMREADAUDIO		0x530e
! #define	LINUX_CDROMEJECT_SW		0x530f
! #define	LINUX_CDROMMULTISESSION		0x5310
! #define	LINUX_CDROM_GET_UPC		0x5311
! #define	LINUX_CDROMRESET		0x5312
! #define	LINUX_CDROMVOLREAD		0x5313
! #define	LINUX_CDROMREADRAW		0x5314
! #define	LINUX_CDROMREADCOOKED		0x5315
! #define	LINUX_CDROMSEEK			0x5316
! #define	LINUX_CDROMPLAYBLK		0x5317
! #define	LINUX_CDROMREADALL		0x5318
! #define	LINUX_CDROMCLOSETRAY		0x5319
! #define	LINUX_CDROMLOADFROMSLOT		0x531a
! #define	LINUX_CDROMGETSPINDOWN		0x531d
! #define	LINUX_CDROMSETSPINDOWN		0x531e
! #define	LINUX_CDROM_SET_OPTIONS		0x5320
! #define	LINUX_CDROM_CLEAR_OPTIONS	0x5321
! #define	LINUX_CDROM_SELECT_SPEED	0x5322
! #define	LINUX_CDROM_SELECT_DISC		0x5323
! #define	LINUX_CDROM_MEDIA_CHANGED	0x5325
! #define	LINUX_CDROM_DRIVE_STATUS	0x5326
! #define	LINUX_CDROM_DISC_STATUS		0x5327
! #define	LINUX_CDROM_CHANGER_NSLOTS	0x5328
! #define	LINUX_CDROM_LOCKDOOR		0x5329
! #define	LINUX_CDROM_DEBUG		0x5330
! #define	LINUX_CDROM_GET_CAPABILITY	0x5331
! #define	LINUX_CDROMAUDIOBUFSIZ		0x5382
! #define	LINUX_DVD_READ_STRUCT		0x5390
! #define	LINUX_DVD_WRITE_STRUCT		0x5391
! #define	LINUX_DVD_AUTH			0x5392
! #define	LINUX_CDROM_SEND_PACKET		0x5393
! #define	LINUX_CDROM_NEXT_WRITABLE	0x5394
! #define	LINUX_CDROM_LAST_WRITTEN	0x5395
  
  #define	LINUX_IOCTL_CDROM_MIN	LINUX_CDROMPAUSE
! #define	LINUX_IOCTL_CDROM_MAX	LINUX_CDROM_LAST_WRITTEN
  
  #define	LINUX_CDROM_LBA		0x01
  #define	LINUX_CDROM_MSF		0x02
+ 
+ #define	LINUX_DVD_LU_SEND_AGID		0
+ #define	LINUX_DVD_HOST_SEND_CHALLENGE	1
+ #define	LINUX_DVD_LU_SEND_KEY1		2
+ #define	LINUX_DVD_LU_SEND_CHALLENGE	3
+ #define	LINUX_DVD_HOST_SEND_KEY2	4
+ #define	LINUX_DVD_AUTH_ESTABLISHED	5
+ #define	LINUX_DVD_AUTH_FAILURE		6
+ #define	LINUX_DVD_LU_SEND_TITLE_KEY	7
+ #define	LINUX_DVD_LU_SEND_ASF		8
+ #define	LINUX_DVD_INVALIDATE_AGID	9
+ #define	LINUX_DVD_LU_SEND_RPC_STATE	10
+ #define	LINUX_DVD_HOST_SEND_RPC_STATE	11
  
  /*
   * console


Greetings,
Boris Nikolaus
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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