1
1
use std:: {
2
2
collections:: HashMap ,
3
- fs:: File ,
4
- io:: { BufWriter , Write } ,
3
+ io:: { Cursor , Read , Seek , Write } ,
5
4
} ;
6
5
7
6
use bstr:: BString ;
8
7
use chrono:: { DateTime , Local , Utc } ;
9
8
use jamjam:: {
10
- jam:: JamMessageBase ,
9
+ jam:: { JamMessage , JamMessageBase } ,
11
10
qwk:: { control:: ControlDat , qwk_message:: QWKMessage } ,
12
11
util:: basic_real:: BasicReal ,
13
12
} ;
@@ -27,6 +26,8 @@ use crate::{
27
26
vm:: TerminalTarget ,
28
27
} ;
29
28
29
+ use super :: u_upload_file:: create_protocol;
30
+
30
31
const MASK_CONFNUMBERS : & str = "0123456789-SDL?" ;
31
32
32
33
impl IcyBoardState {
@@ -103,7 +104,7 @@ impl IcyBoardState {
103
104
break ;
104
105
}
105
106
"U" => {
106
- // TODO
107
+ self . upload_qwk_reply ( ) . await ? ;
107
108
break ;
108
109
}
109
110
"S" => {
@@ -125,11 +126,10 @@ impl IcyBoardState {
125
126
} else {
126
127
self . session . page_len as usize - 4
127
128
} ;
128
- let conferences = & self . board . lock ( ) . await . conferences . clone ( ) ;
129
129
let mut done = false ;
130
130
131
+ let conferences = & self . board . lock ( ) . await . conferences . clone ( ) ;
131
132
let mut number_to_msgid = Vec :: new ( ) ;
132
-
133
133
for ( i, conf) in conferences. iter ( ) . enumerate ( ) {
134
134
if let Some ( areas) = & conf. areas {
135
135
for ( j, _area) in areas. iter ( ) . enumerate ( ) {
@@ -304,7 +304,7 @@ impl IcyBoardState {
304
304
async fn create_qwk_packet ( & mut self ) -> Res < ( ) > {
305
305
let output_path = temp_file:: empty ( ) . path ( ) . to_path_buf ( ) ;
306
306
fs:: create_dir_all ( & output_path) . await ?;
307
- let qwk_package = output_path. join ( "mail.qwk" ) ;
307
+ let mut qwk_package = output_path. join ( "mail.qwk" ) ;
308
308
309
309
{
310
310
let board = self . board . lock ( ) . await ;
@@ -350,13 +350,15 @@ impl IcyBoardState {
350
350
return Ok ( ( ) ) ;
351
351
} ;
352
352
353
- let conferences: crate :: icy_board:: conferences:: ConferenceBase = board. conferences . clone ( ) ;
353
+ if !control_dat. bbs_id . is_empty ( ) {
354
+ qwk_package = output_path. join ( format ! ( "{}.qwk" , control_dat. bbs_id) ) ;
355
+ }
356
+
357
+ let conferences = board. conferences . clone ( ) ;
354
358
let mut conference_number = 1 ;
355
- let messages_dat: File = File :: create ( & output_path. join ( "messages.dat" ) ) ?;
356
- let mut msg_writer = BufWriter :: new ( messages_dat) ;
357
- let mut header = format ! ( "Produced by Icy Board {}" , env!( "CARGO_PKG_VERSION" ) ) . bytes ( ) . collect :: < Vec < u8 > > ( ) ;
358
- header. resize ( 128 , b' ' ) ;
359
- msg_writer. write_all ( & header) ?;
359
+ let mut msg_writer = format ! ( "Produced by Icy Board {}" , env!( "CARGO_PKG_VERSION" ) ) . bytes ( ) . collect :: < Vec < u8 > > ( ) ;
360
+ msg_writer. resize ( 128 , b' ' ) ;
361
+
360
362
let mut cur_block = 2 ;
361
363
let mut ndx_data = HashMap :: new ( ) ;
362
364
for ( i, conf) in conferences. iter ( ) . enumerate ( ) {
@@ -428,7 +430,7 @@ impl IcyBoardState {
428
430
zip. write_all ( & control_dat. to_vec ( ) ) ?;
429
431
430
432
zip. start_file ( "messages.dat" , SimpleFileOptions :: default ( ) ) ?;
431
- zip. write_all ( & fs :: read ( output_path . join ( "messages.dat" ) ) . await ? ) ?;
433
+ zip. write_all ( & msg_writer ) ?;
432
434
433
435
for ( cnf, ndx) in ndx_data. iter ( ) {
434
436
zip. start_file ( & format ! ( "{:03}.ndx" , cnf) , SimpleFileOptions :: default ( ) ) ?;
@@ -445,4 +447,89 @@ impl IcyBoardState {
445
447
fs:: remove_dir_all ( output_path) . await ?;
446
448
Ok ( ( ) )
447
449
}
450
+
451
+ async fn upload_qwk_reply ( & mut self ) -> Res < ( ) > {
452
+ let cur_protocol = if let Some ( user) = & self . session . current_user {
453
+ user. protocol . clone ( )
454
+ } else {
455
+ String :: new ( )
456
+ } ;
457
+
458
+ let prot_str = self . ask_protocols ( & cur_protocol) . await ?;
459
+ if prot_str. is_empty ( ) {
460
+ return Ok ( ( ) ) ;
461
+ }
462
+ let Some ( protocol) = self . get_protocol ( prot_str) . await else {
463
+ return Ok ( ( ) ) ;
464
+ } ;
465
+
466
+ let mut prot = create_protocol ( & protocol) ;
467
+ let bbs_id = {
468
+ let board = self . board . lock ( ) . await ;
469
+ if board. config . qwk_settings . bbs_id . is_empty ( ) {
470
+ board. config . board . name . clone ( )
471
+ } else {
472
+ board. config . qwk_settings . bbs_id . clone ( )
473
+ }
474
+ } ;
475
+ match prot. initiate_recv ( & mut * self . connection ) . await {
476
+ Ok ( mut state) => {
477
+ while !state. is_finished {
478
+ if let Err ( e) = prot. update_transfer ( & mut * self . connection , & mut state) . await {
479
+ log:: error!( "Error while updating file transfer with {:?} : {}" , protocol, e) ;
480
+ self . display_text ( IceText :: TransferAborted , display_flags:: NEWLINE ) . await ?;
481
+ break ;
482
+ }
483
+ }
484
+ self . display_text ( IceText :: TransferSuccessful , display_flags:: NEWLINE | display_flags:: LFBEFORE )
485
+ . await ?;
486
+
487
+ for ( x, path) in state. recieve_state . finished_files {
488
+ self . display_text ( IceText :: ExtractingMessages , display_flags:: NEWLINE | display_flags:: LFBEFORE )
489
+ . await ?;
490
+
491
+ let mut archive = zip:: ZipArchive :: new ( std:: fs:: File :: open ( & path) ?) ?;
492
+ if let Ok ( mut arch) = archive. by_name ( & format ! ( "{}.MSG" , bbs_id) ) {
493
+ let mut buf = Vec :: new ( ) ;
494
+ arch. read_to_end ( & mut buf) ?;
495
+ let mut cursor = Cursor :: new ( buf) ;
496
+ cursor. seek ( std:: io:: SeekFrom :: Start ( 128 ) ) ?;
497
+
498
+ let conferences = & self . board . lock ( ) . await . conferences . clone ( ) ;
499
+ let mut number_to_msgid = Vec :: new ( ) ;
500
+ for ( i, conf) in conferences. iter ( ) . enumerate ( ) {
501
+ if let Some ( areas) = & conf. areas {
502
+ for ( j, _area) in areas. iter ( ) . enumerate ( ) {
503
+ number_to_msgid. push ( ( i, j) ) ;
504
+ }
505
+ }
506
+ }
507
+
508
+ while let Ok ( msg) = QWKMessage :: read ( & mut cursor, true ) {
509
+ if let Some ( ( conf, area) ) = number_to_msgid. get ( msg. msg_number as usize ) {
510
+ let jam_msg = JamMessage :: default ( )
511
+ . with_from ( msg. from )
512
+ . with_to ( msg. to )
513
+ . with_subject ( msg. subj )
514
+ . with_date_time ( Utc :: now ( ) )
515
+ . with_text ( msg. text ) ;
516
+ self . send_message ( * conf as i32 , * area as i32 , jam_msg, IceText :: ReplySuccessful ) . await ?;
517
+ } else {
518
+ self . display_text ( IceText :: ReplyFailed , display_flags:: NEWLINE ) . await ?;
519
+ }
520
+ }
521
+ } else {
522
+ self . display_text ( IceText :: ErrorExtracting , display_flags:: NEWLINE ) . await ?;
523
+ }
524
+
525
+ std:: fs:: remove_file ( & path) ?;
526
+ }
527
+ }
528
+ Err ( e) => {
529
+ log:: error!( "Error while initiating file transfer with {:?} : {}" , protocol, e) ;
530
+ self . println ( TerminalTarget :: Both , & format ! ( "Error: {}" , e) ) . await ?;
531
+ }
532
+ }
533
+ Ok ( ( ) )
534
+ }
448
535
}
0 commit comments