11//
22// This file is part of Dire Wolf, an amateur radio packet TNC.
33//
4- // Copyright (C) 2023 John Langner, WB2OSZ
4+ // Copyright (C) 2023, 2025 John Langner, WB2OSZ
55//
66// This program is free software: you can redistribute it and/or modify
77// it under the terms of the GNU General Public License as published by
@@ -53,6 +53,8 @@ static void unquote (int line, char *pin, char *pout);
5353static int tocall_cmp (const void * px , const void * py );
5454static int mice_cmp (const void * px , const void * py );
5555
56+ static void deviceid_term (void );
57+
5658/*------------------------------------------------------------------
5759 *
5860 * Function: main
@@ -300,6 +302,7 @@ void deviceid_init(void)
300302 //dw_printf ("%d: %s\n", line, stuff);
301303#endif
302304 // This is not very robust; everything better be in exactly the right format.
305+ // TODO: Be more forgiving.
303306
304307 if (strncmp (stuff , "mice:" , strlen ("mice:" )) == 0 ) {
305308 section = mice_section ;
@@ -361,12 +364,18 @@ void deviceid_init(void)
361364 }
362365 if (strncmp (stuff + 3 , "tocall: " , strlen ("tocall: " )) == 0 ) {
363366 // Remove trailing wildcard characters ? * n
367+ // "APZ*" has quotes around it, inconsistent with everything else.
364368 char * r = stuff + strlen (stuff ) - 1 ;
365- while (r >= (char * )stuff && (* r == '?' || * r == '*' || * r == 'n' )) {
369+ while (r >= (char * )stuff && (* r == '?' || * r == '*' || * r == 'n' || * r == '"' )) {
366370 * r -- = '\0' ;
367371 }
368372
369- strlcpy (ptocalls [tocalls_index ].tocall , stuff + 3 + 8 , sizeof (ptocalls [tocalls_index ].tocall ));
373+ if (stuff [3 + 8 ] == '"' ) {
374+ strlcpy (ptocalls [tocalls_index ].tocall , stuff + 3 + 8 + 1 , sizeof (ptocalls [tocalls_index ].tocall ));
375+ }
376+ else {
377+ strlcpy (ptocalls [tocalls_index ].tocall , stuff + 3 + 8 , sizeof (ptocalls [tocalls_index ].tocall ));
378+ }
370379
371380 // Remove trailing CR/LF or spaces.
372381 char * p = stuff + strlen (stuff ) - 1 ;
@@ -375,10 +384,10 @@ void deviceid_init(void)
375384 }
376385 }
377386 else if (strncmp (stuff + 3 , "vendor: " , strlen ("vendor: " )) == 0 ) {
378- ptocalls [tocalls_index ].vendor = strdup (stuff + 3 + 8 );
387+ ptocalls [tocalls_index ].vendor = strdup (stuff + 3 + 8 );
379388 }
380389 else if (strncmp (stuff + 3 , "model: " , strlen ("model: " )) == 0 ) {
381- ptocalls [tocalls_index ].model = strdup (stuff + 3 + 7 );
390+ ptocalls [tocalls_index ].model = strdup (stuff + 3 + 7 );
382391 }
383392 break ;
384393 }
@@ -413,23 +422,61 @@ void deviceid_init(void)
413422
414423 qsort (ptocalls , tocalls_count , sizeof (struct tocalls ), tocall_cmp );
415424
416-
417425#if TEST
418426 dw_printf ("MIC-E:\n" );
419427 for (int i = 0 ; i < mice_count ; i ++ ) {
420- dw_printf ("%s %s %s\n" , pmice [i ].suffix , pmice [i ].vendor , pmice [i ].model );
428+ dw_printf ("%s %s %s %s \n" , pmice [ i ]. prefix , pmice [i ].suffix , pmice [i ].vendor , pmice [i ].model );
421429 }
422430 dw_printf ("TOCALLS:\n" );
423431 for (int i = 0 ; i < tocalls_count ; i ++ ) {
424432 dw_printf ("%s %s %s\n" , ptocalls [i ].tocall , ptocalls [i ].vendor , ptocalls [i ].model );
425433 }
426434#endif
427435
436+ atexit (deviceid_term );
428437 return ;
429438
430439} // end deviceid_init
431440
432441
442+ /*------------------------------------------------------------------
443+ *
444+ * Function: deviceid_term
445+ *
446+ * Purpose: Called when exiting to cleanup.
447+ *
448+ * In/Out: pmice
449+ * mice_count
450+ * ptocalls
451+ * tocalls_count
452+ *
453+ * Description: Free all the allocated memory.
454+ *
455+ * Mystery: Why does Address Sanitizer complain about a data leak
456+ * for 62 strdups?
457+ *
458+ *------------------------------------------------------------------*/
459+
460+ static void deviceid_term (void )
461+ {
462+ for (int n = 0 ; n < tocalls_count ; n ++ ) {
463+ if (ptocalls [n ].model != NULL ) free (ptocalls [n ].model );
464+ if (ptocalls [n ].vendor != NULL ) free (ptocalls [n ].vendor );
465+ }
466+ tocalls_count = 0 ;
467+ free (ptocalls );
468+ ptocalls = NULL;
469+
470+ for (int n = 0 ; n < mice_count ; n ++ ) {
471+ if (pmice [n ].model != NULL ) free (pmice [n ].model );
472+ if (pmice [n ].vendor != NULL ) free (pmice [n ].vendor );
473+ }
474+ mice_count = 0 ;
475+ free (pmice );
476+ pmice = NULL;
477+ }
478+
479+
433480/*------------------------------------------------------------------
434481 *
435482 * Function: unquote
@@ -612,6 +659,7 @@ void deviceid_decode_dest (char *dest, char *device, size_t device_size)
612659 * https://github.com/wb2osz/aprsspec containing:
613660 * APRS Protocol Specification 1.2
614661 * Understanding APRS Packets
662+ *
615663 *------------------------------------------------------------------*/
616664
617665// The strncmp documentation doesn't mention behavior if length is zero.
0 commit comments