1 /**********************************************************
2 * Outbound management.
3 **********************************************************/
4 /*
5 * $Id: outbound.c,v 1.21 2005/08/10 19:45:50 mitry Exp $
6 *
7 * $Log: outbound.c,v $
8 * Revision 1.21 2005/08/10 19:45:50 mitry
9 * Added param to qscandir() to return full path with file name
10 *
11 * Revision 1.20 2005/05/17 18:17:42 mitry
12 * Removed system basename() usage.
13 * Added qbasename() implementation.
14 *
15 * Revision 1.19 2005/05/16 20:33:46 mitry
16 * Code cleaning
17 *
18 * Revision 1.18 2005/05/11 20:17:36 mitry
19 * Changed int var; to size_t var; for strlen()
20 *
21 * Revision 1.17 2005/05/11 16:37:41 mitry
22 * Set initial values to static variables explicitly
23 *
24 * Revision 1.16 2005/05/06 20:36:45 mitry
25 * Major rewrite again
26 *
27 * Revision 1.15 2005/04/14 18:04:26 mitry
28 * Changed scandir() to qscandir()
29 *
30 * Revision 1.14 2005/04/05 09:31:12 mitry
31 * New xstrcpy() and xstrcat()
32 *
33 * Revision 1.13 2005/03/28 16:37:26 mitry
34 * Moved some code to mappath() function (see tools.c)
35 *
36 * Revision 1.12 2005/02/16 21:42:47 mitry
37 * Check the value returned from scandir (n <= 0) for out_aso_rescan(), out_bso_scan_zone(), out_bso_rescan().
38 *
39 * Revision 1.11 2005/02/16 11:25:29 mitry
40 * Next fix for out_bso_scan_zone()
41 *
42 * Revision 1.10 2005/02/15 22:12:26 mitry
43 * Fix for out_bso_scan_zone()
44 *
45 * Revision 1.9 2005/02/15 11:17:39 mitry
46 * Another fix for out_bso_rescan()
47 *
48 * Revision 1.8 2005/02/09 12:44:23 mitry
49 * Changed free() to xfree()
50 * Changed out_bso_rescan() code
51 *
52 * Revision 1.7 2005/02/08 19:57:28 mitry
53 * Added outbound_addr_busy().
54 * Wiped out old outbound_rescan code.
55 * Cleaned code a bit.
56 *
57 */
58
59 #include "headers.h"
60
61 static int bso_defzone = 2;
62 static char *bso_base = NULL;
63 static char *aso_base = NULL;
64 static char *p_domain = NULL;
65 static char *sts_base = NULL;
66 static size_t pd_len = 0;
67 static char out_internal_tmp[MAX_PATH + 5];
68
69 static qeach_t _each = NULL;
70 static int _rslow;
71
72
73 static char *ext_lo[] = {
74 ".pnt", ".req",
75 ".ilo", ".clo", ".dlo", ".flo", ".hlo",
76 NULL
77 };
78
79 static char *ext_ut[] = {
80 ".iut", ".cut", ".dut", ".out", ".hut",
81 NULL
82 };
83
84
outbound_init(const char * asopath,const char * bsopath,const char * stspath,int def_zone)85 int outbound_init(const char *asopath, const char *bsopath,
86 const char *stspath, int def_zone)
87 {
88 int rc = 0;
89 size_t len = 0;
90
91 outbound_done();
92
93 if ( bsopath && *bsopath ) {
94 char *p;
95
96 len = strlen( bsopath ) - 1;
97 xstrcpy( out_internal_tmp, bsopath, MAX_PATH );
98 len = chopc( out_internal_tmp, '/' );
99
100 if ( len ) {
101 p = strrchr( out_internal_tmp, '/' );
102
103 if ( p ) {
104 p_domain = xstrdup( p + 1 );
105 pd_len = strlen( p_domain );
106
107 if ( p == out_internal_tmp )
108 *(p + 1) = '\0';
109 else
110 *p = '\0';
111 bso_base = xstrdup( out_internal_tmp );
112 bso_defzone = def_zone;
113 rc |= BSO;
114 } else
115 len = 0;
116 }
117 }
118
119 if ( !len ) {
120 xfree( bso_base );
121 xfree( p_domain );
122 }
123
124 len = 0;
125
126 if ( asopath && *asopath ) {
127 len = strlen( asopath ) - 1;
128 xstrcpy( out_internal_tmp, asopath, MAX_PATH );
129 len = chopc( out_internal_tmp, '/' );
130
131 if ( !len )
132 aso_base = xstrdup( "/" );
133 else
134 aso_base = xstrdup( out_internal_tmp );
135 rc |= ASO;
136 }
137
138 if ( !rc )
139 return 0;
140
141 if ( stspath && *stspath ) {
142 xstrcpy( out_internal_tmp, stspath, MAX_PATH );
143 len = chopc( out_internal_tmp, '/' );
144 if ( !len )
145 sts_base = xstrdup( "/" );
146 else
147 sts_base = xstrdup( stspath );
148 } else if ( bsopath )
149 sts_base = xstrdup( bsopath );
150 else if ( asopath )
151 sts_base = xstrdup( asopath );
152
153 return rc;
154 }
155
156
outbound_done(void)157 void outbound_done(void)
158 {
159 xfree( bso_base );
160 xfree( p_domain );
161 xfree( aso_base );
162 xfree( sts_base );
163 pd_len = 0;
164 }
165
166
get_outbound_name(int type,const ftnaddr_t * fa)167 static char *get_outbound_name(int type, const ftnaddr_t *fa)
168 {
169 out_internal_tmp[0] = '\0';
170
171 switch( type ) {
172 case ASO:
173 if ( aso_base )
174 snprintf( out_internal_tmp, MAX_PATH, "%s/%d.%d.%d.%d.", aso_base, fa->z, fa->n, fa->f, fa->p) ;
175 break;
176
177 case BSO:
178 if ( bso_base ) {
179 char t[30];
180
181 snprintf( out_internal_tmp, MAX_PATH, "%s/%s", bso_base, p_domain );
182 if ( fa->z != bso_defzone ) {
183 snprintf( t, 30, ".%03x", fa->z );
184 xstrcat( out_internal_tmp, t, MAX_PATH );
185 }
186 snprintf( t, 30, "/%04x%04x.", fa->n, fa->f );
187 xstrcat( out_internal_tmp, t, MAX_PATH );
188 if( fa->p ) {
189 snprintf( t, 30, "pnt/%08x.", fa->p );
190 xstrcat( out_internal_tmp, t, MAX_PATH );
191 }
192 }
193 break;
194
195 default:
196 return NULL;
197 }
198
199 if ( *out_internal_tmp )
200 return out_internal_tmp;
201
202 return NULL;
203 }
204
205
get_pkt_name(int type,const ftnaddr_t * fa,int fl)206 static char *get_pkt_name(int type, const ftnaddr_t *fa, int fl)
207 {
208 char e[] = "eut";
209 char *name = get_outbound_name( type, fa );
210
211 if ( name ) {
212 switch( fl ) {
213 case F_NORM:
214 case F_REQ: *e = 'o'; break;
215 case F_DIR: *e = 'd'; break;
216 case F_CRSH: *e = 'c'; break;
217 case F_HOLD: *e = 'h'; break;
218 case F_IMM: *e = 'i'; break;
219 }
220 xstrcat( name, e, MAX_PATH );
221 }
222
223 return name;
224 }
225
226
get_flo_name(int type,const ftnaddr_t * fa,int fl)227 static char *get_flo_name(int type, const ftnaddr_t *fa, int fl)
228 {
229 char e[] = "elo";
230 char *name = get_outbound_name( type, fa );
231
232 if ( name ) {
233 switch( fl ) {
234 case F_NORM:
235 case F_REQ: *e = 'f'; break;
236 case F_DIR: *e = 'd'; break;
237 case F_CRSH: *e = 'c'; break;
238 case F_HOLD: *e = 'h'; break;
239 case F_IMM: *e = 'i'; break;
240 }
241 xstrcat( name, e, MAX_PATH );
242 }
243
244 return name;
245 }
246
247
get_req_name(int type,const ftnaddr_t * fa)248 static char *get_req_name(int type, const ftnaddr_t *fa)
249 {
250 char *name = get_outbound_name( type, fa );
251
252 if ( name )
253 xstrcat( name, "req", MAX_PATH );
254
255 return name;
256 }
257
258
get_busy_name(int type,const ftnaddr_t * fa,char b)259 static char *get_busy_name(int type, const ftnaddr_t *fa, char b)
260 {
261 char bn[] = "esy";
262 char *name = get_outbound_name( type, fa );
263
264 if ( name ) {
265 *bn = b;
266 xstrcat( name, bn, MAX_PATH );
267 }
268
269 return name;
270 }
271
272
get_status_name(const ftnaddr_t * fa)273 static char *get_status_name(const ftnaddr_t *fa)
274 {
275 if ( sts_base ) {
276 snprintf( out_internal_tmp, MAX_PATH, "%s/%d.%d.%d.%d.qst", sts_base, fa->z, fa->n, fa->f, fa->p);
277 return out_internal_tmp;
278 }
279 return NULL;
280 }
281
282
out_scan_flo(const char * flo_name,const ftnaddr_t * addr)283 static void out_scan_flo(const char *flo_name, const ftnaddr_t *addr)
284 {
285 size_t len = strlen( flo_name );
286
287 DEBUG(('S',3,"out_scan_flo: flo_name == '%s'", flo_name));
288 if ( !strcasecmp( (char *) (flo_name + len - 2), "lo" ))
289 (*_each)( flo_name, addr, T_ARCMAIL, outbound_flavor( flo_name[len - 3] ), _rslow );
290 else if ( !strcasecmp( (char *) (flo_name + len - 2), "ut" ))
291 (*_each)( flo_name, addr, T_NETMAIL, outbound_flavor( flo_name[len - 3] ), _rslow );
292 else if ( !strcasecmp( (char *) (flo_name + len - 3), "req" ))
293 (*_each)( flo_name, addr, T_REQ, F_REQ, _rslow );
294 }
295
296
297 /*
298 * Returns whether the directory entry is an ASO file.
299 */
aso_select(const char * d_name)300 static int aso_select(const char *d_name)
301 {
302 size_t len;
303 char **p;
304
305 DEBUG(('S',3,"aso_select: '%s'",d_name));
306
307 if ( *d_name == '.' )
308 return 0;
309
310 if ( strrchr( d_name, '.' ) == NULL )
311 return 0;
312
313 if ( sscanf( d_name, "%u.%u.%u.%u", &len, &len, &len, &len ) != 4 )
314 return 0;
315
316 len = strlen( d_name ) - 4;
317 for( p = ext_lo; *p; p++ )
318 if ( !strcasecmp( *p, d_name + len )) {
319 DEBUG(('S',3,"aso_select: '%s' OK",d_name));
320 return 1;
321 }
322
323 for( p = ext_ut; *p; p++ )
324 if ( !strcasecmp( *p, d_name + len )) {
325 DEBUG(('S',3,"aso_select: '%s' OK",d_name));
326 return 1;
327 }
328
329 return 0;
330 }
331
332
out_aso_rescan(void)333 static int out_aso_rescan(void)
334 {
335 char **namelist = NULL;
336 int i, n;
337
338 if ( aso_base == NULL )
339 return 0;
340
341 DEBUG(('S',4,"out_aso_rescan: aso_base == '%s'", aso_base));
342
343 n = qscandir( aso_base, &namelist, 0, aso_select, NULL );
344 DEBUG(('S',4,"out_aso_rescan: n == %d", n));
345
346 if ( n < 0 ) /* Error */
347 return 0;
348
349 for( i = 0; i < n; i++ ) {
350 char *f = qbasename( namelist[i] );
351 int az, an, af, ap;
352
353 if ( sscanf( f, "%u.%u.%u.%u", &az, &an, &af, &ap ) == 4 ) {
354
355 FTNADDR_T( a );
356 a.z = (short) az;
357 a.n = (short) an;
358 a.f = (short) af;
359 a.p = (short) ap;
360
361 DEBUG(('S',4,"out_aso_rescan: flo_name == '%s'", namelist[i]));
362 out_scan_flo( namelist[i], &a );
363 }
364 xfree( namelist[i] );
365 }
366
367 xfree( namelist );
368 return ASO;
369 }
370
371
372 /*
373 * Returns whether the directory entry is a BSO file.
374 */
bso_select(const char * d_name)375 static int bso_select(const char *d_name)
376 {
377 size_t len;
378 char **p;
379
380 DEBUG(('S',3,"bso_select: '%s'",d_name));
381
382 if ( *d_name == '.' )
383 return 0;
384
385 len = strlen( d_name );
386 if ( len != 12 )
387 return 0;
388
389 if ( strspn( d_name, "0123456789abcdefABCDEF" ) != 8 )
390 return 0;
391
392 for( p = ext_lo; *p; p++ )
393 if ( !strcasecmp( *p, &d_name[len - 4] )) {
394 DEBUG(('S',3,"bso_select: '%s' OK",d_name));
395 return 1;
396 }
397
398 for( p = ext_ut; *p; p++ )
399 if ( !strcasecmp( *p, &d_name[len - 4] )) {
400 DEBUG(('S',3,"bso_select: '%s' OK",d_name));
401 return 1;
402 }
403
404 return 0;
405 }
406
407
408 /*
409 * Returns whether the directory entry is a BSO zone.
410 */
bso_root_select(const char * d_name)411 static int bso_root_select(const char *d_name)
412 {
413 size_t len = strlen( d_name );
414
415 DEBUG(('S',3,"bso_root_select: '%s'",d_name));
416
417 if ( *d_name == '.' )
418 return 0;
419
420 if ( strncasecmp( p_domain, d_name, pd_len ) != 0 )
421 return 0;
422
423 if ( len == pd_len ||
424 ( len - 4 == pd_len && strspn( d_name + len - 3, "0123456789abcdefABCDEF" ) == 3 ))
425 {
426 DEBUG(('S',3,"bso_root_select: '%s' OK",d_name));
427 return 1;
428 }
429
430 return 0;
431 }
432
433
out_bso_scan_zone(char * zonehold)434 static int out_bso_scan_zone(char *zonehold)
435 {
436 int i, j, n;
437 char *p = NULL, **namelist = NULL;
438 FTNADDR_T ( a );
439
440 DEBUG(('S',3,"out_bso_scan_zone: %s", zonehold));
441
442 n = qscandir( zonehold, &namelist, 0, bso_select, qalphasort );
443 DEBUG(('S',4,"out_bso_scan_zone: n == %d", n));
444
445 if ( n <= 0 ) /* Error */
446 return 0;
447
448 p = strrchr( zonehold, '.' );
449 if ( p != NULL) {
450 sscanf( p, ".%03x", &i );
451 a.z = (short) i;
452 } else
453 a.z = bso_defzone;
454
455 for( i = 0; i < n; i++ ) {
456 int an, af;
457
458 p = qbasename( namelist[i] );
459 sscanf( p, "%04x%04x", &an, &af );
460
461 a.n = (short) an;
462 a.f = (short) af;
463 a.p = 0;
464
465 DEBUG(('S',4,"out_bso_scan_zone: i == %d, lo == '%s'", i, namelist[i]));
466 DEBUG(('S',4,"out_bso_scan_zone: %d:%d/%d.%d", a.z, a.n, a.f, a.p));
467
468 if ( !strcasecmp( p + 8, ".pnt" )) {
469 char **namelist_pnt = NULL;
470 int points;
471
472 points = qscandir( namelist[i], &namelist_pnt, 0, bso_select, qalphasort );
473 DEBUG(('S',4,"out_bso_scan_zone: points %d", points));
474
475 if ( points >= 0 ) {
476 if ( points == 0 ) {
477 DEBUG(('S',4,"out_bso_scan_zone: remove empty points dir'%s'", namelist[i]));
478 rmdir( namelist[i] );
479 } else {
480 for( j = 0; j < points; j++ ) {
481 int ap;
482
483 p = qbasename( namelist_pnt[j] );
484
485 sscanf( p + 4, "%04x", &ap );
486 a.p = (short) ap;
487 DEBUG(('S',4,"out_bso_scan_zone: point %d:%d/%d.%d", a.z, a.n, a.f, a.p));
488 DEBUG(('S',4,"out_bso_scan_zone: flo '%s'", namelist_pnt[j]));
489 out_scan_flo( namelist_pnt[j], &a );
490 xfree( namelist_pnt[j] );
491 }
492 xfree( namelist_pnt );
493 }
494 }
495 } else {
496 out_scan_flo( namelist[i], &a );
497 }
498
499 xfree( namelist[i] );
500 }
501
502 xfree( namelist );
503 return 1;
504 }
505
506
out_bso_rescan(void)507 static int out_bso_rescan(void)
508 {
509 int i, n;
510 char **namelist = NULL;
511
512 if ( bso_base == NULL )
513 return 0;
514
515 DEBUG(('S',4,"out_bso_rescan: bso_base == '%s', p_domain == '%s'", bso_base, p_domain));
516
517 /* Scan the root and find all outbound directory */
518 n = qscandir( bso_base, &namelist, 0, bso_root_select, qalphasort );
519 DEBUG(('S',4,"out_bso_rescan: n == %d", n));
520
521 if ( n < 0 )
522 return 0;
523
524 /* For each directory found do recursive rescan */
525 for( i = 0; i < n; i++ ) {
526 DEBUG(('S',4,"out_bso_rescan: namelist[%d] == '%s'", i, namelist[i]));
527 out_bso_scan_zone( namelist[i] );
528 xfree( namelist[i] );
529 }
530
531 xfree( namelist );
532 return BSO;
533 }
534
535
outbound_rescan(qeach_t each,int rslow)536 int outbound_rescan(qeach_t each, int rslow)
537 {
538 int rc = 0;
539
540 _each = each;
541 _rslow = rslow;
542
543 rc |= out_aso_rescan();
544 rc |= out_bso_rescan();
545
546 return rc;
547 }
548
549
out_lock(int type,const ftnaddr_t * adr,int l)550 static int out_lock(int type, const ftnaddr_t *adr, int l)
551 {
552 char *obn = get_busy_name( type, adr, 'b' );
553
554 if ( !obn )
555 return 0;
556
557 mkdirs( obn );
558
559 if ( islocked( obn ))
560 return 0;
561
562 if ( l == LCK_s )
563 return lockpid( obn );
564
565 if ( l == LCK_t )
566 return getpid();
567
568 if ( islocked( get_busy_name( type, adr, 'c' )))
569 return 0;
570
571 return lockpid( out_internal_tmp );
572 }
573
574
575 /*
576 * Returns whether the address is busy. 0 == free, 1 == busy.
577 */
outbound_addr_busy(const ftnaddr_t * addr)578 int outbound_addr_busy(const ftnaddr_t *addr)
579 {
580 if ( islocked( get_busy_name( ASO, addr, 'b' )))
581 return 1;
582
583 if ( islocked( get_busy_name( ASO, addr, 'c' )))
584 return 1;
585
586 if ( islocked( get_busy_name( BSO, addr, 'b' )))
587 return 1;
588
589 if ( islocked( get_busy_name( BSO, addr, 'c' ) ))
590 return 1;
591
592 return 0;
593 }
594
595
outbound_locknode(const ftnaddr_t * addr,int l)596 int outbound_locknode(const ftnaddr_t *addr, int l)
597 {
598 int rc = 0;
599
600 if ( aso_base && out_lock( ASO, addr, l ))
601 rc |= ASO;
602
603 if ( bso_base && out_lock( BSO, addr, l ))
604 rc |= BSO;
605
606 return rc;
607 }
608
609
outbound_unlocknode(const ftnaddr_t * addr,int l)610 int outbound_unlocknode(const ftnaddr_t *addr, int l)
611 {
612 if ( l == LCK_t )
613 return 1;
614
615 if ( aso_base ) {
616 if ( get_busy_name( ASO, addr, 'b' ))
617 lunlink( out_internal_tmp );
618
619 if ( get_busy_name( ASO, addr, 'c' ))
620 lunlink( out_internal_tmp );
621 }
622
623 if ( bso_base ) {
624 if ( get_busy_name( BSO, addr, 'b' ))
625 lunlink( out_internal_tmp );
626
627 if ( get_busy_name( BSO, addr, 'c' ))
628 lunlink( out_internal_tmp );
629
630 if ( addr->z != bso_defzone )
631 rmdirs( out_internal_tmp );
632 else if ( addr->p ) {
633 rmdir( out_internal_tmp );
634 }
635 }
636
637 return 1;
638 }
639
640
outbound_flavor(char fl)641 int outbound_flavor(char fl)
642 {
643 switch( tolower( fl )) {
644 case 'h': return F_HOLD;
645 case 'f':
646 case 'n':
647 case 'o': return F_NORM;
648 case 'd': return F_DIR;
649 case 'c': return F_CRSH;
650 case 'i': return F_IMM;
651 case 'r': return F_REQ;
652 }
653 return F_ERR;
654 }
655
656
outbound_attach(const ftnaddr_t * addr,int flv,slist_t * files)657 int outbound_attach(const ftnaddr_t *addr, int flv, slist_t *files)
658 {
659 FILE *f = NULL;
660
661 if ( bso_base )
662 f = mdfopen( get_flo_name( BSO, addr, flv ), "at" );
663 if ( !f && aso_base )
664 f = mdfopen( get_flo_name( ASO, addr, flv ), "at" );
665 if ( f ) {
666 slist_t *fl;
667
668 for( fl = files; fl; fl = fl->next )
669 fprintf( f, "%s\n", fl->str );
670 fclose( f );
671 return 1;
672 }
673 return 0;
674 }
675
676
outbound_request(const ftnaddr_t * addr,slist_t * files)677 int outbound_request(const ftnaddr_t *addr, slist_t *files)
678 {
679 FILE *f = NULL;
680
681 if ( bso_base )
682 f = mdfopen( get_req_name( BSO, addr ), "at" );
683 if ( !f && aso_base )
684 f = mdfopen( get_req_name( ASO, addr ), "at" );
685 if ( f ) {
686 slist_t *fl;
687
688 for( fl = files; fl; fl = fl->next )
689 fprintf( f, "%s\r\n", fl->str );
690 fclose( f );
691 return 1;
692 }
693 return 0;
694 }
695
696
outbound_poll(const ftnaddr_t * fa,int flavor)697 int outbound_poll(const ftnaddr_t *fa, int flavor)
698 {
699 if ( flavor == F_ERR ) {
700 char *pf = cfgs( CFG_POLLFLAVOR );
701 flavor = outbound_flavor( *pf );
702 }
703 return outbound_attach( fa, flavor, NULL );
704 }
705
706
outbound_setstatus(const ftnaddr_t * fa,sts_t * st)707 int outbound_setstatus(const ftnaddr_t *fa, sts_t *st)
708 {
709 FILE *f;
710 char *name = get_status_name( fa );
711
712 if((f = mdfopen( name, "wt" ))) {
713 fprintf( f, "%d %d %lu %lu", st->try, st->flags, st->htime, st->utime );
714 if ( st->bp.name && st->bp.flags )
715 fprintf( f, " %d %d %lu %s", st->bp.flags, st->bp.size, st->bp.time, st->bp.name );
716 fclose( f );
717 return 1;
718 }
719 return 0;
720 }
721
722
outbound_getstatus(const ftnaddr_t * fa,sts_t * st)723 int outbound_getstatus(const ftnaddr_t *fa, sts_t *st)
724 {
725 int rc;
726 FILE *f;
727 char *name = get_status_name( fa );
728 char tmp[MAX_PATH + 5];
729
730 tmp[0] = '\0';
731
732 if ( name ) {
733 if ((f = fopen( name, "rt" ))) {
734 rc = fscanf( f, "%d %d %lu %lu %d %d %lu %s",
735 &st->try, &st->flags,
736 (unsigned long*) &st->htime,
737 (unsigned long*) &st->utime,
738 &st->bp.flags, (int*) &st->bp.size,
739 (unsigned long*) &st->bp.time,
740 tmp );
741 fclose( f );
742
743 if ( rc < 8 )
744 memset( &st->bp, 0, sizeof( st->bp ));
745 else if ( *tmp )
746 st->bp.name = xstrdup( tmp );
747
748 if ( rc == 4 || rc == 8 )
749 return 1;
750 write_log( "status file %s corrupted", name );
751 xfree( st->bp.name );
752 }
753 }
754 memset( st, 0, sizeof( sts_t ));
755 return 0;
756 }
757
758
floflist(flist_t ** fl,char * flon)759 static void floflist(flist_t **fl, char *flon)
760 {
761 FILE *f;
762 off_t off;
763 char *p, str[MAX_PATH + 5], *m, *map = cfgs(CFG_MAPOUT), *fp, *fn;
764 struct stat sb;
765
766 DEBUG(('S',2,"Add LO '%s'",flon));
767 if(!stat(flon, &sb))if((f=fopen(flon,"r+b"))) {
768 off = ftello( f );
769 while(fgets(str,MAX_PATH,f)) {
770 p=strrchr(str,'\r');
771 if(!p)p=strrchr(str,'\n');
772 if(p)*p=0;
773 if(!*str)continue;
774 p=str;
775 switch(*p) {
776 case '~':
777 break;
778
779 case '^': /* kill */
780 case '#': /* trunc */
781 case ' ': /* filename starting with directive */
782 p++;
783
784 default:
785 if (( m = mappath( p )) && *m )
786 p = m;
787 fp = xstrdup( p );
788 m = qbasename( fp );
789 if ( map && strchr( map, 'L' ))
790 strlwr( m );
791 else if( map && strchr( map, 'U' ))
792 strupr( m );
793 fn = qbasename( p );
794 mapname( fn, map, MAX_PATH - ( fn - str ) - 1 );
795 addflist( fl, fp, xstrdup( fn ), str[0], off, f, 1 );
796 if( !stat( fp, &sb )) {
797 totalf += sb.st_size;
798 totaln++;
799 }
800 }
801 off = ftello( f );
802 }
803 addflist( fl, xstrdup( flon ), NULL, '^', -1, f, 1 );
804 }
805 }
806
807
asoflist(flist_t ** fl,const ftnaddr_t * fa,int mode)808 int asoflist(flist_t **fl, const ftnaddr_t *fa, int mode)
809 {
810 struct stat sb;
811 char str[MAX_PATH + 5];
812 int fls[] = { F_IMM, F_CRSH, F_DIR, F_NORM, F_HOLD }, i;
813
814 #if 0
815 unsigned long _tm = totalm, _tn = totaln, _tf = totalf;
816
817 DEBUG(('S',2,"asoflist exp in: m %ld, n %ld, f %ld",totalm,totaln,totalf));
818 {
819 char *name = NULL, **flolist = NULL;
820 int t;
821
822 if ( bso_base && ( name = get_outbound_name( BSO, fa ))) {
823 int flo_count = fmatchcase( name, &flolist ), i;
824
825 DEBUG(('S',3,"asoflist: bso name '%s",name));
826 DEBUG(('S',3,"asoflist: bso count %d",flo_count));
827 for( i = 0; flo_count && i < flo_count; i++ ) {
828 t = whattype( flolist[i] );
829 DEBUG(('S',4,"asoflist: type %d, flo '%s'",t,flolist[i]));
830 switch( t ) {
831 case IS_PKT:
832 snprintf( str, MAX_PATH, "%08lx.pkt", sequencer());
833 totalm += sb.st_size;
834 break;
835
836 case IS_REQ:
837 snprintf( str, MAX_PATH, "%04x%04x.req", fa->n, fa->f );
838 totalf += sb.st_size;
839 break;
840
841 case IS_FLO:
842 floflist( fl, flolist[i] );
843 /* Fall through */
844
845 default:
846 t = IS_ERR;
847 }
848
849 if ( t != IS_ERR ) {
850 addflist( fl, xstrdup( flolist[i] ), xstrdup( str ), '^', 0, NULL, 0 );
851 totaln++;
852 }
853 xfree( flolist[i] );
854 }
855 if ( flo_count > 0 )
856 xfree( flolist );
857 }
858 }
859 DEBUG(('S',2,"asoflist exp out: m %ld, n %ld, f %ld",totalm,totaln,totalf));
860
861 totalm = _tm;
862 totaln = _tn;
863 totalf = _tf;
864 #endif
865
866 /* pkt files */
867 for ( i = 0; i < 5; i++ ) {
868 char *name = NULL;
869
870 if ( bso_base && ( name = get_pkt_name( BSO, fa, fls[i] ))) {
871 if ( !stat( name, &sb )) {
872 snprintf( str, MAX_PATH, "%08lx.pkt", sequencer() );
873 addflist( fl, xstrdup( name ), xstrdup( str ), '^', 0, NULL, 0 );
874 totalm += sb.st_size;
875 totaln++;
876 }
877 }
878
879 if ( aso_base && ( name = get_pkt_name( ASO, fa, fls[i] ))) {
880 if ( !stat( name, &sb )) {
881 snprintf( str, MAX_PATH, "%08lx.pkt", sequencer() );
882 addflist( fl, xstrdup( name ), xstrdup( str ), '^', 0, NULL, 0);
883 totalm += sb.st_size;
884 totaln++;
885 }
886 }
887 }
888
889 /* file requests */
890 snprintf( str, MAX_PATH, "%04x%04x.req", fa->n, fa->f );
891 {
892 char *name = get_req_name( BSO, fa );
893
894 if ( bso_base && name && !stat( name, &sb )) {
895 addflist( fl, xstrdup( name ), xstrdup( str ), ' ', 0, NULL, 1);
896 totalf += sb.st_size;
897 totaln++;
898 }
899
900 name = get_req_name( ASO, fa );
901
902 if ( aso_base && name && !stat( name, &sb )) {
903 addflist( fl, xstrdup( name ), xstrdup( str ), ' ', 0, NULL, 1);
904 totalf += sb.st_size;
905 totaln++;
906 }
907 }
908
909 /* flow files */
910 for( i = 0; i < ( 5 - (( cfgi( CFG_HOLDOUT ) == 1) && mode )); i++) {
911 char *name = NULL;
912
913 if ( bso_base && (name = get_flo_name( BSO, fa, fls[i] )))
914 floflist( fl, name );
915 if ( aso_base && (name = get_flo_name( ASO, fa, fls[i] )))
916 floflist( fl, name );
917 }
918 return 0;
919 }
920