1 /*****************************************************************************
2 * HPT --- FTN NetMail/EchoMail Tosser
3 *****************************************************************************
4 * Copyright (C) 1997-1999
5 *
6 * Matthias Tichy
7 *
8 * Fido: 2:2433/1245 2:2433/1247 2:2432/605.14
9 * Internet: mtt@tichy.de
10 *
11 * Grimmestr. 12 Buchholzer Weg 4
12 * 33098 Paderborn 40472 Duesseldorf
13 * Germany Germany
14 *
15 * This file is part of HPT.
16 *
17 * HPT is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2, or (at your option) any
20 * later version.
21 *
22 * HPT is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with HPT; see the file COPYING. If not, write to the Free
29 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30 *****************************************************************************
31 * $Id$
32 */
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <errno.h>
37
38 #include <huskylib/compiler.h>
39 #include <huskylib/huskylib.h>
40 #include <huskylib/cvtdate.h>
41
42 #ifdef HAS_DOS_H
43 #include <dos.h>
44 #endif
45 #ifdef HAS_UNISTD_H
46 #include <unistd.h>
47 #endif
48
49 #include <fidoconf/fidoconf.h>
50 #include <huskylib/xstr.h>
51 #include <fidoconf/common.h>
52 #include <smapi/msgapi.h>
53
54 #include <pkt.h>
55 #include <areafix/areafix.h>
56 #include <global.h>
57
58 #include <version.h>
59
60
createPkt(char * filename,s_pktHeader * header)61 FILE *createPkt(char *filename, s_pktHeader *header)
62 {
63 FILE *pkt = NULL;
64 struct tm *pktTime;
65 unsigned int i;
66 UCHAR dummy;
67
68 i = open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, S_IREAD | S_IWRITE);
69 if( i >0 ) {
70 pkt = fdopen(i, "wb+");
71 if (pkt != NULL) {
72
73 fputUINT16(pkt, (UINT16)header->origAddr.node);
74 fputUINT16(pkt, (UINT16)header->destAddr.node);
75
76 /* create pkt time */
77 pktTime = localtime(&(header->pktCreated));
78
79 /* write time */
80 fputUINT16(pkt, (UINT16)(pktTime->tm_year + 1900)); /* struct tm stores the years since 1900 */
81 fputUINT16(pkt, (UINT16) pktTime->tm_mon);
82 fputUINT16(pkt, (UINT16) pktTime->tm_mday);
83 fputUINT16(pkt, (UINT16) pktTime->tm_hour);
84 fputUINT16(pkt, (UINT16) pktTime->tm_min);
85 fputUINT16(pkt, (UINT16) pktTime->tm_sec);
86
87 /* write unused baud field */
88 fputUINT16(pkt, 0);
89
90 /* write pktver == 2 */
91 fputUINT16(pkt, 2);
92
93 /* write net info */
94 fputUINT16(pkt, (UINT16) header->origAddr.net);
95 fputUINT16(pkt, (UINT16) header->destAddr.net);
96
97 #if 0
98 fputc(header->loProductCode, pkt); /* put lowByte of Prod-Id */
99 fputc(header->majorProductRev, pkt); /* put major version number */
100 #else
101 fputc(HPT_PRODCODE_LOWBYTE, pkt); /* put lowByte of Prod-Id */
102 fputc(VER_MAJOR, pkt); /* put major version number */
103 #endif
104
105 /* write PKT pwd, if strlen(pwd) < 8, fill the rest with \0 */
106 for (i=0; i < strlen((char *) header->pktPassword); i++) fputc(header->pktPassword[i], pkt);
107 for (i=strlen((char *) header->pktPassword); i<8; i++) fputc(0, pkt);
108
109 /* write qzone info */
110 fputUINT16(pkt, (UINT16) header->origAddr.zone);
111 fputUINT16(pkt, (UINT16) header->destAddr.zone);
112
113 fputUINT16(pkt, 0); /* filler */
114
115 /* write byte swapped capability Word */
116 dummy = (UCHAR)(header->capabilityWord / 256);
117 fputc(dummy, pkt);
118 dummy = (UCHAR)(header->capabilityWord % 256);
119 fputc(dummy, pkt);
120
121 #if 0
122 fputc(header->hiProductCode, pkt); /* put hiByte of Prod-Id */
123 fputc(header->minorProductRev, pkt); /* put minor version number */
124 #else
125 fputc(HPT_PRODCODE_HIGHBYTE, pkt); /* put hiByte of Prod-Id */
126 fputc(VER_MINOR, pkt); /* put minor version number */
127 #endif
128
129 fputUINT16(pkt, header->capabilityWord);
130
131 fputUINT16(pkt, (UINT16) header->origAddr.zone);
132 fputUINT16(pkt, (UINT16) header->destAddr.zone);
133
134 fputUINT16(pkt, (UINT16) header->origAddr.point);
135 fputUINT16(pkt, (UINT16) header->destAddr.point);
136
137 fputUINT16(pkt, 0); fputUINT16(pkt, 0); /* write prodData */
138
139 return pkt;
140 }
141 }
142 return NULL;
143 }
144
145 #if 0
146 int writeMsgToPkt(FILE *pkt, s_message msg)
147 {
148 /* write type 2 msg */
149 fputc(2, pkt);
150 fputc(0, pkt);
151
152 /* write net/node info */
153 fputUINT16(pkt, (UINT16) msg.origAddr.node);
154 fputUINT16(pkt, (UINT16) msg.destAddr.node);
155 fputUINT16(pkt, (UINT16) msg.origAddr.net);
156 fputUINT16(pkt, (UINT16) msg.destAddr.net);
157
158 /* write attribute info */
159 fputUINT16(pkt, (UINT16) msg.attributes);
160
161 /* write cost info */
162 fputUINT16(pkt, 0);
163
164 /* write date...info */
165 fwrite(msg.datetime, 20, 1, pkt);
166
167 /* write userNames (max 36 bytes) */
168 if (strlen(msg.toUserName) >= 36) fwrite(msg.toUserName, 35, 1, pkt);
169 else fputs(msg.toUserName, pkt);
170 fputc(0, pkt);
171
172 if (strlen(msg.fromUserName) >= 36) fwrite(msg.fromUserName, 35, 1, pkt);
173 else fputs(msg.fromUserName, pkt);
174 fputc(0, pkt);
175
176 /* write subject */
177 if (strlen(msg.subjectLine) >= 72) fwrite(msg.subjectLine, 71, 1, pkt);
178 else fputs(msg. subjectLine, pkt);
179 fputc(0, pkt);
180
181 /* write text */
182 fputs(msg.text, pkt);
183 fputc(0, pkt);
184
185 return 0;
186 }
187 #endif
188
writeMsgToPkt(FILE * pkt,s_message msg)189 int writeMsgToPkt(FILE *pkt, s_message msg)
190 {
191 char x,y,z;
192 byte *buf;
193 byte *pbuf;
194 INT32 textLen;
195 size_t rc;
196
197 x = strlen(msg.toUserName);
198 if (x >= XMSG_TO_SIZE) x = XMSG_TO_SIZE - 1;
199 y = strlen(msg.fromUserName);
200 if (y >= XMSG_FROM_SIZE) y = XMSG_FROM_SIZE -1;
201 z = strlen(msg.subjectLine);
202 if (z >= XMSG_SUBJ_SIZE) z = XMSG_SUBJ_SIZE - 1;
203 textLen = strlen(msg.text);
204
205 buf = (byte*)safe_malloc(38+x+y+z+textLen);
206 pbuf = buf;
207
208 /* type (2 bytes) */
209 pbuf[0]='\002'; pbuf[1]='\000'; pbuf+=2;
210
211 /* net/node info (8 bytes) */
212 put_word(pbuf,(UINT16)msg.origAddr.node); pbuf+=2;
213 put_word(pbuf,(UINT16)msg.destAddr.node); pbuf+=2;
214 put_word(pbuf,(UINT16)msg.origAddr.net); pbuf+=2;
215 put_word(pbuf,(UINT16)msg.destAddr.net); pbuf+=2;
216
217 /* attribute info (2 bytes) */
218 put_word(pbuf,(UINT16)msg.attributes); pbuf+=2;
219
220 /* cost info (2 bytes) */
221 put_word(pbuf, 0); pbuf+=2;
222
223 /* date info (20 bytes) */
224 memmove(pbuf, msg.datetime, 20); pbuf+=20;
225
226 /* write userNames */
227 memmove(pbuf,msg.toUserName,x); pbuf+=x;
228 pbuf[0]='\0'; pbuf++; /* 1 byte */
229 memmove(pbuf,msg.fromUserName,y); pbuf+=y;
230 pbuf[0]='\0'; pbuf++; /* 1 byte */
231
232 /* write subject */
233 memmove(pbuf,msg.subjectLine,z); pbuf+=z;
234 pbuf[0]='\0'; pbuf++; /* 1 byte */
235
236 /* write text */
237 memmove(pbuf,msg.text,textLen); pbuf+=textLen;
238 pbuf[0]='\0'; pbuf++; /* 1 byte */
239
240 rc = fwrite(buf, pbuf-buf, 1, pkt);
241 nfree(buf);
242
243 return ((rc==1) ? 0 : 1);
244 }
245
closeCreatedPkt(FILE * pkt)246 int closeCreatedPkt(FILE *pkt)
247 {
248 int rc=0;
249 rc += !fwrite("\000\000",2,1,pkt);
250 rc += fclose(pkt);
251 return rc;
252 }
253
openPktForAppending(char * fileName,s_pktHeader * header)254 FILE *openPktForAppending(char *fileName, s_pktHeader *header)
255 {
256 FILE *pkt = NULL;
257
258 if (fexist(fileName)) {
259 if ((pkt = fopen(fileName, "r+b"))==NULL) {
260 printf("can't open pkt: %s (%s)\n",fileName, strerror(errno));
261 exit_hpt("can't open pkt for appending",0);
262 }
263 openPkt(pkt);
264 fseek(pkt, -2, SEEK_END); /* go to \0\0 to add a new msg. */
265 if (ftell(pkt) <= 0) { /* this was a zero length file ... */
266 fclose(pkt);
267 pkt = NULL;
268 }
269 }
270
271 if (pkt == NULL) {
272 pkt = createPkt(fileName, header);
273 } /* endif */
274
275 if (pkt == NULL) {
276 printf("can't create pkt: %s (%s)\n",fileName, strerror(errno));
277 exit_hpt("can't create new pkt",0);
278 }
279
280 return pkt;
281 }
282
283 /* Note:
284 * This is a simply msgid without any hash function...
285 * Imho it is not necessary to create better msgid for this purpose.
286 */
287 /*
288 char *createKludges(const char *area, const ps_addr ourAka, const ps_addr destAka) {
289
290 char *buff = NULL;
291
292 if (area) xscatprintf(&buff, "AREA:%s\r", area);
293 else {
294 xscatprintf(&buff, "\001INTL %u:%u/%u %u:%u/%u\r",
295 destAka->zone, destAka->net, destAka->node,
296 ourAka->zone, ourAka->net, ourAka->node);
297 if (ourAka->point) xscatprintf(&buff, "\001FMPT %d\r", ourAka->point);
298 if (destAka->point) xscatprintf(&buff, "\001TOPT %d\r", destAka->point);
299 }
300
301 sleep(1);
302 if (ourAka->point)
303 xscatprintf(&buff, "\001MSGID: %u:%u/%u.%u %08lx\r",
304 ourAka->zone,ourAka->net,ourAka->node,ourAka->point,time(NULL));
305 else
306 xscatprintf(&buff, "\001MSGID: %u:%u/%u %08lx\r",
307 ourAka->zone,ourAka->net,ourAka->node,time(NULL));
308
309 if (!config->disableTID) xscatprintf(&buff, "\001PID: %s\r", versionStr);
310 xstrcat(&buff, "\001FLAGS NPD\r");
311
312 return buff;
313 }
314 */
315