nmxp_chan.c 16.2 KB
Newer Older
1
2
/*! \file
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
3
 * \brief Channels for Nanometrics Protocol Library
4
5
6
7
8
9
 *
 * Author:
 * 	Matteo Quintiliani
 * 	Istituto Nazionale di Geofisica e Vulcanologia - Italy
 *	quintiliani@ingv.it
 *
10
 * $Id: nmxp_chan.c,v 1.35 2008-02-29 22:16:08 mtheo Exp $
Matteo Quintiliani's avatar
Matteo Quintiliani committed
11
 *
12
13
14
 */

#include "nmxp_chan.h"
Matteo Quintiliani's avatar
Matteo Quintiliani committed
15
#include "nmxp_base.h"
16
17

#include <string.h>
18
#include <stdlib.h>
19

20
int nmxp_chan_cpy_sta_chan(const char *net_dot_station_dot_channel, char *station_code, char *channel_code, char *network_code) {
21
    int ret = 0;
22
23
24
25
26
27
    int errors = 0;
    int i;
    char *period1 = NULL, *period2 = NULL;
    char *tmp_name = NULL;

    if(net_dot_station_dot_channel || station_code || channel_code || network_code) {
28
29
30

	station_code[0] = 0;
	channel_code[0] = 0;
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
	network_code[0] = 0;

	tmp_name = strdup(net_dot_station_dot_channel);
	/* count '.' */
	i=0;
	while(i < strlen(tmp_name)  && !errors) {
	    if(tmp_name[i] == '.') {
		if(!period1) {
		    period1 = tmp_name+i;
		} else if(!period2) {
		    period2 = tmp_name+i;
		} else {
		    errors++;
		}
	    }
	    i++;
	}
	if(!errors && period1) {
	    ret = 1;
	    if(period2) {
		/* NET.STA.CHAN */
		*period1++ = '\0';
		*period2++ = '\0';
		strcpy(network_code, tmp_name);
		strcpy(station_code, period1);
		strcpy(channel_code, period2);
57
	    } else {
58
59
60
61
		/* STA.CHAN */
		*period1++ = '\0';
		strcpy(station_code, tmp_name);
		strcpy(channel_code, period1);
62
	    }
63
	} else {
64
65
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Name %s is not in NET.STA.CHAN format! (NET. is optional)\n",
		    NMXP_LOG_STR(net_dot_station_dot_channel));
66
67
68
69
	}

	if(tmp_name) {
	    free(tmp_name);
70
	}
71

72
    } else {
73
74
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Some parameter is NULL in nmxp_chan_cpy_sta_chan() %s.\n",
		NMXP_LOG_STR(net_dot_station_dot_channel));
75
76
77
78
79
80
    }

    return ret;
}


81

82
83
84
85
86
87
/*
 * Match string against the extended regular expression in
 * pattern, treating errors as no match.
 *
 * return 1 for match, 0 for no match, -1 on error for invalid pattern, -2 on error for invalid station_dot_channel
 */
88
int nmxp_chan_match(const char *net_dot_station_dot_channel, char *pattern)
89
90
91
92
{
    int ret = 0;
    int i, l;
    char sta_pattern[20];
93
    char cha_pattern[20];
94
    char net_pattern[20];
95
96
97
98
    char sta_sdc[20];
    char *cha_sdc;

    /* validate pattern channel */
99
    if(!nmxp_chan_cpy_sta_chan(pattern, sta_pattern, cha_pattern, net_pattern)) {
100
101
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s is not in STA.CHAN format!\n",
		NMXP_LOG_STR(pattern));
102
103
104
	return -1;
    }

105
106
107
108
109
110
111
112
113
    l = strlen(net_pattern);
    i = 0;
    while(i < l  &&  ret != -1) {
	if(  !(
		(net_pattern[i] >= 'A'  &&  net_pattern[i] <= 'Z')
		|| (net_pattern[i] >= 'a'  &&  net_pattern[i] <= 'z')
		|| (net_pattern[i] >= '0'  &&  net_pattern[i] <= '9')
		)
	  ) {
114
115
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s has not valid NET format!\n",
		    NMXP_LOG_STR(pattern));
116
117
118
119
120
	    return -1;
	}
	i++;
    }
    
121
    l = strlen(sta_pattern);
122
123
124
    if(((l == 1) && sta_pattern[0] == '*')) {
	/* do nothing */
    } else {
125
126
127
128
129
130
131
132
133
    i = 0;
    while(i < l  &&  ret != -1) {
	if(  !(
		(sta_pattern[i] >= 'A'  &&  sta_pattern[i] <= 'Z')
		|| (sta_pattern[i] >= 'a'  &&  sta_pattern[i] <= 'z')
		|| (sta_pattern[i] >= '0'  &&  sta_pattern[i] <= '9')
		|| (sta_pattern[i] == '_' )
	     )
	  ) {
134
135
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s has not valid STA format!\n",
		    NMXP_LOG_STR(pattern));
136
137
138
139
	    return -1;
	}
	i++;
    }
140
    }
141
142
143
    
    l = strlen(cha_pattern);
    if(l != 3) {
144
145
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s has not valid CHAN format!\n",
		NMXP_LOG_STR(pattern));
146
147
148
149
150
151
152
153
154
155
156
	return -1;
    }
    i = 0;
    while(i < l  &&  ret != -1) {
	if(  !(
		    (cha_pattern[i] >= 'A'  &&  cha_pattern[i] <= 'Z')
		    || (cha_pattern[i] >= 'a'  &&  cha_pattern[i] <= 'z')
		    || (cha_pattern[i] == '_' )
		    || (cha_pattern[i] == '?' )
	      )
	  ) {
157
158
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel pattern %s has not valid CHAN format!\n",
		    NMXP_LOG_STR(pattern));
159
160
161
162
163
	    return -1;
	}
	i++;
    }

164
    strcpy(sta_sdc, net_dot_station_dot_channel);
165
    if( (cha_sdc = strchr(sta_sdc, '.')) == NULL ) {
166
167
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel %s is not in STA.CHAN format!\n",
		NMXP_LOG_STR(net_dot_station_dot_channel));
168
169
170
171
172
173
174
	return -2;
    }
    if(cha_sdc) {
	*cha_sdc++ = '\0';
    }
    l = strlen(cha_sdc);
    if(l != 3) {
175
176
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Channel %s has not valid CHAN format!\n",
		NMXP_LOG_STR(pattern));
177
178
179
	return -1;
    }

180
181
182
    l = strlen(sta_pattern);
    if ( (strcasecmp(sta_sdc, sta_pattern) == 0) 
	    || ((l == 1) && sta_pattern[0] == '*')) {
183
184
185
186
187
188
189
190
191
192
193
194
195
196
	/* matching CHAN */
	ret = 1;
	i = 0;
	while(i < 3  &&  ret != 0) {
	    ret = ((cha_pattern[i] == '?')? 1 : (cha_pattern[i] == cha_sdc[i]));
	    i++;
	}
    }


    return ret;
}


Matteo Quintiliani's avatar
Matteo Quintiliani committed
197
int nmxp_chan_lookupKey(char* name, NMXP_CHAN_LIST *channelList)
198
{
199
200
    int chan_number = channelList->number;
    int i_chan = 0;
201

202
    for (i_chan = 0; i_chan < chan_number; i_chan++)
203
    {
204
205
	if (strcasecmp(name, channelList->channel[i_chan].name) == 0)
	    return channelList->channel[i_chan].key;
206
207
208
209
210
    }

    return -1;
}

211

212
int nmxp_chan_lookupKeyIndex(int32_t key, NMXP_CHAN_LIST_NET *channelList)
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
{
    int i_chan = 0;
    int ret = -1;

    i_chan = 0;
    while(i_chan < channelList->number  &&  ret == -1)
    {
	if ( key == channelList->channel[i_chan].key ) {
	    ret = i_chan;
	}
	i_chan++;
    }

    return ret;
}


230
char *nmxp_chan_lookupName(int32_t key, NMXP_CHAN_LIST_NET *channelList)
231
{
232
    int i_chan = 0;
233
    static char ret[12];
234

235
236
237
    ret[0] = 0;

    for (i_chan = 0; i_chan < channelList->number; i_chan++)
238
    {
239
	if ( key == channelList->channel[i_chan].key ) {
240
	    strcpy(ret, channelList->channel[i_chan].name);
241
	}
242
243
    }

244
245
246
247
248
    if(ret[0] == 0) {
	return NULL;
    } else {
	return ret;
    }
249
250
}

251

Matteo Quintiliani's avatar
Matteo Quintiliani committed
252
NMXP_CHAN_LIST *nmxp_chan_getType(NMXP_CHAN_LIST *channelList, NMXP_DATATYPE dataType) {
253
254
255
256
257
258
259
260
261
262
    NMXP_CHAN_LIST *ret_channelList = NULL;

    int chan_number = channelList->number;
    int i_chan = 0;

    ret_channelList = (NMXP_CHAN_LIST *) malloc(sizeof(NMXP_CHAN_LIST));
    ret_channelList->number = 0;

    for (i_chan = 0; i_chan < chan_number; i_chan++)
    {
263
	if ( getDataTypeFromKey(channelList->channel[i_chan].key) == dataType) {
264
265
266
267
268
269
270
271
272
	    ret_channelList->channel[ret_channelList->number].key = channelList->channel[i_chan].key;
	    strcpy(ret_channelList->channel[ret_channelList->number].name, channelList->channel[i_chan].name);
	    ret_channelList->number++;
	}
    }

    return ret_channelList;
}

273

274
275
NMXP_CHAN_LIST_NET *nmxp_chan_subset(NMXP_CHAN_LIST *channelList, NMXP_DATATYPE dataType, char *sta_chan_list, const char *network_code_default) {
    NMXP_CHAN_LIST_NET *ret_channelList = NULL;
276
    int istalist, ista;
277
278
    char sta_chan_code_pattern[100];
    int i_chan, ret_match;
279
280
281
    char network_code[20];
    char station_code[20];
    char channel_code[20];
282
283
284
285
    int i_chan_found = -1;
    int i_chan_duplicated = -1;
    char *nmxp_channel_name = NULL;
    char nmxp_channel_name_duplicated[50];
286

287
    ret_channelList = (NMXP_CHAN_LIST_NET *) malloc(sizeof(NMXP_CHAN_LIST_NET));
288
289
    ret_channelList->number = 0;

290
291
    istalist = 0;
    while(sta_chan_list[istalist] != sep_chan_list  &&  sta_chan_list[istalist] != 0) {
292
293
	
	/* Build sta_chan_code_pattern from sta_chan_list */
294
295
	ista = 0;
	while(sta_chan_list[istalist] != sep_chan_list  &&  sta_chan_list[istalist] != 0) {
296
	    sta_chan_code_pattern[ista++] = sta_chan_list[istalist++];
297
	}
298
	sta_chan_code_pattern[ista] = 0;
299
300
301
	if(sta_chan_list[istalist] == sep_chan_list) {
	    istalist++;
	}
302
303
304
305
306
307

	/* Match name to sta_chan_code_pattern and set i_chan_found */
	nmxp_channel_name = NULL;
	nmxp_channel_name_duplicated[0] = 0;
	i_chan_found = -1;
	i_chan_duplicated = -1;
308
309
	ret_match = 1;
	i_chan = 0;
310
	while(i_chan < channelList->number) {
311
	    ret_match = nmxp_chan_match(channelList->channel[i_chan].name, sta_chan_code_pattern);
312
	    if(ret_match == 1) {
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
		    if(getDataTypeFromKey(channelList->channel[i_chan].key) == dataType) {
			/* Check for channel duplication */
			nmxp_channel_name = nmxp_chan_lookupName(channelList->channel[i_chan].key, ret_channelList);
			if(nmxp_channel_name == NULL) {
			    /* Add channel */
			    i_chan_found = i_chan;
			    ret_channelList->channel[ret_channelList->number].key =        channelList->channel[i_chan_found].key;
			    strcpy(ret_channelList->channel[ret_channelList->number].name, channelList->channel[i_chan_found].name);
			    nmxp_chan_cpy_sta_chan(sta_chan_code_pattern, station_code, channel_code, network_code);
			    sprintf(ret_channelList->channel[ret_channelList->number].name, "%s.%s",
				    (network_code[0] != 0)? network_code : network_code_default, channelList->channel[i_chan_found].name);
			    nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "Added %s for %s.\n",
				    ret_channelList->channel[ret_channelList->number].name, sta_chan_code_pattern);
			    ret_channelList->number++;
			} else {
			    strncpy(nmxp_channel_name_duplicated, nmxp_channel_name, 50);
			    i_chan_duplicated = i_chan;
			}
331
332
333
		    }
	    }
	    i_chan++;
334
	}
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

	if(i_chan_duplicated != -1) {
	    /* Error message for duplication */
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Pattern %s duplicates channel %s. (%s, %d, Key %d).\n",
		    sta_chan_code_pattern,
		    channelList->channel[i_chan_duplicated].name,
		    NMXP_LOG_STR(nmxp_channel_name_duplicated),
		    i_chan_duplicated, channelList->channel[i_chan_duplicated].key);
	}

	if(i_chan_found == -1  &&  i_chan_duplicated == -1) {
	    /* Error message for channel not found of channel is not dataType */
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Pattern %s does not match to any key.\n",
		    sta_chan_code_pattern);
	}

351
    }
352
    
353
354
355
356
    return ret_channelList;
}


357
/* Comparison Key Function*/
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
int chan_key_compare(const void *a, const void *b)
{
    int ret = 0;
    NMXP_CHAN_KEY *pa = (NMXP_CHAN_KEY *) a; 
    NMXP_CHAN_KEY *pb = (NMXP_CHAN_KEY *) b;

    if(pa->key > pb->key) {
	ret = 1;
    } else if(pa->key < pb->key) {
	ret = -1;
    }
    return ret;
}

void nmxp_chan_sortByKey(NMXP_CHAN_LIST *channelList) {
    qsort (channelList->channel, channelList->number, sizeof (NMXP_CHAN_KEY), chan_key_compare);
}

376
/* Comparison Name Function*/
377
378
379
380
381
382
383
384
385
386
387
388
int chan_name_compare(const void *a, const void *b)
{
    NMXP_CHAN_KEY *pa = (NMXP_CHAN_KEY *) a; 
    NMXP_CHAN_KEY *pb = (NMXP_CHAN_KEY *) b;

    return strcmp(pa->name, pb->name);
}

void nmxp_chan_sortByName(NMXP_CHAN_LIST *channelList) {
    qsort (channelList->channel, channelList->number, sizeof (NMXP_CHAN_KEY), chan_name_compare);
}

389
390
391
392
393

void nmxp_chan_print_channelList(NMXP_CHAN_LIST *channelList) {
    int chan_number = channelList->number;
    int i_chan = 0;

394
    nmxp_log(NMXP_LOG_NORM_NO, NMXP_LOG_D_CHANNEL, "%04d channels:\n", chan_number);
395
396
397

    for (i_chan = 0; i_chan < chan_number; i_chan++)
    {
398
399
400
401
402
	nmxp_log(NMXP_LOG_NORM_NO, NMXP_LOG_D_ANY, "%04d %12d %6s%c%-11s\n",
		i_chan+1,
		channelList->channel[i_chan].key,
		"    ",
		' ',
403
		NMXP_LOG_STR(channelList->channel[i_chan].name));
404
405
406
407
408
    }

}

void nmxp_chan_print_netchannelList(NMXP_CHAN_LIST_NET *channelList) {
409
410
411
    int chan_number = channelList->number;
    int i_chan = 0;

412
    nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "%04d channels:\n", chan_number);
413
414
415

    for (i_chan = 0; i_chan < chan_number; i_chan++)
    {
416
417
418
	nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "%04d %12d %s\n",
		i_chan+1, channelList->channel[i_chan].key,
		NMXP_LOG_STR(channelList->channel[i_chan].name));
419
420
421
422
    }

}

Matteo Quintiliani's avatar
Matteo Quintiliani committed
423
424
425
426
427

void nmxp_meta_chan_free(NMXP_META_CHAN_LIST **chan_list) {
    NMXP_META_CHAN_LIST *iter = *chan_list;
    NMXP_META_CHAN_LIST *iter_next = NULL;

428
    nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_free()\n");
Matteo Quintiliani's avatar
Matteo Quintiliani committed
429
430
431
432
433
434
435
436
437
438
439
440
441

    if(iter) {
	iter_next = iter->next;
	while(iter) {
	    free(iter);
	    iter = iter_next;
	    iter_next = iter->next;
	}
	*chan_list = NULL;
    }

}

442
int nmxp_meta_chan_compare(NMXP_META_CHAN_LIST *item1, NMXP_META_CHAN_LIST *item2, NMXP_META_CHAN_LIST_SORT_TYPE sorttype) {
443
    int ret = 0;
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
    switch(sorttype) {
	case NMXP_META_SORT_KEY:
	    if(item1->key > item2->key) {
		ret = 1;
	    } else if(item1->key < item2->key) {
		ret = -1;
	    }
	    break;
	case NMXP_META_SORT_NAME:
	    ret = strcmp(item1->name, item2->name);
	    break;
	case NMXP_META_SORT_START_TIME:
	    if(item1->start_time > item2->start_time) {
		ret = 1;
	    } else if(item1->start_time < item2->start_time) {
		ret = -1;
	    }
	    break;
	case NMXP_META_SORT_END_TIME:
	    if(item1->end_time > item2->end_time) {
		ret = 1;
	    } else if(item1->end_time < item2->end_time) {
		ret = -1;
	    }
	    break;
	default:
470
	    nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL, "Sort type %d not defined!\n", sorttype);
471
	    break;
472
473
474
475
    }
    return ret;
}

476
NMXP_META_CHAN_LIST *nmxp_meta_chan_add(NMXP_META_CHAN_LIST **chan_list, int32_t key, char *name, int32_t start_time, int32_t end_time, char *network, NMXP_META_CHAN_LIST_SORT_TYPE sorttype) {
Matteo Quintiliani's avatar
Matteo Quintiliani committed
477
478
479
    NMXP_META_CHAN_LIST *iter = NULL;
    NMXP_META_CHAN_LIST *new_item = NULL;

480
    if(sorttype != NMXP_META_SORT_KEY  &&  sorttype != NMXP_META_SORT_NAME) {
481
482
	nmxp_log(NMXP_LOG_ERR, NMXP_LOG_D_CHANNEL,
		"nmxp_meta_chan_add() can only accept NMXP_META_SORT_KEY or NMXP_META_SORT_NAME. Fixed NMXP_META_SORT_KEY!\n");
483
484
	sorttype = NMXP_META_SORT_KEY;
    }
Matteo Quintiliani's avatar
Matteo Quintiliani committed
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506

    new_item = (NMXP_META_CHAN_LIST *) malloc(sizeof(NMXP_META_CHAN_LIST));
    new_item->key = 0;
    new_item->name[0] = 0;
    new_item->start_time = 0;
    new_item->end_time = 0;
    new_item->network[0] = 0;
    new_item->next = NULL;
    new_item->key = key;
    if(name) {
	strncpy(new_item->name, name, 12);
    }
    new_item->start_time = start_time;
    new_item->end_time = end_time;
    if(network) {
	strncpy(new_item->network, network, 12);
    }


    if(*chan_list == NULL) {
	*chan_list = new_item;
    } else {
507
	if(nmxp_meta_chan_compare(new_item, *chan_list, sorttype) < 0) {
Matteo Quintiliani's avatar
Matteo Quintiliani committed
508
509
510
	    new_item->next = *chan_list;
	    *chan_list = new_item;
	} else {
511
	    for(iter = *chan_list; iter->next != NULL  && nmxp_meta_chan_compare(new_item, iter->next, sorttype) > 0; iter = iter->next) {
Matteo Quintiliani's avatar
Matteo Quintiliani committed
512
513
514
515
516
517
518
519
520
521
522
523
524
	    }
	    new_item->next = iter->next;
	    iter->next = new_item;
	}
    }

    return new_item;
}

NMXP_META_CHAN_LIST *nmxp_meta_chan_search_key(NMXP_META_CHAN_LIST *chan_list, int32_t key) {
    NMXP_META_CHAN_LIST *iter = chan_list;
    int found = 0;

Matteo Quintiliani's avatar
Matteo Quintiliani committed
525
    /* nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_search_key()\n"); */
Matteo Quintiliani's avatar
Matteo Quintiliani committed
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540

    while(iter != NULL  &&  !found) {
	if(iter->key == key) {
	    found = 1;
	} else {
	    iter = iter->next;
	}
    }

    return iter;
}

NMXP_META_CHAN_LIST *nmxp_meta_chan_set_name(NMXP_META_CHAN_LIST *chan_list, int32_t key, char *name) {
    NMXP_META_CHAN_LIST *ret = NULL;

541
    nmxp_log(NMXP_LOG_NORM_NO, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_set_name()\n");
Matteo Quintiliani's avatar
Matteo Quintiliani committed
542
543
544
545
546
547
548
549
550
551
552

    if( (ret = nmxp_meta_chan_search_key(chan_list, key)) ) {
	strncpy(ret->name, name, 12);
    }

    return ret;
}

NMXP_META_CHAN_LIST *nmxp_meta_chan_set_times(NMXP_META_CHAN_LIST *chan_list, int32_t key, int32_t start_time, int32_t end_time) {
    NMXP_META_CHAN_LIST *ret = NULL;

Matteo Quintiliani's avatar
Matteo Quintiliani committed
553
    /* nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_set_times()\n"); */
Matteo Quintiliani's avatar
Matteo Quintiliani committed
554
555
556
557
558
559
560
561
562
563
564
565

    if( (ret = nmxp_meta_chan_search_key(chan_list, key)) ) {
	ret->start_time = start_time;
	ret->end_time = end_time;
    }

    return ret;
}

NMXP_META_CHAN_LIST *nmxp_meta_chan_set_network(NMXP_META_CHAN_LIST *chan_list, int32_t key, char *network) {
    NMXP_META_CHAN_LIST *ret = NULL;

566
    nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_set_network()\n");
Matteo Quintiliani's avatar
Matteo Quintiliani committed
567
568
569
570
571
572
573
574
575
576
577

    if( (ret = nmxp_meta_chan_search_key(chan_list, key)) ) {
	strncpy(ret->network, network, 12);
    }

    return ret;
}

void nmxp_meta_chan_print(NMXP_META_CHAN_LIST *chan_list) {
    NMXP_META_CHAN_LIST *iter = chan_list;
    char str_start_time[200], str_end_time[200];
Matteo Quintiliani's avatar
Matteo Quintiliani committed
578
579
    int i_chan = 0;

Matteo Quintiliani's avatar
Matteo Quintiliani committed
580
581
582
    str_start_time[0] = 0;
    str_end_time[0] = 0;

583
    nmxp_log(NMXP_LOG_NORM, NMXP_LOG_D_CHANNEL, "nmxp_meta_chan_print()\n");
Matteo Quintiliani's avatar
Matteo Quintiliani committed
584
585
586
587
588

    while(iter != NULL) {
	nmxp_data_to_str(str_start_time, iter->start_time);
	nmxp_data_to_str(str_end_time,   iter->end_time);

589
590
	nmxp_log(NMXP_LOG_NORM_NO, NMXP_LOG_D_ANY, "%04d %12d %6s%c%-11s (%s  -  %s)\n",
		i_chan+1,
Matteo Quintiliani's avatar
Matteo Quintiliani committed
591
		iter->key,
592
		NMXP_LOG_STR(iter->network),
593
		(strcmp(iter->network, "")==0)? ' ' : '.',
594
595
596
		NMXP_LOG_STR(iter->name),
		NMXP_LOG_STR(str_start_time),
		NMXP_LOG_STR(str_end_time)
Matteo Quintiliani's avatar
Matteo Quintiliani committed
597
598
		);
	iter = iter->next;
599
	i_chan++;
Matteo Quintiliani's avatar
Matteo Quintiliani committed
600
601
602
603
604
    }
}