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