LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* consistent ioctl for getting all net interfaces?
@ 2004-05-23 4:28 Joshua Kwan
2004-05-23 5:35 ` viro
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Joshua Kwan @ 2004-05-23 4:28 UTC (permalink / raw)
To: linux-kernel
Hi,
I'm interested in not having to parse /proc/net/dev to get a list of all
available (not necessarily even up) interfaces on the system. I
investigated the ioctl SIOCGIFCONF, but it seems to behave differently on
2.4 and 2.6 series kernels, e.g. sometimes it won't return all interfaces.
Is there some end-all ioctl that does what I want, or am I forever doomed
to process /proc/net/dev (in C, no less..)?
Please CC me on replies, I don't read this list very often any more.
Thanks,
--
Joshua Kwan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: consistent ioctl for getting all net interfaces?
2004-05-23 4:28 consistent ioctl for getting all net interfaces? Joshua Kwan
@ 2004-05-23 5:35 ` viro
2004-05-23 5:57 ` Joshua Kwan
2004-05-23 15:20 ` Tigran Aivazian
2004-05-30 20:25 ` Olaf Hering
2 siblings, 1 reply; 9+ messages in thread
From: viro @ 2004-05-23 5:35 UTC (permalink / raw)
To: Joshua Kwan; +Cc: linux-kernel
On Sat, May 22, 2004 at 09:28:28PM -0700, Joshua Kwan wrote:
> Hi,
>
> I'm interested in not having to parse /proc/net/dev to get a list of all
> available (not necessarily even up) interfaces on the system. I
> investigated the ioctl SIOCGIFCONF, but it seems to behave differently on
> 2.4 and 2.6 series kernels, e.g. sometimes it won't return all interfaces.
>
> Is there some end-all ioctl that does what I want, or am I forever doomed
> to process /proc/net/dev (in C, no less..)?
ASCII is tough, let's go shopping?
char name[17];
FILE *in = fopen("/proc/net/dev", "r");
if (!in)
die("can't open");
fscanf(in, "%*[^\n]\n%*[^\n]"); /* skip two lines */
while (fscanf(in, " %16[^:]:%*[^\n]", name) == 1)
do_whatever_you_want(name);
That you are calling "forever doomed"? Wimp...
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: consistent ioctl for getting all net interfaces?
2004-05-23 5:35 ` viro
@ 2004-05-23 5:57 ` Joshua Kwan
2004-05-23 6:05 ` viro
0 siblings, 1 reply; 9+ messages in thread
From: Joshua Kwan @ 2004-05-23 5:57 UTC (permalink / raw)
To: viro; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 271 bytes --]
On Sun, May 23, 2004 at 06:35:38AM +0100, viro@parcelfarce.linux.theplanet.co.uk wrote:
> ASCII is tough, let's go shopping?
> [snip code i already have]
I always found parsing files in C ugly, but I guess I have no choice
then. Thanks anyway.
--
Joshua Kwan
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 881 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: consistent ioctl for getting all net interfaces?
2004-05-23 5:57 ` Joshua Kwan
@ 2004-05-23 6:05 ` viro
0 siblings, 0 replies; 9+ messages in thread
From: viro @ 2004-05-23 6:05 UTC (permalink / raw)
To: joshk, linux-kernel
On Sat, May 22, 2004 at 10:57:59PM -0700, Joshua Kwan wrote:
> On Sun, May 23, 2004 at 06:35:38AM +0100, viro@parcelfarce.linux.theplanet.co.uk wrote:
> > ASCII is tough, let's go shopping?
> > [snip code i already have]
>
> I always found parsing files in C ugly, but I guess I have no choice
> then.
I would argue that ioctl() is inherently ugly, regardless of the language
used to call it. _And_ ioctl-based variant will actually take more code.
> Thanks anyway.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: consistent ioctl for getting all net interfaces?
2004-05-23 4:28 consistent ioctl for getting all net interfaces? Joshua Kwan
2004-05-23 5:35 ` viro
@ 2004-05-23 15:20 ` Tigran Aivazian
2004-05-23 15:25 ` Tigran Aivazian
2004-05-23 15:29 ` Joshua Kwan
2004-05-30 20:25 ` Olaf Hering
2 siblings, 2 replies; 9+ messages in thread
From: Tigran Aivazian @ 2004-05-23 15:20 UTC (permalink / raw)
To: Joshua Kwan; +Cc: linux-kernel
On Sat, 22 May 2004, Joshua Kwan wrote:
> I'm interested in not having to parse /proc/net/dev to get a list of all
> available (not necessarily even up) interfaces on the system. I
> investigated the ioctl SIOCGIFCONF, but it seems to behave differently on
> 2.4 and 2.6 series kernels, e.g. sometimes it won't return all interfaces.
>
> Is there some end-all ioctl that does what I want, or am I forever doomed
> to process /proc/net/dev (in C, no less..)?
>
> Please CC me on replies, I don't read this list very often any more.
Of course this is possible and here is the solution I wrote some time ago
(ioctl-based).
Note that a more simple solution is also possible but is less portable
(because will depend on glibc version).
/* TCPCAP endpoint, just an opaque handle for applications */
struct tcpcap {
int fd; /* socket file descriptor */
struct timeval *ts; /* user supplied addr of timestamp */
struct sockaddr_ll *from; /* user supplied addr of extra info */
int nports; /* number of bits set in ->ports */
int maxport; /* highest port number set in ->ports */
unsigned char *ports; /* ports currently set in ->lsf */
unsigned char *setports; /* pending ports to be added */
unsigned char *clrports; /* pending ports to be removed */
int recv_buflen; /* socket receive buffer size */
struct sock_fprog *lsf; /* compiled filter program */
struct sock_filter *lsf_insns; /* the actual LSF instructions */
int snaplen; /* length of part of each packet */
int pkt_count; /* number of packets seen */
int promisc; /* set interface(s) to promisc. mode */
struct tcpcap_if *iface; /* list of network interfaces */
int ifcount; /* number of elements in ->iface[] */
};
/*
* internal helper: get the list of all IPv4 up interfaces
* and record their name and IP address into pcap->iface[]
* array. Also set promiscuous mode as requested via pcap->promisc.
*/
static int walkiflist(struct tcpcap *pcap)
{
struct ifconf ifc;
struct ifreq *ifreqs, *ifr;
int fd, rq_len, nifs, i, ret = 0;
/* this is a helper datagram socket which we must create
* because the actual packet socket is created later on,
* at tcpcap_start() time.
*/
fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
DPRINTF("socket(), errno=%d (%s)\n",
errno, strerror(errno));
return TERR_SOCKET;
}
ifc.ifc_buf = NULL;
rq_len = 4*sizeof(struct ifreq);
do {
ifc.ifc_len = rq_len;
ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
if (ifc.ifc_buf == NULL) {
DPRINTF("ifc.buf = realloc() failed\n");
ret = TERR_REALLOC;
goto outclose;
}
if(ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
DPRINTF("ioctl(SIOCGIFCONF), errno=%d (%s)\n",
errno, strerror(errno));
if (ifc.ifc_buf)
free(ifc.ifc_buf);
ret = TERR_IOCTL;
goto outclose;
}
rq_len *= 2;
} while (rq_len < sizeof(struct ifreq) + ifc.ifc_len);
nifs = ifc.ifc_len / sizeof(struct ifreq);
ifreqs = realloc(ifc.ifc_buf, nifs*sizeof(struct ifreq));
if (ifreqs == NULL) {
DPRINTF("ifreqs = realloc()\n");
ret = TERR_REALLOC;
free(ifc.ifc_buf);
goto outclose;
}
/* allocate enough space for the maximum number of interfaces */
pcap->iface = zalloc(nifs*sizeof(struct tcpcap_if));
if (pcap->iface == NULL) {
DPRINTF("pcap->iface = zalloc() failed\n");
ret = TERR_ZALLOC;
goto outfree;
}
/* look through what we found and select only the 'interesting' ones */
for (ifr = ifreqs, i=0; i<nifs; ifr++, i++) {
struct sockaddr_in *addr;
/* only interested in IPv4 */
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
/* not interested in loopback */
if (!strncmp(ifr->ifr_name, "lo", 2))
continue;
/* request flags because SIOCGIFCONF only
* initialized name, family and address
*/
if(ioctl(fd, SIOCGIFFLAGS, ifr) < 0) {
DPRINTF("ioctl(SIOCGIFFLAGS), errno=%d (%s)\n",
errno, strerror(errno));
ret = TERR_IOCTL;
goto outfree;
}
/* not interested in down interfaces */
if (!(ifr->ifr_flags & IFF_UP))
continue;
/* OK, this interface passed all our criteria, so
* record it into pcap->iface[] array
*/
pcap->iface[pcap->ifcount].ifname =strdup(ifr->ifr_name);
addr = (struct sockaddr_in *)&(ifr->ifr_addr);
pcap->iface[pcap->ifcount].addr = htonl(addr->sin_addr.s_addr);
/* if required set this interface into promisc. mode,
* unless it is already in promiscuous mode.
*/
if (pcap->promisc && !(ifr->ifr_flags & IFF_PROMISC)) {
/* enable promiscuous mode */
ifr->ifr_flags |= IFF_PROMISC;
/* set interface flags */
if (ioctl(fd, SIOCSIFFLAGS, ifr) == -1) {
DPRINTF("ioctl(SIOCSIFFLAGS), errno=%d (%s)\n",
errno, strerror(errno));
ret = TERR_IOCTL;
goto outfree;
}
/* record the fact that we modified this interface */
pcap->iface[pcap->ifcount].promisc = 1;
DPRINTF("Enabled promisc. mode on %s (0x%x)\n",
pcap->iface[pcap->ifcount].ifname,
pcap->iface[pcap->ifcount].addr);
}
pcap->ifcount++;
}
outfree:
free(ifreqs);
outclose:
close(fd);
return ret;
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: consistent ioctl for getting all net interfaces?
2004-05-23 15:20 ` Tigran Aivazian
@ 2004-05-23 15:25 ` Tigran Aivazian
2004-05-23 15:29 ` Joshua Kwan
1 sibling, 0 replies; 9+ messages in thread
From: Tigran Aivazian @ 2004-05-23 15:25 UTC (permalink / raw)
To: Joshua Kwan; +Cc: linux-kernel
I forgot to mention that I tested on some early 2.6 (pre) and it worked
fine. If SIOCGIFCONF was broken in the more recent 2.6 kernels then I
should re-test and revisit this function...
Kind regards
Tigran
On Sun, 23 May 2004, Tigran Aivazian wrote:
> On Sat, 22 May 2004, Joshua Kwan wrote:
> > I'm interested in not having to parse /proc/net/dev to get a list of all
> > available (not necessarily even up) interfaces on the system. I
> > investigated the ioctl SIOCGIFCONF, but it seems to behave differently on
> > 2.4 and 2.6 series kernels, e.g. sometimes it won't return all interfaces.
> >
> > Is there some end-all ioctl that does what I want, or am I forever doomed
> > to process /proc/net/dev (in C, no less..)?
> >
> > Please CC me on replies, I don't read this list very often any more.
>
> Of course this is possible and here is the solution I wrote some time ago
> (ioctl-based).
>
> Note that a more simple solution is also possible but is less portable
> (because will depend on glibc version).
>
> /* TCPCAP endpoint, just an opaque handle for applications */
> struct tcpcap {
> int fd; /* socket file descriptor */
> struct timeval *ts; /* user supplied addr of timestamp */
> struct sockaddr_ll *from; /* user supplied addr of extra info */
> int nports; /* number of bits set in ->ports */
> int maxport; /* highest port number set in ->ports */
> unsigned char *ports; /* ports currently set in ->lsf */
> unsigned char *setports; /* pending ports to be added */
> unsigned char *clrports; /* pending ports to be removed */
> int recv_buflen; /* socket receive buffer size */
> struct sock_fprog *lsf; /* compiled filter program */
> struct sock_filter *lsf_insns; /* the actual LSF instructions */
> int snaplen; /* length of part of each packet */
> int pkt_count; /* number of packets seen */
> int promisc; /* set interface(s) to promisc. mode */
> struct tcpcap_if *iface; /* list of network interfaces */
> int ifcount; /* number of elements in ->iface[] */
> };
>
>
> /*
> * internal helper: get the list of all IPv4 up interfaces
> * and record their name and IP address into pcap->iface[]
> * array. Also set promiscuous mode as requested via pcap->promisc.
> */
> static int walkiflist(struct tcpcap *pcap)
> {
> struct ifconf ifc;
> struct ifreq *ifreqs, *ifr;
> int fd, rq_len, nifs, i, ret = 0;
>
> /* this is a helper datagram socket which we must create
> * because the actual packet socket is created later on,
> * at tcpcap_start() time.
> */
> fd = socket(PF_INET, SOCK_DGRAM, 0);
> if (fd < 0) {
> DPRINTF("socket(), errno=%d (%s)\n",
> errno, strerror(errno));
> return TERR_SOCKET;
> }
>
> ifc.ifc_buf = NULL;
> rq_len = 4*sizeof(struct ifreq);
> do {
> ifc.ifc_len = rq_len;
> ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
> if (ifc.ifc_buf == NULL) {
> DPRINTF("ifc.buf = realloc() failed\n");
> ret = TERR_REALLOC;
> goto outclose;
> }
> if(ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
> DPRINTF("ioctl(SIOCGIFCONF), errno=%d (%s)\n",
> errno, strerror(errno));
> if (ifc.ifc_buf)
> free(ifc.ifc_buf);
> ret = TERR_IOCTL;
> goto outclose;
> }
> rq_len *= 2;
> } while (rq_len < sizeof(struct ifreq) + ifc.ifc_len);
>
> nifs = ifc.ifc_len / sizeof(struct ifreq);
> ifreqs = realloc(ifc.ifc_buf, nifs*sizeof(struct ifreq));
> if (ifreqs == NULL) {
> DPRINTF("ifreqs = realloc()\n");
> ret = TERR_REALLOC;
> free(ifc.ifc_buf);
> goto outclose;
> }
>
> /* allocate enough space for the maximum number of interfaces */
> pcap->iface = zalloc(nifs*sizeof(struct tcpcap_if));
> if (pcap->iface == NULL) {
> DPRINTF("pcap->iface = zalloc() failed\n");
> ret = TERR_ZALLOC;
> goto outfree;
> }
>
> /* look through what we found and select only the 'interesting' ones */
> for (ifr = ifreqs, i=0; i<nifs; ifr++, i++) {
> struct sockaddr_in *addr;
>
> /* only interested in IPv4 */
> if (ifr->ifr_addr.sa_family != AF_INET)
> continue;
>
> /* not interested in loopback */
> if (!strncmp(ifr->ifr_name, "lo", 2))
> continue;
>
> /* request flags because SIOCGIFCONF only
> * initialized name, family and address
> */
> if(ioctl(fd, SIOCGIFFLAGS, ifr) < 0) {
> DPRINTF("ioctl(SIOCGIFFLAGS), errno=%d (%s)\n",
> errno, strerror(errno));
> ret = TERR_IOCTL;
> goto outfree;
> }
>
> /* not interested in down interfaces */
> if (!(ifr->ifr_flags & IFF_UP))
> continue;
>
> /* OK, this interface passed all our criteria, so
> * record it into pcap->iface[] array
> */
> pcap->iface[pcap->ifcount].ifname =strdup(ifr->ifr_name);
> addr = (struct sockaddr_in *)&(ifr->ifr_addr);
> pcap->iface[pcap->ifcount].addr = htonl(addr->sin_addr.s_addr);
>
> /* if required set this interface into promisc. mode,
> * unless it is already in promiscuous mode.
> */
> if (pcap->promisc && !(ifr->ifr_flags & IFF_PROMISC)) {
>
> /* enable promiscuous mode */
> ifr->ifr_flags |= IFF_PROMISC;
>
> /* set interface flags */
> if (ioctl(fd, SIOCSIFFLAGS, ifr) == -1) {
> DPRINTF("ioctl(SIOCSIFFLAGS), errno=%d (%s)\n",
> errno, strerror(errno));
> ret = TERR_IOCTL;
> goto outfree;
> }
>
> /* record the fact that we modified this interface */
> pcap->iface[pcap->ifcount].promisc = 1;
> DPRINTF("Enabled promisc. mode on %s (0x%x)\n",
> pcap->iface[pcap->ifcount].ifname,
> pcap->iface[pcap->ifcount].addr);
> }
>
> pcap->ifcount++;
> }
>
> outfree:
> free(ifreqs);
>
> outclose:
> close(fd);
>
> return ret;
> }
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: consistent ioctl for getting all net interfaces?
2004-05-23 15:20 ` Tigran Aivazian
2004-05-23 15:25 ` Tigran Aivazian
@ 2004-05-23 15:29 ` Joshua Kwan
1 sibling, 0 replies; 9+ messages in thread
From: Joshua Kwan @ 2004-05-23 15:29 UTC (permalink / raw)
To: Tigran Aivazian; +Cc: linux-kernel mailing list
[-- Attachment #1: Type: text/plain, Size: 825 bytes --]
On Sun, May 23, 2004 at 04:20:57PM +0100, Tigran Aivazian wrote:
> Note that a more simple solution is also possible but is less portable
> (because will depend on glibc version).
That uses if_nameindex, right? It's also affected by kernel version.
> if(ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
> DPRINTF("ioctl(SIOCGIFCONF), errno=%d (%s)\n",
> errno, strerror(errno));
> if (ifc.ifc_buf)
> free(ifc.ifc_buf);
> ret = TERR_IOCTL;
> goto outclose;
> }
As I said, when I tried SIOCGIFCONF, results varied..
I think it's slightly more reliable to just keep using /proc/net/dev for
now. (My parser is more robust than viro's ;))
I took a look at the net-tools ifconfig source and saw that it also
parsed /proc/net/dev to pick up what SIOCGIFCONF didn't. Shudder.
--
Joshua Kwan
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 881 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: consistent ioctl for getting all net interfaces?
2004-05-23 4:28 consistent ioctl for getting all net interfaces? Joshua Kwan
2004-05-23 5:35 ` viro
2004-05-23 15:20 ` Tigran Aivazian
@ 2004-05-30 20:25 ` Olaf Hering
2 siblings, 0 replies; 9+ messages in thread
From: Olaf Hering @ 2004-05-30 20:25 UTC (permalink / raw)
To: Joshua Kwan, netdev; +Cc: linux-kernel
On Sat, May 22, Joshua Kwan wrote:
> Hi,
>
> I'm interested in not having to parse /proc/net/dev to get a list of all
> available (not necessarily even up) interfaces on the system. I
> investigated the ioctl SIOCGIFCONF, but it seems to behave differently on
> 2.4 and 2.6 series kernels, e.g. sometimes it won't return all interfaces.
you should bring that to netdev@oss.sgi.com instead of lkml.
IF the ioctl has really changed, then it would be a bug. I just played
with ipconfig from the klibc distribution, and it returns only
interfaces in UP state. I'm sure that ipconfig binary worked when the
code was written.
If the ioctl is supposed to work how it does in 2.6, there is still
/sys/class/net/*. Thats (probably) more reliable than a text parser.
See `nameif -r 'foo: bar' eth0` as example.
--
USB is for mice, FireWire is for men!
sUse lINUX ag, nÜRNBERG
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: consistent ioctl for getting all net interfaces?
@ 2004-05-23 12:35 Albert Cahalan
0 siblings, 0 replies; 9+ messages in thread
From: Albert Cahalan @ 2004-05-23 12:35 UTC (permalink / raw)
To: linux-kernel mailing list; +Cc: viro, joshk
Viro cluelessly writes:
On Sat, May 22, 2004 at 09:28:28PM -0700, Joshua Kwan wrote:
>> I'm interested in not having to parse /proc/net/dev to get
>> a list of all available (not necessarily even up) interfaces
>> on the system. I investigated the ioctl SIOCGIFCONF, but it
>> seems to behave differently on 2.4 and 2.6 series kernels,
>> e.g. sometimes it won't return all interfaces.
>>
>> Is there some end-all ioctl that does what I want, or am
>> I forever doomed to process /proc/net/dev (in C, no less..)?
>
> ASCII is tough, let's go shopping?
>
> char name[17];
> FILE *in = fopen("/proc/net/dev", "r");
> if (!in)
> die("can't open");
> fscanf(in, "%*[^\n]\n%*[^\n]"); /* skip two lines */
> while (fscanf(in, " %16[^:]:%*[^\n]", name) == 1)
> do_whatever_you_want(name);
>
> That you are calling "forever doomed"? Wimp...
What makes you think you got that right? Do you have a
specification for the grammar? Let's look at an example
of /proc/net/dev, and I'll use my extensive /proc-parsing
experience to count your errors. Here is a sample:
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
eth0:3077476015 33231846 0 0 0 0 0 0 101565261 774586 0 0 0 0 0 0
lo: 1360 24 0 0 0 0 0 0 1360 24 0 0 0 0 0 0
tap0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
eth1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
eth2: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Excuse me while I vomit.
Let's start with the device names. Users can change
them at will, and some driver authors aren't normal.
So, in C notation, a name could be "x1: 1 2 3\n".
It doesn't even need to that evil to screw up your
wimpy parser. A simple "av6:3" would do nicely.
Think it won't happen? Sorry, but it does and will.
This is the nature of /proc crap.
Now we get to format changes. Don't you think the
above is kind of ugly? I sure do. I'm not crazy
enough to touch the formatting, but that readable
ASCII is a temptation for many. Just look at the
history of /proc/cpuinfo, which long ago looked a
bit more like the above in terms of ':' placement.
Also, it's foolish to rely on that leading space.
Here is what my data might look like in a few years:
Iface | Receive | Transmit
name |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
eth0 :3077476015 33231846 0 0 0 0 0 0 101565261 774586 0 0 0 0 0 0
lo : 1360 24 0 0 0 0 0 0 1360 24 0 0 0 0 0 0
tap0 : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
eth1 : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
eth2 : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Subtle, isn't it? Your parser broke.
(then there is performance, or lack of it...)
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-05-30 20:27 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-23 4:28 consistent ioctl for getting all net interfaces? Joshua Kwan
2004-05-23 5:35 ` viro
2004-05-23 5:57 ` Joshua Kwan
2004-05-23 6:05 ` viro
2004-05-23 15:20 ` Tigran Aivazian
2004-05-23 15:25 ` Tigran Aivazian
2004-05-23 15:29 ` Joshua Kwan
2004-05-30 20:25 ` Olaf Hering
2004-05-23 12:35 Albert Cahalan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).