From bbc6bb9192167ada554c0438bb1fcc9fe13eecf9 Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Mon, 12 Oct 1998 00:38:29 +0000 Subject: [PATCH 1/4] Import the if_de driver from NetBSD-current as of yesterday onto the vendor branch. This isn't visible anywhere unless the changes are merged into the 3.0 mainline or the 2.2 branch. There are a number of important bugfixes here, but I'm waiting on a go/no-go from Jordan as to whether or not to risk it before 3.0. --- sys/pci/if_de.c | 136 ++++++++++++++++++++++++++++----------------- sys/pci/if_devar.h | 8 ++- 2 files changed, 89 insertions(+), 55 deletions(-) diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c index c9885517c43..b233af1bf1e 100644 --- a/sys/pci/if_de.c +++ b/sys/pci/if_de.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_de.c,v 1.72 1998/07/05 06:49:14 jonathan Exp $ */ +/* $NetBSD: if_de.c,v 1.80 1998/09/25 18:06:53 matt Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -2294,11 +2294,13 @@ tulip_identify_accton_nic( switch (sc->tulip_chipid) { case TULIP_21140A: strcat(sc->tulip_boardid, "EN1207 "); - sc->tulip_boardsw = &tulip_21140_accton_boardsw; + if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw) + sc->tulip_boardsw = &tulip_21140_accton_boardsw; break; case TULIP_21140: strcat(sc->tulip_boardid, "EN1207TX "); - sc->tulip_boardsw = &tulip_21140_eb_boardsw; + if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw) + sc->tulip_boardsw = &tulip_21140_eb_boardsw; break; case TULIP_21040: strcat(sc->tulip_boardid, "EN1203 "); @@ -2496,7 +2498,7 @@ tulip_srom_decode( switch (type & 0x3f) { case 0: { /* 21140[A] GPR block */ tulip_media_t media; - srom_media = (tulip_srom_media_t) dp[0]; + srom_media = (tulip_srom_media_t)(dp[0] & 0x3f); for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) { if (tulip_srom_mediums[idx3].sm_srom_type == srom_media) break; @@ -2585,7 +2587,7 @@ tulip_srom_decode( } case 2: { /* 2114[23] SIA block */ tulip_media_t media; - srom_media = (tulip_srom_media_t) dp[0]; + srom_media = (tulip_srom_media_t)(dp[0] & 0x3f); for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) { if (tulip_srom_mediums[idx3].sm_srom_type == srom_media) break; @@ -2595,10 +2597,10 @@ tulip_srom_decode( break; mi->mi_type = TULIP_MEDIAINFO_SIA; sc->tulip_mediums[media] = mi; - if (type & 0x40) { - mi->mi_sia_connectivity = dp[0] + dp[1] * 256; - mi->mi_sia_tx_rx = dp[2] + dp[3] * 256; - mi->mi_sia_general = dp[4] + dp[5] * 256; + if (dp[0] & 0x40) { + mi->mi_sia_connectivity = dp[1] + dp[2] * 256; + mi->mi_sia_tx_rx = dp[3] + dp[4] * 256; + mi->mi_sia_general = dp[5] + dp[6] * 256; dp += 6; } else { switch (media) { @@ -2625,8 +2627,8 @@ tulip_srom_decode( } } } - mi->mi_sia_gp_control = (dp[0] + dp[1] * 256) << 16; - mi->mi_sia_gp_data = (dp[2] + dp[3] * 256) << 16; + mi->mi_sia_gp_control = (dp[1] + dp[2] * 256) << 16; + mi->mi_sia_gp_data = (dp[3] + dp[4] * 256) << 16; mi++; bad_media: break; @@ -3186,6 +3188,7 @@ tulip_reset( sc->tulip_flags |= TULIP_INRESET; sc->tulip_flags &= ~(TULIP_NEEDRESET|TULIP_RXBUFSLOW); sc->tulip_if.if_flags &= ~IFF_OACTIVE; + sc->tulip_if.if_start = tulip_ifstart; } #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX) @@ -3473,11 +3476,12 @@ tulip_rx_intr( eh = *mtod(ms, struct ether_header *); #if NBPFILTER > 0 - if (sc->tulip_bpf != NULL) + if (sc->tulip_bpf != NULL) { if (me == ms) TULIP_BPF_TAP(sc, mtod(ms, caddr_t), total_len); else TULIP_BPF_MTAP(sc, ms); + } #endif sc->tulip_flags |= TULIP_RXACT; if ((sc->tulip_flags & (TULIP_PROMISC|TULIP_HASHONLY)) @@ -3692,6 +3696,8 @@ tulip_tx_intr( if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER) break; + ri->ri_free++; + descs++; d_flag = ri->ri_nextin->d_flag; if (d_flag & TULIP_DFLAG_TxLASTSEG) { if (d_flag & TULIP_DFLAG_TxSETUPPKT) { @@ -3792,8 +3798,6 @@ tulip_tx_intr( if (++ri->ri_nextin == ri->ri_last) ri->ri_nextin = ri->ri_first; - ri->ri_free++; - descs++; if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) sc->tulip_if.if_flags &= ~IFF_OACTIVE; } @@ -3818,7 +3822,7 @@ tulip_print_abnormal_interrupt( const char * const *msgp = tulip_status_bits; const char *sep; u_int32_t mask; - const char thrsh[] = "72|128\0\0\096|256\0\0\0128|512\0\0160|1024\0"; + const char thrsh[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024"; csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1; printf(TULIP_PRINTF_FMT ": abnormal interrupt:", TULIP_PRINTF_ARGS); @@ -4187,6 +4191,7 @@ tulip_txput( TULIP_PRINTF_ARGS, (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : ""); sc->tulip_flags |= TULIP_WANTTXSTART; + sc->tulip_dbg.dbg_txput_finishes[0]++; goto finish; } #endif @@ -4218,42 +4223,55 @@ tulip_txput( free = ri->ri_free; #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX) + /* + * Reclaim some dma maps from if we are out. + */ + if (sc->tulip_txmaps_free == 0) { +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_no_txmaps++; +#endif + free += tulip_tx_intr(sc); + } if (sc->tulip_txmaps_free > 0) { - map = sc->tulip_txmaps[--sc->tulip_txmaps_free]; + map = sc->tulip_txmaps[sc->tulip_txmaps_free-1]; } else { sc->tulip_flags |= TULIP_WANTTXSTART; +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[1]++; +#endif goto finish; } error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT); - if (error == EFBIG) { - /* - * The packet exceeds the number of transmit buffer - * entries that we can use for one packet, so we have - * to recopy it into one mbuf and then try again. - */ - m = tulip_mbuf_compress(m); - if (m == NULL) - goto finish; - error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT); - if (error) { + if (error != 0) { + if (error == EFBIG) { + /* + * The packet exceeds the number of transmit buffer + * entries that we can use for one packet, so we have + * to recopy it into one mbuf and then try again. + */ + m = tulip_mbuf_compress(m); + if (m == NULL) { +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[2]++; +#endif + goto finish; + } + error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT); + } + if (error != 0) { printf(TULIP_PRINTF_FMT ": unable to load tx map, " "error = %d\n", TULIP_PRINTF_ARGS, error); +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[3]++; +#endif goto finish; } - } else if (error != 0) { - /* - * Some other error (possibly resource shortage?) has ocurred. - * Report it. - */ - printf(TULIP_PRINTF_FMT ": unable to load tx map, error = %d\n", - TULIP_PRINTF_ARGS, error); - goto finish; } if ((free -= (map->dm_nsegs + 1) / 2) <= 0 /* * See if there's any unclaimed space in the transmit ring. */ - || (free += tulip_tx_intr(sc)) <= 0) { + && (free += tulip_tx_intr(sc)) <= 0) { /* * There's no more room but since nothing * has been committed at this point, just @@ -4261,6 +4279,10 @@ tulip_txput( * mbuf and return. */ sc->tulip_flags |= TULIP_WANTTXSTART; +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[4]++; +#endif + bus_dmamap_unload(sc->tulip_dmatag, map); goto finish; } for (; map->dm_nsegs - segcnt > 1; segcnt += 2) { @@ -4289,6 +4311,7 @@ tulip_txput( TULIP_TXMAP_PRESYNC(sc, map); M_SETCTX(m, map); map = NULL; + --sc->tulip_txmaps_free; /* commit to using the dmamap */ #else /* !TULIP_BUS_DMA */ @@ -4330,6 +4353,9 @@ tulip_txput( * mbuf and return. */ sc->tulip_flags |= TULIP_WANTTXSTART; +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[1]++; +#endif goto finish; } } @@ -4423,6 +4449,7 @@ tulip_txput( if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) { sc->tulip_if.if_flags |= IFF_OACTIVE; + sc->tulip_if.if_start = tulip_ifstart; TULIP_PERFEND(txput); return NULL; } @@ -4431,9 +4458,11 @@ tulip_txput( * switch back to the single queueing ifstart. */ sc->tulip_flags &= ~TULIP_WANTTXSTART; - sc->tulip_if.if_start = tulip_ifstart_one; if (sc->tulip_txtimer == 0) sc->tulip_txtimer = TULIP_TXTIMER; +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[5]++; +#endif /* * If we want a txstart, there must be not enough space in the @@ -4445,6 +4474,9 @@ tulip_txput( * WANTTXSTART thereby causing TXINTR to be cleared. */ finish: +#if defined(TULIP_DEBUG) + sc->tulip_dbg.dbg_txput_finishes[6]++; +#endif if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_DOINGSETUP)) { sc->tulip_if.if_flags |= IFF_OACTIVE; sc->tulip_if.if_start = tulip_ifstart; @@ -4452,13 +4484,11 @@ tulip_txput( sc->tulip_intrmask |= TULIP_STS_TXINTR; TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); } -#if 0 /* this isn't working right yet */ } else if ((sc->tulip_flags & TULIP_PROMISC) == 0) { if (sc->tulip_intrmask & TULIP_STS_TXINTR) { sc->tulip_intrmask &= ~TULIP_STS_TXINTR; TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); } -#endif } TULIP_PERFEND(txput); return m; @@ -4755,6 +4785,8 @@ tulip_ifstart( break; } } + if (sc->tulip_if.if_snd.ifq_head == NULL) + sc->tulip_if.if_start = tulip_ifstart_one; } TULIP_PERFEND(ifstart); @@ -5466,7 +5498,7 @@ tulip_pci_attach( int retval, idx; u_int32_t revinfo, cfdainfo, id; #if !defined(TULIP_IOMAPPED) && defined(__FreeBSD__) - vm_offset_t pa_csrs; + vaddr_t pa_csrs; #endif unsigned csroffset = TULIP_PCI_CSROFFSET; unsigned csrsize = TULIP_PCI_CSRSIZE; @@ -5503,14 +5535,14 @@ tulip_pci_attach( #endif /* __bsdi__ */ if (PCI_VENDORID(id) == DEC_VENDORID) { - if (PCI_CHIPID(id) == CHIPID_21040) chipid = TULIP_21040; - else if (PCI_CHIPID(id) == CHIPID_21140) { - chipid = (revinfo >= 0x20) ? TULIP_21140A : TULIP_21140; - } else if (PCI_CHIPID(id) == CHIPID_21142) { - chipid = (revinfo >= 0x20) ? TULIP_21143 : TULIP_21142; - } - else if (PCI_CHIPID(id) == CHIPID_21041) chipid = TULIP_21041; - else if (PCI_CHIPID(id) == CHIPID_21142) chipid = TULIP_21142; + if (PCI_CHIPID(id) == CHIPID_21040) + chipid = TULIP_21040; + else if (PCI_CHIPID(id) == CHIPID_21041) + chipid = TULIP_21041; + else if (PCI_CHIPID(id) == CHIPID_21140) + chipid = (revinfo >= 0x20) ? TULIP_21140A : TULIP_21140; + else if (PCI_CHIPID(id) == CHIPID_21142) + chipid = (revinfo >= 0x20) ? TULIP_21143 : TULIP_21142; } if (chipid == TULIP_CHIPID_UNKNOWN) return; @@ -5551,11 +5583,11 @@ tulip_pci_attach( sc->tulip_features |= TULIP_HAVE_POWERMGMT; if (chipid == TULIP_21041 || chipid == TULIP_21142 || chipid == TULIP_21143) { sc->tulip_features |= TULIP_HAVE_DUALSENSE; - if (chipid != TULIP_21041 || sc->tulip_revinfo >= 0x20) + if (chipid != TULIP_21041 || revinfo >= 0x20) sc->tulip_features |= TULIP_HAVE_SIANWAY; if (chipid != TULIP_21041) sc->tulip_features |= TULIP_HAVE_SIAGP|TULIP_HAVE_RXBADOVRFLW|TULIP_HAVE_STOREFWD; - if (chipid != TULIP_21041 && sc->tulip_revinfo >= 0x20) + if (chipid != TULIP_21041 && revinfo >= 0x20) sc->tulip_features |= TULIP_HAVE_SIA100; } @@ -5603,7 +5635,7 @@ tulip_pci_attach( #if defined(TULIP_IOMAPPED) retval = pci_map_port(config_id, PCI_CBIO, &csr_base); #else - retval = pci_map_mem(config_id, PCI_CBMA, (vm_offset_t *) &csr_base, &pa_csrs); + retval = pci_map_mem(config_id, PCI_CBMA, (vaddr_t *) &csr_base, &pa_csrs); #endif if (!retval) { free((caddr_t) sc, M_DEVBUF); @@ -5617,7 +5649,7 @@ tulip_pci_attach( #if defined(TULIP_IOMAPPED) csr_base = ia->ia_iobase; #else - csr_base = (vm_offset_t) mapphys((vm_offset_t) ia->ia_maddr, ia->ia_msize); + csr_base = (vaddr_t) mapphys((vaddr_t) ia->ia_maddr, ia->ia_msize); #endif #endif /* __bsdi__ */ diff --git a/sys/pci/if_devar.h b/sys/pci/if_devar.h index eaa9e7a65c1..66d4aa41059 100644 --- a/sys/pci/if_devar.h +++ b/sys/pci/if_devar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_devar.h,v 1.27 1998/05/25 22:13:28 mark Exp $ */ +/* $NetBSD: if_devar.h,v 1.31 1998/09/29 22:40:52 matt Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -166,7 +166,7 @@ typedef struct { * architecture which can't handle unaligned accesses) because with * 100Mb/s cards the copying is just too much of a hit. */ -#if defined(__alpha__) || defined(__arm32__) +#if !defined(__i386__) && !defined(__vax__) #define TULIP_COPY_RXDATA 1 #endif @@ -630,6 +630,8 @@ struct _tulip_softc_t { u_int32_t dbg_rxintrs; u_int32_t dbg_last_rxintrs; u_int32_t dbg_high_rxintrs_hz; + u_int32_t dbg_no_txmaps; + u_int32_t dbg_txput_finishes[8]; u_int32_t dbg_txprobes_ok[TULIP_MEDIA_MAX]; u_int32_t dbg_txprobes_failed[TULIP_MEDIA_MAX]; u_int32_t dbg_events[TULIP_MEDIAPOLL_MAX]; @@ -998,7 +1000,7 @@ extern struct cfdriver de_cd; #if !defined(TULIP_BUS_DMA) || defined(TULIP_BUS_DMA_NORX) || defined(TULIP_BUS_DMA_NOTX) #if defined(__alpha__) /* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */ -#define TULIP_KVATOPHYS(sc, va) alpha_XXX_dmamap((vm_offset_t)(va)) +#define TULIP_KVATOPHYS(sc, va) alpha_XXX_dmamap((vaddr_t)(va)) #endif #endif #endif /* __NetBSD__ */ From 743b865fa90176ab9e8dca059c0590980b29dce9 Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Sun, 14 Mar 1999 06:43:49 +0000 Subject: [PATCH 2/4] Update if_de driver from NetBSD as at rev 1.82 - import to vendor branch. --- sys/pci/if_de.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c index b233af1bf1e..b5e2829eefc 100644 --- a/sys/pci/if_de.c +++ b/sys/pci/if_de.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_de.c,v 1.80 1998/09/25 18:06:53 matt Exp $ */ +/* $NetBSD: if_de.c,v 1.82 1999/02/28 17:08:51 explorer Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -3176,7 +3176,8 @@ tulip_reset( * to properly reset its internal pathways to the right places. * Grrrr. */ - if (sc->tulip_boardsw->bd_media_preset != NULL) + if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0 + && sc->tulip_boardsw->bd_media_preset != NULL) (*sc->tulip_boardsw->bd_media_preset)(sc); TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); @@ -4437,8 +4438,6 @@ tulip_txput( ri->ri_nextout->d_status = TULIP_DSTS_OWNER; TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout, sizeof(u_int32_t)); - TULIP_CSR_WRITE(sc, csr_txpoll, 1); - /* * This advances the ring for us. */ @@ -4448,6 +4447,7 @@ tulip_txput( TULIP_PERFEND(txput); if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) { + TULIP_CSR_WRITE(sc, csr_txpoll, 1); sc->tulip_if.if_flags |= IFF_OACTIVE; sc->tulip_if.if_start = tulip_ifstart; TULIP_PERFEND(txput); @@ -4490,6 +4490,7 @@ tulip_txput( TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); } } + TULIP_CSR_WRITE(sc, csr_txpoll, 1); TULIP_PERFEND(txput); return m; } @@ -5014,7 +5015,7 @@ tulip_attach( #if defined(__NetBSD__) && NRND > 0 rnd_attach_source(&sc->tulip_rndsource, sc->tulip_dev.dv_xname, - RND_TYPE_NET); + RND_TYPE_NET, 0); #endif } @@ -5491,10 +5492,10 @@ tulip_pci_attach( (sc)->tulip_pci_busno = parent; \ (sc)->tulip_pci_devno = pa->pa_device; \ } while (0) -#endif /* __NetBSD__ */ #if defined(__alpha__) tulip_media_t media = TULIP_MEDIA_UNKNOWN; #endif +#endif /* __NetBSD__ */ int retval, idx; u_int32_t revinfo, cfdainfo, id; #if !defined(TULIP_IOMAPPED) && defined(__FreeBSD__) @@ -5605,14 +5606,13 @@ tulip_pci_attach( * force a probe. */ switch ((cfdainfo >> 8) & 0xff) { - case 1: media = chipid > TULIP_DE425 ? - TULIP_MEDIA_AUI : TULIP_MEDIA_AUIBNC; break; - case 2: media = chipid > TULIP_DE425 ? - TULIP_MEDIA_BNC : TULIP_MEDIA_UNKNOWN; break; - case 3: media = TULIP_MEDIA_10BASET; break; - case 4: media = TULIP_MEDIA_10BASET_FD; break; - case 5: media = TULIP_MEDIA_100BASETX; break; - case 6: media = TULIP_MEDIA_100BASETX_FD; break; + case 1: media = chipid > TULIP_DE425 ? TULIP_MEDIA_AUI : TULIP_MEDIA_AUIBNC; break; + case 2: media = chipid > TULIP_DE425 ? TULIP_MEDIA_BNC : TULIP_MEDIA_UNKNOWN; break; + case 3: media = TULIP_MEDIA_10BASET; break; + case 4: media = TULIP_MEDIA_10BASET_FD; break; + case 5: media = TULIP_MEDIA_100BASETX; break; + case 6: media = TULIP_MEDIA_100BASETX_FD; break; + default: media = TULIP_MEDIA_UNKNOWN; break; } #endif @@ -5783,11 +5783,13 @@ tulip_pci_attach( #endif s = TULIP_RAISESPL(); - tulip_reset(sc); +#if defined(__alpha__) && defined(__NetBSD__) + sc->tulip_media = media; +#endif tulip_attach(sc); #if defined(__alpha__) && defined(__NetBSD__) - if (media != TULIP_MEDIA_UNKNOWN) - tulip_linkup(sc, media); + if (sc->tulip_media != TULIP_MEDIA_UNKNOWN) + tulip_linkup(sc, media); #endif TULIP_RESTORESPL(s); } From 9e19fa498064531729edc14c16b8f8e263b85bec Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Sun, 8 Aug 1999 19:40:01 +0000 Subject: [PATCH 3/4] Import NetBSD if_de driver as at rev 1.86 (990809) to vendor branch. --- sys/pci/if_de.c | 115 +++++++++++++++++++++++++++++++++++++++------ sys/pci/if_devar.h | 4 +- 2 files changed, 103 insertions(+), 16 deletions(-) diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c index b5e2829eefc..5ad8dfad556 100644 --- a/sys/pci/if_de.c +++ b/sys/pci/if_de.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_de.c,v 1.82 1999/02/28 17:08:51 explorer Exp $ */ +/* $NetBSD: if_de.c,v 1.86 1999/06/01 19:17:59 thorpej Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -2372,6 +2372,45 @@ tulip_identify_asante_nic( } } +static void +tulip_identify_compex_nic( + tulip_softc_t * const sc) +{ + strcpy(sc->tulip_boardid, "COMPEX "); + if (sc->tulip_chipid == TULIP_21140A) { + int root_unit; + tulip_softc_t *root_sc = NULL; + + strcat(sc->tulip_boardid, "400TX/PCI "); + /* + * All 4 chips on these boards share an interrupt. This code + * copied from tulip_read_macaddr. + */ + sc->tulip_features |= TULIP_HAVE_SHAREDINTR; + for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) { + root_sc = TULIP_UNIT_TO_SOFTC(root_unit); + if (root_sc == NULL + || !(root_sc->tulip_features & TULIP_HAVE_SLAVEDINTR)) + break; + root_sc = NULL; + } + if (root_sc != NULL + && root_sc->tulip_chipid == sc->tulip_chipid + && root_sc->tulip_pci_busno == sc->tulip_pci_busno) { + sc->tulip_features |= TULIP_HAVE_SLAVEDINTR; + sc->tulip_slaves = root_sc->tulip_slaves; + root_sc->tulip_slaves = sc; + } else if(sc->tulip_features & TULIP_HAVE_SLAVEDINTR) { + printf("\nCannot find master device for de%d interrupts", + sc->tulip_unit); + } + } else { + strcat(sc->tulip_boardid, "unknown "); + } + /* sc->tulip_boardsw = &tulip_21140_eb_boardsw; */ + return; +} + static int tulip_srom_decode( tulip_softc_t * const sc) @@ -2746,6 +2785,7 @@ static const struct { { tulip_identify_cogent_nic, { 0x00, 0x00, 0x92 } }, { tulip_identify_asante_nic, { 0x00, 0x00, 0x94 } }, { tulip_identify_accton_nic, { 0x00, 0x00, 0xE8 } }, + { tulip_identify_compex_nic, { 0x00, 0x80, 0x48 } }, { NULL } }; @@ -2800,7 +2840,7 @@ tulip_read_macaddr( * it's the best we can do until every one switches to * the new SROM format. */ - + sc->tulip_boardsw = &tulip_21140_eb_boardsw; } tulip_srom_read(sc); @@ -3094,7 +3134,11 @@ tulip_addr_filter( while (enm != NULL) { if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) { hash = tulip_mchash(enm->enm_addrlo); +#if BYTE_ORDER == BIG_ENDIAN + sp[hash >> 4] |= bswap32(1 << (hash & 0xF)); +#else sp[hash >> 4] |= 1 << (hash & 0xF); +#endif } else { sc->tulip_flags |= TULIP_ALLMULTI; sc->tulip_flags &= ~(TULIP_WANTHASHONLY|TULIP_WANTHASHPERFECT); @@ -3108,14 +3152,28 @@ tulip_addr_filter( */ if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) { hash = tulip_mchash(etherbroadcastaddr); +#if BYTE_ORDER == BIG_ENDIAN + sp[hash >> 4] |= bswap32(1 << (hash & 0xF)); +#else sp[hash >> 4] |= 1 << (hash & 0xF); +#endif if (sc->tulip_flags & TULIP_WANTHASHONLY) { hash = tulip_mchash(sc->tulip_enaddr); +#if BYTE_ORDER == BIG_ENDIAN + sp[hash >> 4] |= bswap32(1 << (hash & 0xF)); +#else sp[hash >> 4] |= 1 << (hash & 0xF); +#endif } else { +#if BYTE_ORDER == BIG_ENDIAN + sp[39] = ((u_int16_t *) sc->tulip_enaddr)[0] << 16; + sp[40] = ((u_int16_t *) sc->tulip_enaddr)[1] << 16; + sp[41] = ((u_int16_t *) sc->tulip_enaddr)[2] << 16; +#else sp[39] = ((u_int16_t *) sc->tulip_enaddr)[0]; sp[40] = ((u_int16_t *) sc->tulip_enaddr)[1]; sp[41] = ((u_int16_t *) sc->tulip_enaddr)[2]; +#endif } } } @@ -3129,9 +3187,15 @@ tulip_addr_filter( ETHER_FIRST_MULTI(step, TULIP_ETHERCOM(sc), enm); for (; enm != NULL; idx++) { if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) { +#if BYTE_ORDER == BIG_ENDIAN + *sp++ = ((u_int16_t *) enm->enm_addrlo)[0] << 16; + *sp++ = ((u_int16_t *) enm->enm_addrlo)[1] << 16; + *sp++ = ((u_int16_t *) enm->enm_addrlo)[2] << 16; +#else *sp++ = ((u_int16_t *) enm->enm_addrlo)[0]; *sp++ = ((u_int16_t *) enm->enm_addrlo)[1]; *sp++ = ((u_int16_t *) enm->enm_addrlo)[2]; +#endif } else { sc->tulip_flags |= TULIP_ALLMULTI; break; @@ -3142,17 +3206,29 @@ tulip_addr_filter( * Add the broadcast address. */ idx++; +#if BYTE_ORDER == BIG_ENDIAN + *sp++ = 0xFFFF << 16; + *sp++ = 0xFFFF << 16; + *sp++ = 0xFFFF << 16; +#else *sp++ = 0xFFFF; *sp++ = 0xFFFF; *sp++ = 0xFFFF; +#endif } /* * Pad the rest with our hardware address */ for (; idx < 16; idx++) { +#if BYTE_ORDER == BIG_ENDIAN + *sp++ = ((u_int16_t *) sc->tulip_enaddr)[0] << 16; + *sp++ = ((u_int16_t *) sc->tulip_enaddr)[1] << 16; + *sp++ = ((u_int16_t *) sc->tulip_enaddr)[2] << 16; +#else *sp++ = ((u_int16_t *) sc->tulip_enaddr)[0]; *sp++ = ((u_int16_t *) sc->tulip_enaddr)[1]; *sp++ = ((u_int16_t *) sc->tulip_enaddr)[2]; +#endif } } #if defined(IFF_ALLMULTI) @@ -3206,7 +3282,8 @@ tulip_reset( (1 << (TULIP_BURSTSIZE(sc->tulip_unit) + 8)) |TULIP_BUSMODE_CACHE_ALIGN8 |TULIP_BUSMODE_READMULTIPLE - |(BYTE_ORDER != LITTLE_ENDIAN ? TULIP_BUSMODE_BIGENDIAN : 0)); + |(BYTE_ORDER != LITTLE_ENDIAN ? + TULIP_BUSMODE_DESC_BIGENDIAN : 0)); sc->tulip_txtimer = 0; sc->tulip_txq.ifq_maxlen = TULIP_TXDESCS; @@ -3490,7 +3567,6 @@ tulip_rx_intr( && !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_enaddr)) goto next; accept = 1; - total_len -= sizeof(struct ether_header); } else { ifp->if_ierrors++; if (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG)) { @@ -3565,7 +3641,7 @@ tulip_rx_intr( MGETHDR(m0, M_DONTWAIT, MT_DATA); if (m0 != NULL) { #if defined(TULIP_COPY_RXDATA) - if (!accept || total_len >= MHLEN) { + if (!accept || total_len >= (MHLEN - 2)) { #endif MCLGET(m0, M_DONTWAIT); if ((m0->m_flags & M_EXT) == 0) { @@ -3585,25 +3661,30 @@ tulip_rx_intr( eh.ether_type = ntohs(eh.ether_type); #endif #if !defined(TULIP_COPY_RXDATA) - ms->m_data += sizeof(struct ether_header); - ms->m_len -= sizeof(struct ether_header); ms->m_pkthdr.len = total_len; ms->m_pkthdr.rcvif = ifp; +#if defined(__NetBSD__) + (*ifp->if_input)(ifp, ms); +#else + m_adj(ms, sizeof(struct ether_header); ether_input(ifp, &eh, ms); +#endif /* __NetBSD__ */ #else #ifdef BIG_PACKET #error BIG_PACKET is incompatible with TULIP_COPY_RXDATA #endif - if (ms == me) - bcopy(mtod(ms, caddr_t) + sizeof(struct ether_header), - mtod(m0, caddr_t), total_len); - else - m_copydata(ms, 0, total_len, mtod(m0, caddr_t)); + m0->m_data += 2; /* align data after header */ + m_copydata(ms, 0, total_len, mtod(m0, caddr_t)); m0->m_len = m0->m_pkthdr.len = total_len; m0->m_pkthdr.rcvif = ifp; +#if defined(__NetBSD__) + (*ifp->if_input)(ifp, m0); +#else + m_adj(m0, sizeof(struct ether_header); ether_input(ifp, &eh, m0); +#endif /* __NetBSD__ */ m0 = ms; -#endif +#endif /* ! TULIP_COPY_RXDATA */ } ms = m0; } @@ -4923,7 +5004,7 @@ tulip_attach( ifp->if_start = tulip_ifstart; ifp->if_watchdog = tulip_ifwatchdog; ifp->if_timer = 1; -#if !defined(__bsdi__) || _BSDI_VERSION < 199401 +#if (!defined(__bsdi__) || _BSDI_VERSION < 199401) && !defined(__NetBSD__) ifp->if_output = ether_output; #endif #if defined(__bsdi__) && _BSDI_VERSION < 199401 @@ -5676,6 +5757,12 @@ tulip_pci_attach( printf(": unable to map device registers\n"); return; } + + /* Make sure bus mastering is enabled. */ + pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, + pci_conf_read(pa->pa_pc, pa->pa_tag, + PCI_COMMAND_STATUS_REG) | + PCI_COMMAND_MASTER_ENABLE); } #endif /* __NetBSD__ */ diff --git a/sys/pci/if_devar.h b/sys/pci/if_devar.h index 66d4aa41059..0f0c972710f 100644 --- a/sys/pci/if_devar.h +++ b/sys/pci/if_devar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_devar.h,v 1.31 1998/09/29 22:40:52 matt Exp $ */ +/* $NetBSD: if_devar.h,v 1.32 1999/04/01 14:55:25 tsubai Exp $ */ /*- * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com) @@ -1060,7 +1060,7 @@ extern struct cfdriver de_cd; #ifndef TULIP_RAISESOFTSPL #define TULIP_RAISESOFTSPL() splnet() #endif -#ifndef TULUP_RESTORESPL +#ifndef TULIP_RESTORESPL #define TULIP_RESTORESPL(s) splx(s) #endif From 3ae9291301ebfc1278c62a15e0ef1bba671106dc Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Sun, 19 Dec 1999 13:50:37 +0000 Subject: [PATCH 4/4] Import NetBSD's mailwrapper to redirect /usr/sbin/sendmail to the user's chosen mailer. Obtained from: NetBSD --- etc/mail/mailer.conf | 8 ++ etc/mailer.conf | 8 ++ share/man/man5/mailer.conf.5 | 97 +++++++++++++++++ usr.sbin/mailwrapper/Makefile | 13 +++ usr.sbin/mailwrapper/mailwrapper.8 | 144 +++++++++++++++++++++++++ usr.sbin/mailwrapper/mailwrapper.c | 165 +++++++++++++++++++++++++++++ 6 files changed, 435 insertions(+) create mode 100644 etc/mail/mailer.conf create mode 100644 etc/mailer.conf create mode 100644 share/man/man5/mailer.conf.5 create mode 100644 usr.sbin/mailwrapper/Makefile create mode 100644 usr.sbin/mailwrapper/mailwrapper.8 create mode 100644 usr.sbin/mailwrapper/mailwrapper.c diff --git a/etc/mail/mailer.conf b/etc/mail/mailer.conf new file mode 100644 index 00000000000..6d2b3c5ec3c --- /dev/null +++ b/etc/mail/mailer.conf @@ -0,0 +1,8 @@ +# $NetBSD: mailer.conf,v 1.2 1999/02/05 18:11:23 perry Exp $ +# +# Execute the "real" sendmail program, named /usr/libexec/sendmail/sendmail +# +sendmail /usr/libexec/sendmail/sendmail +send-mail /usr/libexec/sendmail/sendmail +mailq /usr/libexec/sendmail/sendmail +newaliases /usr/libexec/sendmail/sendmail diff --git a/etc/mailer.conf b/etc/mailer.conf new file mode 100644 index 00000000000..6d2b3c5ec3c --- /dev/null +++ b/etc/mailer.conf @@ -0,0 +1,8 @@ +# $NetBSD: mailer.conf,v 1.2 1999/02/05 18:11:23 perry Exp $ +# +# Execute the "real" sendmail program, named /usr/libexec/sendmail/sendmail +# +sendmail /usr/libexec/sendmail/sendmail +send-mail /usr/libexec/sendmail/sendmail +mailq /usr/libexec/sendmail/sendmail +newaliases /usr/libexec/sendmail/sendmail diff --git a/share/man/man5/mailer.conf.5 b/share/man/man5/mailer.conf.5 new file mode 100644 index 00000000000..6901cd733d1 --- /dev/null +++ b/share/man/man5/mailer.conf.5 @@ -0,0 +1,97 @@ +.\" $NetBSD: mailer.conf.5,v 1.2 1999/05/29 18:18:30 christos Exp $ +.\" +.\" Copyright (c) 1998 +.\" Perry E. Metzger. 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. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgment: +.\" This product includes software developed for the NetBSD Project +.\" by Perry E. Metzger. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. +.\" +.\" The following requests are required for all man pages. +.Dd December 16, 1998 +.Dt MAILER.CONF 5 +.Os +.Sh NAME +.Nm mailer.conf +.Nd configuration file for +.Xr mailwrapper 8 . +.Sh DESCRIPTION +.Pp +The file +.Pa /etc/mailer.conf +contains a series of pairs. The first member of each pair is the name +of a program invoking +.Xr mailwrapper 8 +which is typically a symbolic link to +.Pa /usr/sbin/sendmail . +(On a typical system, +.Xr newaliases 1 +and +.Xr mailq 1 +would be set up this way.) +The second member of each pair is the name of the program to +actually execute when the first name is invoked. The file may also +contain comments, denoted by a # mark in the first column of any line. +.Sh EXAMPLES +The following is an example of how to set up an +.Nm +for traditional sendmail invocation behavior. +.Bd -literal +# Execute the "real" sendmail program, named /usr/libexec/sendmail/sendmail +sendmail /usr/libexec/sendmail/sendmail +send-mail /usr/libexec/sendmail/sendmail +mailq /usr/libexec/sendmail/sendmail +newaliases /usr/libexec/sendmail/sendmail +.Ed +.Pp +This example shows how to invoke the fictitious "newmail" program in +place of sendmail. +.Bd -literal +# Emulate sendmail using postfix +sendmail /usr/libexec/postfix/sendmail +send-mail /usr/libexec/postfix/sendmail +mailq /usr/libexec/postfix/sendmail +newaliases /usr/libexec/postfix/sendmail +.Ed +.Sh FILES +/etc/mailer.conf +.Sh SEE ALSO +.Xr mail 1 , +.Xr mailq 1 , +.Xr mailwrapper 8 , +.Xr newaliases 1 , +.Xr sendmail 8 . +.Sh HISTORY +.Nm +appeared in +.Nx 1.4 . +.Sh AUTHORS +Perry E. Metzger +.Sh BUGS +The entire reason this program exists is a crock. Instead, a command +for how to submit mail should be standardized, and all the "behave +differently if invoked with a different name" behavior of things like +.Xr mailq 1 +should go away. diff --git a/usr.sbin/mailwrapper/Makefile b/usr.sbin/mailwrapper/Makefile new file mode 100644 index 00000000000..ed1130fbfcf --- /dev/null +++ b/usr.sbin/mailwrapper/Makefile @@ -0,0 +1,13 @@ +# $NetBSD: Makefile,v 1.4 1999/03/25 16:40:18 is Exp $ + +PROG= mailwrapper +MAN= mailwrapper.8 mailer.conf.5 + +DPADD+= ${LIBUTIL} +LDADD+= -lutil + +SYMLINKS= /usr/sbin/mailwrapper /usr/sbin/sendmail \ + /usr/sbin/mailwrapper /usr/bin/newaliases \ + /usr/sbin/mailwrapper /usr/bin/mailq + +.include diff --git a/usr.sbin/mailwrapper/mailwrapper.8 b/usr.sbin/mailwrapper/mailwrapper.8 new file mode 100644 index 00000000000..eb34a12becc --- /dev/null +++ b/usr.sbin/mailwrapper/mailwrapper.8 @@ -0,0 +1,144 @@ +.\" $NetBSD: mailwrapper.8,v 1.6 1999/03/25 16:40:17 is Exp $ +.\" +.\" Copyright (c) 1998 +.\" Perry E. Metzger. 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. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgment: +.\" This product includes software developed for the NetBSD Project +.\" by Perry E. Metzger. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. +.\" +.\" The following requests are required for all man pages. +.Dd December 16, 1998 +.Dt MAILWRAPPER 8 +.Os +.Sh NAME +.Nm mailwrapper +.Nd invoke appropriate MTA software based on configuration file +.Sh SYNOPSIS +Special. See below. +.Sh DESCRIPTION +At one time, the only Mail Transfer Agent (MTA) software easily available +was +.Xr sendmail 8 . +As a result of this, most Mail User Agents (MUAs) such as +.Xr mail 1 +had the path and calling conventions expected by +.Xr sendmail 8 +compiled in. +.Pp +Times have changed, however. +On a modern +.Nx +system, the administrator may wish to use one of several +available MTAs. +.Pp +It would be difficult to modify all MUA software typically available +on a system, so most of the authors of alternative MTAs have written +their front end message submission programs so that they use the same +calling conventions as +.Xr sendmail 8 +and may be put into place instead of +.Xr sendmail 8 +in +.Pa /usr/sbin/sendmail . +.Pp +.Xr sendmail 8 +also typically has aliases named +.Xr mailq 1 +and +.Xr newaliases 1 +linked to it. The program knows to behave differently when its +.Va argv[0] +is +.Dq mailq +or +.Dq newaliases +and behaves appropriately. Typically, replacement MTAs provide similar +functionality, either through a program that also switches behavior +based on calling name, or through a set of programs that provide +similar functionality. +.Pp +Although having replacement programs that plug replace +.Xr sendmail 8 +helps in installing alternative MTAs, it essentially makes the +configuration of the system depend on hard installing new programs in +.Pa /usr . +This leads to configuration problems for many administrators, since +they may wish to install a new MTA without altering the system +provided +.Pa /usr . +(This may be, for example, to avoid having upgrade problems when a new +version of the system is installed over the old.) +They may also have a shared +.Pa /usr +among several +machines, and may wish to avoid placing implicit configuration +information in a read-only +.Pa /usr . +.Pp +The +.Nm +program is designed to replace +.Pa /usr/sbin/sendmail +and to invoke an appropriate MTA instead of +.Xr sendmail 8 +based on configuration information placed in +.Pa /etc/mailer.conf . +This permits the administrator to configure which MTA is to be invoked on +the system at run time. +.Sh FILES +Configuration for +.Nm +is kept in +.Pa /etc/mailer.conf . +.Pa /usr/sbin/sendmail +is typically set up as a symlink to +.Nm +which is not usually invoked on its own. +.Sh DIAGNOSTICS +.Nm +will return an error value and print a diagnostic if its configuration +file is missing or malformed, or does not contain a mapping for the +name under which +.Nm +was invoked. +.Sh SEE ALSO +.Xr mail 1 , +.Xr mailq 1 , +.Xr mailer.conf 5 , +.Xr newaliases 1 , +.Xr sendmail 8 . +.Sh HISTORY +.Nm +appeared in +.Nx 1.4 . +.Sh AUTHORS +Perry E. Metzger +.Sh BUGS +The entire reason this program exists is a crock. Instead, a command +for how to submit mail should be standardized, and all the "behave +differently if invoked with a different name" behavior of things like +.Xr mailq 1 +should go away. diff --git a/usr.sbin/mailwrapper/mailwrapper.c b/usr.sbin/mailwrapper/mailwrapper.c new file mode 100644 index 00000000000..4d7d67d1a8d --- /dev/null +++ b/usr.sbin/mailwrapper/mailwrapper.c @@ -0,0 +1,165 @@ +/* $NetBSD: mailwrapper.c,v 1.3 1999/05/29 18:18:15 christos Exp $ */ + +/* + * Copyright (c) 1998 + * Perry E. Metzger. 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgment: + * This product includes software developed for the NetBSD Project + * by Perry E. Metzger. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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. + */ + +#include +#include +#include +#include +#include +#include + +#define _PATH_MAILERCONF "/etc/mailer.conf" + +struct arglist { + size_t argc, maxc; + char **argv; +}; + +int main __P((int, char *[], char *[])); + +static void initarg __P((struct arglist *)); +static void addarg __P((struct arglist *, const char *, int)); +static void freearg __P((struct arglist *, int)); + +extern const char *__progname; /* from crt0.o */ + +static void +initarg(al) + struct arglist *al; +{ + al->argc = 0; + al->maxc = 10; + if ((al->argv = malloc(al->maxc * sizeof(char *))) == NULL) + err(1, "mailwrapper"); +} + +static void +addarg(al, arg, copy) + struct arglist *al; + const char *arg; + int copy; +{ + if (al->argc == al->maxc) { + al->maxc <<= 1; + if ((al->argv = realloc(al->argv, + al->maxc * sizeof(char *))) == NULL) + err(1, "mailwrapper"); + } + if (copy) { + if ((al->argv[al->argc++] = strdup(arg)) == NULL) + err(1, "mailwrapper:"); + } else + al->argv[al->argc++] = (char *)arg; +} + +static void +freearg(al, copy) + struct arglist *al; + int copy; +{ + size_t i; + if (copy) + for (i = 0; i < al->argc; i++) + free(al->argv[i]); + free(al->argv); +} + +int +main(argc, argv, envp) + int argc; + char *argv[]; + char *envp[]; +{ + FILE *config; + char *line, *cp, *from, *to, *ap; + size_t len, lineno = 0; + struct arglist al; + + initarg(&al); + for (len = 0; len < argc; len++) + addarg(&al, argv[len], 0); + + if ((config = fopen(_PATH_MAILERCONF, "r")) == NULL) + err(1, "mailwrapper: can't open %s", _PATH_MAILERCONF); + + for (;;) { + if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) { + if (feof(config)) + errx(1, "mailwrapper: no mapping in %s", + _PATH_MAILERCONF); + err(1, "mailwrapper"); + } + +#define WS " \t\n" + cp = line; + + cp += strspn(cp, WS); + if (cp[0] == '\0') { + /* empty line */ + free(line); + continue; + } + + if ((from = strsep(&cp, WS)) == NULL) + goto parse_error; + + cp += strspn(cp, WS); + + if ((to = strsep(&cp, WS)) == NULL) + goto parse_error; + + if (strcmp(from, __progname) == 0) { + for (ap = strsep(&cp, WS); ap != NULL; + ap = strsep(&cp, WS)) + if (*ap) + addarg(&al, ap, 0); + break; + } + + free(line); + } + + (void)fclose(config); + + execve(to, al.argv, envp); + freearg(&al, 0); + free(line); + err(1, "mailwrapper: execing %s", to); + /*NOTREACHED*/ +parse_error: + freearg(&al, 0); + free(line); + errx(1, "mailwrapper: parse error in %s at line %lu", + _PATH_MAILERCONF, (u_long)lineno); + /*NOTREACHED*/ +}