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