* Middle button on usb mice @ 2016-09-24 3:26 lemon 2016-09-24 13:03 ` [9front] " cinap_lenrek 0 siblings, 1 reply; 12+ messages in thread From: lemon @ 2016-09-24 3:26 UTC (permalink / raw) To: 9front I've recently installed 9front on a lenovo thinkpad x220 and when using usb mice, the middle button or scroll button (I have a 3 and a 2 button mouse) doesn't seem to be recognized. The middle button on the laptop works fine. I've tried ps2, ps2intellimouse and intellimouse with the laptop trackpad and point both enabled and disabled, and in efi and bios mode. If I do echo 'debug 2' > /dev/usb/epN.1 then I'll recieve output onto the console when the middle button is pressed, but cat /dev/mouse yields nothing. The mice behave appropriately under linux and under plan9 on my raspberry pi. What's the next step I can try? I'm very new to plan9 and 9front and I really appreciate any help you can give me. If this is the wrong mailing list, please let me know. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-24 3:26 Middle button on usb mice lemon @ 2016-09-24 13:03 ` cinap_lenrek 2016-09-26 23:13 ` lemon 0 siblings, 1 reply; 12+ messages in thread From: cinap_lenrek @ 2016-09-24 13:03 UTC (permalink / raw) To: 9front the mouse port prompt on boot doesnt matter... that applies to ps/2 and serial mouse only. usb mice have no fixed protocol, but a blob (hid descriptor) that describes the bits in the data packet and how they should be interpreted. to debug this, first, we need to get rid of the automatically spawned nusb/kb process thats still attached to the device. run ps -a | grep kb, you'll get something like: cinap_lenrek 259856 0:00 0:00 156K Pread kb [readerproc /dev/usb/ep5.1] that tells you the assigned device address (5 in this case), then kill that process: kill kb | rc next, we run nusb/kb -ddd 5 replace 5 with the address you got from above there... the -ddd enables some debug prints. the output will look like this: report descriptor: 0x05 0x01 0x09 0x02 0xa1 0x01 0x09 0x01 0xa1 0x00 0x05 0x09 0x19 0x01 0x29 0x03 0x15 0x00 0x25 0x01 0x95 0x03 0x75 0x01 0x81 0x02 0x95 0x01 0x75 0x05 0x81 0x01 0x05 0x01 0x09 0x30 0x09 0x31 0x09 0x38 0x15 0x81 0x25 0x7f 0x75 0x08 0x95 0x03 0x81 0x06 0xc0 0x09 0x3c 0x15 0x00 0x25 0x01 0x75 0x01 0x95 0x01 0xb1 0x22 0x95 0x07 0xb1 0x01 0xc0 hidparse: t=8 f=2 usage=90001 v=0 hidparse: t=8 f=2 usage=90002 v=0 hidparse: t=8 f=2 usage=90003 v=0 hidparse: t=8 f=6 usage=10030 v=0 hidparse: t=8 f=6 usage=10031 v=1 hidparse: t=8 f=6 usage=10038 v=0 ... my suspicion is that we eigther fail to read the hid descriptor (then no "report descriptor:" should be printed with debug on), and then assume the default bootproto one for mouse, or the descriptor is malformed in some way that we do not understand. the code is here: /sys/src/cmd/nusb/kb/kb.c the code starts with reading the hid descriptor and setting the protocol in setproto(). then it spawns readerproc which reads packets from the endpoint and tries to parse it with repparse(), which takes the descriptor as input and calls hidparse() for each item described by the descriptor. hidparse() then extracts the data from the actual packet for the given item information. you can add debug prints if you want, run mk, kill the old process an start a new one with the usb address as explained before. -- cinap ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-24 13:03 ` [9front] " cinap_lenrek @ 2016-09-26 23:13 ` lemon 2016-09-26 23:30 ` cinap_lenrek 0 siblings, 1 reply; 12+ messages in thread From: lemon @ 2016-09-26 23:13 UTC (permalink / raw) To: 9front On Sat, Sep 24, 2016 at 03:03:23PM +0200, cinap_lenrek@felloff.net wrote: > my suspicion is that we eigther fail to read the hid > descriptor (then no "report descriptor:" should be > printed with debug on), and then assume the default > bootproto one for mouse, or the descriptor is malformed > in some way that we do not understand. running nusb/kb -ddd N returns a "report descripter:" followed by a bunch of hex similar to your output so the descriptor may be malformed then? > the code is here: /sys/src/cmd/nusb/kb/kb.c I'll see what I can find here. Are there any older versions of this code I could check out? If there is another version that works, I think it would be easier to bisect the problem. Thanks for your help cinap. If I find a fix, should I add it here or submit a bug report? ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-26 23:13 ` lemon @ 2016-09-26 23:30 ` cinap_lenrek 2016-09-28 2:13 ` lemon 0 siblings, 1 reply; 12+ messages in thread From: cinap_lenrek @ 2016-09-26 23:30 UTC (permalink / raw) To: 9front > running nusb/kb -ddd N returns a "report descripter:" followed by a > bunch of hex similar to your output so the descriptor may be malformed > then? the debug output including the descriptor would be usefull. show what it outputs when you click the middle mouse button. > I'll see what I can find here. Are there any older versions of this code > I could check out? no. > If there is another version that works, I think it would be easier to bisect > the problem. no. -- cinap ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-26 23:30 ` cinap_lenrek @ 2016-09-28 2:13 ` lemon 2016-09-28 13:27 ` cinap_lenrek 2016-09-28 14:20 ` cinap_lenrek 0 siblings, 2 replies; 12+ messages in thread From: lemon @ 2016-09-28 2:13 UTC (permalink / raw) To: 9front > the debug output including the descriptor would be usefull. show what > it outputs when you click the middle mouse button. report descriptor: 0x05 0x01 0x09 0x02 0xa1 0x01 0x09 0x01 0xa1 0x00 0x05 0x09 0x19 0x01 0x29 0x03 0x15 0x00 0x25 0x01 0x95 0x08 0x75 0x01 0x81 0x02 0x05 0x01 0x09 0x30 0x09 0x31 0x09 0x38 0x15 0x81 0x25 0x7f 0x75 0x08 0x95 0x03 0x81 0x06 0xc0 0xc0 hidparse: t=8 f=2 usage=90001 v=0 hidparse: t=8 f=2 usage=90002 v=0 hidparse: t=8 f=2 usage=90003 v=0 hidparse: t=8 f=2 usage=90003 v=0 hidparse: t=8 f=2 usage=90003 v=0 hidparse: t=8 f=2 usage=90003 v=0 hidparse: t=8 f=2 usage=90003 v=0 hidparse: t=8 f=2 usage=90003 v=0 hidparse: t=8 f=6 usage=10030 v=0 hidparse: t=8 f=6 usage=10031 v=0 hidparse: t=8 f=6 usage=10038 v=0 -- lemon ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-28 2:13 ` lemon @ 2016-09-28 13:27 ` cinap_lenrek 2016-09-28 14:20 ` cinap_lenrek 1 sibling, 0 replies; 12+ messages in thread From: cinap_lenrek @ 2016-09-28 13:27 UTC (permalink / raw) To: 9front >> the debug output including the descriptor would be usefull. show what >> it outputs when you click the middle mouse button. > report descriptor: > 0x05 0x01 0x09 0x02 0xa1 0x01 0x09 0x01 > 0xa1 0x00 0x05 0x09 0x19 0x01 0x29 0x03 > 0x15 0x00 0x25 0x01 0x95 0x08 0x75 0x01 > 0x81 0x02 0x05 0x01 0x09 0x30 0x09 0x31 > 0x09 0x38 0x15 0x81 0x25 0x7f 0x75 0x08 > 0x95 0x03 0x81 0x06 0xc0 0xc0 that decodes to: 0x05 0x01 USAGE PAGE(GENERIC DESKTOP) 0x09 0x02 USAGE (Mouse) 0xa1 0x01 COLLECTION (Application) 0x09 0x01 USAGE (Pointer) 0xa1 0x00 COLLECTION (Physical) 0x05 0x09 USAGE PAGE(Button) 0x19 0x01 USAGE MINIMUM (Button1) 0x29 0x03 USAGE MAXIMUM (Button3) 0x15 0x00 LOCAL MINIMUM (0) 0x25 0x01 LOCAL MAXIMUM (1) 0x95 0x08 REPORT COUNT (8) 0x75 0x01 REPORT SIZE (1) 0x81 0x02 INPUT (Data,Var,Abs) 0x05 0x01 USAGE 0x09 0x30 X 0x09 0x31 Y 0x09 0x38 WHEEL 0x15 0x81 Logical min -127 0x25 0x7f Logical max 127 0x75 0x08 REPORT SIZE(8) 0x95 0x03 REPORT COUNT(3) 0x81 0x06 INPUT (Data,Var,Rel) 0xc0 END COLLECTION 0xc0 END COLLECTION note that it maps the buttons 1-3 to bits 0-7 of the first byte; meaning there are more bits than buttons. normally, the buttons are mapped like 1-3 -> bits 0-2, and then theres a dummy report count(1), report size(5) to cover the rest of the byte. > hidparse: t=8 f=2 usage=90001 v=0 # button1 > hidparse: t=8 f=2 usage=90002 v=0 # button2 > hidparse: t=8 f=2 usage=90003 v=0 > hidparse: t=8 f=2 usage=90003 v=0 > hidparse: t=8 f=2 usage=90003 v=0 > hidparse: t=8 f=2 usage=90003 v=0 > hidparse: t=8 f=2 usage=90003 v=0 > hidparse: t=8 f=2 usage=90003 v=0 # button3 button3 item is reported multiple times here (for bits 2-7 of the first byte) > hidparse: t=8 f=6 usage=10030 v=0 # X > hidparse: t=8 f=6 usage=10031 v=0 # Y > hidparse: t=8 f=6 usage=10038 v=0 # Z this indeed explains why the middle button doesnt work, but not why the mouse wheel doesnt work... i'll look in the specification when i get home to see if it sais anything about disabiguating the max usage vs. report count case. anyway, the packet format is 1 byte buttons, and then 3 bytes X,Y,Z in the report packet. you can hexdump these and veryfy that button3 indeed asserts bit 2 in the first byte. -- cinap ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-28 2:13 ` lemon 2016-09-28 13:27 ` cinap_lenrek @ 2016-09-28 14:20 ` cinap_lenrek 2016-09-30 3:47 ` lemon 1 sibling, 1 reply; 12+ messages in thread From: cinap_lenrek @ 2016-09-28 14:20 UTC (permalink / raw) To: 9front in fact, you might try this (untested): diff -r 38db1b2cd29e sys/src/cmd/nusb/kb/kb.c --- a/sys/src/cmd/nusb/kb/kb.c Thu Sep 22 11:04:43 2016 +0200 +++ b/sys/src/cmd/nusb/kb/kb.c Wed Sep 28 16:20:13 2016 +0200 @@ -234,8 +234,7 @@ for(i=l[UsagMin]; i<=l[UsagMax] && l[UsgCnt] < Nu; i++) l[Nl + l[UsgCnt]++] = i; for(i=0; i<g[RepCnt]; i++){ - if(i < l[UsgCnt]) - l[Usage] = l[Nl + i]; + l[Usage] = i < l[UsgCnt] ? l[Nl + i] : 0; (*f)(t, v, g, l, c, a); } break; -- cinap ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-28 14:20 ` cinap_lenrek @ 2016-09-30 3:47 ` lemon 2016-09-30 6:41 ` cinap_lenrek 2016-09-30 7:37 ` cinap_lenrek 0 siblings, 2 replies; 12+ messages in thread From: lemon @ 2016-09-30 3:47 UTC (permalink / raw) To: 9front > diff -r 38db1b2cd29e sys/src/cmd/nusb/kb/kb.c > --- a/sys/src/cmd/nusb/kb/kb.c Thu Sep 22 11:04:43 2016 +0200 > +++ b/sys/src/cmd/nusb/kb/kb.c Wed Sep 28 16:20:13 2016 +0200 > @@ -234,8 +234,7 @@ > for(i=l[UsagMin]; i<=l[UsagMax] && l[UsgCnt] < Nu; i++) > l[Nl + l[UsgCnt]++] = i; > for(i=0; i<g[RepCnt]; i++){ > - if(i < l[UsgCnt]) > - l[Usage] = l[Nl + i]; > + l[Usage] = i < l[UsgCnt] ? l[Nl + i] : 0; > (*f)(t, v, g, l, c, a); > } > break; Thanks for giving it a shot. It compiles cleanly but did not fix the issue and when running nusb/kb -ddd N I had the same output as before. If there's any more information I can share that'll help, let me know. -- lemon ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-30 3:47 ` lemon @ 2016-09-30 6:41 ` cinap_lenrek 2016-10-18 0:46 ` lemon 2016-09-30 7:37 ` cinap_lenrek 1 sibling, 1 reply; 12+ messages in thread From: cinap_lenrek @ 2016-09-30 6:41 UTC (permalink / raw) To: 9front > Thanks for giving it a shot. It compiles cleanly but did not fix the > issue and when running nusb/kb -ddd N I had the same output as before. are you really sure? you should see: hidparse: t=8 f=2 usage=90001 v=0 hidparse: t=8 f=2 usage=90002 v=0 hidparse: t=8 f=2 usage=90003 v=0 hidparse: t=8 f=2 usage=0 v=0 hidparse: t=8 f=2 usage=0 v=0 hidparse: t=8 f=2 usage=0 v=0 hidparse: t=8 f=2 usage=0 v=0 hidparse: t=8 f=2 usage=0 v=0 ... (notice, usage=90003 should appear only once per report and usage=0 should appear 5 times after the usage=90003 line) have you run this manually? because to make this effective for hotplug you'll have to update both /bin/nusb/kb and build a new kernel as the *effective* command is included in (and run from) the kernel image (so you have keyboard's and mouse work before a root filesystem can be mounted). to build new kernel, run mk install in /sys/src/9/pc and then copy the 9pcf file to 9fat. (9fs 9fat; cp 9pcf /n/9fat) > If there's any more information I can share that'll help, let me know. yes, print the first byte from the packet please. like in readerproc() fprint(2, "p0 = %x\n", p.p[0]); > -- > lemon -- cinap ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-30 6:41 ` cinap_lenrek @ 2016-10-18 0:46 ` lemon 0 siblings, 0 replies; 12+ messages in thread From: lemon @ 2016-10-18 0:46 UTC (permalink / raw) To: 9front On Fri, Sep 30, 2016 at 08:41:16AM +0200, cinap_lenrek@felloff.net wrote: > update both /bin/nusb/kb and build a new kernel Just to follow up, (a bit late I know), but your provided fix worked perfectly, thank you. -- lemon ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-30 3:47 ` lemon 2016-09-30 6:41 ` cinap_lenrek @ 2016-09-30 7:37 ` cinap_lenrek 2016-09-30 7:40 ` cinap_lenrek 1 sibling, 1 reply; 12+ messages in thread From: cinap_lenrek @ 2016-09-30 7:37 UTC (permalink / raw) To: 9front Attach: /sys/src/cmd/nusb/kb/a.c i'm pretty confident the change works because i fed your descriptor into repparse() with the change and i'm getting the expected result: cpu% 8c -I../lib a.c cpu% 8l a.8 cpu% ./8.out hidparse: t=8 f=2 usage=90001 v=0 hidparse: t=8 f=2 usage=90002 v=0 hidparse: t=8 f=2 usage=90003 v=1 hidparse: t=8 f=2 usage=0 v=0 hidparse: t=8 f=2 usage=0 v=0 hidparse: t=8 f=2 usage=0 v=0 hidparse: t=8 f=2 usage=0 v=0 hidparse: t=8 f=2 usage=0 v=0 hidparse: t=8 f=6 usage=10030 v=0 hidparse: t=8 f=6 usage=10031 v=0 hidparse: t=8 f=6 usage=10038 v=0 -- cinap ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [9front] Middle button on usb mice 2016-09-30 7:37 ` cinap_lenrek @ 2016-09-30 7:40 ` cinap_lenrek 0 siblings, 0 replies; 12+ messages in thread From: cinap_lenrek @ 2016-09-30 7:40 UTC (permalink / raw) To: 9front [-- Attachment #1: Type: text/plain, Size: 33 bytes --] screwed up attachment.. -- cinap [-- Attachment #2: a.c --] [-- Type: text/plain, Size: 5504 bytes --] #include <u.h> #include <libc.h> #include <thread.h> #include "usb.h" #include "hid.h" typedef struct Hidreport Hidreport; struct Hidreport { int x; int y; int z; int b; int m; int absx; int absy; int absz; int nk; uchar k[64]; int o; uchar *e; uchar p[128]; }; static int debug = 3; static int signext(int v, int bits) { int s; s = sizeof(v)*8 - bits; v <<= s; v >>= s; return v; } static int getbits(uchar *p, uchar *e, int bits, int off) { int v, m; p += off/8; off %= 8; v = 0; m = 1; if(p < e){ while(bits--){ if(*p & (1<<off)) v |= m; if(++off == 8){ if(++p >= e) break; off = 0; } m <<= 1; } } return v; } enum { Ng = RepCnt+1, UsgCnt = Delim+1, /* fake */ Nl = UsgCnt+1, Nu = 256, }; static uchar* repparse1(uchar *d, uchar *e, int g[], int l[], int c, void (*f)(int t, int v, int g[], int l[], int c, void *a), void *a) { int z, k, t, v, i; while(d < e){ v = 0; t = *d++; z = t & 3, t >>= 2; k = t & 3, t >>= 2; switch(z){ case 3: d += 4; if(d > e) continue; v = d[-4] | d[-3]<<8 | d[-2]<<16 | d[-1]<<24; break; case 2: d += 2; if(d > e) continue; v = d[-2] | d[-1]<<8; break; case 1: d++; if(d > e) continue; v = d[-1]; break; } switch(k){ case 0: /* main item*/ switch(t){ case Collection: memset(l, 0, Nl*sizeof(l[0])); d = repparse1(d, e, g, l, v, f, a); continue; case CollectionEnd: return d; case Input: case Output: case Feature: if(l[UsgCnt] == 0 && l[UsagMin] != 0 && l[UsagMin] < l[UsagMax]) for(i=l[UsagMin]; i<=l[UsagMax] && l[UsgCnt] < Nu; i++) l[Nl + l[UsgCnt]++] = i; for(i=0; i<g[RepCnt]; i++){ l[Usage] = i < l[UsgCnt] ? l[Nl + i] : 0; (*f)(t, v, g, l, c, a); } break; } memset(l, 0, Nl*sizeof(l[0])); continue; case 1: /* global item */ if(t == Push){ int w[Ng]; memmove(w, g, sizeof(w)); d = repparse1(d, e, w, l, c, f, a); } else if(t == Pop){ return d; } else if(t < Ng){ if(t == RepId) v &= 0xFF; else if(t == UsagPg) v &= 0xFFFF; else if(t != RepSize && t != RepCnt){ v = signext(v, (z == 3) ? 32 : 8*z); } g[t] = v; } continue; case 2: /* local item */ if(l[Delim] != 0) continue; if(t == Delim){ l[Delim] = 1; } else if(t < Delim){ if(z != 3 && (t == Usage || t == UsagMin || t == UsagMax)) v = (v & 0xFFFF) | (g[UsagPg] << 16); l[t] = v; if(t == Usage && l[UsgCnt] < Nu) l[Nl + l[UsgCnt]++] = v; } continue; case 3: /* long item */ if(t == 15) d += v & 0xFF; continue; } } return d; } /* * parse the report descriptor and call f for every (Input, Output * and Feature) main item as often as it would appear in the report * data packet. */ static void repparse(uchar *d, uchar *e, void (*f)(int t, int v, int g[], int l[], int c, void *a), void *a) { int l[Nl+Nu], g[Ng]; memset(l, 0, sizeof(l)); memset(g, 0, sizeof(g)); repparse1(d, e, g, l, 0, f, a); } static void hidparse(int t, int f, int g[], int l[], int, void *a) { Hidreport *p = a; int v, m; if(t != Input) return; if(g[RepId] != 0){ if(p->p[0] != g[RepId]){ p->o = 0; return; } if(p->o < 8) p->o = 8; /* skip report id byte */ } v = getbits(p->p, p->e, g[RepSize], p->o); p->o += g[RepSize]; if((f & (Fconst|Fdata)) != Fdata) return; if(debug > 1) fprint(2, "hidparse: t=%x f=%x usage=%x v=%x\n", t, f, l[Usage], v); if((l[Usage]>>16) == 0x07){ /* keycode */ if((f & (Fvar|Farray)) == Fvar) if(v != 0) v = l[Usage] & 0xFF; if(p->nk < nelem(p->k) && v != 0) p->k[p->nk++] = v; return; } if(g[LogiMin] < 0) v = signext(v, g[RepSize]); if((f & (Fvar|Farray)) == Fvar && v >= g[LogiMin] && v <= g[LogiMax]){ /* * we use logical units below, but need the * sign to be correct for mouse deltas. * so if physical unit is signed but logical * is unsigned, convert to signed but in logical * units. */ if((f & (Fabs|Frel)) == Frel && g[PhysMin] < 0 && g[PhysMax] > 0 && g[LogiMin] >= 0 && g[LogiMin] < g[LogiMax]) v -= (g[PhysMax] * (g[LogiMax] - g[LogiMin])) / (g[PhysMax] - g[PhysMin]); switch(l[Usage]){ case 0x090001: case 0x090002: case 0x090003: case 0x090004: case 0x090005: case 0x090006: case 0x090007: case 0x090008: m = 1<<(l[Usage] - 0x090001); p->m |= m; p->b &= ~m; if(v != 0) p->b |= m; break; case 0x010030: if((f & (Fabs|Frel)) == Fabs){ p->x = (v - p->absx); p->absx = v; } else { p->x = v; p->absx += v; } break; case 0x010031: if((f & (Fabs|Frel)) == Fabs){ p->y = (v - p->absy); p->absy = v; } else { p->y = v; p->absy += v; } break; case 0x010038: if((f & (Fabs|Frel)) == Fabs){ p->z = (v - p->absz); p->absz = v; } else { p->z = v; p->absz += v; } break; } } } static void usage(void) { fprint(2, "usage: %s [-d] devid\n", argv0); threadexits("usage"); } static uchar rep[] ={ 0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, 0x03, 0x81, 0x06, 0xc0, 0xc0, }; void threadmain(int argc, char* argv[]) { Hidreport p = {0}; p.o = 0; p.e = p.p + 3; p.p[0] = 1<<2; repparse(rep, rep+sizeof(rep), hidparse, &p); } ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2016-10-18 0:45 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-09-24 3:26 Middle button on usb mice lemon 2016-09-24 13:03 ` [9front] " cinap_lenrek 2016-09-26 23:13 ` lemon 2016-09-26 23:30 ` cinap_lenrek 2016-09-28 2:13 ` lemon 2016-09-28 13:27 ` cinap_lenrek 2016-09-28 14:20 ` cinap_lenrek 2016-09-30 3:47 ` lemon 2016-09-30 6:41 ` cinap_lenrek 2016-10-18 0:46 ` lemon 2016-09-30 7:37 ` cinap_lenrek 2016-09-30 7:40 ` cinap_lenrek
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).