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 // ------------------------------------------------------------------
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Library General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // Library General Public License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public
18 // License along with this program; if not, write to the Free
19 // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 // MA 02111-1307, USA
21 // ------------------------------------------------------------------
22 // $Id: gmopcbd3.cpp,v 1.10 2006/05/14 11:45:05 ssianky Exp $
23 // ------------------------------------------------------------------
24 // PCBoard msgbase handling.
25 // ------------------------------------------------------------------
26
27
28 // ------------------------------------------------------------------
29
30 #include <gmemdbg.h>
31 #include <gdbgtrk.h>
32 #include <gstrall.h>
33 #include <gutlmisc.h>
34
35 #include <gmopcbd.h>
36
37
38 // ------------------------------------------------------------------
39
load_message(int __mode,gmsg * __msg,PcbHdr & __hdr)40 int PcbArea::load_message(int __mode, gmsg* __msg, PcbHdr& __hdr) {
41
42 // Read index record for msg
43 PcbIdx _idx;
44 lseekset(data->fhidx, (__msg->msgno-data->base.lowmsgno)*sizeof(PcbIdx));
45 read(data->fhidx, &_idx, sizeof(PcbIdx));
46 __msg->txtstart = _idx.offset;
47
48 // Read message header
49 lseekset(data->fhmsg, AbsV(_idx.offset));
50 read(data->fhmsg, &__hdr, sizeof(PcbHdr));
51 __msg->txtlength = (__hdr.blocks-1)*128;
52 __msg->txtblocks = __hdr.blocks;
53
54 __msg->timesread = 1;
55
56 // Convert attributes
57 __msg->pcboard.status = __hdr.status;
58 if(not islocal())
59 __msg->attr.uns(__hdr.date[5] != '\xC4');
60 __msg->attr.pvt((__hdr.status == '*') or (__hdr.status == '+'));
61 __msg->attr.rcv((__hdr.status == '+') or (__hdr.status == '-') or (__hdr.status == '`') or (__hdr.status == '^') or (__hdr.status == '#'));
62 __msg->attr.del(__hdr.activestatus == 226);
63 __msg->pcboard.exthdrflags = __hdr.exthdrflags;
64
65 // Convert msgno and replylinks
66 __hdr.msgno = B2L(__hdr.msgno);
67 __hdr.refno = B2L(__hdr.refno);
68 __msg->link.to_set(__hdr.refno);
69
70 // Convert date and time
71 int _year, _month, _day, _hour, _minute;
72 sscanf(__hdr.date, "%d%*c%d%*c%2d", &_month, &_day, &_year);
73 sscanf(__hdr.time, "%d%*c%2d", &_hour, &_minute);
74 struct tm _tm;
75 _tm.tm_year = (_year < 80) ? (_year+100) : _year;
76 _tm.tm_mon = _month - 1;
77 _tm.tm_mday = _day;
78 _tm.tm_hour = _hour;
79 _tm.tm_min = _minute;
80 _tm.tm_sec = 0;
81 _tm.tm_isdst = -1;
82 time32_t a = gmktime(&_tm);
83 struct tm tp; ggmtime(&tp, &a);
84 tp.tm_isdst = -1;
85 time32_t b = gmktime(&tp);
86 __msg->written = a + a - b;
87 __msg->arrived = 0;
88
89 // Convert names and subject and password
90 strtrim(strncpy(__msg->by, __hdr.origname, 25));
91 strtrim(strncpy(__msg->to, __hdr.destname, 25));
92 strtrim(strncpy(__msg->re, __hdr.subject, 25));
93 strtrim(strncpy(__msg->pcboard.password, __hdr.password, 12));
94
95 uint _msgsize = (uint)__msg->txtlength;
96
97 // Allocate memory for the message text
98 __msg->txt = (char*)throw_realloc(__msg->txt, _msgsize+256);
99 char* _tmptxt = (char*)throw_calloc(1, _msgsize+1);
100
101 // Read the message text, trim spaces and translate PCB linefeeds
102 read(data->fhmsg, _tmptxt, _msgsize);
103 strtrim(_tmptxt);
104 if(not wide->foreign)
105 strchg(_tmptxt, 0xE3, 0x0D);
106
107 //int _line = 0;
108 char _eby[122] = {""};
109 char _eto[122] = {""};
110 char* _dst = __msg->txt;
111 char* _src = _tmptxt;
112 while(*_src) {
113 //char* _begline = _src;
114
115 // Check for extended header
116 PcbExtHdr* _ehdr = (PcbExtHdr*)_src;
117 if(_ehdr->id == 0x40FF) {
118 if( strnieql(_ehdr->function, "TO ", 7))
119 strncpy(_eto, _ehdr->desc, 60);
120 else if(strnieql(_ehdr->function, "TO2 ", 7))
121 strncpy(_eto+60, _ehdr->desc, 60);
122 else if(strnieql(_ehdr->function, "FROM ", 7))
123 strncpy(_eby, _ehdr->desc, 60);
124 else if(strnieql(_ehdr->function, "FROM2 ", 7))
125 strncpy(_eby+60, _ehdr->desc, 60);
126 else if(strnieql(_ehdr->function, "SUBJECT", 7))
127 strtrim(strncpy(__msg->re, _ehdr->desc, 60));
128 _src += sizeof(PcbExtHdr);
129 }
130 else {
131 while(*_src) {
132 *_dst++ = *_src;
133 if(*_src++ == CR) {
134 #if 0
135 // Get address and attribute from FidoPCB
136 if(isnet()) {
137 _line++;
138 if((_line == 1) and (*_begline == '(' /*)*/)) {
139 Addr _addr;
140 _addr.ResetFast();
141 char* _ptr = _begline + 1;
142 int _incoming = false;
143 if(strnieql(_ptr, "FROM:", 5)) {
144 _incoming = true;
145 _ptr += 5;
146 }
147 _addr.set(strskip_wht(_ptr));
148 if(not _incoming and strieql(__msg->by, WideUsername[0])) {
149 __msg->dest = _addr;
150 __msg->odest = _addr;
151 }
152 else {
153 __msg->orig = _addr;
154 __msg->oorig = _addr;
155 }
156 }
157 else if((_line == 2) and (*_begline == '(' /*)*/)) {
158 _src[-1] = NUL;
159 if(striinc("HOLD", _begline))
160 __msg->attr.hld1();
161 if(striinc("IMM", _begline))
162 __msg->attr.imm1();
163 if(striinc("CRASH", _begline))
164 __msg->attr.cra1();
165 if(striinc("INTL", _begline))
166 __msg->attr.zon1();
167 _src[-1] = CR;
168 }
169 }
170 #endif
171 break;
172 }
173 }
174 }
175 }
176 *_dst = NUL;
177 strtrim(_eby);
178 if(*_eby)
179 strxcpy(__msg->by, _eby, sizeof(__msg->by));
180 strtrim(_eto);
181 if(*_eto)
182 strxcpy(__msg->to, _eto, sizeof(__msg->to));
183
184 if(isnet() and not isemail()) {
185 char* ptr = strchr(__msg->by, '@');
186 if(ptr) {
187 *ptr++ = NUL;
188 __msg->orig.reset(ptr);
189 __msg->oorig = __msg->orig;
190 }
191 ptr = strchr(__msg->to, '@');
192 if(ptr) {
193 *ptr++ = NUL;
194 char* ptr2 = strskip_txt(ptr);
195 if(*ptr2) {
196 *ptr2++ = NUL;
197 while(*ptr2) {
198 if(*ptr2 == '+') {
199 // get flags
200 switch(g_toupper(*(++ptr2))) {
201 case 'C': __msg->attr.cra1(); break;
202 case 'D': __msg->attr.dir1(); break;
203 }
204 }
205 else if(*ptr2 == '[') {
206 // get from-aka address
207 ptr2++;
208 char* ptr3 = ptr2;
209 ptr2 = strskip_to(ptr2, ']');
210 if(*ptr2) {
211 *ptr2++ = NUL;
212 __msg->orig.reset(ptr3);
213 __msg->oorig = __msg->orig;
214 }
215 }
216 ptr2++;
217 }
218 }
219 __msg->dest.reset(ptr);
220 __msg->odest = __msg->dest;
221 }
222 }
223
224 throw_free(_tmptxt);
225
226 if(not (__mode & GMSG_TXT))
227 throw_release(__msg->txt);
228
229 GFTRK(0);
230
231 return true;
232 }
233
234
235 // ------------------------------------------------------------------
236
load_hdr(gmsg * __msg)237 int PcbArea::load_hdr(gmsg* __msg) {
238
239 GFTRK("PcbLoadHdr");
240
241 PcbHdr _hdr;
242 return load_message(GMSG_HDR, __msg, _hdr);
243 }
244
245
246 // ------------------------------------------------------------------
247
load_msg(gmsg * __msg)248 int PcbArea::load_msg(gmsg* __msg) {
249
250 GFTRK("PcbLoadMsg");
251
252 PcbHdr _hdr;
253 return load_message(GMSG_HDRTXT, __msg, _hdr);
254 }
255
256
257 // ------------------------------------------------------------------
258
259