forked from oe5hpm/openBCM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fwd_fbb.cpp
1728 lines (1669 loc) · 58.3 KB
/
fwd_fbb.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/***************************************************************
BayCom(R) Packet-Radio fuer IBM PC
OpenBCM-Mailbox
----------------------------------------------
Forward-Ein- und Ausgabe fuer F6FBB-Forwarding
----------------------------------------------
Copyright (C) Dietmar Zlabinger
Reinberg-Heidenreichstein 31
A-3861 Eggern
Alle Rechte vorbehalten / All Rights Reserved
***************************************************************/
//19980116 OE3DZW commented out unreachable code
//19980124 OE3DZW added rejreason (needed for logging)
// trace for unpacking corr. position
// fbb: at trace-msges
// Added b->readfiles
// When no mails to send, wait 5min, check every 18s
//19980125 OE3DZW Added waitfor() in "find a filename"
// Added log when yapp-error rx occurs
//19980128 OE3DZW changed delay to max. 3min
// fixed:starts with rx when no mails to send (sf..)
//19980202 OE3DZW workaround for blocking when cannot read fwd-triggerfile
//19980207 OE3DZW removed ugly bug under dos - huffman was set very long
//19980208 OE3DZW generates a new bid if there is an old mail without bid
//19980208 OE3DZW on rx length of subject and offset are tested
// removed trailing \r and \n from subject
// ignoring trailing fields on fbb-rx
//19980211 OE3DZW fixed: will not forward erased mails
// found that workaround "cannot rd fwd-file" no longer here
//19980215 OE3DZW cosmetic changes to erasefwded()
// new tem filename on rx -> stops after 99 tries
// added crc-check for file-crc (fbb)
// crc in proposal obligatory if [D1] in SID
//19980223 OE3DZW file-crc check only for [B1]-protocoll, not for B
// make another check for tmp-bid if we already receive it
//19980302 OE3DZW bigger buffer for recvd_status (7->10char per proposal)
// added b->fwdprop (before only in ascii-fwd)
//19980304 OE3DZW fixed bug, bulletins were erased after forwarding
//19980307 OE3DZW win32-typecast for rx-file-crc
// added timeout to yapp-head, yapp-end
// now uses time2filename for temporary files
// will not erase but hold if personal, also when o_r
// debug replog when sending empty proposal
// moved timeout to correct position
//19980309 OE3DZW added reason to add_hold
// better info in lastcmd
//19980311 OE3DZW added timeout-trigger to sendonemail
// better info in last-cmd
//19980312 OE3DZW fixed sendnum, returns 0 if there is no mail to send
//19980313 OE3DZW black friday 13th
//19980318 OE3DZW more robust against trash in fwd-triggerfile
//19980329 OE3DZW corrected fwd-rx/tx byte-infos
//19980404 OE3DZW removed debug-output "not this one"
// removed last_cmd/timeout in fwd-delay (not usefull)
// bin mails caused empty-proposals, fixed
//19980408 OE3DZW mailpath into log when fopen err
//19980421 OE3DZW added memset when receiving mail subject
// added two s_fsetopt=erase on disconnect
//19980427 OE3DZW fwd-option -u ->do not wait
//19980506 OE3DZW defer caused removal from fwd-list, fixed
//19980609 OE3DZW usermails will be erased when replied with "no" in userfwd
// sfhold - added parameter
//19980610 OE3DZW sfhold - not for "sysop" mails of type "p"
//19980614 OE3DZW added update_mail -> will reroute mail received in fbb-fwd
//19980615 OE3DZW using fwdproc_reply
//19980615 OE3DZW log/lostcommand with at
//19980620 OE3DZW string was too short, fixed (output of ps)
//19980904 OE3DZW fixed check for bid
// started implementation of resume
//19980905 OE3DZW finished implementation of resume, first tests
//19980916 OE3DZW checked sema at check_fragement-routine
// added signature
//19990206 OE3DZW added check for huffman-err
//19990411 OE3DZW fwd-proposal: if b->at==""->b->logincall used
//19990615 DH3MB adapted for new CRC classes
// CRC/checksum after proposal ist optional again (This is,
// what the SPEC says!)
//19990616 DH3MB reduced parseprop()-parameters to "char *prop",
// CRC-/Checksum-calculation is now done in replyprop()
//19990703 DH3MB Changed "recv" to "rx" and "send" to "tx"
// Changed "& 0xff" to "% 0x100" when sending the
// CRCs, should be architecture independent noew
//20000104 OE3DZW fixed problem with -u, did not delay in fwd
//20000116 DK2UI (dzw) added ui-options
//20000116 OE3DZW fixed problem with -u again
//20000118 OE3DZW mail-f-open now binary
//20000131 OE3DZW added some lastcmds on fwd-rx (debug to find bug)
#include "baycom.h"
/*---------------------------------------------------------------------------*/
fbb::fbb (void)
//*************************************************************************
//
// Initialization
//
//*************************************************************************
{
strcpy(signature, SIGNATURSTR);
}
/*---------------------------------------------------------------------------*/
fbb::~fbb (void)
//*************************************************************************
//
// Deinitialization
//
//*************************************************************************
{
if (strcmp(signature, SIGNATURSTR))
trace(fatal, "fbb", "sig broken");
}
/*---------------------------------------------------------------------------*/
char fbb::tx_proposal (char *tosend, char *recvd_status)
//*************************************************************************
//
// Checks if there is mail waiting in the outgoing queue, if there
// is some mail it sends a proposal and receives the reply
// Returns: 0 = there is no mail
// 1..5 = there were 1..5 mails in the proposal
//
//*************************************************************************
{
char name[20];
strcpy(name, "fbb:tx_proposal");
lastfunc(name);
char sendnum = 0; // Number of mails in the list
char *p; // Pointer for the list
int i, j; // Counter
FILE *f; // Pointer for mail file
crcthp prop_crc; // CRCthp of the proposal (if [D] in SID)
char prop_sum = 0; // Checksum of the proposal (if no [D] in SID)
char was_error; // Was there an error in the last proposal?
char error; // Was there an error in the current proposal?
if (another_fwd_sender(b->logincall) || ! chkforward(b->logincall)) return 0;
do
{
waitfor(e_ticsfull);
p = tosend; // Move pointer to the begin of the list
sendnum = 0; // No entries in the list yet
was_error = 0; // No error - yet ;-)
if (b->forwarding == fwd_standard) // Normal S&F -> forward-trigger-file
{
sendnum += getfwdlistentry(b->logincall, 'u', FBB_MAX_PROP - sendnum, &p);
if (sendnum < FBB_MAX_PROP && isforwardtime(b->logincall, 1))
sendnum += getfwdlistentry(b->logincall, 'i', FBB_MAX_PROP - sendnum, &p);
// e/m-msges only if d(iebox) compatible system
if (sendnum < FBB_MAX_PROP && (b->opt & o_d) && isforwardtime(b->logincall, 2))
sendnum += getfwdlistentry(b->logincall, 'm', FBB_MAX_PROP - sendnum, &p);
} // User S&F -> list-file of the user
else sendnum += getfwdlistentry(b->logincall, 'l', FBB_MAX_PROP, &p);
waitfor(e_ticsfull);
p = tosend; // Move pointer to the begin of the list
if (sendnum > FBB_MAX_PROP)
trace(fatal, name, "sendnum %d", sendnum); //debug, should never happen
for (i = 0; i < sendnum; i++)
{
error = 0; // No error - yet
if (p[1] != ' ') // Bulletin or personal mail -> Examine mail file
{
if (strlen(p) < 9) //sometimes there is trash in the triggerfile -> debug
{
trace(serious, name, "trash: %s", p);
error = 1;
}
if (setfullpath(p))
{
strlwr(b->mailpath);
if ((f = s_fopen(b->mailpath, "lrb")) != NULL)
{
if (! scanheader(f, fpara()))
error = 1; //checks if binary mail
}
else
{
trace(report, name, "mailfile not existing");
error = 1;
}
}
else
{
trace(serious, name, "dir %s", board_aus_path(p));
error = 1;
}
}
waitfor(e_ticsfull);
if (error) // Error -> Delete from forward-list / mark as forwarded
{
if (b->forwarding == fwd_standard)
{
delfwdlistentry(p); //eg. bin mail when no bin-fwd
trace(report, name, "fwd del: %s", p);
}
else
{
markerased('F', 0, 0);
delfwdlistentry(p); //eg. bin mail when no bin-fwd
trace(report, name, "fwd erased: %s", p);
}
was_error = 1;
}
p += strlen(p) + 1; // Move to next entry in the forward list
waitfor(e_ticsfull);
}
}
while (was_error);
p = tosend; // Move pointer to the begin of the list
for (i = 0; i < sendnum; i++)
{
if (p[1] == ' ') // E/M-mail
{
mbsend_parse(p, 0);
b->mailtype = 'B';
b->bytes = 80L;
}
else // Bulletin or personal mail
{
setfullpath(p);
parse_headerline();
}
if (! *b->bid) //if there is no bid, generate a new one;
//this SHOULD not happen, but if someone makes
//an update from a very old version this is
//usefull (else we get a protocol error)
{
strcpy(b->bid, newbid());
trace(replog, name, "gen newbid $%s %s>%s",
b->bid, b->herkunft, b->ziel);
}
if (! (b->opt & o_d))
b->ziel[6] = 0; // No [D] in SID -> use max. 6 characters in boardname
if (b->forwarding == fwd_user || ! *b->at)
strcpy(b->at, b->logincall);
if (b->opt & o_d)
strcpy(b->line, D_PROPOSE);
else
{
if (b->opt & o_b)
strcpy(b->line, FBB_COMPPROP); // only correct if text-msg
else
strcpy(b->line, FBB_PROPOSE); // old ascii-protocol
}
snprintf(b->line + strlen(b->line), BUFLEN - strlen(b->line),
" %c %s %s %s %s %ld", b->mailtype, b->herkunft,
b->at, b->ziel, b->bid, b->bytes);
if ((b->opt & o_d) && b->lifetime) // [D] in SID -> Send lifetime
snprintf(b->line + strlen(b->line), BUFLEN - strlen(b->line),
" %d", b->lifetime);
fwdput(b->line, "");
for (j = 0; j < strlen (b->line); j++)
if (b->opt & o_d)
prop_crc.update(b->line[j]); // use CRCthp/Checksum depending
// on [D] in SID
else
prop_sum += b->line[j];
if (! (b->opt & o_d)) prop_sum += 13; // CR is included in the checksum
p += strlen(p) + 1; // Move to next entry in the forward list
}
if (! sendnum) //if no proposal was found to be valid,
{ //ignore that problem, fix it later..
//trace(report, name, "nothing to send");
wdelay(8909); //should no longer loop at all, but it does..
return 0;
}
if (b->opt & o_d) // Use CRCthp/Checksum depending on [D] in SID
snprintf(b->line, BUFLEN, " %02X%02X",
prop_crc.result % 0x100, prop_crc.result / 0x100);
else
snprintf(b->line, BUFLEN, " %02X", (-prop_sum) & 0xff);
fwdput(FBB_PROMPT, b->line);
fwdget(recvd_status, 3 + 10 * FBB_MAX_PROP);
return (sendnum);
}
/*---------------------------------------------------------------------------*/
void fbb::tx_yapp_header (void)
//*************************************************************************
//
// Sends the mail header and calculate the CRCs
//
//*************************************************************************
{
int i;
//lastcmd("fwd: Send mailheader");
fwdlog("---- ", "[mail header]", 'S');
/* accept any offset
if (b->fbboffset > 999999L)
{
trace(replog, "fbb:tx_yapp_", "fbboffset %ld", b->fbboffset);
b->fbboffset = 999999L;
}
*/
snprintf(b->line, BUFLEN, "%6lu", b->fbboffset);
bputv(SOH);
bputv(strlen(b->betreff) + strlen(b->line) +2); //variable length of offset
putf("%s", b->betreff);
bputv(NUL);
putf("%s", b->line);
bputv(NUL);
waitfor(e_ticsfull);
// CRCfbb only covers the subject, if [D] in SID
if (b->opt & o_d)
for (i = 0; i < strlen(b->betreff); i++)
mail_crcfbb->update(b->betreff[i]);
// CRCthp covers subject, offset and null-bytes
for (i = 0; i < strlen(b->betreff); i++)
mail_crcthp->update(b->betreff[i]);
mail_crcthp->update((char) 0);
for (i = 0; i < strlen(b->line); i++)
mail_crcthp->update(b->line[i]);
mail_crcthp->update((char) 0);
waitfor(e_ticsfull);
}
/*---------------------------------------------------------------------------*/
void fbb::tx_yapp_data (char *buf, unsigned short int length)
//*************************************************************************
//
// Sends an FBB-YAPP block
//
//*************************************************************************
{
unsigned short int i;
crcfbb block_crc;
char name[20]; // Name for syslog
strcpy(name, "fbb:tx_yapp_block");
if (! length)
{
trace(serious, name, "Try to send 0-byte YAPP block");
return;
}
bputv(STX);
if (length == 256) bputv(0);
else bputv(length);
for (i = 0; i < length; i++) // Send the YAPP-block
{
bputv(buf[i]);
block_crc.update(buf[i]);
mail_crcthp->update(buf[i]);
mail_checksum += buf[i];
}
if (b->opt & o_d1) // Send block CRC if [D1] in SID
{
bputv(block_crc.result % 0x100);
bputv(block_crc.result / 0x100);
}
timeout(m.fwdtimeout);
t->last_input = ad_time();
waitfor(e_ticsfull);
}
/*---------------------------------------------------------------------------*/
void fbb::tx_yapp_end (void)
//*************************************************************************
//
// Sends the end-of-transfer block (EOT+Checksum/CRCthp)
//
//*************************************************************************
{
//lastcmd("fwd: Send EOT");
fwdlog("---- ", "[end of mail]", 'S');
bputv(EOT); // End of transfer identifier
if ((b->opt & o_d) && ! (b->opt & o_b1)) // [D], no [B1] -> send CRCthp
{
bputv(mail_crcthp->result % 0x100);
bputv(mail_crcthp->result / 0x100);
}
else
bputv(-mail_checksum); // Send the checksum otherwise
}
/*---------------------------------------------------------------------------*/
char fbb::tx_onemail (void)
//*************************************************************************
//
// Sends a mail in FBB/YAPP-format
// Returns 1 on success, 0 otherwise
//
//*************************************************************************
{
char name[20];
strcpy(name, "fbb:tx_onemail"); // Name for syslog
lastfunc(name);
int retwert = 0;
FILE *f; // Pointer for the mail file
handle fh; // Handle for the compressed mail file
unsigned short int bytes; // Number of bytes in the YAPP block
// (max. 256 Bytes)
char unpackedfname[25]; // Name of the uncompressed file
char packedfname[25]; // Name of the compressed file
char predatanum = 0; // Number of bytes we must send
unsigned long real_tx_bytes = 0; // uncompressed amount of TX-Bytes
time_t starttime, txtime = 0L, delta_lastmeasure;
fwdpara_t *ff = fpara();
int i;
long routing_quality_old = 0;
char lbuf[80];
if (! (b->opt & o_b)) // Partner does not support compressed forward :-(
{
fwdlog("---- ", "[mail title]", 'S');
putf("%s\n", b->betreff);
timeout(m.fwdtimeout);
t->last_input = ad_time();
fwdlog("---- ", "[text file]", 'S');
b->readfiles++;
if (! strcmp(b->ziel, "M") || ! strcmp(b->ziel, "E"))
putf("\n***sysfile\n\n");
else
if ((f = s_fopen(b->mailpath, "srb")) != NULL)
{ // Skip the whole header
fgets(b->line, BUFLEN - 1, f); // mail header line
fgets(b->line, BUFLEN - 1, f); // forward trigger line
fgets(b->line, BUFLEN - 1, f); // 'Read:' line
fgets(b->line, BUFLEN - 1, f); // title line
readmail(f, 0); // f is closed within readmail()
}
else
{
trace(serious, name, ms(m_filenotopen), b->mailpath);
retwert = 0;
goto ende;
}
putf("\032\n"); // Ctrl-Z
real_tx_bytes = b->txbytes;
}
else
{
// Initialize CRCs and checksum
mail_crcthp = new (crcthp);
mail_crcfbb = new (crcfbb);
mail_checksum = 0;
huffcod huff(mail_crcfbb);
if (huff.err)
trace(fatal, name, "huffman error");
timeout(m.fwdtimeout);
t->last_input = ad_time();
tx_yapp_header();
waitfor(e_ticsfull);
snprintf(unpackedfname, sizeof(unpackedfname),
FBBPATH "/%s.fbb", time2filename(0));
strlwr(unpackedfname);
snprintf(packedfname, sizeof(packedfname),
FBBPATH "/%s.lha", time2filename(0));
strlwr(packedfname);
//trace(report, name, " pack fn %s", unpackedfname);
if (! strcmp(b->ziel, "M") || ! strcmp(b->ziel, "E"))
{
if ((f = s_fopen(unpackedfname, "swb")) != NULL)
{
fprintf(f, NEWLINE "***sysfile" NEWLINE NEWLINE); // Create a dummy
// mail body
s_fclose(f); // for system-files
}
else
{
trace(serious, name, "fopen %s errno=%d %s", unpackedfname,
errno, strerror(errno));
delete(mail_crcthp);
delete(mail_crcfbb);
retwert = 0;
goto ende;
}
}
else
if ((f = s_fopen(b->mailpath, "lrb")) != NULL)
{ // Skip the whole header
fgets(b->line, BUFLEN - 1, f); // mail header line
fgets(b->line, BUFLEN - 1, f); // forward trigger line
fgets(b->line, BUFLEN - 1, f); // 'Read:' line
fgets(b->line, BUFLEN - 1, f); // title line
b->oldoutput = t->output;
t->output = io_file;
if (! (b->outputfile = s_fopen(unpackedfname, "swb")))
{
trace(serious, name, "fopen %s errno=%d %s", unpackedfname,
errno, strerror(errno));
delete(mail_crcthp);
delete(mail_crcfbb);
retwert = 0;
goto ende;
}
s_fsetopt(b->outputfile, 1);
unsigned long true_rx = b->rxbytes;
unsigned long true_tx = b->txbytes;
readmail(f, 1); // f is closed within readmail()
real_tx_bytes = b->txbytes;
b->rxbytes = true_rx;
b->txbytes = true_tx;
s_fclose(b->outputfile);
t->output = (io_t) b->oldoutput;
}
else
{
trace(serious, name, "fopen %s", b->mailpath);
delete(mail_crcthp);
delete(mail_crcfbb);
retwert = 0;
goto ende;
}
waitfor(e_ticsfull);
huff.encode(unpackedfname, packedfname);
xunlink(unpackedfname);
fwdlog("---- ", "[mail body]", 'S');
b->readfiles++;
if ((fh = s_open(packedfname, "lrb")) == EOF)
{
trace(serious, name, "open packedfile error");
delete(mail_crcthp);
delete(mail_crcfbb);
retwert = 0;
goto ende;
}
s_setopt(fh, 2); // Remove file on disconnect or after close()
// [B1] in SID: The CRCfbb over the whole file is included in
// the first datablock
if (b->opt & o_b1)
{
b->line[0] = mail_crcfbb->result % 0x100;
b->line[1] = mail_crcfbb->result / 0x100;
predatanum = 2;
// If the partner wishes to resume a file, we must also repeat
// the first 4 bytes (= the filelength) before sending the rest
// of the file
if (b->fbboffset)
{
_read(fh, b->line + 2, 4);
predatanum = 6;
lseek(fh, (long) b->fbboffset - 2L, SEEK_SET);
}
}
starttime = ad_time();
while ((bytes =
_read(fh, b->line + predatanum, 256 - predatanum)+predatanum) > 0)
{
predatanum = 0;
tx_yapp_data(b->line, bytes);
}
txtime = ad_time() - starttime;
if (! txtime) txtime = 1L;
s_close(fh); // File is removed automatically via s_setopt()
tx_yapp_end();
// Delete the CRC objects
delete(mail_crcthp);
delete(mail_crcfbb);
} // end of huffcod (end of locking in DOS version)
ff->txf++;
retwert = 1;
//----
if (ff->routing_quality == WPROT_MIN_ROUTING)
{
ff->routing_txf = 0;
ff->lastmeasure = 0;
ff->lastwpr = 0;
}
delta_lastmeasure = ad_time() - ff->lastmeasure;
if (real_tx_bytes > 0 && (real_tx_bytes > 512 || delta_lastmeasure > 3600))
{
ff->routing_txf++;
ff->current_routing_quality = txtime * 100000L / real_tx_bytes;
if (ff->current_routing_quality == 0) ff->current_routing_quality = 1;
// quality auf 100kByte normalisieren
sprintf(lbuf, "M %-6.6s %-6.6s %s (%ld) 10 1 %-5ld (%ldm/%-5ldg)\n",
ff->call, b->logincall, datestr(ad_time(), 12),
ad_time(), ff->current_routing_quality, ff->routing_txf,
ff->routing_quality);
wprotlog(lbuf, ff->call);
//Aging of quality
if (delta_lastmeasure <= DAY)
{
for (i = 1; i < 12; i++)
{
if ((delta_lastmeasure > i*HOUR) && (delta_lastmeasure < (i+1)*HOUR))
{
routing_quality_old = ff->routing_quality;
ff->routing_quality = ff->routing_quality + ff->routing_quality*i/5; //+20% pro Stunde
if (ff->routing_quality == routing_quality_old)
ff->routing_quality = ff->routing_quality + i; //mindestens aber um +1 pro Stunde
}
}
}
if (delta_lastmeasure > DAY) ff->routing_quality = WPROT_MIN_ROUTING;
if (delta_lastmeasure > 3*DAY) ff->routing_quality = 0; //? correct?
sprintf(lbuf, "A %-6.6s %-6.6s %s (%ld/%ld) (%-5ldg) %ldb\n",
ff->call, b->logincall, datestr(ff->lastmeasure, 12),
ff->lastmeasure, delta_lastmeasure, ff->routing_quality, real_tx_bytes);
wprotlog(lbuf, ff->call);
//The quality is the mean value of all measurements
ff->routing_quality = (ff->routing_quality*(ff->routing_txf - 1)
+ ff->current_routing_quality)/ff->routing_txf;
if (ff->routing_quality < 1)
ff->routing_quality = 1; //mindestens Wert von 1
ff->lastmeasure = ad_time();
sprintf(lbuf, "N %-6.6s %-6.6s %s (%ld) 10 1 %-5ld\n",
ff->call, b->logincall, datestr(ff->lastmeasure, 12),
ff->lastmeasure, ff->routing_quality);
wprotlog(lbuf, ff->call);
}
if ((ad_time() - ff->lastwpr) > 5*HOUR) // after 5h
{
wpdata_t *wp = (wpdata_t*) t_malloc(sizeof(wpdata_t), "wps");
safe_strcpy(wp->bbs, ff->call);
wp->bversion = BVERSION;
ff->lastwpr = wp->mybbstime = ff->lastmeasure;
wp->hops = 1; // wird in addwp_r +1 erhoeht
wp->qual = ff->routing_quality;
wprotlog("C ", wp->bbs);
addwp_r(wp);
ff->routing_txf = 1;
t_free(wp);
}
//----
ende:
return (retwert);
}
/*---------------------------------------------------------------------------*/
char fbb::tx_mails (char *tosend, char sendnum, char *recvd_status)
//*************************************************************************
//
// Sends the mails to the partner
//
//*************************************************************************
{
lastfunc("fbb:tx_mails");
char *p = tosend;
char *state = recvd_status + 3;
char i;
FILE *f;
int was_locked = 0;
if ( strncmp(FBB_STATUS, recvd_status, strlen(FBB_STATUS))
|| recvd_status[strlen(FBB_STATUS)] != ' ')
{
fwdput("*** received status prompt invalid", "");
return (0);
}
for (i = 0; i < sendnum; i++)
{
{
char c[40];
snprintf(c, sizeof(c), "fwd: tx mail %d/%d", i + 1, sendnum);
lastcmd(c);
}
b->fbboffset = 0L;
switch (*state)
{
case FBB_NO:
case FBB_NO_:
case FBB_REJECT:
case FBB_ERROR:
case FBB_LATER: //TODO
case FBB_LATER_: break; //TODO
case FBB_RESUME:
case FBB_RESUME_: b->fbboffset = atol(state + 1);
while (isdigit(*(state + 1))) state++;
// fall through
case FBB_HOLD:
case FBB_YES:
case FBB_YES_:
if (p[1] == ' ')
mbsend_parse(p, 0); // E/M-mail
else // Bulletin or user-mail
{
setfullpath(p);
strlwr(b->mailpath);
if (! (f = s_fopen(b->mailpath, "lrb")))
{
trace(serious, "fbb:tx_mails", "open mailfile error");
return (0);
}
if (mbhadrok(b->at) == 1) do
{
if (! sema_lock(b->mailpath))
{
s_fclose(f);
wdelay(7077);
f = s_fopen(b->mailpath, "lrb");
was_locked = 1;
}
else was_locked = 0;
}
while (was_locked);
rewind(f);
fgets(b->line, BUFLEN - 1, f); // Read command header line
b->line[254] = 0;
mbsend_parse(b->line, 0);
fgets(b->line, BUFLEN - 1, f); // Read forward trigger line
if (*b->line == '*') // Has msg been erased/fwded in the meanwhile?
{
fwdput("*** msg is erased", "");
sema_unlock(b->mailpath);
s_fclose(f);
return (0);
}
fgets(b->line, BUFLEN - 1, f); // Skip 'Read:' line
fgets(b->betreff, BETREFFLEN, f);
rm_crlf(b->betreff);
b->betreff[79] = 0;
s_fclose(f);
}
// Mark mail as proposed
if (! (b->mailtype == 'B'))
{
char c[LINELEN+1];
if (b->fwdprop < 127) b->fwdprop++;
writemailflags();
snprintf(c, LINELEN, "fwd: tx $%s (%s%c%s < %s)",
b->bid, b->ziel, b->at[0] ? '@' : ' ',
atcall(b->at), b->herkunft);
lastcmd(c);
trace(report, "fwd-tx", "$%s (%s%c%s < %s)", b->bid, b->ziel,
*b->at ? '@' : ' ', atcall (b->at), b->herkunft);
//dh8ymb: nun in tx_onemail
// fwdpara_t *ff = fpara();
// ff->txf++;
}
waitfor (e_ticsfull);
if (! tx_onemail())
{
fwdput("*** internal error sending mail", "");
sema_unlock(b->mailpath);
return (0);
}
//sema_unlock(b->mailpath); // -> now when all mails of proposal
// have been forwarded
waitfor(e_ticsfull);
break;
default:
if (*state) fwdput("*** invalid fbbstatus character", "");
else fwdput("*** fbbstatus too short", "");
return (0);
}
state++;
p += (strlen(p) + 1); // Move pointer to next entry
waitfor(e_ticsfull);
}
return (1);
}
/*---------------------------------------------------------------------------*/
void fbb::erase_forwarded (char sendnum, char *tosend, char *recvd_status)
//*************************************************************************
//
// Removes forwarded mails from the forward-queue
//
//*************************************************************************
{
lastfunc("fbb:erase_forwarded");
char *p = tosend; // list of strings from fwd-triggerfile
char *state = recvd_status+3; // received status from fwd-partner,
// e.g. "++--="
char i;
for (i = 0; i < sendnum; i++)
{
if (p[1] == ' ')
delfwdlistentry(p); // E/M-mail
else // normal mail (user/info of type B,P,A)
{
setfullpath(p);
strlwr(b->mailpath);
if (! parse_headerline())
{
trace(serious, "fbb:eraseforwarded", "open mailfile error");
return;
}
else
{
switch (*state)
{
case FBB_LATER: // "I am just receiving this mail, maybe
case FBB_LATER_: // its me, so better let it remain in the queue
wdelay(31341); //on local links to make it slower
break;
case FBB_NO: // "I have this mail"
case FBB_NO_:
// erase this mail if personal & proposed
// hold if personal and not proposed
if (b->forwarding == fwd_standard) delfwdlistentry(p);
fwdproc_reply(FBB_NO);
break;
case FBB_REJECT: // "I don't have the mail and I don't want it"
case FBB_ERROR:
if (b->forwarding == fwd_standard) delfwdlistentry(p);
fwdproc_reply(FBB_REJECT);
break;
case FBB_RESUME: // "I want this mail"
case FBB_RESUME_:
if (b->forwarding == fwd_standard) delfwdlistentry(p);
b->fbboffset = atol(state + 1);
while (isdigit(*(state + 1))) state++;
// fall through
case FBB_HOLD:
case FBB_YES:
case FBB_YES_:
default:
// erase this mail if personal mail, mark as forwarded else
if (b->forwarding == fwd_standard) delfwdlistentry(p);
fwdproc_reply(FBB_YES);
break;
}
}
sema_unlock(b->mailpath); // now sema will be unlocked when
// all proposals are forwarded
}
state++;
p += strlen(p) + 1; // Move pointer to next entry
waitfor(e_ticsfull);
}
}
/*---------------------------------------------------------------------------*/
char fbb::parse_proposal (char *prop)
//*************************************************************************
//
// Scans one line of a proposal
// Returns 1, if the format was correct, 0 if not
//
//*************************************************************************
{
lastfunc("fbb:parse_proposal");
char *p;
char buf[11];
// A proposal line always starts with "FA ", "FB " or "FD "
if (prop[0] != 'F'
|| (prop[1] != 'A' && prop[1] != 'B' && prop[1] != 'D')
|| prop[2] != ' ')
return (0);
p = prop + 3;
b->mailtype = *p;
p += 2;
p = nexttoken(p, b->herkunft, CALLEN);
p = nexttoken(p, b->at, HADRESSLEN);
p = nexttoken(p, b->ziel, DIRLEN);
strcpy(b->zielboard, b->ziel);
// If a mail is addressed to the local SYSOP-board, we will deliver
// it directly to the sysop (the one specified in init.bcm)
if (! strcmp(b->zielboard, "SYSOP") && homeadr(b->at))
{
strcpy(b->zielboard, m.sysopcall);
strcpy(b->ziel, m.sysopcall); //df3vi: auch ziel aendern!
b->mailtype = 'P';
}
p = nexttoken(p, b->bid, BIDLEN);
p = nexttoken(p, buf, 10);
b->bytes = atoi(buf);
p = nexttoken(p, buf, 3);
if (*buf) b->lifetime = atoi(buf); // Lifetime is optional
else b->lifetime = 0;
waitfor(e_ticsfull);
// We keep the mailbox, we have the mail received from in mind
if (b->forwarding == fwd_standard) strcpy(b->frombox, b->logincall);
else *b->frombox = 0;
// If we receive a mail addressed to us in S&F, we will throw
// away the address, so that the message will be forwarded to the
// user's home BBS
if (b->forwarding != fwd_none && ! strcmp(atcall(b->at), m.boxname))
*b->at = 0;
return (b->mailtype && *b->herkunft && *b->ziel && *b->bid && b->bytes);
}
/*---------------------------------------------------------------------------*/
unsigned long int fbb::check_fragment (unsigned long &offset, int &idx)
//*************************************************************************
//
// Checks if we already have received a part of that mail before,
// returns
// 0..this mail is new, no fragment available
// else..offset of mail
// checking for access (sema) is necessary, but no locking needs
// to be done - there is a bid...
//
// note: it is not necessary to check if the old part is equal to the
// new one because if the fragments differ, the crc over the whole
// file will be invalid - and things will start at the very beginning.
//
//*************************************************************************
{
char name[20];
strcpy(name, "fbb:check_fragment");
lastfunc(name);
FILE *pf; //compressed file
char packedfname[25];
int found_file = 0; //found correct part
time_t pft; //time of packed file
time_t now = ad_time();
unsigned long fpsize; //size of file
header_t header;
idx = 0; //counter for compressed files
do
{
idx++;
// check if file is correct
// try to open file
snprintf(packedfname, sizeof(packedfname),
FBBPATH "/%s%02d.lhb", b->logincall, idx);
strlwr(packedfname);
// existing?
if (! (pft = file_isreg(packedfname))) continue;
// too old?
if ((now - pft) > (7L * DAY)) // older than one week
{
xunlink(packedfname); continue;
}
// check if this file is used by another task
if (sema_access(packedfname)) continue;
// try to open
if (! (pf = s_fopen(packedfname, "lrb")))
{
trace(serious, name, ms(m_filenotopen), packedfname);
continue;
}
// check size, at least 2kBytes
fseek (pf, 0, SEEK_END);
if ((fpsize = ftell(pf)) < 2048UL)
{
s_fclose(pf);
xunlink(packedfname);
continue;
}
rewind(pf);
// read header
fread(&header, sizeof(header_t), 1, pf);
// check signature
if ( strcmp(header.signature ,FBBHSIGN)
|| strcmp(header.signatur2 ,FBBHSIGN))
{
trace(serious, name, "sign broken %s", packedfname);
s_fclose(pf);
xunlink(packedfname);
continue;
}
// check version
if (strcmp(header.version, FBBHVERS))
{
s_fclose(pf);
xunlink(packedfname);
continue;
}
// check if correct file
if (strcmp(header.bid, b->bid))
{
s_fclose(pf);
continue;
}
// now we are sure that it is the correct file and that the
// file is good.
s_fclose(pf);
offset = fpsize - 1024UL - (unsigned long) sizeof(header_t);
found_file = 1;
}
while (! found_file && idx < MAXCOMPRFILE);
if (! found_file)
{
idx = 0;
return 0L;
}
return offset;
}
/*---------------------------------------------------------------------------*/
char fbb::reply_proposal (want_status_t *want_status)
//*************************************************************************
//
// Reads proposal and checks, which mails we want
// Then the reply is sent
// Returns: 0..5 = We want 0..5 mails from the partner
// FBB_RECV_FINE = Partner has no mail (has sent "FF")
// FBB_RECV_QUIT = Partner wants to quit (has sent "FQ")
// FBB_RECV_ERROR = An error occured
//
//*************************************************************************