1 // This may look like C code, but it is really -*- C++ -*-
2
3 // ------------------------------------------------------------------
4 // The Goldware Library
5 // Copyright (C) 1990-1999 Odinn Sorensen
6 // Copyright (C) 1999-2000 Alex. S. Aganichev
7 // ------------------------------------------------------------------
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
17 //
18 // You should have received a copy of the GNU Library General Public
19 // License along with this program; if not, write to the Free
20 // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 // MA 02111-1307, USA
22 // ------------------------------------------------------------------
23 // $Id: gmohuds3.cpp,v 1.9 2006/05/14 11:45:05 ssianky Exp $
24 // ------------------------------------------------------------------
25 // Hudson / Goldbase msgbase handling
26 // ------------------------------------------------------------------
27
28
29 // ------------------------------------------------------------------
30
31 template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
32 msgn_t _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::get_hdr_idx(gmsg* __msg, char* __file__, int __line__) {
33
34 GFTRK("HudsGetHdrIdx");
35
36 msgn_t _count = 0;
37 msgn_t _total = (msgn_t)(wide->msgidxsize/sizeof(HudsIdx));
38 HudsIdx* _msgidx_ptr = wide->msgidxptr;
39
40 uint32_t _msgno = __msg->msgno;
41 if(_msgidx_ptr) {
42 while(_count <= _total) {
43 if(_msgno == _msgidx_ptr->msgno) {
44 GFTRK(0);
45 return _count;
46 }
47 _msgidx_ptr++;
48 _count++;
49 }
50 }
51
52 // Report error
53 uint32_t _lmsgno = lastread ? Msgn->at(lastread-1) : Msgn->at(0);
54 uint32_t _lread = wide->lastrec[board()-1];
55 uint32_t _active = wide->msginfo.active[board()-1];
56 WideLog->errindex(__file__, __line__);
57 WideLog->printf("! Failed to locate a msgno in an internal %s index.", __HUDSON ? HUDS_NAME : GOLD_NAME);
58 WideLog->printf(": Msgno %u (%Xh) in board %u (%s,%u,%u).", _msgno, _msgno, board(), echoid(), Msgn->Count(), lastread);
59 WideLog->printf(": First Msgno : %u (%Xh).", Msgn->at(0), Msgn->at(0));
60 WideLog->printf(": Msgno at lastread : %u (%Xh).", _lmsgno, _lmsgno);
61 WideLog->printf(": Real lastread msg : %u (%Xh).", _lread, _lread);
62 WideLog->printf(": Real active msgs : %u (%Xh).", _active, _active);
63 if(Msgn->Count() > 2) {
64 _lmsgno = Msgn->at(Msgn->Count()-3);
65 WideLog->printf(": Highest-2 msgno : %u (%Xh).", _lmsgno, _lmsgno);
66 }
67 if(Msgn->Count() > 1) {
68 _lmsgno = Msgn->at(Msgn->Count()-2);
69 WideLog->printf(": Highest-1 msgno : %u (%Xh).", _lmsgno, _lmsgno);
70 }
71 if(Msgn->Count()) {
72 _lmsgno = Msgn->at(Msgn->Count()-1);
73 WideLog->printf(": Highest msgno : %u (%Xh).", _lmsgno, _lmsgno);
74 }
75 if(_msgno == 0xEEEEEEEEL) {
76 WideLog->printf("+ Info: This indicates a serious bug.");
77 WideLog->printf("+ Advice: Report to the Author immediately.");
78 }
79 WideLog->printf("+ Advice: Restart or run a msgbase index rebuild utility.");
80 IndexErrorExit();
81
82 GFTRK(0);
83
84 return (msgn_t)(__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO);
85 }
86
87
88 // ------------------------------------------------------------------
89
90 template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
load_message(int __mode,gmsg * __msg,HudsHdr & __hdr)91 int _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::load_message(int __mode, gmsg* __msg, HudsHdr& __hdr) {
92
93 if(__msg->msgno == 0) {
94 GFTRK(0);
95 return false;
96 }
97
98 // Read header
99 msgn_t _hdridx = get_hdr_idx(__msg, __FILE__, __LINE__);
100 wide->fhhdr.LseekSet((int32_t)_hdridx*(int32_t)sizeof(HudsHdr));
101 wide->fhhdr.Read(&__hdr, sizeof(HudsHdr));
102
103 __msg->msgno = __hdr.msgno;
104 __msg->link.to_set(__hdr.replyto);
105 __msg->link.first_set(__hdr.reply1st);
106
107 __msg->cost = __hdr.cost;
108 __msg->board = __hdr.board;
109 __msg->timesread = __hdr.timesread;
110
111 strnp2cc(__msg->by, __hdr.by, 35);
112 strnp2cc(__msg->to, __hdr.to, 35);
113 strnp2cc(__msg->re, __hdr.re, 72);
114
115 __msg->orig.zone = __msg->oorig.zone = __hdr.origzone;
116 __msg->orig.net = __msg->oorig.net = __hdr.orignet;
117 __msg->orig.node = __msg->oorig.node = __hdr.orignode;
118 __msg->orig.point = __msg->oorig.point = 0;
119
120 __msg->dest.zone = __msg->odest.zone = __hdr.destzone;
121 __msg->dest.net = __msg->odest.net = __hdr.destnet;
122 __msg->dest.node = __msg->odest.node = __hdr.destnode;
123 __msg->dest.point = __msg->odest.point = 0;
124
125 // Convert date and time
126 int _year, _month, _day, _hour, _minute;
127 sscanf(__hdr.date+1, "%d%*c%d%*c%2d", &_month, &_day, &_year);
128 sscanf(__hdr.time+1, "%d%*c%2d", &_hour, &_minute);
129 struct tm _tm;
130 _tm.tm_year = (_year < 80) ? (_year+100) : _year;
131 _tm.tm_mon = _month - 1;
132 _tm.tm_mday = _day;
133 _tm.tm_hour = _hour;
134 _tm.tm_min = _minute;
135 _tm.tm_sec = 0;
136 _tm.tm_isdst = -1;
137 time32_t a = gmktime(&_tm);
138 struct tm tp; ggmtime(&tp, &a);
139 tp.tm_isdst = -1;
140 time32_t b = gmktime(&tp);
141 __msg->written = a + a - b;
142 __msg->arrived = 0;
143
144 // Convert attributes
145 __msg->attr.del(__hdr.msgattr & HUDS_DELETED);
146 __msg->attr.pvt(__hdr.msgattr & HUDS_PVT);
147 __msg->attr.rcv(__hdr.msgattr & HUDS_RECEIVED);
148 __msg->attr.loc(__hdr.msgattr & HUDS_LOCAL);
149 __msg->attr.grp(__hdr.msgattr & HUDS_GROUPMSG);
150 __msg->attr.k_s(__hdr.netattr & HUDS_KILLSENT);
151 __msg->attr.att(__hdr.netattr & HUDS_ATTACH);
152 __msg->attr.cra(__hdr.netattr & HUDS_CRASH);
153 __msg->attr.rrq(__hdr.netattr & HUDS_RETRECREQ);
154 __msg->attr.arq(__hdr.netattr & HUDS_AUDITREQ);
155 __msg->attr.rrc(__hdr.netattr & HUDS_RETREC);
156 __msg->attr.frq(__hdr.netattr & HUDS_FREQ);
157 __msg->attr.uns((__hdr.netattr & HUDS_SENT) ? 0 : ((__hdr.msgattr & (HUDS_NETTRANS|HUDS_ECHOTRANS)) ? 1 : 0));
158 __msg->attr.snt(__msg->attr.loc() and not (__msg->attr.uns() or __msg->attr.rcv()));
159
160 __msg->txtstart = __hdr.startrec;
161 __msg->txtlength = __hdr.numrecs;
162
163 // If message text is used
164 if(__mode & GMSG_TXT) {
165
166 // Get length of message text
167 uint _numrecs = __hdr.numrecs;
168
169 // Allocate memory for message text
170 __msg->txt = (char*)throw_realloc(__msg->txt, _numrecs*256+256);
171 *__msg->txt = NUL;
172
173 // Read message text and convert it to a NUL-terminated C string
174 if(_numrecs) {
175
176 // Seek to, and read the raw text
177 wide->fhtxt.LseekSet((int32_t)__hdr.startrec*256L);
178 wide->fhtxt.Read(__msg->txt, _numrecs*256);
179
180 // Set up loop variables
181 char* _src = __msg->txt;
182 char* _dst = _src;
183 uint _count = 0;
184
185 // Conversion loop
186 while(_count++ < _numrecs) {
187
188 // Get block length
189 byte _len = *_src++;
190
191 // Move text over the length byte
192 memmove(_dst, _src, _len);
193
194 // Move pointers
195 _dst += _len;
196 _src += _len;
197 }
198
199 // NUL-terminate the text
200 *_dst = NUL;
201 }
202 }
203
204 GFTRK(0);
205
206 return true;
207 }
208
209
210 // ------------------------------------------------------------------
211
212 template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
load_hdr(gmsg * __msg)213 int _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::load_hdr(gmsg* __msg) {
214
215 GFTRK("HudsLoadHdr");
216
217 HudsHdr _hdr;
218 return load_message(GMSG_HDR, __msg, _hdr);
219 }
220
221
222 // ------------------------------------------------------------------
223
224 template <class msgn_t, class rec_t, class attr_t, class board_t, class last_t, bool __HUDSON>
load_msg(gmsg * __msg)225 int _HudsArea<msgn_t, rec_t, attr_t, board_t, last_t, __HUDSON>::load_msg(gmsg* __msg) {
226
227 GFTRK("HudsLoadMsg");
228
229 HudsHdr _hdr;
230 return load_message(GMSG_HDRTXT, __msg, _hdr);
231 }
232
233
234 // ------------------------------------------------------------------
235
236