Dear nntpcache-authors and nntpcache-community :) Last week I gave the nnpcache version 1.0.6.5 a second chance and noticed that it dumps core under Solaris 2.5 + natice cc after the first connect ended. This was caused by a SIGBUS-signal which was raised through improper type-alignments in the statistics code. I have solved that problem in a fast and ugly manner by creating a union of the different structures, and referring to them by the suitable-components (see the patches for ipc.h and ipc.c below). Beside I see that the statistics-code is already in the todo-file. I noticed that the communication for statistics relies on that the entire struct is transmitted with one write() - read() between the child- and parent-process, This doesn't work imho securely in all cases. I would suggest, if implemented in read-write manner, to use buffered-io with freopen(), fread(), fwrite(), first transmit one char seperately, which selects the type of the further data, and then the rest with a definite length. One Windows-client (I think it was called News-Xpress, or something like that) uses in some cases the LAST-command of the nntp-protocol. Unless that I turned "relayUnknowns" on in the config-file it worked. regards + sorry for raped english (I am never sure about that), David *** ipc.h.orig Fri Jun 27 00:34:45 1997 --- ipc.h Fri Jun 27 00:37:04 1997 *************** *** 130,132 **** --- 130,139 ---- int body_artnum; char servername[1]; /* nul if totall */ }; + + union ipc_align { + char char_buf[MAX_BFR]; + struct set_group set_group; + struct set_listgroup set_listgroup; + struct stats stats; + }; *** ipc.c.orig Fri Jun 27 00:34:25 1997 --- ipc.c Fri Jun 27 00:49:39 1997 *************** *** 154,169 **** { int cc; ! char buf[MAX_BFR], reply[MAX_BFR]; ! if ((cc = read (fd, buf, sizeof buf)) < 1) return FALSE; Stats->ipc_messages_in++; Stats->ipc_messages_in_bytes += cc; ! switch (*buf) { case IPC_GET_KEY: { ! char *val = hisGetDbz (buf + 1); if (val) { *reply = IPC_KEY; --- 154,172 ---- { int cc; ! /* char buf[MAX_BFR], reply[MAX_BFR]; */ ! char reply[MAX_BFR]; ! union ipc_align buf; ! char *cbuf = (char *)&buf.char_buf; ! if ((cc = read (fd, cbuf, sizeof buf)) < 1) return FALSE; Stats->ipc_messages_in++; Stats->ipc_messages_in_bytes += cc; ! switch (cbuf[0]) { case IPC_GET_KEY: { ! char *val = hisGetDbz (cbuf + 1); if (val) { *reply = IPC_KEY; *************** *** 184,190 **** } case IPC_ADD_KEY: { ! if (!hisAddDbz (buf + 1, buf + 1 + strlen (buf + 1) + 1)) *reply = IPC_ADD_KEY_FAILED; else *reply = IPC_ADD_KEY_OK; --- 187,193 ---- } case IPC_ADD_KEY: { ! if (!hisAddDbz (cbuf + 1, cbuf + 1 + strlen (cbuf + 1) + 1)) *reply = IPC_ADD_KEY_FAILED; else *reply = IPC_ADD_KEY_OK; *************** *** 196,202 **** } case IPC_SET_GROUP: { ! struct set_group *s = (struct set_group *)buf; struct newsgroup *n=newsgroup_find_add(s->group, NULL, TRUE); if (n) { --- 199,205 ---- } case IPC_SET_GROUP: { ! struct set_group *s = &buf.set_group; struct newsgroup *n=newsgroup_find_add(s->group, NULL, TRUE); if (n) { *************** *** 207,213 **** } case IPC_SET_LISTGROUP: { ! struct set_listgroup *s = (struct set_listgroup *)buf; struct newsgroup *n=newsgroup_find_add(s->group, NULL, TRUE); if (n) { --- 210,216 ---- } case IPC_SET_LISTGROUP: { ! struct set_listgroup *s = &buf.set_listgroup; struct newsgroup *n=newsgroup_find_add(s->group, NULL, TRUE); if (n) { *************** *** 236,250 **** case IPC_STATS: { int *i, *o; ! struct stats *p = (struct stats *) buf; if (cc < sizeof *p) { logw (("short IPC_STATS %d<%d", cc, sizeof *p)); break; } for (o = &Stats->active_len, i = &p->active_len; i <= (int *) &p->newsgroups_entries; o++, i++) if (*i) *o = *i; for (o = &Stats->server_connects, i = &p->server_connects; i < (int *) &p->servername; *o++ += *i++) ; /* add */ break; } --- 239,255 ---- case IPC_STATS: { int *i, *o; ! struct stats *p = &buf.stats; if (cc < sizeof *p) { logw (("short IPC_STATS %d<%d", cc, sizeof *p)); break; } + for (o = &Stats->active_len, i = &p->active_len; i <= (int *) &p->newsgroups_entries; o++, i++) if (*i) *o = *i; + for (o = &Stats->server_connects, i = &p->server_connects; i < (int *) &p->servername; *o++ += *i++) ; /* add */ break; }