1 /*
2   PKTAPI Source, Version 1.00
3 
4   (c) & (p) 1999-2000 by Oliver 'Attila' Grimm
5 
6   Alle Rechte vorbehalten.
7 */
8 
9 #include <fcntl.h>
10 #include <sys\stat.h>
11 #include <share.h>
12 #include <io.h>
13 #include <string.h>
14 
15 #include "pktapi.h"
16 #include "api_pkt2.h"
17 #include "platform_pkt.h"
18 
19 static HPKT hpOpen = 0;
20 
21 static struct _papifuncs pkt2_funcs =
22 {
23   Pkt2ClosePkt,
24   Pkt2ReadMsg,
25   Pkt2WriteMsg,
26   Pkt2ReadMsgComplete
27 };
28 
NewHpkt(word type,word mode)29 static HPKT NewHpkt(word type, word mode)
30 {
31   HPKT hp;
32 
33   if ((hp=calloc(sizeof(*hp),1))==NULL)
34     return NULL;
35 
36   hp->id = PKTAPI_ID;
37   hp->len = sizeof(struct _pktapi);
38   hp->type = type;
39   hp->mode = mode;
40 
41   hp->prod_code = 0xFE;
42 
43   return hp;
44 }
45 
_Pkt2OpenFile(HPKT hp,byte far * name,word mode)46 static sword _Pkt2OpenFile(HPKT hp, byte far *name, word mode)
47 {
48   /* All PKT-Files opened in DENY_READ and DENY_WRITE-Modes */
49 
50   if ((P2d->pfd=sopen(name,
51                       mode | O_RDWR | O_BINARY,
52                       SH_DENYRW,
53                       S_IREAD | S_IWRITE)) == -1)
54   {
55     return 0;
56   }
57 
58   return 1;
59 }
60 
_Pkt2GetStoneAge(HPKT hp,PKT2HEADER * pkth)61 static void _Pkt2GetStoneAge(HPKT hp, PKT2HEADER *pkth)
62 {
63   hp->orig.zone = pkth->orig_zone;
64   hp->orig.net  = pkth->orig_net;
65   hp->orig.node = pkth->orig_node;
66 
67   hp->dest.zone = pkth->dest_zone;
68   hp->dest.net  = pkth->dest_net;
69   hp->dest.node = pkth->dest_node;
70 
71   memcpy(hp->password, pkth->passwd, 8);
72 
73   hp->date_written.date.yr = pkth->year - 1900;
74   hp->date_written.date.mo = pkth->month+1;
75   hp->date_written.date.da = pkth->day;
76   hp->date_written.time.hh = pkth->hour;
77   hp->date_written.time.mm = pkth->min;
78   hp->date_written.time.ss = pkth->sec;
79 
80   hp->prod_code = pkth->prod_code;
81 
82   hp->type = PKTTYPE_2;
83 }
84 
_Pkt2Get2Plus(HPKT hp,PKT2PHEADER * pkth)85 static void _Pkt2Get2Plus(HPKT hp, PKT2PHEADER *pkth)
86 {
87   _Pkt2GetStoneAge(hp, (PKT2HEADER *)pkth);
88 
89   hp->orig.point= pkth->orig_point;
90 
91   hp->dest.point= pkth->dest_point;
92 
93   hp->capability= pkth->cap_word;
94 
95   hp->type = PKTTYPE_2_PLUS;
96 }
97 
_Pkt2Get2_2(HPKT hp,PKT22HEADER * pkth)98 static void _Pkt2Get2_2(HPKT hp, PKT22HEADER *pkth)
99 {
100   _Pkt2GetStoneAge(hp, (PKT2HEADER *)pkth);
101 
102   hp->orig.point= pkth->orig_point;
103 
104   hp->dest.point= pkth->dest_point;
105 
106   memset(&hp->date_written, 0, sizeof(struct _stamp));
107 
108   hp->type = PKTTYPE_2_2;
109 }
110 
_Pkt2OpenExisting(HPKT hp,byte far * name)111 static sword _Pkt2OpenExisting(HPKT hp, byte far *name)
112 {
113   PKT2PHEADER pkth;
114   word endmark;
115 
116   memset(&pkth, 0, sizeof(pkth));
117 
118   /* Try to open an EXISTING File */
119 
120   if (!_Pkt2OpenFile(hp, name, 0))
121     return 0;
122 
123   if (!(readPKTHEADER(P2d->pfd,(PKTHEADER *) &pkth) & PKTTYPE_2))
124   {
125     close(P2d->pfd);
126     P2d->pfd = 0;
127     return 0;
128   }
129 
130   if (pkth.pkt_ver != 2)
131   {
132     close(P2d->pfd);
133     P2d->pfd = 0;
134     return 0;
135   }
136 
137   lseek(P2d->pfd, -sizeof(endmark), SEEK_END);
138 
139   if (read(P2d->pfd, &endmark, sizeof(endmark)) != sizeof(endmark))
140   {
141     close(P2d->pfd);
142     P2d->pfd = 0;
143     return 0;
144   }
145 
146   if (endmark != 0)
147   {
148     close(P2d->pfd);
149     P2d->pfd = 0;
150     return 0;
151   }
152 
153   if (hp->mode == PKTMODE_WRITE)
154   {
155 
156      _chsize(P2d->pfd, _filelength(P2d->pfd)-sizeof(endmark));
157 
158      lseek(P2d->pfd, 0, SEEK_END);
159 
160   }
161   else
162     lseek(P2d->pfd, sizeof(pkth), SEEK_SET);
163 
164   if (pkth.baud == 2)
165   {
166     _Pkt2Get2_2(hp, (PKT22HEADER *) &pkth);
167     return 1;
168   }
169 
170   if ( ((byte *)&pkth.cap_word)[0] != ((byte *)&pkth.cwcopy)[1] ||
171        ((byte *)&pkth.cap_word)[1] != ((byte *)&pkth.cwcopy)[0])
172   {
173     _Pkt2GetStoneAge(hp, (PKT2HEADER *) &pkth);
174     return 1;
175   }
176 
177   _Pkt2Get2Plus(hp, (PKT2PHEADER *) &pkth);
178 
179   return 1;
180 }
181 
_Pkt2OpenCreate(HPKT hp,byte far * name)182 static sword _Pkt2OpenCreate(HPKT hp, byte far *name)
183 {
184   PKT2PHEADER pkth;
185   time_t timeval;
186   struct tm *tim;
187 
188   /* Try to create a NEW file ! Error, when file exists */
189 
190   if (!_Pkt2OpenFile(hp, name, O_CREAT))
191     return 0;
192 
193   timeval = time(0);
194   tim = localtime(&timeval);
195 
196   memset(&pkth, 0, sizeof(pkth));
197 
198   pkth.pkt_ver = 2;
199 
200   pkth.year = tim->tm_year+1900;
201   pkth.month = tim->tm_mon-1;
202   pkth.day = tim->tm_mday;
203   pkth.hour = tim->tm_hour;
204   pkth.min = tim->tm_min;
205   pkth.sec = tim->tm_sec;
206 
207   pkth.prod_code = 0xFE;
208 
209   writePKT2PHEADER(P2d->pfd, &pkth);
210 
211   return 1;
212 }
213 
Pkt2OpenPkt(byte far * name,word mode,word type)214 HPKT PKTAPI Pkt2OpenPkt(byte far *name, word mode, word type)
215 {
216   HPKT hp;
217   sword fopened = 0;
218 
219   if ((hp=NewHpkt(type, mode)) == NULL)
220     return NULL;
221 
222   if ((hp->apidata=malloc(sizeof(PKT2DATA))) == NULL)
223   {
224     free(hp);
225     return NULL;
226   }
227 
228   memset(hp->apidata, 0, sizeof(PKT2DATA));
229 
230   /* Allocate memory to hold the function pointers */
231 
232   if ((hp->api=(struct _papifuncs *)malloc(sizeof(struct _papifuncs)))==NULL)
233   {
234     free(hp->apidata);
235     free(hp);
236     return NULL;
237   }
238 
239   *hp->api=pkt2_funcs;
240 
241   if (mode == PKTMODE_READ || mode == PKTMODE_WRITE)
242     fopened = _Pkt2OpenExisting(hp, name);
243 
244   if (!fopened && mode == PKTMODE_WRITE)
245     fopened = _Pkt2OpenCreate(hp, name);
246 
247   if (!fopened)
248   {
249     free(hp->api);
250     free(hp->apidata);
251     free(hp);
252     return NULL;
253   }
254 
255   /* Add to linked list of open packets */
256   P2d->next = hpOpen;
257   hpOpen = hp;
258 
259   return hp;
260 }
261 
_Pkt2ClosePkt(HPKT hp)262 static sword _Pkt2ClosePkt(HPKT hp)
263 {
264   word endmark = 0l;
265   PKT2PHEADER pkth;
266 
267   if (hp->mode == PKTMODE_WRITE)
268   {
269     /* If in-message, when closing area, write end-of-mail tag first */
270     if (P2d->in_msg)
271     {
272       byte endmark = 0;
273       write(P2d->pfd, &endmark, 1);
274       P2d->in_msg = 0;
275     }
276 
277     memset(&pkth, 0, sizeof(pkth));
278 
279     /* _ever_ write 2+ Header */
280     pkth.orig_node = hp->orig.node;
281     pkth.dest_node = hp->dest.node;
282     pkth.year      = hp->date_written.date.yr+1900;
283     pkth.month     = hp->date_written.date.mo-1;
284     pkth.day       = hp->date_written.date.da;
285     pkth.hour      = hp->date_written.time.hh;
286     pkth.min       = hp->date_written.time.mm;
287     pkth.sec       = hp->date_written.time.ss;
288     pkth.pkt_ver   = 2;
289     pkth.orig_net  = hp->orig.net;
290     pkth.dest_net  = hp->dest.net;
291     pkth.prod_code = hp->prod_code;
292     memcpy(pkth.passwd, hp->password, 8);
293     pkth.orig_zone = hp->orig.zone;
294     pkth.dest_zone = hp->dest.zone;
295 
296     /* Neue/Modifizierte Packete sind _immer_ Typ 2+ */
297     pkth.cap_word  = 0x2;
298     pkth.cwcopy = 0x200;
299 
300     pkth.orig_point = hp->orig.point;
301     pkth.dest_point = hp->dest.point;
302 
303     lseek(P2d->pfd, 0, SEEK_SET);
304     writePKT2PHEADER(P2d->pfd, &pkth);
305 
306     /* write EOP-Mark */
307 
308     lseek(P2d->pfd, 0, SEEK_END);
309     write(P2d->pfd, &endmark, sizeof(endmark));
310   }
311 
312   close(P2d->pfd);
313 
314   return 0;
315 }
316 
Pkt2ClosePkt(HPKT hp)317 sword PKTAPI Pkt2ClosePkt(HPKT hp)
318 {
319   HPKT p;
320 
321   if (PktInvalidPh(hp))
322     return 1;
323 
324   _Pkt2ClosePkt(hp);
325 
326   /* Remove from openarealist */
327   if (hpOpen == hp)
328     hpOpen = P2d->next;
329   else
330   {
331     p = hpOpen;
332     while (p)
333     {
334       if (((PKT2DATA *)p->apidata)->next == hp)
335       {
336         ((PKT2DATA *)p->apidata)->next = P2d->next;
337         p = 0;
338       }
339       else
340         p = ((PKT2DATA *)p->apidata)->next;
341     }
342   }
343 
344   free(hp->api);
345   free(hp->apidata);
346   free(hp);
347 
348   return 0;
349 }
350 
_Pkt2ClosePackets()351 void PKTAPI _Pkt2ClosePackets()
352 {
353   while (hpOpen)
354   {
355     printf("PKTAPI is closing an open PKT...\n");
356     if (Pkt2ClosePkt(hpOpen))
357       return;
358   }
359 }
360 
361